2012-11-28 26 views
13

Ich bin auf der Suche nach einer Möglichkeit, meine benutzerdefinierte opengl Anrufe in einem Qtquick 2.0-Element zu rendern. Um Ihnen einen Kontext zu geben: Ich habe eine C++ 3D-Engine, die OpenGL zum Rendern verwendet. Das Ziel ist es, es in einer qtquick 2.0 UI rendern zu lassen.Rendering benutzerdefinierte opengl in qt5 qtquick 2.0

Was ich herausgefunden habe, ist, dass vor qt 5.0 (qtquick 2.0) würden Sie ein QtGlWidget verwenden und das in die QDeclarativeView einbetten. Eine andere Methode, die ich gefunden habe, wäre, ein QtDeclarativeItem zu verwenden und die Methode void QDeclarativeItem :: paint (QPainter * p, const QStyleOptionGraphicsItem * o, QWidget * w) zu überschreiben.

Wie ich es verstehe, ist dies nicht mehr möglich, da QtQuick 2.0 einen neuen Renderer verwendet, der auf OpenGl basiert. Es ist daher so, wie es scheint, nicht so einfach wie das Überschreiben einer Malmethode.

Weiß jemand, wie ich ein QQuickItem implementieren würde, das das Rendern meiner Opengl-Aufrufe ermöglicht?

Antwort

3

Rendern Sie in Ihrer 3D-Engine in eine Textur und verwenden Sie QQuickItemQSGSimpleTextureNode, um die Renderergebnisse anzuzeigen. QtQuick behält seinen eigenen GL-Status bei, den Sie sonst durcheinander bringen könnten. Aus diesem Grund wird empfohlen, nur die QSG * -Klassen zum Anzeigen von benutzerdefiniertem Inhalt zu verwenden. Im Grunde genommen ist einfaches QtQuick ein Werkzeug zum Rendern von Rechtecken, nicht von 3D-Inhalten im Allgemeinen.

(Lame) Beispiel:

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; 
    } 
} 

Sie müssen auch ein Timer instanziiert den Inhalt zu aktualisieren. Sie können dies innerhalb des QQuickItems tun.

8

Sie können eines von zwei Dingen tun. Sie können den Inhalt entweder in eine Textur umwandeln oder im OpenGL-Kontext des Szenengraphen rendern, indem Sie die Signale QQuickWindow::beforeRendering oder QQuickWindow::afterRendering einhängen.

Ein Beispiel dafür, wie FBO und Textur können Sie hier: http://doc.qt.io/qt-5/qtquick-scenegraph-openglunderqml-example.html

+0

FBO (für: http://doc.qt.io/qt-5/qtquick-scenegraph-textureinsgnode-example.html

Ein Beispiel dafür, wie direkt aus der Szene Diagramm, um den OpenGL-Kontext zu machen finden Sie hier Qt 5.2): http://qt.apidoc.info/5.2.0/qtquick/qtquick-scenegraph-textureinsgnode-example.html Szenengraph - OpenGL unter QML (für Qt 5): http: // qt-project. org/doc/qt-5/qtquick-scenegraf-openglunderqml-beispiel.html – troyane