Advice/Suggestions on how to improve speed

Started by
5 comments, last by OscarYang 12 years, 4 months ago
I'm making a 2D tile-based game with rigid body physics.

Regularly my engine runs at about 80-90 fps (on my desktop computer).
On my desktop computer I can render about 40,000 textured static tiles with ease at about 40 fps without culling.
With culling enabled the engine runs at around 70-80 fps.

On my acer laptop it seems that rendering even a few textured tiles greatly hurts the performance.

In my engine the maximum amount of static tiles that can be rendered in a frame is 40,000(without culling).
Rendering 40,000 static tiles on my laptop is painfully slow.
I only get about 20fps.

With culling enabled I can reduce the maximum amount to of static tiles rendered per frame to 192.
Even with culling enabled I still get around 35 fps if I render 192 tiles.
my ideal speed for the acer is around 50fps.

This is what happens when i render a single tile.

void Polygon::RenderPolygon(){
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,TextureRef);
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, 0.550f);
glBegin(GL_POLYGON);
glColor3f(0.9,0.9,0.9);
for(unsigned int K = 0; K < ParticleList.size();K++){
Vector2D & CP = ParticleList[K]->Position;
Vector2D & CTC = TextureChords[K];
glTexCoord2f(CTC.X,CTC.Y);
glVertex4f(CP.X,CP.Y,Depth,Intensity);
}
glEnd();
glDisable(GL_ALPHA_TEST);
glDisable(GL_TEXTURE_2D);
}

The code spacing is all messed up..hopefully this is good enough.

Basically every tile is a convex hull. The actual Render routine just iterates through a list of pointers of type Polygon and calls the RenderPolygon() method.

So what are my options?
How can improve performance?

I'm not really sure if more information is needed.
I'm pretty sure i've isolated the problem to just opengl but for some reason I can help but question my own judgment.
Advertisement
My suggestion would be to draw all the tiles at the same time, because I recall there being a significant overhead to glBegin and glEnd calls.

My suggestion would be to draw all the tiles at the same time, because I recall there being a significant overhead to glBegin and glEnd calls.


I reduced glBegin and glEnd calls by testing if the current texture and the next texture are the same.
I saw a significant speed boost on my desktop computer,however, the acer is still slow at around 35fps.

Its important that i have a bit of extra speed on the acer because physics is quite expensive.

Here's what the new function looks like:

void Render_Cell_Quads(std::vector<Polygon*> & StaticPolygons){
if(StaticPolygons.size() < 1){
return;
}

glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, 0.550f);
glEnable(GL_TEXTURE_2D);

unsigned int Q_I = 0;
Polygon * CP = StaticPolygons[0];
GLuint CurrentTexture = StaticPolygons[0]->TextureRef;
GLuint NextTexture = StaticPolygons[0]->TextureRef;

LOAD_NEW_TEXTURE:

glBindTexture(GL_TEXTURE_2D,NextTexture);
glBegin(GL_QUADS);
glColor3f(0.9,0.9,0.9);
for(Q_I = Q_I ;Q_I < StaticPolygons.size()-1;Q_I++ ){
CP = StaticPolygons[Q_I];
CurrentTexture = CP->TextureRef;
NextTexture = StaticPolygons[Q_I+1]->TextureRef;

for(unsigned int K = 0; K < CP->ParticleList.size(); K++){
Vector2D & CV = CP->ParticleList[K]->Position;
Vector2D & CTV = CP->TextureChords[K];
glTexCoord2f(CTV.X,CTV.Y);
glVertex4f(CV.X,CV.Y,CP->Depth,CP->Intensity);
}

if (NextTexture!=CurrentTexture){
goto LOAD_NEW_TEXTURE;
}
}
glEnd();
StaticPolygons[Q_I]->RenderPolygon();


glDisable(GL_ALPHA_TEST);
glDisable(GL_TEXTURE_2D);
}
Have you considered using Vertex Arrays or VBOs instead of immediate rendering?
Co-founder/Lead Programmer
Bonafide Software, L.L.C.
Fairmont, WV 26554 US

Have you considered using Vertex Arrays or VBOs instead of immediate rendering?


I havent considered Vertex Arrays or VBOs.
If I had to implement one i'd choose vertex arrays because VBOs require extensions.
Even vertex arrays would speed up rendering. I suggest looking into them. The only time I ever use immediate rendering is if I am developing a tool of some sort (such as a level editor) where rendering speed isn't necessarily top priority.
Co-founder/Lead Programmer
Bonafide Software, L.L.C.
Fairmont, WV 26554 US
Definitely use VBO as it is becoming a standard in OpenGL along with the use of GLSL. The argument is simple: Do you think your program will be fast if you are making say 1,000 function calls JUST to define vertices? Perhaps another 1,000 calls to define normals if you are using them. This may not be obvious, but function calls are expensive. Even though it is becoming less expensive with better CPUs, this is one place you can optimize. Also, using VBO enables you to use Graphic Card memory compared to only using Main Memory. It may seem subtle, but the difference is HUGE. The slowest part of ALL computer today, is the memory and perhaps the bandwidth. This is why we use techniques such as caching and as a result, we need to exploit locality, and parallelism. Thus, without any actual analysis, optimizing memory read/write will almost always give you good return in terms of performance.

VBO is perhaps the biggest performance issue unless you are making some silly mistakes such as non-aligned struct. Some small improvement would be perhaps inline functions, use macros, don't abuse inheritance...

I can't think of any other things right now.
Youtube:
My Channel

Video Lessons:
Java Programming Lessons

Tutorials Written (Not-Active):
Introduction to A.I.

This topic is closed to new replies.

Advertisement