4

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

我使用以下参数启动了 D3D:

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

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

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

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

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

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

无论如何,我怎样才能启用垂直同步?

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

4

5 回答 5

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 设置,而是窗口设置。您必须启用双缓冲,否则您仍然会撕裂。

于 2015-10-13T06:38:13.517 回答
0

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

于 2011-01-14T15:36:16.820 回答
0

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

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

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

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

于 2013-06-20T11:01:10.757 回答
0

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

于 2012-05-09T15:24:54.287 回答
0

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

于 2011-06-20T22:03:44.527 回答