PDA

View Full Version : Drawing my quads faster?



nhartung
06-16-2010, 10:45 AM
I'm currently working on a 2D tiling map editor. The map is made up of several floors which are made of several layers which are made up of several tiles. I have just finished writing the code to draw my map and I noticed that the program was running very slowly. The window would take a second to react when i tried to move it and when I resize the window it takes awhile for my reshape function to redraw everything properly. I went back and looked at my code and realized that even my basic example map with a size of 100x100 tiles was actually very large considering it was drawing all of the floors and layers for each floor on every iteration. My first run was actually drawing around 1 million quads every iteration. So I decided to tone down the amount of floors and layers in my map but it was still running slowly. I just got done implementing it with vertex arrays because I thought that it may increase the speed which it didn't. My question is there anyway to speed up the way I draw my quads? Or do I just need to find a way to not redraw so many? Here is the code im currently using to draw my map. This is the lowest level of abstration so this code just draws a single tile but this is the code that it being looped through for each tile.



void tile::draw(unsigned int tileset[])
{
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);

glBindTexture(GL_TEXTURE_2D, tileset[textureID]);
glPushMatrix();
glTranslatef(xPos, yPos, 0);

glTexCoordPointer(2, GL_FLOAT, 0, Colors);
glVertexPointer(2, GL_FLOAT, 0, Vertices);

glDrawArrays(GL_QUADS, 0, 4);

glPopMatrix();

glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
}

carsten neumann
06-16-2010, 03:29 PM
What is likely killing performance here is that you go through a state change for each quad (you change textures) and that you only issue one quad at a time.

Group your tiles by texture and issue all quads with the same texture with one glDrawArrays() call.

If you have a large number of textures, copy multiple(/all?) of them into one big texture and adjust the texture coordinates accordingly then issue just one glDrawArrays() call for all quads.

mhagain
06-16-2010, 03:43 PM
Move your glEnableClientState and glDisableClientState calls outside the loop. Don't use matrix transforms to position your quads, instead manually add the x and y positions to the vertexes before submitting them to render (subtract them after if you need to). As you seem to be using an orthographic projection with non-repeating textures, consider building a texture atlas and start batching things up. Check in software to see which floors are fully occluded and don't bother even rendering them.

That should get you running well.

nhartung
06-16-2010, 07:31 PM
I was thinking about this at work today and I figured I should try to find a way to see which tiles are actually in view of the user and only display those, as mhagain suggested. If I manually add the x and y positions to the vertexes would it still make sense to use a vertex array or should I just manually draw them? How much time, if any, does a vertex array really save me here? And I love the idea of a texture atlas, it would mean writing a little more logic but if it helps my program speed it will definitely be worth it.

mhagain
06-17-2010, 01:30 AM
You should probably still use a vertex array anyway as it will ultimately allow you to batch them better. It might be worth trying some glBegin/glEnd code to simplify your setup during the transition however.