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(垂直同步关闭),但是当我想使用鼠标调整窗口大小时,程序挂断了。然后我必须使用“ctrl+ alt + del”并手动终止进程(调试器不包含任何消息)。可能有什么问题?

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

4

1 回答 1

1

我假设您在 Windows 上,因为您使用关闭程序

ctrl+ alt + del

ms = 0您确实renderScene()在尽可能快地测量使用事件的处理性能时。当 Qtimer 超时时,它会将QTimerEvent. 您的计时器不断超时并排队QTimerEvent和充斥事件队列。当您调整窗口大小时,会在充满计时器事件的队列中放置一个调整大小事件,并且仅在这些事件之后处理。由于应用程序没有及时处理事件,应用程序出现无响应

ms != 0由于操作系统计时器不准确而导致您的测量不准确时。当我在开发一个多平台播放器时,我注意到在我的 Windows 上,从 1ms 到 15ms 的任何时间延迟都在 15ms 左右可以直接测试。如果您在 linux 上运行相同的测试,您会看到 1ms 的 fps 比 10 ms 更好(仍然不能保证 1ms 的分辨率)

所以总结一下:

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

编辑:上面的参数ms != 0对于 Qt 4.8 和 Qt 5 中的默认TimerType(Qt::CoarseTimer) 有效。您可以使用setTimerType(Qt::PreciseTimer)毫秒精度,但不能保证成功

在 Windows 上,Qt 将为 Qt::PreciseTimer 使用 Windows 的多媒体计时器工具(如果可用),为 Qt::CoarseTimer 和 Qt::VeryCoarseTimer 使用普通的 Windows 计时器。

于 2014-10-14T20:15:10.403 回答