在 qt5 的 qtquick 2.0 中渲染自定义 opengl



我正在寻找一种在 qtquick 2.0 项目中呈现我的自定义 opengl 调用的方法。给你一些背景:我有一个使用 opengl 进行渲染的C++ 3D 引擎。目标是让它在 qtquick 2.0 UI 中呈现。

我发现,在qt 5.0(qtquick 2.0)之前,您将使用QtGlWidget并将其嵌入到QDeclarativeView中。我发现的另一种方法是使用 QtDeclarativeItem 并覆盖 void QDeclarativeItem::p aint(QPainter *p, const QStyleOptionGraphicsItem *o, QWidget *w) 方法。

据我了解,这不再可能,因为QtQuick 2.0使用基于OpenGl的新渲染器。因此,这似乎不像覆盖油漆方法那么容易。

有谁知道我将如何实现允许渲染我的 opengl 调用的 QQuickItem?

您可以执行以下两项操作之一。将内容渲染为纹理,或者通过使用QQuickWindow::beforeRenderingQQuickWindow::afterRendering信号挂钩在场景图的 OpenGL 上下文中渲染。

有关如何使用FBO和纹理的示例可以在此处找到:http://doc.qt.io/qt-5/qtquick-scenegraph-textureinsgnode-example.html

有关如何直接渲染到场景图的 OpenGL 上下文的示例可在此处找到:http://doc.qt.io/qt-5/qtquick-scenegraph-openglunderqml-example.html

在 3D 引擎中,渲染为纹理,并在QQuickItem中使用QSGSimpleTextureNode来显示渲染结果。QtQuick维护它自己的GL状态,否则你可能会搞砸,这就是为什么建议只使用QSG*类来显示自定义内容。基本上,普通的QtQuick是一种渲染矩形的工具,而不是一般的3D内容。

(跛脚)示例:

QScopedPointer<QSGTexture> texture_;
QSGNode* MyItem::updatePaintNode(QSGNode* node, UpdatePaintNodeData*)
{
  if (width() <= 0 || height() <= 0)
  {
    texture_.reset();
    delete node;
    return 0;
  }
  else
  {
    if (!node)
    {
      node = new QSGSimpleTextureNode;
      static_cast<QSGSimpleTextureNode*>(node)
        ->setFiltering(QSGTexture::Nearest);
    }
    // else do nothing
    static_cast<QSGSimpleTextureNode*>(node)->setRect(boundingRect());
    getTheTextureFrom3DEngine(texture_);
    Q_ASSERT(texture_);
    static_cast<QSGSimpleTextureNode*>(node)->setTexture(texture_.data());
    return node;
  }
}

您还需要实例化计时器以更新内容。您可以从QQuickItem中执行此操作。

最新更新