Speeding Up My Game (My FPS is Crap)...

Started by
16 comments, last by GroZZleR 20 years, 4 months ago
It saddens me to see a 3D Engine run at 72 fps constant, and my little tiled game run at a super-sweet 30 fps =P I'm just wondering how I can improve my rendering time? I'm really doing nothing intensive, just drawing a bunch of quads in ortho-view. Right now all my entities have their own glBegin and glEnd, in their Render system. Something like this:

void Draw() {
     glLoadIdentity();
     glTranslatef((float)m_Origin.m_dX, (float)m_Origin.m_dY, 0.0f);
     glRotatef(m_dAngle, 0.0f,0.0f,1.0f);
     glBegin(GL_QUADS);	
          glVertex2d(-16, 16);
          glVertex2d( 16, 16);
          glVertex2d( 16,-16);
          glVertex2d(-16,-16);
     glEnd();
}
I'm sure theres a much better way to do this, so can anyone toss out some tips? I haven't included the texture co-ordinates for the sake of clarity. To draw, I just loop through all of the entities in my entities list and call their draw function. [edited by - GroZZleR on December 14, 2003 12:34:10 AM]
Advertisement
First, use a profiler and figure out where you''re spending your time.

Then, fix that place.

If you''re submitting a bunch of stuff that''s not actually within the field of view, then perhaps that''s slowing you down.

Also, lots of state changes may slow you down.
enum Bool { True, False, FileNotFound };
quote:Original post by GroZZleR
...Right now all my entities have their own glBegin and glEnd...


Though I''m not an OpenGL expert, your problem is right there.
I''m guessing that you bind a different texture for each quad that you draw, regardless of whether or not you already have the texture bound from the previous quad. You could probably gain a speedup by sorting your quads into groups that share the same texture, and then draw them all together, that way you aren''t incurring the penalty of a texture bind per quad. To take it a step further, you could build vertex arrays out of the quads that share textures, and then draw them with one glDrawElements() call.

----------------
Amusing quote deleted at request of owner
----------------Amusing quote deleted at request of owner
You''re mostly likely not getting any higher than 72fps because you have vertical sync on, and you''re locking to the refresh rate. Try turning it off and see if there''s any change.
---------------------Ryan Bujnowicz[ vangelis ]
The Anonymous Poster is right.


The real speed in OpenGL is rendering things in batches (ie. collections of tiles, rather than a single tile at a time).

Every time you call Draw() your function is performing transformations (in the glLoadIdentity() ... glRotatef() bit)

glBegin(GL_QUADS) and glEnd() also incur a lot of overhead.

A more practical and efficent way to do this is to batch them as follows

glLoadIdentity();
glTranslated(map.origin.m_dX, map.origin.m_dY, 0.0f);
glRotated(map.angle, 0.0f, 0.0f, 1.0f);

glBegin(GL_QUADS)
for (i = 0; i < NumTilesOnScreenInX; i++)
{
for (j = 0; j < NumTilesOnScreenInY; j++)
{
glVertex2d(i * 32, (j + 1) * 32);
glVertex2d((i + 1)* 16, (j + 1) * 32);
glVertex2d((i + 1) * 16, j * 32);
glVertex2d(i * 32 , j * 32);
}
}
glEnd();

Notice how, every single vertex is specified between the same glBegin() and glEnd() pair?

you could even remove the multiplications from inside your loop (by keeping running variables and adding 32 on each time too)

Of course, the above example iwll only really work for tiled systems. If you wanted free moving entities (like sprites that make up characters or explosiosn or something) then you will want to do pretty much what you''ve been doing before.

Also, are you clipping away tiles that don''t need to be rendered (ie. those that are outside your viewport). The reason I ask is that OpenGL actually does clip them, but it is still quicker to not even send them to OpenGL.

Hope that helped
do unto others... and then run like hell.
Hm... glBegin and glEnd aren''t *that* bad. You can easily call them a few thousand times per frame and stay at vsync rate even on a GF2MX. Just how many of these things are you drawing?

A few points:
- do you really need double precision? doubles can be very slow.
- if your entities can only move and rotate in 2d it''ll be faster to calculate the vertex coords by yourself with trig than use glRotate/glTranslate.
- how often do you bind textures? If you have a ton of projectiles etc using the same texture, you shouldn''t bind the texture when you draw each one.
glBegin/glEnd aint that bad, true, but submitting each vertex one at the time is horribly slow, thats why batching is used with Vertex Arrays etc to speed it up
Is it necessary to have one big vertex array? Or is it efficient enough to change between individual vertex array for each entity?
Hmm, I am all for getting the "most" for your c(g)pu, but if you get 72 FPS why do you care? That''s fast enough, getting higher than 72FPS is just optimizing for the sake of optimizing... now if 72 FPs is all you get and you have a top end card, then yeah I guess some changes are in order
super genius

This topic is closed to new replies.

Advertisement