QtQuick自定义OpenGL渲染

时间:2016-08-08 09:44:27

标签: opengl qtquick2 qt-quick qquickitem

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

现在发生的事情是,为了以后访问,在 QQuickFramebufferObject :: createRenderer()中创建的渲染器实际上是缓存的(它实际上是在 QQuickFramebufferObject 构造函数中实例化的并简单地返回 QQuickFramebufferObject :: createRenderer()。这很好用,我可以看到没有直接的其他方式来编码它,因为创建的渲染器后来用于响应事件,如 geometryChanged < / strong>或 mousePressEvent ,例如

////////////////////////////////////////////////////////////////////////////////
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是我的自定义 QQuickFramebufferObject m_renderer 是我的自定义 QQuickFramebufferObject :: Renderer

问题是 createRenderer()是const(实际上并不是缓存内容的邀请),而this paper明确指出不应缓存渲染器 - (尽管它官方文件中没有说明。

这里有什么收获?有没有我错过的东西?你能看到另一种干净的方式来编码吗?

2 个答案:

答案 0 :(得分:2)

嗯,渲染器在QQuickFramebufferObject中获得非常量synchronize(QQuickFramebufferObject *item)

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

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

当我记得GUI线程正在自由运行时,

Renderer::render()发生在渲染线程中。因此,没有数据可以传递到那里。

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

答案 1 :(得分:2)

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

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

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