Windows下的CVDisplayLink替代方案?

7
在Mac OS X上,CVDisplayLink提供了一种可靠更新屏幕以实现60fps动画而不会出现撕裂的好方法。在Windows上是否有类似的接口,与OpenGL兼容?
当然,可以阻塞等待垂直同步,但这对于需要同时进行动画的多个窗口来说并不可行。在Windows上,它们都会互相等待(因此,每个等待垂直同步的两个窗口将降至30fps),而在OS X上则不同。
例如,视频播放器如何实现平滑的屏幕更新?

这是一篇关于该问题的背景信息的博客文章:http://www.virtualdub.org/blog/pivot/entry.php?id=157 - Frederik Slijkerman
那篇文章看起来很奇怪。30/60隔行扫描问题不是NTSC视频的硬件特性吗? - Steve Wart
交错仍然是一种有效的优化方法 - 在最好的情况下,它可以将填充率消耗减半 - 在最坏的情况下,它会使其加倍 - 这完全取决于硬件。 :) - jheriko
1个回答

1

Windows的典型架构与Mac不同,因为您控制主循环而不是操作系统库 - 没有必要使用CVDisplayLink等效(尽管如果API更好,则无需了解太多特定信息即可实现此目的)。

如果您正在使用无限旋转的循环,则在循环结束时等待vsync即可。 如果您有多个窗口,您需要相应地安排渲染,以便所有渲染提交后,“主更新循环”以等待vsync结束。

通常我会这样做:

while(!toldToQuit)
{
    Render();
    Update();

    WaitForVsync();
}

这使得CPU可以在GPU进行渲染的同时进行更新(下一帧)的工作...

如果驱动程序将垂直同步作为其默认行为,则SwapBuffers(HDC)将等待垂直同步,否则可以使用wgl扩展来设置垂直同步-wglSwapIntervalEXT(int):

http://www.opengl.org/registry/specs/EXT/wgl_swap_control.txt

我一直实现“不同步”的方法是通过单缓冲渲染,而不调用SwapBuffers...因为在我测试过的任何硬件上,wglSwapIntervalEXT(0)都无法实现这一点。


1
你的答案只在每个进程中的单个渲染循环(例如全屏游戏)的情况下有效。对于一个进程中有多个窗口,每个窗口都有自己的OpenGL上下文和渲染线程,这种方法行不通:ATI驱动程序会对所有垂直同步刷新进行串行化处理,因此线程/上下文最终会互相等待。 - Frederik Slijkerman
为什么您认为我会为多个窗口使用多个循环,而不是一个循环来管理它们所有?我认为您将我的代码放在了您想象的架构错误的层次上。或者也许我误解了您的意思... - jheriko

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接