Рендеринг настраиваемого opengl в qt5 qtquick 2.0
Я ищу способ отображения своих пользовательских вызовов opengl внутри элемента qtquick 2.0. Чтобы дать вам некоторый контекст: у меня есть С++ 3d engine, который использует opengl для рендеринга. Цель состоит в том, чтобы сделать рендеринг внутри пользовательского интерфейса qtquick 2.0.
То, что я узнал, это то, что pre qt 5.0 (qtquick 2.0) вы использовали QtGlWidget и вставляете его в QDeclarativeView. Другой способ, который я нашел, - использовать QtDeclarativeItem и переопределить метод void QDeclarativeItem:: paint (QPainter * p, const QStyleOptionGraphicsItem * o, QWidget * w).
Как я понимаю, это невозможно, поскольку QtQuick 2.0 использует новый рендерер, основанный на OpenGl. Поэтому, как представляется, это не так просто, как переопределение метода краски.
Кто-нибудь знает, как я буду реализовывать QQuickItem, который позволяет выполнять мои вызовы opengl?
Ответы
Ответ 1
Вы можете сделать одну из двух вещей. Либо сделайте свой контент в текстуре, либо визуализируйте в контексте OpenGL графика сцены, подключив его с помощью сигналов QQuickWindow::beforeRendering
или QQuickWindow::afterRendering
.
Пример использования FBO и текстуры можно найти здесь: http://doc.qt.io/qt-5/qtquick-scenegraph-textureinsgnode-example.html
Пример того, как визуализировать непосредственно контекст OpenGL графа сцены можно найти здесь: http://doc.qt.io/qt-5/qtquick-scenegraph-openglunderqml-example.html
Ответ 2
В вашем 3D-движке визуализируйте текстуру и в QQuickItem
используйте QSGSimpleTextureNode
, чтобы показать результаты рендеринга. QtQuick поддерживает его собственное состояние GL, которое вы могли бы испортить, поэтому рекомендуется использовать только классы QSG * для показа пользовательского контента. В принципе, простой QtQuick - это инструмент для рендеринга прямоугольников, а не 3D-контента в целом.
Пример (Lame):
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.