Qt 5.1.1和OpenGL - 渲染速度

4

我基于以下Qt类创建了我的OpenGL应用程序:QWindow、QOpenGLContext和QOpenGLFunctions_4_3_Core。我使用QTimer来渲染场景:

QTimer* timer = new QTimer( this );
connect( timer, SIGNAL( timeout() ), this, SLOT( renderScene() ) );
timer->start( ms );

当ms = 0时,我可以检查最大FPS。结果是 ~2200 fps(v-sync关闭),但是当我想要使用鼠标调整窗口大小时,程序会挂起。然后我必须使用“ctrl+alt+del”并手动杀死进程(调试器没有任何消息)。可能有什么问题?

我还想知道为什么当定时器间隔设置为1时,我只得到64 fps(应该是1000 fps)?其他结果:间隔=10也是64 fps,间隔=50 -> 16 fps,间隔=100 -> 9 fps。只有最后一个结果(100 ms -> 9fps)似乎是正确的。如何解释这些结果?


你调整了GL上下文的大小以适应新的尺寸吗? - ratchet freak
是的:connect( this, SIGNAL( widthChanged( int ) ), this, SLOT( resizeGL() ) ); connect( this, SIGNAL( heightChanged( int ) ), this, SLOT( resizeGL() ) ); 对于计时器间隔 > 0,重新调整大小运作正常。 - Irbis
当 QTimer 的超时为 0 时,它将绕过操作系统消息队列,并在没有其他事件需要处理时被调用,操作系统队列通常会施加很大的开销。 - ratchet freak
我在其他OpenGL应用程序中使用Freeglut,当程序以最大帧率运行时,我可以调整窗口大小,那么在Qt中是否也能实现这一点呢? - Irbis
正如文档所述,QTimer 有一定的开销。不要使用它,改为使用 QObject::startTimer()。无论如何,我觉得您正在错误地使用 OpenGL。您是否阅读了 Qt OpenGL 文档?它是否说要使用计时器进行渲染? - marco.m
1个回答

1
我假定您正在使用Windows,鉴于您使用了关闭程序的操作。
ctrl+ alt + del

ms = 0 时,您确实是在使用尽可能快的事件来度量处理 renderScene() 的性能。当 QTimer 超时时,它会排队一个 QTimerEvent。您的计时器不断超时并排队 QTimerEvent 并淹没事件队列。当您调整窗口大小时,调整大小事件被放置在充满计时器事件的队列中,仅在这些事件之后才会被处理。因为应用程序未能及时处理该事件,所以应用程序似乎无响应。

ms!= 0 时,您的测量结果是不准确的,因为操作系统定时器是不准确的。当我开发多平台播放器时,我注意到在 我的 Windows 上,从1毫秒到15毫秒的任何时间延迟都约为15毫秒可以直接测试的内容。如果您在 Linux 上运行相同的测试,您将看到1ms比10ms具有更好的fps(1ms分辨率仍然不能保证)

总之:

  • 你的测试结果差异与Open-GL无关
  • 你的测试结果差异与Windows有很大关系
  • 操作系统和操作系统版本中的计时差异是使用外部设备生成时间码的好理由
  • 如果你需要在真实程序中使用零延迟定时器(很可能需要),它需要在不同于主事件队列的事件队列中运行。

编辑:上述ms!= 0的论点对于Qt 4.8有效,并且对于Qt 5中的默认TimerTypeQt :: CoarseTimer )也有效。您可以使用setTimerType(Qt :: PreciseTimer)进行毫秒级准确性,但不能保证成功

在Windows上,如果可用,Qt将使用Windows的多媒体定时器功能(用于Qt :: PreciseTimer),并使用普通Windows定时器用于Qt :: CoarseTimer和Qt :: VeryCoarseTimer。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接