【问题标题】:QOpenGLWidget: Drawing at 60FPS while not interfering with its existing timing?QOpenGLWidget:以 60FPS 绘制而不干扰其现有时间?
【发布时间】:2015-04-18 20:34:54
【问题描述】:

我正在使用 C++、Qt 和 OpenGL 编写着色器编辑器。我希望渲染的场景是交互式的,并且我希望用户能够使用来自周围环境的变量,例如鼠标坐标或窗口尺寸。

就目前而言,每次基本上有任何类型的输入(鼠标移动、窗口聚焦、按键等)时,都会重绘 OpenGL 小部件。这就是 Qt 的渲染正常工作的方式。

但是,我还想让用户使用定期更改的输入其值不依赖于用户交互,例如系统时间、随机数,甚至可能是网络摄像头。为了以有意义的方式做到这一点,我必须定期更新屏幕(事实上,我可能会让用户自定义)。

如果用户输入触发了渲染,而计时器也触发了渲染,或者反之亦然,那么我将面临竞争条件。 如何避免这种情况?

【问题讨论】:

  • 如果用户输入触发了渲染,而计时器也触发了渲染,反之亦然,那么我将面临竞争条件。 你为什么这么认为?每当场景依赖的东西发生变化时,只需 update() gl 小部件即可。这会将更新事件发布到事件队列中,并且此类事件被压缩,因此无论您多久调用一次update,一旦事件循环重新获得控制,将只有一次重新渲染。简单的。如果您要求其他内容,请使用相关详细信息或代码更新问题。 “渲染场景”——在哪里?在QGLWidgetQOpenGLWidget 上,或者?

标签: c++ qt opengl frame-rate


【解决方案1】:

您可能需要一个渲染队列。每当用户或系统触发渲染时,您都会将其推送到队列中。然后,您将拥有一个渲染线程,该线程会定期轮询队列以启动渲染。但是,我看不出这将如何成为一种竞争条件,因为无论发生了什么变化,对渲染的调用都应该更新屏幕。 拥有队列还可以帮助您优化代码,因为您可以避免执行多个连续的不必要的渲染调用。

【讨论】:

  • 不是我想要的。我不需要队列,因为每个渲染调用都将渲染相同的场景(目前)。我想,这更像是一个 Qt/OpenGL 问题,而不是一般的渲染问题。
  • 那就不明白这个问题了。您问:“如果用户输入触发了渲染,而计时器也触发了渲染,反之亦然,那么我将与竞争条件搏斗。我该如何避免这种情况?”。在处理竞争条件时,无论上下文如何,您都希望使用不可变结构、线程安全结构或围绕线程不安全调用的锁。在您的问题中,我看不到它询问任何特定于 QT/OpenGL 的内容。
  • 我想我可能没有使用正确的术语;我没有明确使用线程,尽管我毫不怀疑计时器会。 “竞争条件”是指“如果用户的鼠标移动已经在一个称为渲染的计时器中间触发了渲染怎么办?”
【解决方案2】:

使用QTimer。这将在与其他更新事件相同的 Qt 线程上触发重绘事件,因此您无需担心竞争条件。例如,在您的 QOpenGLWidget 派生构造函数中:

auto pTimer = new QTimer(this);
connect(pTimer, &QTimer::timeout, this, &QOpenGLWidget::update); 
pTimer->start(1000 / 60.0);

【讨论】:

    猜你喜欢
    • 2020-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-15
    • 2016-01-22
    • 1970-01-01
    • 2021-12-27
    • 1970-01-01
    相关资源
    最近更新 更多