4

这就是发生的事情:

  • usleep正如建议的那样,由于 a , drawGL 函数在帧的确切结束处被调用。这已经保持了稳定的帧速率。

  • 渲染缓冲区的实际呈现发生在drawGL(). 测量执行此操作所需的时间会给我带来波动的执行时间,从而导致我的动画卡顿。这个计时器使用 mach_absolute_time 所以它非常准确

  • 在我的框架结束时,我测量timeDifference. 是的,平均为 1 毫秒,但偏差很大,从 0.8 毫秒到 1.2 毫秒不等,峰值高达 2 毫秒以上。

例子:

// Every something of a second I call tick
-(void)tick
{
  drawGL(); 
}

- (void)drawGL
{   
  // startTime using mach_absolute_time;

  glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer); 
  [context presentRenderbuffer:GL_RENDERBUFFER_OES];

 // endTime using mach_absolute_time;
 // timeDifference = endTime - startTime;
}

我的理解是,一旦创建了帧缓冲区,无论帧的复杂性如何,呈现渲染缓冲区都应该始终付出同样的努力?这是真的?如果没有,我该如何防止这种情况?

顺便说一下,这是一个 iPhone 应用程序的示例。所以我们在这里讨论的是 OpenGL ES,尽管我不认为这是一个特定于平台的问题。如果是,那是怎么回事?这不应该不会发生吗?再说一次,如果是这样,我怎样才能防止这种情况发生?

4

5 回答 5

1

您遇到的偏差可能是由很多因素引起的,包括操作系统调度程序启动并将 cpu 提供给另一个进程或类似问题。事实上,普通人不会区分 1 到 2 毫秒的渲染时间。电影以 25 fps 的速度运行,这意味着每帧显示大约 40 毫秒,并且对于人眼来说看起来很流畅。

至于动画口吃,您应该检查如何保持恒定的动画速度。我见过的最常见的方法大致是这样的:

while(loop)
{
  lastFrameTime; // time it took for last frame to render
  timeSinceLastUpdate+= lastFrameTime;

  if(timeSinceLastUpdate > (1 second / DESIRED_UPDATES_PER_SECOND))
  {
     updateAnimation(timeSinceLastUpdate);
     timeSinceLastUpdate = 0;
  }

  // do the drawing

  presentScene();
}

或者您可以将 lastFrameTime 传递给每帧的 updateAnimation 并在动画状态之间进行插值。结果将更加流畅。

如果你已经在使用类似上面的东西,也许你应该在渲染循环的其他部分寻找罪魁祸首。在 Direct3D 中,代价高昂的事情是调用图元和更改渲染状态,因此您可能想检查一下 OpenGL 的类似物。

于 2009-03-24T13:58:23.407 回答
1

我一直以来最喜欢的 OpenGL 表达方式:“特定于实现”。我认为它在这里非常适用。

于 2009-03-26T10:59:17.270 回答
1

A quick search for mach_absolute_time results in this article: Link

Looks like precision of that timer on an iPhone is only 166.67 ns (and maybe worse). While that may explain the large difference, it doesn't explain that there is a difference at all.

The three main reasons are probably:

  • Different execution paths during renderbuffer presentation. A lot can happen in 1ms and just because you call the same functions with the same parameters doesn't mean the exact same instructions are executed. This is especially true if other hardware is involved.
  • Interrupts/other processes, there is always something else going on that distracts the CPU. As far as I know the iPhone OS is not a real-time OS and so there's no guarantee that any operation will complete within a certain time limit (and even a real-time OS will have time variations).
  • If there are any other OpenGL calls still being processed by the GPU that might delay presentRenderbuffer. That's the easiest to test, just call glFinish() before getting the start time.
于 2009-03-28T16:26:34.800 回答
0

出于多种原因,最好不要依赖高恒定帧速率,最重要的是操作系统可能会在后台执行一些减慢速度的操作。最好对计时器进行采样并计算出每帧经过了多少时间,这应该可以确保动画流畅。

于 2009-03-24T22:05:02.957 回答
0

即使返回小数点 0.8->2.0,计时器是否可能不准确到亚毫秒级别?

于 2009-03-25T21:01:39.170 回答