当我第一次打开手机时,为什么我的OpenGL ES iPhone游戏会闪烁?

时间:2008-10-16 20:42:43

标签: iphone opengl-es

我使用OpenGL ES为iPhone做了一个简单的游戏。除了这个问题,一切正常:

我完全关闭手机,然后重新打开,然后启动我的应用程序,我得到了这个奇怪的闪烁!每隔一帧都是正确的...不正确的帧一遍又一遍地是同一帧。如果我退出应用程序,再次启动它一切都很好。如果我连续10次退出并重新启动,那么每次都很好。

但是,如果我关闭手机,然后重新启动,那么启动应用程序时,我第一次启动应用程序时会出现相同的闪烁。

为什么会发生这种情况?!

还有其他人有这个问题吗?

干杯!

5 个答案:

答案 0 :(得分:3)

Apple发布了有关此问题的其他信息:

  

问:我的OpenGL ES应用程序闪烁。   特别是在iPhone 3GS上运行时,   闪烁似乎每次都发生   帧。我该如何解决这个问题?

     

答:默认情况下,a的内容   renderbuffer在它之后失效   显示在屏幕上(通过调用   -EAGLContext / presentRenderbuffer :)。您的申请必须完全   重绘内容   每次画一个渲染缓冲区   框架,否则你可能会观察到   闪烁或其他意外   结果

     

你必须为每个人提供一种颜色   屏幕上的像素。一开始   你的绘图代码,这是一个很好的   想要使用glClear()进行初始化   颜色缓冲区。全屏清晰   每种颜色,深度和   模板缓冲区(如果您正在使用它们)   在帧的开头也可以   通常会改善您的应用程序   性能

     

如果您的应用需要保留   帧之间的可绘制内容,   你可以添加选项   kEAGLDrawablePropertyRetainedBacking =   您的CAEAGLLayer对象是   drawableProperties属性。运用   此选项需要额外的内存   并可以减少您的应用程序   性能

答案 1 :(得分:1)

嗯。我没有在iPhone上使用OpenGL做太多,但我不得不说我没有注意到其他应用程序的这种行为。我怀疑它与你如何切换活动帧缓冲区有关。

也许看看一些示例代码,看看你的做法有何不同?

答案 2 :(得分:1)

你是否有可能在没有做任何OpenGL更新的情况下调用glRenderBuffer()并将presentRenderBuffer消息发送到你的EAGLContext,也就是说,没有新的glDrawElements或glDrawArrays。如果在没有将kEAGLDrawablePropertyRetainedBacking设置为YES的情况下执行此操作,则可能会出现恼人的闪烁。

查看CAEAGLLayer的drawableProperties属性中的kEAGLDrawablePropertyRetainedBacking。此属性确定可绘制曲面显示其内容后的行为。如果此属性设置为NO,则不保留内容,因此不保证在显示后保持不变。如果将其设置为YES,则内容将保留,并在显示后保持不变。

我认为将kEAGLDrawablePropertyRetainedBacking设置为YES会掩盖问题,但不会修复它。

答案 3 :(得分:1)

我认为这个问题与iphone操作系统控制应用程序(锁定和恢复,或警告弹出窗口)时发生的顶点缓冲区中的损坏有关。我也有这个问题但是没有找到合适的修复,它似乎是场景中的一个或多个对象。我们使用纹理图集,并且共享纹理的其他对象似乎都没有受到影响。也许破坏和重新创建顶点缓冲区将解决问题。

答案 4 :(得分:1)

我在当前图像和固定图像之间交替闪烁/闪烁时遇到了同样的问题......它会发生在3GS上,而不是3G,第一代或模拟器。

在我的情况下,问题是在我在ESRenderer中设置上下文时引起的,但实际上没有绘制任何内容,即在下面的代码中[场景绘制]在某些状态下没有绘制任何内容。在较旧的iPhone和Sim上,当你没有绘制任何东西时,它似乎没有翻转OpenGL缓冲区......但是在3GS上它确实如此。无论如何,我的解决方法是在我没有绘制任何东西时停止那些状态下的动画(即停止调用绘图rountine的计时器)。

- (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];   
}