如何在D3D窗口应用程序中启用VSYNC?

时间:2010-10-12 13:50:50

标签: directx direct3d direct3d9 vsync

所以,我在窗口应用程序中使用D3D。

我使用以下参数进入D3D:

windowed: true;
backbufferformat: D3DFMT_X8R8G8B8;
presentinterval: D3DPRESENT_INTERVAL_ONE;
swapeffect: DISCARD

每次调用OnPaint时,我都会将图像渲染到后备缓冲区并将其显示在前面。

据我所知(MSDN也是如此),一旦我设置了D3DPRESENT_INTERVAL_ONE,vsync就会起作用。

但在这种情况下,水平拖动时图像会被撕掉。

(似乎图像上有一条线,显示器上方的线下方显示图像,上面的部分如下所示。)

有些网站称D3DPRESENT_INTERVAL_ONE在窗口应用程序中不起作用。

我怎样才能启用vsync?

P.S。我终于发现D3D vsync已启用,而某些窗口设置不正确,可能是窗口本身未同步。不过,我还没看好这些设置。

5 个答案:

答案 0 :(得分:4)

我假设您正在使用D3D9?应该添加该标签。在D3DPRESENT_PARAMS变量上:

if (bVysncEnabled)
{
    presentParams.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
    presentParams.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
}
else
{
    presentParams.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
    presentParams.FullScreen_RefreshRateInHz = 0;
}

如果你已经完成了这项并且你正在使用旧的GDI内容,那么你的vsync设置不是错误的,而是窗口设置。你必须启用双缓冲,否则你仍然会撕裂。

答案 1 :(得分:0)

在窗口中,仅在全屏模式下,您无法进行vsync。但是,您可以通过从默认显示中获取信息并查找刷新率,然后将渲染器缩小到仅以该速率渲染来进行伪装...尽管我不建议使用该路径。

答案 2 :(得分:0)

历史上没有能够为d3d提供窗口,只有在最近才能实现这一点,当在WinVista或Win7中启用aero并且应用程序未在演示模式下运行时。

答案 3 :(得分:0)

不完全是D3D,但是AntiTearing.html描述了MPC-HC如何使用窗口化EVR等来尝试避免撕裂窗口显示。这里的链接:http://betterlogic.com/roger/2012/05/gdi-vsync-to-avoid-tearing/也可能对同步很有用(虽然有些解决方法)。

答案 4 :(得分:0)

您多久拨打:: OnPaint?我问的原因是,你必须比连接的显示器的刷新率更频繁地调用:: OnPaint。

对我来说,只要消息循环空闲并使窗口无效,我就会通过强制:: OnPaint来解决刷新问题。如果你这样做会发生什么,是D3D的RenderPresent命令将等待,直到图形卡完成渲染,这为你提供了一个非常精确的:: OnPaint时间与实际的显示器刷新率同步!

我在这方面取得了很大的成功,并且窗口模式上面的语句不能vsync绝对不是真的。即使在DirectX 9 Win XP中,这也是有效的。

哦,最后但并非最不重要的是,如果您连接了多个显示器,请确保与显示窗口的实际显示屏进行vsync。这似乎有点棘手。