14

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

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

据我了解,这是不可能的,因为 QtQuick 2.0 使用了基于 OpenGL 的新渲染器。因此,它似乎不像覆盖绘画方法那么容易。

有人知道我将如何实现一个允许渲染我的 opengl 调用的 QQuickItem 吗?

4

2 回答 2

8

你可以做两件事之一。将您的内容渲染到纹理中,或者通过使用QQuickWindow::beforeRenderingorQQuickWindow::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

于 2013-06-04T06:03:24.377 回答
3

在您的 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;
  }
}

您还需要实例化一个 Timer 来更新内容。您可以在 QQuickItem 中执行此操作。

于 2013-01-04T13:17:10.940 回答