This is the implementation of GeomBatch.setSolidColor():
public void setSolidColor(ColorRGBA color) {
if (colorBuf == null)
colorBuf = BufferUtils.createColorBuffer(vertQuantity);
colorBuf.rewind();
for (int x = 0, cLength = colorBuf.remaining(); x < cLength; x += 4) {
colorBuf.put(color.r);
colorBuf.put(color.g);
colorBuf.put(color.b);
colorBuf.put(color.a);
}
colorBuf.flip();
}
There are at least two things wrong with this.
First, colors that come in as byte-based RGBA (or BGRA) colors should not be turned into floats -- that takes up four times the memory! (And memory is speed).
Second, if the object has a solid color, then it is more efficient to just call glColor() than to bind an entire color buffer. Especially if you try to animate the color of the object using this function! The documentation says nothing about this.
Actually, on some ATI hardware, they don't support glColor(), and synthesize it in the driver, but on most hardware, glColor() is a lot faster than passing the data by an array.
Actually, looking at the code, it seems as if the arrays are being passed separately. There is a limit over which the graphics card fetch will start running slower (or the driver will re-pack the data) when you have more vertex streams. That limit used to be 1, but I think on NVIDIA it's up to 4 these days. Spending some effort to interlace the data, and/or at least support pre-interlaced data, would be useful from a performance point of view. Perhaps the lock functions do this? The documentation is silent on this subject...
Anyway, there you have it: some suggestions for the future, if you want to run faster with more complex geometry.