2012-03-26 103 views
4

我的应用程序可以快速渲染(通常每帧1-6毫秒),双缓冲和同步到vblank启用。在我的主循环中,我想睡10毫秒左右,然后读取一些实时输入并尽可能晚地进行渲染,同时仍然在截止日期之前更新帧(对于实时60 FPS渲染,延迟时间最短)。寻找OpenGL的垂直回扫时间

我可以交换缓冲区但不幸的是在某些系统上使用后glfinish在(Linux的非合成,至少)这似乎等不只有等到下一个缓冲交换,但直到图像已经发出了HDMI端口(总等待25毫秒的范围,应用程序以30 FPS运行)。在其他系统上(Linux复合),这种方法工作正常。没有glFinish更多的工作被缓冲,造成更长的延迟,所以这也不好。

我对更精确的帧定时有什么选择?主要平台为Windows,Linux和OS X.

+1

对启用了垂直同步的帧进行定时是没有意义的。 – Thomas 2012-03-26 02:06:24

+0

它可以启用同步工作,但我很乐意做没有,太 - 只要有(当然,没有撕裂,)的可靠方法。 – Tronic 2012-03-26 02:55:05

+0

在OS X,你可以使用['CGDisplayModeGetRefreshRate'(http://developer.apple.com/library/mac/#documentation/GraphicsImaging/Reference/Quartz_Services_Ref/Reference/reference.html)。 – user1118321 2012-03-26 05:17:17

回答

2

我想睡大约10毫秒,然后读取一些实时输入并尽可能晚地进行渲染,同时仍然在截止日期之前更新帧(对于固体60 FPS渲染,延迟最小)。

这是一种非常不可靠的方法。我建议你把所有的渲染操作放到它们自己的线程中,这会阻塞缓冲区交换直到交换发生。在所有输入数据被计算的单独线程中执行所有输入处理。在进行交换之前,您应该在处理线程上解除互斥锁或信号量,这是缓冲区交换期间的事情。

请记住,您不应该延迟渲染实用程序非常接近的V-Sync,因为这可能会导致您错过它。相反,你应该在垂直回溯时间间隔开始时假设你有75%的时间用于渲染你的东西,而其余的25%应该保留为紧急余量。另外,如果你正在运行一个合成器,这个也需要一些GPU的时间。

如果您提前或延迟渲染,视觉效果没有区别。如果你关心你的模拟时间:姑且你居然会做出最后期限,使模拟的状态时,它会在V-Sync的时间。在任何数据输入上使用Kalman filter进行模拟,以便根据预测进行渲染并“仅”调整新输入。

交换缓冲区后,但不幸的是在某些系统(Linux的非合成,至少)这似乎等不只有等到下一个缓冲交换,但直到图像已经发出了HDMI端口,我可以使用glfinish在(总计等待时间为25 ms,应用程序以30 FPS运行)。

如果您的时序错过了V-Sync,则会发生这种情况:SwapBuffers将等待完整的垂直回扫期。恕我直言SwapBuffers应该添加某种超时参数,但到目前为止它没有。

+0

非常好的答案。有一点需要补充:glFinish真的没有意义。正确的做法正如datenwolf所说:渲染尽可能快,考虑GPU和输出黑盒子。不要试图用它作为时钟。渲染可能会被许多无法控制的缓冲区延迟。请参阅:http://superuser.com/questions/419070/transatlantic-ping-faster-than-sending-a-pixel-to-the-screen获得准确的时钟已经足够困难。使用它的图形显示是虐待的:) – starmole 2012-05-22 09:22:46