LWJGL rendering optimizations

Started by lemmy101, September 26, 2011, 16:50:22

Previous topic - Next topic

lemmy101

Hey all, I'm working on Project Zomboid and am trying to optimize the rendering a bit. Thing is now, with all the optimizations I've done, profilers show that the majority of time is spent inside nglTexCoord2f but I can't really think of any way I can optimize this further. We have texture pages to cut down on the amount of binds necessary, and those the majority of time is spent changing the UV coords between texture draws (and to a lesser extent, vertex colors, since the tiles are lit x-com style based on visibility / light levels)

Problem is it'd be nice to use VBOs or similar to batch drawing (at the moment I'm just outputting via GL_QUADS) but due to the isometric viewpoint and therefore a strict draw order of the tiles, I'm having to draw moveable characters at indeterminate places during drawing the tiles of the map, not to mention altering the color settings as the character move / time of day changes, so having a static unmodifiable vertex list will not (as far as I can see) be possible.

I toyed with using the depth buffer to allow the tiles to be drawn in a less strict order, however this causes major unresolvable transparency issues so is not really an option.

Just wondered if anyone had any clever general optimizations that could be made, without shaders and preferably without increasing from GL12 since we're trying to cater for low spec machines as possible. (That said, it would be interesting to know how high OpenGL I could go without risking cutting off lower end cards) I wondered if something would be possible by having more textures bound and switching between them or something, but I have to confess I'm no expert at rendering stuff.

Thank you!

Chris

avm1979

Have you looked at vertex arrays?

The idea is that instead of making many glVertex/glColor/glTexCoord calls that send data to the video card, you instead put the data into buffers and send it in batches. If you can get the batches to be of a decent size it'll be significantly faster than immediate mode (which is what you're using now).

You wouldn't see much improvement from batching up the vertices of a single quad, for example, but a bit more than that and it'll make a big difference. The bigger that batch size, the better. From what you're saying, it sounds like you could batch up everything that's using the same texture, and since you're using atlases, that should be a lot.


And yes, you'll be sending extra color data - for each vertex, instead of setting it once when the color changes - but it's worth it. You could also call glColor prior to drawing the vertex array and not enable the GL_COLOR_ARRAY client state. Depends on how often the color changes - if you can get large batches with the same color value, the second approach could be better.