如何在每个垂直同步中完成一个渲染(不重复,不跳过)?

sla*_*aro 11 opengl directx direct3d vsync direct2d

我正在尝试进行垂直同步渲染,以便每个垂直同步完成一次渲染,而不跳过或重复任何帧.我需要这个在Windows 7和(将来)Windows 8下工作.

它基本上包括绘制QUADS适合屏幕的序列,以便原始图像中的像素与屏幕上的1:1像素匹配.使用OpenGL或DirectX,渲染部分不是问题.问题是正确的同步.

我以前尝试使用OpenGL,WGL_EXT_swap_control扩展,绘图然后调用

SwapBuffers(g_hDC);
glFinish();
Run Code Online (Sandbox Code Playgroud)

我尝试了这两个指令的所有组合和置换以及glFlush(),并且它不可靠.

然后我尝试使用Direct3D 10,通过绘图然后调用

g_pSwapChain->Present(1, 0);
pOutput->WaitForVBlank();
Run Code Online (Sandbox Code Playgroud)

其中g_pSwapChainIDXGISwapChain*pOutputIDXGIOutput*关联到该SwapChain.

两个版本,OpenGL和Direct3D,都是相同的:第一个序列,比方说,60帧,并没有达到应有的水平(而不是大约1000毫秒,60hz,持续时间等于1030或1050ms),以下似乎工作正常(约1000.40ms),但不时似乎跳过一帧.我做测量QueryPerformanceCounter.

在Direct3D上,尝试仅使用WaitForVBlank的循环,1000次迭代的持续时间始终为1000.40,几乎没有变化.

因此,这里的问题不是确切地知道每个被调用的函数何时返回,以及交换是否在垂直同步期间完成(不是更早,以避免撕裂).

理想情况下(如果我没有记错),要实现我想要的,它将执行一次渲染,等待同步开始,在同步期间交换,然后等待直到同步完成.如何使用OpenGL或DirectX做到这一点?

编辑:WaitForVSync60x的测试循环始终从1000.30ms到1000.50ms.与Present(1,0)之前相同的循环WaitForVSync,没有别的,没有渲染,需要相同的时间,但有时它会失败并需要1017毫秒,就像重复一帧一样.没有渲染,所以这里有问题.

mil*_*aki 0

创建 Direct3D 设备时,将结构体PresentationInterval的参数设置为。D3DPRESENT_PARAMETERSD3DPRESENT_INTERVAL_DEFAULT