在没有 DirectX 的 Windows 上获得精确的屏幕刷新率

Get the precise screen refresh rate on Windows without DirectX?

本文关键字:刷新率 屏幕 DirectX Windows      更新时间:2023-10-16

我知道有两种方法可以在Windows上获取屏幕刷新率。 第一个是简单的EnumDisplaySettings函数,它填充一个结构,其中包含以 fps 为单位的圆形屏幕刷新率值。 第二种是使用 DirectX,在初始化期间,您可以选择通过将分子和分母除以彼此来检索刷新率。

根据我自己的经验,第一种方法是不够的。 我的笔记本电脑显示器无法实现 60 的精确帧速率 - 相反,它具有多种设置,在 fps 中接近 59.9 和 60.1。 第二种方法给了我一个精确的浮点值,可以用来实现VSync的效果,而无需直接使用VSync。

问这个问题是因为OpenGL中缺乏可靠的VSync,我不想在启动时依赖额外的图形API,只是为了将其用于一个小功能。 还有别的办法吗?

跟进我们的评论,有效地 VSYNC 导致阻塞...但更准确地说,当交换链充满需要交换的后台缓冲区时,它会阻塞。三重缓冲可用于减少 VSYNC 实现中的阻塞,但 WGL 和 GLX 都不会公开对交换链中后台缓冲区数量的任意控制,因此您必须修改驱动程序设置以在 OpenGL 上下文中启用它。

在OpenGL中,GL本身不处理缓冲区交换或VSYNC,正如我在之前的评论中指出的那样,您必须使用特定于平台的窗口系统层(例如WGL,GLX,AGL/CGL,EGL)来设置称为交换间隔的东西。

  • 将交换间隔设置为 1 将启用 VSYNC
  • 将交换间隔设置为 0 将禁用 VSYNC

  • 将交换间隔设置为 -1 将在较新的驱动程序上启用自适应 VSYNC

    支持取决于以下各项的存在:

    WGL_EXT_swap_control_tear (视窗)

    GLX_EXT_swap_control_tear(任何使用 X11 的平台,例如 Linux)

自适应 VSYNC 是一项有趣的新功能,如果您的应用程序超过显示器的刷新率,该功能会阻止,但当您低于刷新率时允许撕裂。这与正常行为相反,在正常行为中,低于刷新率的任何内容都会被限制为刷新率的某个较低因子。


无论如何,由于您在此示例中使用的是Windows,因此您需要研究 wglSwapIntervalEXT (...)

在不创建任何设备的情况下使用 DXGI 并没有那么多开销,因此它不像"包含另一个 API"那么重。

这一切都变成了对 GDI32.DLL 导出的 D3DKMT 函数的调用,GDI32.DLL 已经加载到每个进程中。