views:

670

answers:

5

Hello,

Me and my friend are trying to accelerate a 2D game with OpenGL. The video chipset is Radeon X1250 which seems to be underpowered and can display up to some 80 1366x768 full frames/s. Given that we are drawing many sprites on top of each other the performace drops dramatically under the 60 FPS we are targeting at. Could you please provide optimization tips for rendering fast 2D with OpenGL?

EDIT: some clarifications: Development takes place in C++ under Linux. We did it with SDL but the performance was unsatisfactory so we decided to switch to OpenGL which proved much faster, Of course then there was a push to implement more features requiring us to redraw entire screen every frame.

Our test program renders textured 256x256 quad tiles across the 1366x768 screen. If a single layer of tiles is laid before buffer swap it yields 80 FPS, if two layers are laid framerate drops below 60 FPS. Given that the board will be required to decode and render some small MPEGs at the same time this might be unsatisfactory.

I just thought that I could look for optimizations resulting from the fact that the game is 2D - I thought of, for example: 1) if this is possible to disable texture scaling. 2) render directly to frame buffer (though we've heard that glDrawPixels is supposed to be slow.

+2  A: 

Are you sure rendering is an issue, or do you have logic tied into rendering? Performance optimization in OpenGL is a pretty big topic, so I'll just point you to a resource.

First link on google

Stefan Kendall
+2  A: 

OpenGL is designed to be fast, but it is possible to write it so it can have poor performance.

There are too many unknowns to be able to help much. For example, which language (I would guess C++), which framework are you using, or did you write your own?

How much of the screen are you recreating? For example, do you regenerate every object rather than just translating them?

You may find question useful: http://stackoverflow.com/questions/166356/what-are-some-best-practices-for-opengl-coding-esp-w-r-t-object-orientation

If you could provide some examples of where you have profiled, to determine where the slowdown is, that would be helpful.

If you just used a wireframe, no fill or texture, how is your performance?

What does your game loop look like? For example, is there any interaction with a mouse or keyboard, and does that logic impact the framerate?

I had that problem at one point where I was redrawing 70fps but my music wasn't starting or ending on the correct millisecond, so, I change the loop to only do 30fps and increase how often I am processing the music, and my performance increased.

James Black
+2  A: 

One optimisation would to be to draw your layers front to back (though this does assume no transparency) with Z-Buffering enabled and take advantage or the Early Z feature.

But the other comments are correct. Its impossible to say how you can get speed ups with so little information ...

Goz
+2  A: 

As always, if you have specified the version of OpenGL you target, it would be easier to come up with a more precise answer. Seems that this is something which is missing from most OpenGL-related questions on StackOverflow.

If you upload a lot of per-vertex data to the server, make sure you store the vertex data in buffer objects. Never use immediate mode, aka glBegin/glEnd pairs. Instead use glDrawArrays, glDrawElements or another array draw call. This already makes for an immense performance boost.

Overdrawing isn't slow in itself, but it sure burns fillrate for no reason. But occlusion culling is often not worth the initial performance setup cost. And per-fragment blending burns a lot of fillrate.

If these tips don't help, I recommend you check if your application is really GPU-bound. I have my doubts. The bottleneck could be somewhere else. Perhaps your X visual/FBConfig isn't hardware accelerated?

Mads Elvheim
+2  A: 

Sounds like you're up against the maximum fill rate of the card, coupled with the fact that you're doing blending so reads as well as writes are required.

If you overdraw enough of the frame buffer (particularly at high res), then you're going to drop the frame rate eventually, because of limitations in the fill rate of the card.

Although modern cards can do a lot of operations, they still have a limit to how many pixels they can push.

To reduce this some suggestions are:

  • Don't draw everything every frame - if possible - render some parts to other buffers, then blend those over - at a lower resolution if possible
  • Don't use blending if you don't have to - blending is much slower than drawing opaque stuff
  • Use a cheaper fragment shader / fragment program - if you're using a programmable pipeline (NB: I don't know how you can really tell how expensive it is)
  • Use as much culling as you can - avoid drawing things which can't be seen at all. If a sprite is entirely (or mostly) hidden behind others, you don't need to draw it.
  • Scaling / interpolation is probably relatively cheap - use lower res textures and scale them - particularly if your textures are "blurry" to begin with.

If you're doing this to get some funky smoke / particle effect, you probably can't use all or many of these optimisations.

MarkR