I'm looking for a way to render my custom opengl calls inside a qtquick 2.0 item. To give you some context: I have a C++ 3d engine that uses opengl for rendering. The goal is to have it rendering inside a qtquick 2.0 UI.
What I found out is that pre qt 5.0 (qtquick 2.0) you would use a QtGlWidget and embed that into the QDeclarativeView. Another way I found would be to use a QtDeclarativeItem and override the void QDeclarativeItem::paint(QPainter *p, const QStyleOptionGraphicsItem *o, QWidget *w) method.
As I understand it this is not possible anymore as QtQuick 2.0 uses a new renderer which is based on OpenGl. It is therefore as it seems not as easy as overriding a paint method.
Does anybody know how I would go about implementing a QQuickItem that allows rendering of my opengl calls?
You can do one of two things. Either render your content into a texture or render in the OpenGL context of the scene graph by hooking using the QQuickWindow::beforeRendering
or QQuickWindow::afterRendering
signals.
An example on how to use FBO and texture can be found here: http://doc.qt.io/qt-5/qtquick-scenegraph-textureinsgnode-example.html
An example on how to render directly to the OpenGL context of the scene graph can be found here: http://doc.qt.io/qt-5/qtquick-scenegraph-openglunderqml-example.html
In your 3D engine, render into a texture and in your QQuickItem
use QSGSimpleTextureNode
to show the rendering results. QtQuick maintains it's own GL state, which you could otherwise mess up, that's why it is recommended to use only the QSG* classes to show custom content. Basically, plain QtQuick is a tool for rendering rectangles, not 3D content generally.
(Lame) example:
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;
}
}
You also need to instantiate a Timer to update the contents. You can do this from within the QQuickItem.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With