views:

1384

answers:

7

I made a simple game for the iPhone using OpenGL ES. Everything works fine except for this problem:

I turn the phone completely off, then back on, then launch my app and I get this wierd flickering! Every other frame is correct... the incorrect frames are just the same frame over and over again. If I quit the app, launch it again everything is fine. If I quit and restart 10 times in a row everything is fine every time.

But if I turn the phone off, then back on, then launch the app I get the same flickering the first time I launch the app.

Why is this happening?!

Has anyone else had this problem?

Cheers!

+1  A: 

Hmm. I haven't done much with OpenGL on the iPhone, but I have to say I haven't noticed this behavior with other applications. I'd suspect it's something to do with how you're switching active framebuffers.

Maybe take a look at some of the sample code, and see what you're doing differently?

Mark Bessey
FWIW, I just experimented with my own OpenGL app on my iPhone, and I don't see any problems.
Kristopher Johnson
+1  A: 

I have the same problem. Notice that the problem occurs more often when the rendering fps is increased. In fact, I was able to reproduce the problem using the Crash Landing sample code by setting the renderingFPS to 200 and it took abt 20 tries. The flashing/flickering alternates between the current image (animated) and a fixed image which seems to be the previous frame buffer values.

Has anyone else encountered this? Any workarounds?

+1  A: 

Happens to me as well. Rearranging game update and rendering order, playing with NSTimer (I don't have it repeating now, starting every time again after rendering done), also I have glFlush/glFinish calls before swapping buffers (every update!) - so, after all this problem sill happens. Seems to be reduced, but not gone. Anybody knows how to fix it?

+1  A: 

Is it possible you are calling glRenderBuffer() and sending the presentRenderBuffer message to your EAGLContext without having done any OpenGL updates, that is, no new glDrawElements or glDrawArrays. If you do this without kEAGLDrawablePropertyRetainedBacking set to YES, then you can get an annoying flicker.

Take a look a the kEAGLDrawablePropertyRetainedBacking on your CAEAGLLayer's drawableProperties property. This property determines the behavior of the drawable surface after it has displayed its contents. If this property is set to NO, then the contents are not retained and therefore not guaranteed to remain unchanged after display. If you set it to YES, then the contents are retained and will remain unchanged after display.

I believe setting kEAGLDrawablePropertyRetainedBacking to YES will mask the issue, but not fix it.

Rob Jones
+1  A: 

I believe this issue has to do with a corruption in the vertex buffer that occurs when the iphone OS takes control of the application(lock and resume, or warning popup). I have this issue as well but have not found a suitable fix, it seems to be one or more objects in the scene. We use a texture atlas and none of the other objects that share the texture seem to be affected. Perhaps destroying and recreating your vertex buffers will fix the issue.

Medran
+1  A: 

I had the same problem with the flashing/flicker alternating between the current image and a fixed image... it would happen on a 3GS, but not a 3G, first gen, or the simulator.

In my case the problem was caused when I would set up the context in ESRenderer, but not actually draw anything, i.e. in the code below [scene draw] didn't draw anything in certain states. On the older iPhones and the Sim, when you don't draw anything, it didn't seem to flip the OpenGL buffers... but on the 3GS it does. Anyway, my workaround was to stop animation in those states (i.e. stop the timer that calls the draw rountine) when I was not drawing anything.

- (void) draw
{
   [EAGLContext setCurrentContext:context]; 
   glBindFramebufferOES(GL_FRAMEBUFFER_OES, defaultFramebuffer);
   glViewport(0, 0, backingWidth, backingHeight);

   //Render the GLScene...
   [scene draw];

   glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer);
   [context presentRenderbuffer:GL_RENDERBUFFER_OES];   
}
gulchrider
+2  A: 

Apple published additional information about this issue:

Q: My OpenGL ES application flickers. Especially when running on iPhone 3GS, the flickering seems to happen every frame. How do I fix this problem?

A: By default, the contents of a renderbuffer are invalidated after it is presented to the screen (by calling -EAGLContext/presentRenderbuffer:). Your application must completely redraw the contents of the renderbuffer every time you draw a frame, otherwise you may observe flickering or other unexpected results.

You must provide a color to every pixel on the screen. At the beginning of your drawing code, it is a good idea to use glClear() to initialize the color buffer. A full-screen clear of each of your color, depth, and stencil buffers (if you're using them) at the start of a frame can also generally improve your application's performance.

If your application needs to preserve the drawable contents between frames, you can add the option kEAGLDrawablePropertyRetainedBacking = YES to your CAEAGLLayer object's drawableProperties property. Using this option requires additional memory and can reduce your application's performance.

mOlind