winapi - 在没有 vsync 的情况下与监视器刷新同步

标签 winapi opengl directx direct3d

当 vsync 不是一个选项时,与监视器刷新同步的首选方法是什么?我们启用了 vsync,但是,一些用户在驱动程序设置中将其禁用,并且这些用户会覆盖应用程序首选项。我们需要可靠的可预测帧长度来正确模拟世界,做一些视觉效果,并同步音频(更准确地说,我们需要估计一帧将在屏幕上显示多长时间,以及何时显示在屏幕上)。

有什么方法可以强制驱动程序启用 vsync,不管用户在驱动程序中设置了什么?或者询问 Windows 何时会发生监视器刷新?当我们的帧边界与 vblank 紧密对齐时,我们会遇到手动休眠问题。它会导致偶尔丢失帧,以及最多 1 个额外帧的输入延迟。

我们主要使用 OpenGL,但也欢迎 Direct3D 建议。

最佳答案

您不应根据垂直同步和帧显示的准确时间来构建您的应用程序的时间。这些天游戏不会这样做,并且已经有一段时间没有这样做了。这就是让他们即使开始丢帧也能保持一致速度的原因;因为它们的计时、物理计算、AI 等不是基于帧的显示时间,而是基于实际计时。

游戏帧时间通常足够小(小于 50 毫秒),人类无法检测到任何音频/视频同步问题。因此,如果您想要显示一张应该伴随声音播放的图像,只要声音在图像的大约 30 毫秒内开始播放,就可以了。

哦,不要费心尝试切换到 Vulkan/D3D12 来解决这个问题。他们没有。特别是 Vulkan 将演示与其他任务分离,因此基本上不可能知道图像开始出现在屏幕上的确切时间。您给 Vulkan 一个图像,它会在下一个最合适的时刻呈现它。您可以控制选择那个时刻的方式,但即使是这些选择也可能会根据您无法控制的因素受到限制。

设计您的程序以避免需要严格的垂直同步。请改用内部计时。

关于winapi - 在没有 vsync 的情况下与监视器刷新同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57161140/

相关文章:

c# - 在 Java 中使用 DirectX 进行快速屏幕捕获(从 C# 中的现有代码重写到 Java)

.net - OpenGL 是否可以使用 .NET 形式?

c++ - 向控制台应用程序发送 Windows 消息

c++ - 什么是 UpdatePerUserSystemParameters?

opengl 用粒子建模火箭火焰和 Steam 轨迹

OpenGL super 采样抗锯齿?

c++ - 在 OpenGL 中绘制 VBO 不起作用

c - 加载图片 directx 12 oculus 裂痕

c++ - 如何检测 Windows 是否正在关闭或重新启动

c++ - 使用 directx9 加载表面太慢