【问题标题】:Qt & OpenGL: how to render as frequent as possible?Qt & OpenGL:如何尽可能频繁地渲染?
【发布时间】:2012-03-14 08:35:48
【问题描述】:

我正在将 OpenGL 应用程序从 win32 项目移植到 Qt 项目。

在 win32 项目中,我只是有一个主循环,它会在上一帧完成后立即执行下一帧。

在我找到的关于 Qt 和 OpenGL 的教程中,他们使用计时器来控制场景的更新。但是,我想尽可能频繁地渲染帧 - 怎么做?

【问题讨论】:

  • 为什么要渲染尽可能多的帧?您确定只渲染监视器可以显示的帧数还不够吗?通常是每秒 60 帧。

标签: qt opengl timer game-loop


【解决方案1】:

但是,我希望尽可能频繁地渲染帧 - 怎么做?

不适用于 Qt。 Qt 完全控制了事件循环,因此不会为您提供任何直接执行空闲操作的方法。在 Qt 中执行空闲操作的标准方法是使用超时为 0 的 QTime。

另一种可能性是使用第二个线程仅用于 OpenGL 操作。但是,为了可靠地工作,您应该为该线程创建一个专用的 OpenGL 上下文。

Qt 根本不适合那些主循环的主要任务是渲染图片而输入和事件管理只是次要的程序。

【讨论】:

  • 严格来说,QApplication.exec_() 采用事件循环。应该有一种方法可以使用QApplication.processEvents() 来设置典型的渲染循环。我在这方面取得了一些成功,当我解决一些松散的问题时我会发布。
  • @Kos:见 paulm 的评论。
  • @paulm 实际上,我在某个时候放弃了那个骇客,最终对在 0 超时计时器中进行渲染感到满意。我相信这相当于每次清空事件循环时运行一个回调,这看起来等同于我手动编写的代码。
【解决方案2】:

尝试在绘制处理程序结束时调用 update()

这将使另一个重绘事件排队。

【讨论】:

  • 排队 = 与 Mat 所问的问题相同:如果渲染时间过长,并且等待的更新事件过多,如何处理?
  • @OlivierPons 仅在上一次绘制事件完成后才调用更新。它不会更新太频繁。
【解决方案3】:

Qt 和 OpenGL 的内在原则不是尽快渲染,而是随时随地我们想要渲染(巨大的差异)。

您必须询问系统最大帧速率(在 OpenGL 中搜索示例,对不起,我不记得在哪里看到的)。完成此操作后,只需根据此最大帧速率创建一个计时器,即可获得所需的内容。

【讨论】:

  • 但是如果一帧需要更长的时间来渲染并且计时器在前一帧完成渲染之前触发会发生什么?
  • 然后你会在其他帧中渲染一次。 一旦渲染完成,计时器将被重置。因此,通过这种方式,您将尽快进行渲染,但您需要快速渲染以跟上最大帧速率。这个原则是天才,因为它适应机器的力量:慢的机器会做 5 fps,而快的机器会做 60fps,使用相同的代码,并且(最重要的)它们都将 工作(即使速度慢可能会给用户带来不好的体验......无论如何它会工作)。
  • 所以我建议根据例子编写代码,使用定时器来控制场景的更新。
  • OpenGL 没有尽快渲染的“内在原则”。这取决于你和你在做什么。事实上,平滑动画在与显示器刷新同步时看起来最好(这是人们在要求“尽可能频繁地渲染”时通常想要的)。
【解决方案4】:

但是,我想尽可能频繁地渲染帧 - 怎么做?

使用带零的 QTimer interval

【讨论】:

  • 至少对于 Qt 5.15,这是行不通的。如果我在我的一个示例中这样做,我每秒获得的帧数比我以 10 毫秒的间隔运行时要少。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-04-02
  • 2013-11-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-17
  • 1970-01-01
相关资源
最近更新 更多