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

Posted

技术标签:

【中文标题】如何在 D3D 窗口应用程序中启用 VSYNC?【英文标题】:How to enable VSYNC in D3D windowed app? 【发布时间】:2011-04-24 08:17:09 【问题描述】:

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

我使用以下参数初始化 D3D:

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

每次调用 OnPaint 时,我都会将图像渲染到后台缓冲区并将其呈现到前面。

据我所知(MSDN 也是这么说的),一旦我设置了D3DPRESENT_INTERVAL_ONE,vsync 就会起作用。

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

(图中好像有一条线,线下方的图像显示在监视器上,然后是上面的部分。)

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

我怎样才能启用垂直同步?

附言我终于发现 D3D vsync 已启用,而某些窗口设置不正确,可能是窗口本身未同步。不过,我还没有查看设置。

【问题讨论】:

你试过swapeffect:FLIP吗? 我按照你的建议试过了,但是没用.. TBH 我的理解一直是你不能垂直同步窗口渲染器。也许我错了,但有了这个假设,我从来没有失望过;) 您的目标是哪个 Windows 操作系统? “窗口模式”和“全屏模式”是什么意思?没有模式,只有一系列要设置的标志。全屏只是一个没有装饰/边框的窗口,与整个屏幕大小相同。只需设置 D3DPRESENT_INTERVAL_ONE 即可使 vsync 工作。 【参考方案1】:

我假设您使用的是 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 东西,那么错误的不是你的垂直同步设置,而是窗口设置。您必须启用双缓冲,否则您仍然会撕裂。

【讨论】:

【参考方案2】:

您不能在窗口模式下进行垂直同步,只能在全屏模式下进行。但是,您可能会通过从默认显示获取信息并找到刷新率,然后削弱您的渲染器以仅以该速率进行渲染……尽管我不建议这样做。

【讨论】:

【参考方案3】:

Windowed 历史上无法为 d3d 进行垂直同步,直到最近才有可能,当时在 WinVista 或 Win7 中启用了 aero 并且应用程序没有立即在演示模式下运行。

【讨论】:

【参考方案4】:

您多久调用一次 ::OnPaint ?我问的原因是,您调用 ::OnPaint 的频率必须高于连接显示器的刷新率。

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

我在这方面取得了很大的成功,上面关于窗口模式不能垂直同步的陈述绝对不是真的。即使在 DirectX 9 Win XP 中,这也能正常工作。

最后但同样重要的是,如果您连接了多个显示器,请确保与显示您的窗口的实际显示器进行垂直同步。这似乎有点棘手。

【讨论】:

【参考方案5】:

不完全是 D3D,但 AntiTearing.html 描述了 MPC-HC 如何使用窗口化 EVR 等来尝试避免窗口化显示器的撕裂。此处的链接:http://betterlogic.com/roger/2012/05/gdi-vsync-to-avoid-tearing/ 也可能对同步有用(尽管可以解决一些问题)。

【讨论】:

MPC-HC 的链接坏了,这是最后一个存档:web.archive.org/web/20120505154244/http://… BTW,我没有看到任何描述。

以上是关于如何在 D3D 窗口应用程序中启用 VSYNC?的主要内容,如果未能解决你的问题,请参考以下文章

使用 vsync (OpenGL) 时 CPU 利用率为 100%

打开 Bootstrap 模式弹出窗口时启用背景

D3D实战-在窗口中画一个三角形

D3D->CreateDevice() 在注入的 DLL 中失败

D3D创建窗口

什么是垂直同步