I'm working with an iPad OpenGL game. The game has plenty of small characters (32 x 32) with animations and alpha. They run really well until I add a background to the scene... then everything starts running really bad! Game speed falls dramatically when printing the background, which is a 768 x 1024 .jpg image without alpha. What can be happening? If I don't draw the background the game runs well, but when drawing it game speed falls down...
I'm using Cocos2D and I found the iPad to be much faster than the iPhone or the simulator.
How many calls to drawArrays and drawElements do you have? Each one has overhead. You may have to start batching some draws together (drawing all tiles at once, then drawing all monsters at once, etc) to keep your framerate up.
I have a single background (768 x 1024), a (128 x 128) image, and 10 (32 x 32) images. My game used to run at 60 fps, and it does in the menu where no game logic is processed. However, when it runs during gameplay the fps fall to 20 or 30 when I print the background (if I comment the background printing line fps are still 60)...
I don't know how can this be, it's a direct port from an iPhone app (in fact I've taken the iPhone app directory, copied it and start working with)... Maybe there's something that I must change before, a different OpenGL framework to import, or some settings that must be changed before working with iPad?
I've tried commenting the blending enabling / disabling for all printed images but nothing seems to happen... However, transparencies are still well-drawn, so I'm not sure if I'm really disabling blending...
Here is the function I use to print each image (both background and small images):
Hm, interesting... So you mean that if my game is running slow in the simulator (about x2 or x3 times slowly than it should run) it may run well on a real device, so actually there's no need to worry about it (the same game runs well on the iPhone, what I've just done is to make some images larger)?
That would be really great, because it is completely senseless for me... If I draw a 320 x 480 image (the same I used in the iPhone), so the rest of screen background rests black, fps run as they should do, but if I draw the entire 768 x 1024 image fps dramatically decreases, and I think there shouldn't be problem about this because I'm just printing a full-screen image, which most of the OpenGL games (in fact all of them) do it...
Here is the function I use to print each image (both background and small images):
(snip code)
Woah! That's not a fast way to render at all. You don't want to be pushing and popping and disable and enabling states like for every single render. Set up these things once, and then render all your images. You should try to minimise the number of state changes.
Quote:
PS: And no, I'm not in the real device yet, I'm testing in the simulator (but I think it should run even better in the simulator)...
Any speed measurements on the Simulator are completely meaningless. Don't worry about it until you get it running on an actual device. If you find you can't hit 60 consistently, you're better dropping to a steady 30 than having a variable frame rate.
__________________
Visit Mr Jack Games for my blog and more about my games
I've changed something in my code to stop enabling / disabling things each time a image is drawn and I've grouped those functions at the start and finish of the renderScene method, so now I have this:
Code:
-(void)renderScene
{
[EAGLContext setCurrentContext:context];
glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
glViewport(0, 0, backingWidth, backingHeight);
// Clear screen
glClear(GL_COLOR_BUFFER_BIT);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
// Enable Texture_2D
glEnable(GL_TEXTURE_2D);
// Assuming OpenGL is now initialized, here goes all draw methods...
(... draw backgrounds and all game elements here with the "renderAtPoint" method...)
glDisable(GL_TEXTURE_2D);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
[context presentRenderbuffer:GL_RENDERBUFFER_OES];
}
- (void)renderAt:(CGPoint)point texCoords:(GLfloat[])texCoords quadVertices:(GLfloat[])quadVertices{
glPushMatrix();
glTranslatef(point.x, point.y, 0.0f);
glRotatef(-rotation, 0.0f, 0.0f, 1.0f);
glScalef(scale, scale, 1.0f);
glColor4f(colourFilter[0], colourFilter[1], colourFilter[2], colourFilter[3]);
glBindTexture(GL_TEXTURE_2D, [texture name]);
glVertexPointer(2, GL_FLOAT, 0, quadVertices);
glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
// Only enable blending if the image have transparencies
if (!noTransparent) {
glEnable(GL_BLEND);
}
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
if (!noTransparent) {
glDisable(GL_BLEND);
}
glPopMatrix();
}
Is this what you're meaning? Sorry but I don't know much about OpenGl...
Maybe the "glPushMatrix" and the "glPopMatrix" shouldn't be called for each image?
Is this what you're meaning? Sorry but I don't know much about OpenGl...
Maybe the "glPushMatrix" and the "glPopMatrix" shouldn't be called for each image?
It's better but, personally, I'd be transforming your point arrays (I use a 'dirty' flag to recalculate only when needed) rather than altering glTransform, glRotate, etc. for each image.
__________________
Visit Mr Jack Games for my blog and more about my games
Thanks for your help, I'll take care of that by checking if it's really needed to call the gl function so no unneeded functions are called for each image.