使用 qt 和 opengl 显示图像,计时精度和 vsync 问题,c++
Display image with qt & opengl, timing accuracy and vsync issues, c++
我正在构建一个应该以特定速率显示图像的模块(未预先定义,但不是很高 - 图像交换最大 10Hz)。
根据我的研究,我得出结论,在使用 openGL 调用(SwapInterval 系列)启用垂直同步后,QGLWidget 是完成此任务的正确工具。
但是,我不确定如何实际实施交换机制 - 我应该使用计时器吗?如果我将定时器设置为 333.3 毫秒(3 赫兹),当刷新率为 60 赫兹(每个周期 16.67,因此定时器为 20 个周期)时,我确定时间会好吗?如果速率应该是 9Hz,我需要将定时器设置为 100+16.67,因为这是我能得到的最好值?
如果计时器没问题,我应该在它向我发送超时事件时调用 paintGL() 吗?
谢谢
should I use a timer?
是的,但不是天真。如果您只是使用定时器来精确定位图像的呈现,您的定时器频率将 beat 与显示器 V-Sync/refresh 振荡器 - 从与显示器输出不同的时钟源编程定时器 运行 .
这种跳动将导致错过交换间隔,这将被视为帧卡顿。
相反,您应该执行以下操作:使用 V-Synced 缓冲区交换 (SwapBuffers¹) 作为参考点来启动高精度时间 测量 计时器。
然后为您打算的未来的下一个演示时间渲染帧;考虑到帧间隔以显示刷新间隔粒度出现——除非使用 G-Sync 或 FreeSync。使用 glFinish
强制完成帧渲染过程,然后停止计时器并确定渲染帧需要多长时间。如果帧早于刷新周期完成,您的目标是添加一个(高分辨率延迟),将您的程序延迟到目标显示周期(目标是周期的中间),然后是 SwapBuffers
将作为下一次迭代的参考点。
¹:这仅适用于 Nvidia 和 AMD 卡及其专有驱动程序。 Intel GPU 的驱动程序具有不同的时序行为。
我正在构建一个应该以特定速率显示图像的模块(未预先定义,但不是很高 - 图像交换最大 10Hz)。
根据我的研究,我得出结论,在使用 openGL 调用(SwapInterval 系列)启用垂直同步后,QGLWidget 是完成此任务的正确工具。
但是,我不确定如何实际实施交换机制 - 我应该使用计时器吗?如果我将定时器设置为 333.3 毫秒(3 赫兹),当刷新率为 60 赫兹(每个周期 16.67,因此定时器为 20 个周期)时,我确定时间会好吗?如果速率应该是 9Hz,我需要将定时器设置为 100+16.67,因为这是我能得到的最好值? 如果计时器没问题,我应该在它向我发送超时事件时调用 paintGL() 吗?
谢谢
should I use a timer?
是的,但不是天真。如果您只是使用定时器来精确定位图像的呈现,您的定时器频率将 beat 与显示器 V-Sync/refresh 振荡器 - 从与显示器输出不同的时钟源编程定时器 运行 .
这种跳动将导致错过交换间隔,这将被视为帧卡顿。
相反,您应该执行以下操作:使用 V-Synced 缓冲区交换 (SwapBuffers¹) 作为参考点来启动高精度时间 测量 计时器。
然后为您打算的未来的下一个演示时间渲染帧;考虑到帧间隔以显示刷新间隔粒度出现——除非使用 G-Sync 或 FreeSync。使用 glFinish
强制完成帧渲染过程,然后停止计时器并确定渲染帧需要多长时间。如果帧早于刷新周期完成,您的目标是添加一个(高分辨率延迟),将您的程序延迟到目标显示周期(目标是周期的中间),然后是 SwapBuffers
将作为下一次迭代的参考点。
¹:这仅适用于 Nvidia 和 AMD 卡及其专有驱动程序。 Intel GPU 的驱动程序具有不同的时序行为。