在OpenGL ES中打嗝。什么是正确的实施?

时间:2009-05-07 13:46:06

标签: iphone optimization opengl-es

我正在使用OpenGL ES在iPhone上制作游戏。 不幸的是,我看到小的(和不规则的)打嗝。

我使用带睡眠的计时器,每隔60秒调用一次绘图功能,以保证稳定的帧速率。我试图改变我的计时器从睡眠中唤醒的时刻,给予绘制功能更多的时间来执行。一旦绘制函数被赋予更多时间,打嗝确实会减少。在8毫秒的时间内,动画几乎是流畅的。我的发现是:

  1. 显然让GPU有更多时间来执行实际绘图,从而产生(几乎)完美的流体动画。
  2. 在我的框架的确切结束处绘制导致口吃,打嗝和什么不是。
  3. 现在我知道了,我不确定如何继续。关于这种行为的原因我有两个矛盾的想法:

    1. 首先,可能是OpenGL命令干扰了前一帧的绘制吗?据我所知,由于命令是存储的,因此不会出现这种情况,只会在执行时执行给出了draw命令。
    2. 其次,绘制命令的波动时间是否会导致计时器跳过勾号?
    3. 那么哪种解释更有可能?或者不是?当然我可以尝试将绘图功能放在一个单独的线程中,看看是否能解决我的问题。但我希望能够更多地了解OpenGL。

      这是被调用的函数,并解释了我正在采取的措施:

      - (void) drawView
      {
          // measure time with mach_absolute_time
      
          // gameEngine update    
          // OpenGL commands (translate, rotate, drawArrays etc.) 
      
          // end measure time with mach_absolute_time
          // usleep(animationInterval - duration  - constant) 
          // constant is the time to start executing
      
          // draw
          glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
          [context presentRenderbuffer:GL_RENDERBUFFER_OES];    
      }
      

1 个答案:

答案 0 :(得分:1)

您可能需要阅读此article about game loops,这解释了很多。通常,最好的解决方案是在单独线程内的无限循环中调用draw例程(请参阅this question),并根据自上次更新以来经过的时间更新基础游戏模型。这将为您提供平稳的动作。

编辑:至于“打嗝”的来源,它们可能与OpenGL无关。在60帧/秒时,我们说的是每帧1/60秒≈17毫秒。这是一个很容易错过的紧凑计划,因为设备上还运行着其他进程。 Safari或Mail.app在后台唤醒,设备会考虑一段时间,现在你的帧需要30毫秒甚至更多。如果您的模型期望完全稳定的帧速率,则很容易发现。解决方案是根据实际经过的时间更新模型,如上所述。链接的文章彻底解释了这一点。