我正在尝试进行垂直同步渲染,以便每次垂直同步完成一次渲染,而不会跳过或重复任何帧。我需要它在 Windows 7 和(将来)Windows 8 下工作。
它基本上包括绘制QUADS
适合屏幕的序列,以便原始图像中的像素与屏幕上的像素 1:1 匹配。无论是使用 OpenGL 还是 DirectX,渲染部分都不是问题。问题是正确的同步。
我以前尝试使用带有WGL_EXT_swap_control
扩展名的 OpenGL,通过绘制然后调用
SwapBuffers(g_hDC);
glFinish();
我尝试了这两条指令的所有组合和排列以及 glFlush(),但它并不可靠。
然后我尝试使用 Direct3D 10,通过绘图然后调用
g_pSwapChain->Present(1, 0);
pOutput->WaitForVBlank();
其中g_pSwapChain
a是IDXGISwapChain*
与该 SwapChain 关联的。pOutput
IDXGIOutput*
OpenGL 和 Direct3D 这两个版本的结果是一样的:第一个序列,比如 60 帧,并没有持续应有的时间(而不是在 60hz 下大约 1000 毫秒,而是持续大约 1030 或 1050 毫秒),以下的似乎工作正常(大约 1000.40 毫秒),但它似乎时不时地跳过一帧。我用 进行测量QueryPerformanceCounter
。
在 Direct3D 上,仅尝试 WaitForVBlank 循环,1000 次迭代的持续时间始终为 1000.40,几乎没有变化。
所以这里的麻烦是不知道每个调用的函数何时返回,以及交换是否在垂直同步期间完成(不是更早,以避免撕裂)。
理想情况下(如果我没记错的话),要实现我想要的,应该是执行一次渲染,等到同步开始,在同步期间交换,然后等到同步完成。如何使用 OpenGL 或 DirectX 做到这一点?
编辑:只有 60 倍
的测试循环WaitForVSync
需要从 1000.30 毫秒到 1000.50 毫秒。Present(1,0)
与before相同的循环WaitForVSync
,没有其他内容,没有渲染,花费相同的时间,但有时它会失败并花费 1017 毫秒,就好像重复了一帧一样。没有渲染,所以这里有问题。