问题描述
我正在构建一个模块,该模块应该以一定的速率显示图像(未预先定义,但不是很高-交换图像时最大10Hz).
I'm building a module that is supposed to display images at a certain rate (not pre defined, but not very high - 10Hz max for the swapping of images).
从我的研究中,我得出的结论是,在使用openGL调用(SwapInterval系列)启用vsync之后,QGLWidget是执行此任务的正确工具.
From my research I got to the conclusion that QGLWidget is the right tool for this task, after enabling vsync with openGL calls(SwapInterval family).
但是,我不确定如何真正实现交换机制-我应该使用计时器吗?如果我将计时器设置为333.3 ms(3 Hz),则刷新频率为60 Hz(每个周期16.67,因此该计时器为20个周期),并且我确定定时是否合适?如果速率应为9Hz,则我需要将计时器设置为100 + 16.67,因为这是我能得到的最好的结果?如果计时器正常,当它向我发送超时事件时,我应该只调用paintGL()吗?
Yet, I am not sure how to actually implement the swapping mechanisem - should I use a timer? If I set a timer for 333.3 ms(3 Hz), when the refresh rate is 60 Hz (16.67 per cycle, thus the timer is 20 cycles), and I be sure that timing will be fine? And if the rate should be 9Hz, I need to set the timer for 100+16.67 because this is the best I can get?And if a timer is ok, should I just call paintGL() when it sends me the timeout event?
谢谢
推荐答案
是的,但不是幼稚的方式.如果您只是使用计时器来精确定位图像的呈现,则计时器频率将在显示垂直同步振荡器/刷新振荡器上跳动 –程序计时器从与显示输出不同的时钟源运行.
Yes, but not in a naive way. If you'd simply use a timer for pinpointing the presentation of the images your timer frequency will beat against the display V-Sync/refresh oscillator – program timers run from a different clock source than the display output.
此跳动将导致丢失交换间隔,这将被视为帧停顿.
This beating will result in missed swap intervals, which will be perceived as frame stuttering.
相反,您应该执行以下操作:使用V同步缓冲区交换(SwapBuffers¹)作为参考点,以启动高精度时间测量计时器.
Instead you should do the following: Use a V-Synced buffer swap (SwapBuffers¹) as a reference point to start a high precision time measurement timer.
然后在您希望的将来的下一个演示时间渲染框架;考虑到帧间隔是以显示刷新间隔的粒度输入的,除非使用了G-Sync或FreeSync.使用glFinish
强制完成帧渲染过程,然后停止计时器并确定渲染帧所花费的时间.如果该帧早于刷新周期完成,则您确实希望添加(高分辨率延迟),该延迟将程序延迟到目标显示周期(该周期的中间目标),后跟一个SwapBuffers
下一次迭代的参考点.
Then render the frame for the next presentation time in the future you aim for; take into account that frame intervals come in at the display refresh interval granularity – unless G-Sync or FreeSync are used. Use glFinish
to force completion of the frame rendering process, then stop the timer and determine how long it took to render the frame. If the frame was finished earlier than the refresh period you did aim for add a (high resolution delay) that delays your program into the aimed for display period (aim for the middle of the period), followed by a SwapBuffers
which will be the reference point for the next iteration.
¹:这仅对Nvidia和AMD卡及其专有驱动程序可靠地起作用.英特尔GPU的驱动程序具有不同的时序行为.
¹: This will work reliably only for Nvidia and AMD cards and their proprietary drivers. The drivers for Intel GPUs have a different timing behaviour.
这篇关于用qt&显示图像opengl,时序准确性和vsync问题,C ++的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!