我正在寻找一种在 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 吗?
您可以执行以下两件事之一。将内容渲染到纹理中,或者通过使用
QQuickWindow::beforeRendering
或 QQuickWindow::afterRendering
信号进行挂钩,在场景图的 OpenGL 上下文中渲染。
可以在此处找到有关如何使用 FBO 和纹理的示例:https://doc.qt.io/qt-5/qtquick-scenegraph-rendernode-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;
}
}
还需要实例化一个Timer来更新内容。您可以从 QQuickItem 中执行此操作。