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

zfciruhq  于 2022-11-27  发布在  Windows
关注(0)|答案(2)|浏览(339)

我知道在Windows上有两种获取屏幕刷新率的方法。第一种是简单的EnumDisplaySettings函数,它填充一个包含以fps为单位的舍入屏幕刷新率值的结构体。第二种是使用DirectX,它在初始化过程中提供了通过将分子和分母相除来获取刷新率的选项。
从我的经验来看,第一种方法是不够的。我的笔记本电脑显示器无法达到60帧的精确帧率,而是有多个设置,大约在59.9和60.1 fps之间。第二种方法给了我一个精确的浮点值,可以用来实现VSync的效果,而不需要直接使用VSync。
我问这个问题是因为OpenGL中缺乏可靠的VSync,我不想在启动时依赖额外的图形API来使用它来实现一个小功能。有没有其他方法?

jogvjijk

jogvjijk1#

根据我们的评论,VSYNC实际上会导致阻塞......但更准确地说,当交换链充满需要交换的后台缓冲区时,它会阻塞。三重缓冲可用于减少VSYNC实现中的阻塞,但WGL和GLX都无法对交换链中的后台缓冲区数量进行任意控制,因此您必须修改驱动程序设置以在OpenGL环境中启用它。
在OpenGL中,GL本身不处理缓冲区交换或VSYNC,正如我在前面的评论中指出的,您必须使用特定于平台的窗口系统层(例如WGL、GLX、AGL/CGL、EGL)来设置称为交换间隔的内容。

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

支撑由以下因素决定:
WGL_EXT_swap_control_tear(Windows操作系统)

GLX_EXT_swap_control_tear(任何使用X11的平台,例如Linux)
自适应VSYNC是一个有趣的新特性,如果您的应用程序超过显示器的刷新率,它将阻止,但当您低于刷新率时,它将允许撕裂。这与正常行为相反,正常行为中,任何低于刷新率的内容都将被调节到刷新率的某个较低因子。
在任何情况下,由于您在本例中使用的是Windows,因此需要查看wglSwapIntervalEXT (...)

vfhzx4xs

vfhzx4xs2#

在不创建任何设备的情况下使用DXGI并没有太多的开销,所以它几乎没有“包括另一个API”那么重。
所有这些都变成了对GDI32.DLL导出的D3DKMT函数的调用,并且GDI32.DLL已经加载到每个进程中。

相关问题