views:

9382

answers:

7

I'm developing a 2D game for the iPhone using OpenGL ES and I'd like to use a 320x480 bitmapped image as a persistent background.

My first thought was to create a 320x480 quad and then map a texture onto it that represents the background. So... I created a 512x512 texture with a 320x480 image on it. Then I mapped that to the 320x480 quad.

I draw this background every frame and then draw animated sprites on top of it. This works fine except that the drawing of all of these objects (background + sprites) is too slow.

I did some testing and discovered that my slowdown is in the pixel pipeline. Not surprisingly, the large background image is the main culprit. To prove this, I removed the background draw and everything else rendered very fast.

I am looking for advice on how to keep my background and also improve performance.

Here's some more info:

1) I am currently testing on the Simulator (still waiting on Apple for the license)

2) The background is a PVR texture squeezed down to 128k

3) I had hoped that there might be a way to cache this background into a color buffer but haven't had any luck with that. that may be due to my inexperience with OpenGL ES or it just might be a stupid idea that won't work :)

4) I realize that the entire background does not always have to refresh, just the parts that have been drawn over by the moving sprites. I started to look into techniques for refreshing (as necessary) parts of the the background either as separate textures or with a scissor box, however this seems less than elegant.

Any tips/advice would be greatly appreciated...

Thank you.

+1  A: 

I dont have much experience with OpenGL ES, but this problem occurs generally.

Your idea about the 'color buffer' is good intuition, essentially you want to be storing your background as a frame buffer and loading it directly onto your rendering buffer before drawing the foreground.

In OpenGL this is fairly straight forward with Frame Buffer Objects (FBO's). Unfortunatly I dont think OpenGL ES supports them, but it might give you somewhere to start looking.

Akusete
It's strange... it seems like the framebuffer object extension is supported in OpenGL ES 1.0 but I can't get confirmation that the extension is available on the iphone. I guess I'll just test it out and post my findings. thanks.
Whoops, to clarify... The framebuffer extension is supported. What I need to test is the creation of a second Framebuffer that I will then attach a texture to.
A: 

you may want to try using VBOs (Vertex Buffer Objects) and see if that speeds up things. Tutorial is here

In addition, I just saw, that since OpenGL ES v1.1, there is a function called glDrawTex (Draw Texture) that is designed for

fast rendering of background paintings, bitmapped font glyphs, and 2D framing elements in games

Sebastian
I'm actually using vbos already. The bottleneck that I'm experiencing is in the pixel pipeline. I was able to prove this by eliminating all of the textures and rendering only wireframes. The application runs very fast in this configuration. Thanks...
+4  A: 

If you're making a 2D game, is there any reason you aren't using an existing library? Specifically, the cocos2d for iPhone may be worth your time. I can't answer your question about how to fix the issue doing it all yourself, but I can say that I've done exactly what you're talking about (having one full screen background with sprites on top) with cocos2d and it works great. (Assuming 60 fps is fast enough for you.) You may have your reasons for doing it yourself, but if you can, I would highly suggest at least doing a quick prototype with cocos2d and seeing if that doesn't help you along. (Details and source for the iPhone version are here: http://code.google.com/p/cocos2d-iphone/)

Adam Byram
Cocos is awesome.
Genericrich
I prefer to build from scratch just to have that extra degree of control. That said;I'll definitely check out cocoas2d. One of the issues is that, in addition to the background, I have 10+ large sprites that appear onscreen simultaneously. Have you done anything like this with cocoas2d? Thanks
+5  A: 
Andreas
I'm running only on the simulator because that's all I have right now ;) Still waiting on apple. Also, I'm not clearing the framebuffer, have effects turned off, and tried the 2bit texture (looks bad). as you suggest I may have to go with effects as background. I see that in a lot of games. thanks.
A: 
  1. You could use frame buffer objects similar to the GLPaint example from Apple.
  2. Use a texture atlas to minimize the number of draw calls you make. You can use glTexCoordPointer for setting your texture coordinates that maps each image to its correct position. Remember to set your vertex buffer too. Ideally one draw call will render your entire 2D scene.
  3. Avoid enabling/disabling states where possible.
Dimitris
+3  A: 

Thanks to everyone who provided info on this. All of the advice helped out in one way or another.

However, I wanted to make it clear that the main issue here turned out to be the behavior of simulator itself (as implied by Andreas in his response). Once I was able to get the application on the device, it performed much, much better. I mention this because, prior to developing my game, I had seen a lot of posts that indicated that the device was much slower than the simulator. This might be true in some instances (e.g. general application logic) but in my experience, animation (particularly 3d transformations) are much faster on the device.

A: 

Sorry, I not found the glDrawText, where can I find? Have you some example?

Thanks!