1

我正在使用带有自定义 OpenGL 渲染器的 QtQuick(从 QtQuick 的角度自定义,因为它只是OpenSceneGraph)。为此,我创建了一个继承自QQuickFramebufferObject的自定义QQuickItem ,然后创建了一个继承自QQuickFramebufferObject ::createRenderer()中的QQuickFramebufferObject::Renderer的自定义渲染器。这是有据可查的,这些步骤没有问题。

现在发生的情况是,为了以后访问,在QQuickFramebufferObject::createRenderer()中创建的渲染器实际上是缓存的(它实际上是在QQuickFramebufferObject构造函数中实例化并简单地在QQuickFramebufferObject::createRenderer()中返回。这工作正常,我可以看不到直接的其他编码方式,因为创建的渲染器稍后用于对诸如geometryChangedmousePressEvent 之类的事件做出反应,例如

////////////////////////////////////////////////////////////////////////////////
void OsgItem::geometryChanged(const QRectF& newGeometry, const QRectF& oldGeometry)
{
    if (m_renderer)
        m_renderer->m_window->getEventQueue()->windowResize(newGeometry.x(), newGeometry.y(), newGeometry.width(), newGeometry.height());


    QQuickFramebufferObject::geometryChanged(newGeometry, oldGeometry);
}

////////////////////////////////////////////////////////////////////////////////
void OsgItem::mousePressEvent(QMouseEvent *event)
{
    m_renderer->m_window->getEventQueue()->mouseButtonPress(event->x(), event->y(), button(*event));

    update();
}

,其中 OsgItem 是我的自定义QQuickFramebufferObjectm_renderer是我的自定义QQuickFramebufferObject::Renderer

问题是createRenderer()是 const (这并不是真正的缓存东西的邀请),并且这篇论文明确指出不应该缓存渲染器 - (尽管官方文档中没有说明)。

这里有什么问题?有什么我错过的吗?你能看到我可以编码的另一种干净的方式吗?

4

2 回答 2

3

Velkan 提供了将 Raw/Custom OpenGL 与QQuickFramebufferObject. 由于我们刚刚完成了一个集成 OSG 和 QtQuick 的项目,我想分享一些我们的经验。

是的,当然,您永远不应该缓存渲染器。createRenderer是 const 是有原因的,这就是 Qt 团队设计这些类的方式。根据我们的实验,该createRenderer函数可能会被多次调用。

为了在 QQuickFramebufferObject 和它的渲染器之间同步,我们QQueue在 QQuickFramebufferObject 中添加一个,当我们感兴趣的任何事件发生时,我们将它们放入队列中。而在渲染器中,当synchronize被调用时,我们将队列从fbo复制到渲染器,并在render函数中执行某些操作。

于 2016-08-21T08:28:29.100 回答
2

好吧,渲染器QQuickFramebufferObjectsynchronize(QQuickFramebufferObject *item).

发生这种情况是因为您不应该Renderer在 GUI 线程中使用mousePressEventRenderer如我所见,没有任何可以在 GUI 线程中执行的函数)之类的东西。当Renderer::synchronize()GUI 线程被阻塞时,它在渲染线程中执行:所以它是进行数据传输的地方。

通常,当由于输入而发生某些变化时,GUI 线程必须要求同步。这会导致它停止,然后synchronize()在渲染线程中调用场景图。有一个同步图(没有提到Renderer,但必须遵循相同的原则):http ://doc.qt.io/qt-5/qtquick-visualcanvas-scenegraph.html

Renderer::render()我记得在 GUI 线程自由运行时发生在渲染线程中。因此,不能在那里传递任何数据。

QQuickItem::geometryChanged在 GUI 线程中(可能与调试器一起检查),所以不要混合渲染。

于 2016-08-08T20:48:06.467 回答