简体   繁体   English

使用QT和OpenGL显示图像,定时精度和垂直同步问题,C ++

[英]Display image with qt & opengl, timing accuracy and vsync issues, c++

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). 我正在构建一个模块,该模块应该以一定的速率显示图像(未预先定义,但不是很高-交换图像时最大10Hz)。

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). 从我的研究中,我得出的结论是,在使用openGL调用(SwapInterval系列)启用vsync之后,QGLWidget是完成此任务的正确工具。

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? 如果我将计时器设置为333.3 ms(3 Hz),则刷新频率为60 Hz(每个周期16.67,因此该计时器为20个周期),并且我确定定时是否合适? 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? 如果速率应为9Hz,我需要将计时器设置为100 + 16.67,因为这是我能得到的最好的结果? And if a timer is ok, should I just call paintGL() when it sends me the timeout event? 如果计时器正常,当它向我发送超时事件时,我应该只调用paintGL()吗?

Thanks 谢谢

should I use a timer? 我应该使用计时器吗?

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. 这种跳动将导致错过交换间隔,这将被视为帧停顿。

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. 相反,您应该执行以下操作:使用V同步缓冲区交换(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. 考虑到帧间隔是以显示刷新间隔的粒度输入的,除非使用了G-Sync或FreeSync。 Use glFinish to force completion of the frame rendering process, then stop the timer and determine how long it took to render the frame. 使用glFinish强制完成帧渲染过程,然后停止计时器并确定渲染帧所花费的时间。 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. 如果该帧早于刷新周期完成,则您确实希望添加一个(高分辨率延迟),该延迟将程序延迟到目标显示周期(该周期的中间),然后是SwapBuffers ,它将作为参考指向下一次迭代。


¹: This will work reliably only for Nvidia and AMD cards and their proprietary drivers. ¹:这仅对Nvidia和AMD卡及其专有驱动程序可靠地起作用。 The drivers for Intel GPUs have a different timing behaviour. 英特尔GPU的驱动程序具有不同的时序行为。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM