Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. OpenGL view in QML

OpenGL view in QML

Scheduled Pinned Locked Moved QML and Qt Quick
22 Posts 8 Posters 34.1k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    Merinas
    wrote on last edited by
    #1

    Hi,

    I've been trying to draw opengl stuff in a QML view. I write my plugin on the widget example. And I can't make it work.
    Here my code @class GLWidget : public QGLWidget
    {
    Q_OBJECT

    public:
    GLWidget(QWidget *parent = 0)
    : QGLWidget(QGLFormat(QGL::SampleBuffers), parent){}

    protected:

    void paintGL()
    {
    glClear(GL_COLOR_BUFFER_BIT);
    glLoadIdentity();
    //something here
    }

    void resizeGL(int width, int height)
    {
    int side = qMin(width, height);
    glViewport((width - side) / 2, (height - side) / 2, side, side);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(-0.5, +0.5, -0.5, +0.5, 4.0, 15.0);
    glMatrixMode(GL_MODELVIEW);
    }
    };

    class MyPushButton : public QGraphicsProxyWidget
    {
    Q_OBJECT

    public:
    MyPushButton(QGraphicsItem* parent = 0)
    : QGraphicsProxyWidget(parent)
    {
    widget = new GLWidget();
    widget->setAttribute(Qt::WA_NoSystemBackground);
    setWidget(widget);
    }

    private:
    GLWidget *widget;
    };

    class QWidgetsPlugin : public QDeclarativeExtensionPlugin
    {
    Q_OBJECT
    public:
    void registerTypes(const char *uri)
    {
    qmlRegisterType<MyPushButton>(uri, 1, 0, "MyPushButton");
    }
    };

    #include "qwidgets.moc"

    Q_EXPORT_PLUGIN2(qmlqwidgetsplugin, QWidgetsPlugin);@

    I've also updated the .pro bu adding opengl. When I test it I've got nothing else than a white window. I've expected at least a black square somewhere on my window.

    Did I do something wrong? I know this is possible since I've seen "that":http://labs.qt.nokia.com/2010/08/10/qml3d-demo/
    At least, did someone know where I could the source code of the video?

    Thanks

    1 Reply Last reply
    0
    • B Offline
      B Offline
      baysmith
      wrote on last edited by
      #2

      QGraphicsProxyWidget is not compatible with QGLWidgets since the proxy widget uses the QWidget::render() function to render to a QPainter but OpenGL can't be rendered to a QPainter.

      If you create a QDeclarativeView backed by a QGLWidget viewport, you can create custom QML components which can render to OpenGL.

      @
      QDeclarativeView *view = new QDeclarativeView;
      QGLWidget *glWidget = new QGLWidget;
      view->setViewport(glWidget);
      @

      Alternatively, you could use the QML/3D project which will do this for you and provide much more capabilities. The project is found at http://qt.gitorious.org/qt-labs/qt3d. The source code for the "Monkey God" video can be found in http://qt.gitorious.org/qt-labs/qt3d/trees/master/demos/declarative/monkeygod

      Nokia Certified Qt Specialist.

      1 Reply Last reply
      0
      • M Offline
        M Offline
        mbrasser
        wrote on last edited by
        #3

        Hi,

        Another approach might be to subclass QDeclarativeItem, and use QPainter::beginNativePainting() and QPainter::endNativePainting in your paint function. (You'll also need to make sure you set a QGLWidget as the viewport of your QDeclarativeView)

        Regards,
        Michael

        1 Reply Last reply
        0
        • M Offline
          M Offline
          Merinas
          wrote on last edited by
          #4

          Thanks a lot for your answers. I will try to make it work with your suggestions.

          Regards,
          Merinas

          1 Reply Last reply
          0
          • M Offline
            M Offline
            Merinas
            wrote on last edited by
            #5

            I've failed for now. And after thinking I don't see any difference between yours solutions.
            I've tried that : (.hpp)
            @#ifndef QWIDGETS_HPP
            #define QWIDGETS_HPP

            #include <QDeclarativeItem>

            class MDE : public QDeclarativeItem
            {
            Q_OBJECT

            public:
            MDE(QDeclarativeItem *parent = 0);
            void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
            };

            #endif // QWIDGETS_HPP
            @
            (cpp)
            @#include "qwidgets.hpp"
            #include <qdeclarative.h>
            #include <QDeclarativeView>
            #include <QApplication>
            #include <QGLWidget>
            #include <QPainter>

            MDE::MDE(QDeclarativeItem *parent )
            {
            setFlag(QGraphicsItem::ItemHasNoContents, false);
            }

            void MDE::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
            {
            painter->beginNativePainting();
            glClear(GL_COLOR_BUFFER_BIT);
            glLoadIdentity();
            glBegin(GL_QUADS);
            glColor3ub(0,0,255);
            glVertex2d(-0.75,-0.75);
            glVertex2d(-0.75,0.75);
            glColor3ub(255,0,0);
            glVertex2d(0.75,0.75);
            glVertex2d(0.75,-0.75);
            glEnd();
            painter->endNativePainting();
            }

            int main(int argc, char *argv[])
            {
            QApplication app(argc, argv);

            qmlRegisterType<MDE>("MDEPlugins", 1, 0, "MDE");

            QDeclarativeView view;
            QGLWidget *glWidget = new QGLWidget;
            view.setViewport(glWidget);
            view.setSource(QUrl::fromLocalFile("test.qml"));
            view.show();
            return app.exec();
            }@

            And that still doesn't work. I'm not quite sure I've understand what setViewport does. Is it creating a valid context for my DeclarativeItem ? So why at least I haven't my black square from the glclear.

            I've also look at QML/3D project(I failed to build it an error occurs during link "cannot find -lQt3Dd"). Anyway, it does too much for me. I just need a valid context for my DeclarativeItem. I don't want to controller the opengl content of my view or does something dynamic, I just want to draw static predefined vertex.

            Thanks

            1 Reply Last reply
            0
            • M Offline
              M Offline
              mbrasser
              wrote on last edited by
              #6

              Hi,

              You are right, the approaches suggested are essentially the same (I just didn't read Bradley's answer closely enough before posting mine :-) )

              The following works for me (in my case I replaced the current paint function of QDeclarativeRectangle with the following code):

              @
              p->beginNativePainting();
              glBegin(GL_QUADS);
              glColor3ub(0,0,255);
              glVertex2d(0, 0);
              glVertex2d(0, height());
              glColor3ub(255,0,0);
              glVertex2d(width(), height());
              glVertex2d(width(), 0);
              glEnd();
              p->endNativePainting();
              @

              Does it work for you?

              Regards,
              Michael

              1 Reply Last reply
              0
              • M Offline
                M Offline
                Merinas
                wrote on last edited by
                #7

                Great, that work great! Thanks a lot.

                For other user who may read that. The code I've posted earlier work with the modification of mbrasser. (I've used Qt 4.7.1 win/gcc)

                I've got few last questions about the viewport. The default opengl projection is something like gluOrtho2D(0,width(),0,height()) ? If I want to change it, should I did it between the nativepainting's call? How does the transformation affect opengl (rotation, z translation) ?

                Thanks again for helping me build my opengl declarative item.

                1 Reply Last reply
                0
                • H Offline
                  H Offline
                  honeyheng
                  wrote on last edited by
                  #8

                  Hi, I'm trying this too these days. Can you tell me how the test.qml call the paint method? thank you very much~

                  1 Reply Last reply
                  0
                  • M Offline
                    M Offline
                    Merinas
                    wrote on last edited by
                    #9

                    The paint function is called when the component has just finish to load and after a geometry update. To have an update at each frame you can create a slot which call paint, or put a timer.

                    1 Reply Last reply
                    0
                    • Q Offline
                      Q Offline
                      qtd1d1
                      wrote on last edited by
                      #10

                      Is it possible to use this approach of creating an opengl declarative item to solve tearing and vsync problems?

                      1 Reply Last reply
                      0
                      • M Offline
                        M Offline
                        Merinas
                        wrote on last edited by
                        #11

                        For what I know this is the only solution for drawing opengl content in QML. What are the problems your are talking about? I have never seen such issue in QML.

                        1 Reply Last reply
                        0
                        • Q Offline
                          Q Offline
                          qtd1d1
                          wrote on last edited by
                          #12

                          thank you for your fast response :)

                          Actually I am searching for a solution to a different problem.
                          I started a project to use QML (UI) and QT C++(Logic) on embedded devices (right now I am using the i.MX53).

                          My animation is quite simple: I am moving an image and fade it in and out.

                          During this animation tearing appears. OpenGL is used to benefit from hardware accerlation.

                          My idea is, to use following algorithm (it's similar to qml scene graph) :
                          @
                          while (animationIsRunning) {
                          paintQMLScene();
                          swapAndBlockForNextVSync();
                          }@

                          One of my problems is, how to do the blocking and generally to understand the communication between qml and qt c++ regarding painting.

                          1 Reply Last reply
                          0
                          • H Offline
                            H Offline
                            Huemac
                            wrote on last edited by
                            #13

                            I'm a little confused. Merinas could you paste what's inside your "test.qml" please?

                            1 Reply Last reply
                            0
                            • M Offline
                              M Offline
                              Merinas
                              wrote on last edited by
                              #14

                              Nothing special just something like

                              @import QtQuick 1.0

                              OpenGLItem{
                              width:200
                              height:200
                              }@

                              1 Reply Last reply
                              0
                              • H Offline
                                H Offline
                                Huemac
                                wrote on last edited by
                                #15

                                Merinas,

                                Test.qml:3:1: OpenGLItem is not a type
                                OpenGLItem{
                                ^

                                What am I doing wrong?

                                Could someone just .zip and email somekind of example project using OpenGL in QML.

                                I'm trying to get "this":http://developer.qt.nokia.com/doc/qt-4.8/opengl-textures.html example to show inside a QML rectangle element.

                                1 Reply Last reply
                                0
                                • U Offline
                                  U Offline
                                  ultramanjones
                                  wrote on last edited by
                                  #16

                                  I second what Merinas said.

                                  I may not be the best Googler, but I have been searching for days for a simple example of OpenGL in QML. Everything I find is either incomplete or shows no QML at all, just C++ code with the Qt API included in it.

                                  Specifically could someone point me to a simple, complete example of an OpenGL context implemented inside a QML element (such as a rectangle). Honestly I find it quite surprising that this isn't spelled out in the documentation. Some of us really don't get much from reading 3 page long class definitions like the ones in the Qt Documentation. Not to mention, that none of them say anything specifically about implementing QML with C++/OpenGL.

                                  I will be forever in your debt if you can help me (and all the other new guys) by showing an example of how this is done.

                                  I am posting this reply here on this thread, because I believe it belongs here. Although the original poster found an answer to his question, this thread is named OpenGL view in QML and there are only 5 lines of QML posted here and they are, at best, lonely and incomplete.

                                  Cheers!

                                  1 Reply Last reply
                                  0
                                  • M Offline
                                    M Offline
                                    Merinas
                                    wrote on last edited by
                                    #17

                                    You can found all you need "on this post":http://qt-project.org/forums/viewthread/4109/#24968 and the two or three next.

                                    I compile it all here for you and other like you :

                                    (.h)
                                    @ #ifndef QWIDGETS_HPP
                                    #define QWIDGETS_HPP

                                    #include <QDeclarativeItem>
                                     
                                    class MDE : public QDeclarativeItem
                                    {
                                     Q_OBJECT
                                     
                                    public:
                                     MDE(QDeclarativeItem *parent = 0);
                                     void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
                                    };
                                     
                                    #endif // QWIDGETS_HPP
                                    

                                    @

                                    (cpp)
                                    @ #include "qwidgets.hpp"
                                    #include <qdeclarative.h>
                                    #include <QDeclarativeView>
                                    #include <QApplication>
                                    #include <QGLWidget>
                                    #include <QPainter>

                                    MDE::MDE(QDeclarativeItem *parent )
                                    {
                                     setFlag(QGraphicsItem::ItemHasNoContents, false);
                                    }
                                     
                                    void MDE::paint(QPainter *p, const QStyleOptionGraphicsItem *o, QWidget *w)
                                    {
                                    p->beginNativePainting();
                                    glBegin(GL_QUADS);
                                    glColor3ub(0,0,255);
                                    glVertex2d(0, 0);
                                    glVertex2d(0, height());
                                    glColor3ub(255,0,0);
                                    glVertex2d(width(), height());
                                    glVertex2d(width(), 0);
                                    glEnd();
                                    p->endNativePainting();
                                    
                                    }
                                     
                                     
                                    int main(int argc, char *argv[])
                                    {
                                     QApplication app(argc, argv);
                                     
                                     qmlRegisterType<MDE>("MDEPlugins", 1, 0, "MDE");
                                     
                                     QDeclarativeView view;
                                     QGLWidget *glWidget = new QGLWidget;
                                     view.setViewport(glWidget);
                                     view.setSource(QUrl::fromLocalFile&#40;"test.qml"&#41;);
                                     view.show();
                                     return app.exec();
                                    }
                                    

                                    @

                                    (test.qml)

                                    @ import QtQuick 1.0

                                    MDE{
                                        width:200
                                        height:200
                                    }
                                    

                                    @

                                    And if you want to use a qmlviewer don't forget -opengl option to active it.

                                    But you're right this is neither obvious or explain in the Qt doc. This should be easy and well documented.

                                    1 Reply Last reply
                                    0
                                    • U Offline
                                      U Offline
                                      ultramanjones
                                      wrote on last edited by
                                      #18

                                      THANKS so much for your quick reply. I am in the process of trying to implement that right now.

                                      So far I have tried to run this and I get error:

                                      @MDE is not a type.@

                                      Along with a blank white window.

                                      Incidentally, I was already trying to implement this same code and getting nowhere. Unfortunately, I am still getting nowhere.

                                      I simply created a new QtQuick Application and inserted the code you listed above along with editing the .pro file appropriately

                                      I'm just going to post what exactly what I did, as silly as it may look to someone who knows what they are doing:

                                      The .pro file (QMLOpenGLtest.pro):

                                      @# Add more folders to ship with the application, here
                                      folder_01.source = qml/QMLOpenGLtest
                                      folder_01.target = qml
                                      DEPLOYMENTFOLDERS = folder_01

                                      Additional import path used to resolve QML modules in Creator's code model

                                      QML_IMPORT_PATH =

                                      The .cpp file which was generated for your project. Feel free to hack it.

                                      SOURCES +=
                                      main.cpp

                                      Please do not modify the following two lines. Required for deployment.

                                      include(qmlapplicationviewer/qmlapplicationviewer.pri)
                                      qtcAddDeployment()

                                      HEADERS +=
                                      qwidgets.hpp

                                      QT += opengl
                                      script
                                      declarative

                                      OTHER_FILES +=
                                      test.qml@

                                      The qwidgets.hpp:

                                      @#ifndef QWIDGETS_HPP
                                      #define QWIDGETS_HPP

                                      #include <QDeclarativeItem>
                                      #include <QGLWidget>

                                      class MDE : public QDeclarativeItem
                                      {
                                      Q_OBJECT

                                      public:
                                      MDE(QDeclarativeItem *parent = 0);
                                      void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
                                      };

                                      #endif // QWIDGETS_HPP@

                                      The main.cpp:

                                      @#include "qwidgets.hpp"
                                      #include <qdeclarative.h>
                                      #include <QDeclarativeView>
                                      #include <QApplication>
                                      #include <QGLWidget>
                                      #include <QPainter>

                                      MDE::MDE(QDeclarativeItem *parent )
                                      {
                                      setFlag(QGraphicsItem::ItemHasNoContents, false);
                                      }

                                      void MDE::paint(QPainter *p, const QStyleOptionGraphicsItem *o, QWidget *w)
                                      {
                                      p->beginNativePainting();
                                      glBegin(GL_QUADS);
                                      glColor3ub(0,0,255);
                                      glVertex2d(0, 0);
                                      glVertex2d(0, height());
                                      glColor3ub(255,0,0);
                                      glVertex2d(width(), height());
                                      glVertex2d(width(), 0);
                                      glEnd();
                                      p->endNativePainting();

                                      }

                                      int main(int argc, char *argv[])
                                      {
                                      QApplication app(argc, argv);

                                      qmlRegisterType<MDE>("MDEPlugins", 1, 0, "MDE");

                                      QDeclarativeView view;
                                      QGLWidget *glWidget = new QGLWidget;
                                      view.setViewport(glWidget);
                                      view.setSource(QUrl::fromLocalFile("test.qml"));
                                      view.show();
                                      return app.exec();
                                      }
                                      @

                                      The test.qml:

                                      @import QtQuick 1.0

                                      MDE{
                                      width:200
                                      height:200
                                      }
                                      @

                                      That is all. That is the ENTIRE project (except for the auto-generated qmlapplicationviewer files) All created within a "New QtQuick Application" started from the QtCreator wizard thing.

                                      Although it may be obvious that I am missing something (or half of the program) to somebody somewhere, that is why I asked for a complete example. I have no idea what is wrong here. For all I know, this was never intended to stand alone.

                                      Still trying. If any one can help it will be most appreciated...

                                      Thanks

                                      1 Reply Last reply
                                      0
                                      • U Offline
                                        U Offline
                                        ultramanjones
                                        wrote on last edited by
                                        #19

                                        I found the problem. The test.qml file should look like this:

                                        @import QtQuick 1.0
                                        import MDEPlugins 1.0

                                        MDE{
                                        width:200
                                        height:200
                                        }@

                                        Apparently, MDEPlugins is created as a resource (URI) that needs to be imported into the QML. I was laboring under the wrong idea that qmlRegisterType was enough to "expose" the MDE class for use in the QML simply by using the new keyword "MDE" as designated in the main.cpp on line 33:

                                        @qmlRegisterType<MDE>("MDEPlugins", 1, 0, "MDE");@

                                        In fact, the "MDEPlugins" part of that C++ template names a URI for the type, and this needs to be imported into the QML just like any other resource before the type can be used. the "1,0" in the middle designates the "version", so that is why you import it with:

                                        @import MDEPlugins 1.0@

                                        I'm pretty sure I didn't change anything else in the code from my last post, just added that.

                                        I hope this will save someone some time. Cost me a couple days.

                                        Cheers!
                                        ultramanjones

                                        1 Reply Last reply
                                        0
                                        • B Offline
                                          B Offline
                                          bhaskarm
                                          wrote on last edited by
                                          #20

                                          Hi,
                                          I have the same requirement.I already had QGLWiget ,QWidget based application but now i have to use this and imprement in QML.I saw the above code works for basic operations but my in my requirement I have to rotate the image rendered in GLwidget to -180 to 180 degrees in x,y,z axis.I have requirement I should get called InitiliazeGl and resizeGL .Could you please tell me how to achieve this.

                                          Thanks,
                                          MBR

                                          1 Reply Last reply
                                          0

                                          • Login

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • Users
                                          • Groups
                                          • Search
                                          • Get Qt Extensions
                                          • Unsolved