我使用 OpenGL ES 为 iPhone 制作了一个简单的游戏。除此问题外,一切正常:
我完全关闭手机,然后重新打开,然后启动我的应用程序,我得到了这个奇怪的闪烁!每隔一帧都是正确的……不正确的帧只是一遍又一遍的同一帧。如果我退出应用程序,再次启动它一切都很好。如果我连续退出并重新启动 10 次,那么每次都很好。
但是,如果我关闭手机,然后重新打开,然后启动应用程序,我会在第一次启动应用程序时得到同样的闪烁。
为什么会这样?!
有没有其他人有这个问题?
干杯!
Apple 发布了有关此问题的其他信息:
问:我的 OpenGL ES 应用程序闪烁。尤其是在 iPhone 3GS 上运行时,闪烁似乎每帧都会发生。我该如何解决这个问题?
答:默认情况下,渲染缓冲区的内容在呈现到屏幕后会失效(通过调用 -EAGLContext/presentRenderbuffer:)。您的应用程序必须在每次绘制帧时完全重绘渲染缓冲区的内容,否则您可能会观察到闪烁或其他意外结果。
您必须为屏幕上的每个像素提供一种颜色。在绘图代码的开头,最好使用 glClear() 来初始化颜色缓冲区。在帧开始时全屏清除每个颜色、深度和模板缓冲区(如果您正在使用它们)通常也可以提高应用程序的性能。
如果您的应用程序需要在帧之间保留可绘制内容,您可以将选项 kEAGLDrawablePropertyRetainedBacking = YES 添加到 CAEAGLLayer 对象的 drawableProperties 属性中。使用此选项需要额外的内存,并且会降低应用程序的性能。
唔。我对 iPhone 上的 OpenGL 做的不多,但我不得不说我没有注意到其他应用程序的这种行为。我怀疑这与您切换活动帧缓冲区的方式有关。
也许看看一些示例代码,看看你在做什么不同?
您是否有可能在没有进行任何 OpenGL 更新的情况下调用 glRenderBuffer() 并将 presentRenderBuffer 消息发送到您的 EAGLContext,即没有新的 glDrawElements 或 glDrawArrays。如果您在没有将 kEAGLDrawablePropertyRetainedBacking 设置为 YES 的情况下执行此操作,则可能会出现烦人的闪烁。
查看 CAEAGLLayer 的 drawableProperties 属性上的 kEAGLDrawablePropertyRetainedBacking。此属性确定可绘制表面在显示其内容后的行为。如果此属性设置为 NO,则不保留内容,因此不保证显示后保持不变。如果设置为YES,则内容保留,显示后保持不变。
我相信将 kEAGLDrawablePropertyRetainedBacking 设置为 YES 会掩盖问题,但不能解决问题。
我相信这个问题与 iphone OS 控制应用程序(锁定和恢复,或警告弹出)时发生的顶点缓冲区损坏有关。我也有这个问题,但没有找到合适的解决方法,它似乎是场景中的一个或多个对象。我们使用纹理图集,共享纹理的其他对象似乎都没有受到影响。也许销毁和重新创建您的顶点缓冲区将解决这个问题。
我在当前图像和固定图像之间交替闪烁/闪烁时遇到了同样的问题……它会发生在 3GS 上,但不会发生在 3G、第一代或模拟器上。
在我的情况下,问题是当我在 ESRenderer 中设置上下文时引起的,但实际上没有绘制任何东西,即在下面的代码中 [场景绘制] 在某些状态下没有绘制任何东西。在较旧的 iPhone 和 Sim 上,当您不绘制任何东西时,它似乎不会翻转 OpenGL 缓冲区……但在 3GS 上却可以。无论如何,我的解决方法是在我不绘制任何东西时停止那些状态下的动画(即停止调用绘制程序的计时器)。
- (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];
}