根据微软的这篇文章,用户设置的屏幕刷新率可以是(而且大部分是)一个分数。 用户设置59Hz,屏幕按60Hz的屏幕显示运行,但实际上是59.94Hz。 我需要一个非常stream畅的animation是59.94Hz。
使用IDirect3DDevice9 :: GetDisplayMode我只能得到一个int值,不能通过定义代表真正的时间( EnumDisplaySettings也是如此 )。 我每秒都会遇到一个可见的口吃,因为它报告了四舍五入/截断的59.如果我手动将我的应用程序中报告的时间更正为59.94,它会平稳运行。
任何人都知道我可以如何检索真正的屏幕刷新率?
我目前的解决方法是映射60Hz和59Hz都恒定59.94Hz,但这并不令人满意。
如果您的目标是Windows Vista或更高版本,则答案取决于您的应用程序运行的模式。
如果是窗口化应用程序(或全屏窗口),则根据用户设置和其他因素通过桌面窗口管理器(DWM)控制刷新率。 使用DwmGetCompositionTimingInfo并查看DWM_TIMING_INFO :: rateRefresh以获取显示器刷新率。
如果应用程序为全屏幕,则创建的全屏交换链将覆盖系统默认值。 但是,您选择的刷新率(DXGI_SWAP_CHAIN_FULLSCREEN_DESC :: RefreshRate)应该与显示器支持的刷新率之一匹配。 您可以使用IDXGIOutput :: GetDisplayModeList获取支持刷新率的列表。 这里是一个如何做的例子:
UINT numModes = 0; dxgiOutput->GetDisplayModeList(DXGI_FORMAT_B8G8R8A8_UNORM, 0, &numModes, NULL); DXGI_MODE_DESC* modes = new DXGI_MODE_DESC[numModes]; dxgiOutput->GetDisplayModeList(DXGI_FORMAT_B8G8R8A8_UNORM, 0, &numModes, modes); // see modes[i].RefreshRate
无论如何,如果你是三重缓冲的,你不应该看到有什么问题。 您应该尽可能快地呈现,操作系统将按时出现。 如果将三重缓冲与自定义托管帧时序结合起来,则可以保证实际上不会实现三重缓冲,并且每当vblank阶段发生漂移时(即使您拥有完美的值刷新率)。 如果你想坚持三重缓冲,只要能够尽可能快地呈现,并让操作系统负责演示时间。 如果您使用自己的时间来驱动Present()(例如,获得低延迟响应),则应该在另一个线程中调用IDXGIOutput :: WaitForVBlank以帮助同步帧时序。 如果你最终这样做,你也应该使用IDXGISwapChain :: GetFrameStatistics来确保你从任何虚假的故障中恢复,否则你会最终落后一帧。
祝你好运!