Question

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!

Was it helpful?

Solution

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.

OTHER TIPS

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?

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.

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.

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];   
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top