February 28, 2011

Merinas Merinas
Lab Rat
89 posts

OpenGL view in QML

Page  
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

  1. class GLWidget : public QGLWidget
  2.  {
  3.   Q_OBJECT
  4.  
  5.  public:
  6.   GLWidget(QWidget *parent = 0)
  7.   : QGLWidget(QGLFormat(QGL::SampleBuffers), parent){}
  8.  
  9.  protected:
  10.  
  11.   void paintGL()
  12.   {
  13.    glClear(GL_COLOR_BUFFER_BIT);
  14.    glLoadIdentity();
  15.    //something here
  16.   }
  17.  
  18.  
  19.   void resizeGL(int width, int height)
  20.   {
  21.    int side = qMin(width, height);
  22.    glViewport((width - side) / 2, (height - side) / 2, side, side);
  23.  
  24.    glMatrixMode(GL_PROJECTION);
  25.    glLoadIdentity();
  26.    glOrtho(-0.5, +0.5, -0.5, +0.5, 4.0, 15.0);
  27.    glMatrixMode(GL_MODELVIEW);
  28.   }
  29.  };
  30.  
  31.  
  32. class MyPushButton : public QGraphicsProxyWidget
  33. {
  34.     Q_OBJECT
  35.  
  36.  
  37. public:
  38.     MyPushButton(QGraphicsItem* parent = 0)
  39.         : QGraphicsProxyWidget(parent)
  40.     {
  41.   widget = new GLWidget();
  42.         widget->setAttribute(Qt::WA_NoSystemBackground);
  43.         setWidget(widget);
  44.     }
  45.  
  46. private:
  47.  GLWidget *widget;
  48. };
  49.  
  50. class QWidgetsPlugin : public QDeclarativeExtensionPlugin
  51. {
  52.     Q_OBJECT
  53. public:
  54.     void registerTypes(const char *uri)
  55.     {
  56.         qmlRegisterType<MyPushButton>(uri, 1, 0, "MyPushButton");
  57.     }
  58. };
  59.  
  60. #include "qwidgets.moc"
  61.  
  62. 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 [labs.qt.nokia.com]
At least, did someone know where I could the source code of the video?

Thanks

21 replies

February 28, 2011

Bradley Bradley
Lab Rat
314 posts

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.

  1. QDeclarativeView *view = new QDeclarativeView;
  2. QGLWidget *glWidget = new QGLWidget;
  3. 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

 Signature 

Nokia Certified Qt Specialist.

March 1, 2011

mbrasser mbrasser
Ant Farmer
452 posts

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

March 1, 2011

Merinas Merinas
Lab Rat
89 posts

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

Regards,
Merinas

March 1, 2011

Merinas Merinas
Lab Rat
89 posts

I’ve failed for now. And after thinking I don’t see any difference between yours solutions.
I’ve tried that : (.hpp)

  1. #ifndef QWIDGETS_HPP
  2. #define QWIDGETS_HPP
  3.  
  4. #include <QDeclarativeItem>
  5.  
  6. class MDE : public QDeclarativeItem
  7. {
  8.  Q_OBJECT
  9.  
  10. public:
  11.  MDE(QDeclarativeItem *parent = 0);
  12.  void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
  13. };
  14.  
  15. #endif // QWIDGETS_HPP

(cpp)
  1. #include "qwidgets.hpp"
  2. #include <qdeclarative.h>
  3. #include <QDeclarativeView>
  4. #include <QApplication>
  5. #include <QGLWidget>
  6. #include <QPainter>
  7.  
  8.  
  9. MDE::MDE(QDeclarativeItem *parent )
  10. {
  11.  setFlag(QGraphicsItem::ItemHasNoContents, false);
  12. }
  13.  
  14. void MDE::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
  15. {
  16.  painter->beginNativePainting();
  17.  glClear(GL_COLOR_BUFFER_BIT);
  18.  glLoadIdentity();
  19.  glBegin(GL_QUADS);
  20.   glColor3ub(0,0,255);
  21.   glVertex2d(-0.75,-0.75);
  22.   glVertex2d(-0.75,0.75);
  23.   glColor3ub(255,0,0);
  24.   glVertex2d(0.75,0.75);
  25.   glVertex2d(0.75,-0.75);
  26.  glEnd();
  27.  painter->endNativePainting();
  28. }
  29.  
  30.  
  31. int main(int argc, char *argv[])
  32. {
  33.  QApplication app(argc, argv);
  34.  
  35.  qmlRegisterType<MDE>("MDEPlugins", 1, 0, "MDE");
  36.  
  37.  QDeclarativeView view;
  38.  QGLWidget *glWidget = new QGLWidget;
  39.  view.setViewport(glWidget);
  40.  view.setSource(QUrl::fromLocalFile("test.qml"));
  41.  view.show();
  42.  return app.exec();
  43. }

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

March 2, 2011

mbrasser mbrasser
Ant Farmer
452 posts

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):

  1. p->beginNativePainting();
  2. glBegin(GL_QUADS);
  3. glColor3ub(0,0,255);
  4. glVertex2d(0, 0);
  5. glVertex2d(0, height());
  6. glColor3ub(255,0,0);
  7. glVertex2d(width(), height());
  8. glVertex2d(width(), 0);
  9. glEnd();
  10. p->endNativePainting();

Does it work for you?

Regards,
Michael

March 2, 2011

Merinas Merinas
Lab Rat
89 posts

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.

August 17, 2011

honeyheng honeyheng
Lab Rat
1 posts

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

August 17, 2011

Merinas Merinas
Lab Rat
89 posts

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.

November 21, 2011

qtd1d1 qtd1d1
Lab Rat
71 posts

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

November 21, 2011

Merinas Merinas
Lab Rat
89 posts

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.

November 21, 2011

qtd1d1 qtd1d1
Lab Rat
71 posts

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) :

  1. while (animationIsRunning) {
  2.     paintQMLScene();
  3.     swapAndBlockForNextVSync();
  4. }

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

January 11, 2012

Huemac Huemac
Lab Rat
2 posts

I’m a little confused. Merinas could you paste what’s inside your “test.qml” please?

January 18, 2012

Merinas Merinas
Lab Rat
89 posts

Nothing special just something like

  1. import QtQuick 1.0
  2.  
  3. OpenGLItem{
  4.     width:200
  5.     height:200
  6. }

January 25, 2012

Huemac Huemac
Lab Rat
2 posts

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 [developer.qt.nokia.com] example to show inside a QML rectangle element.

May 21, 2012

ultramanjones ultramanjones
Lab Rat
8 posts

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!

Page  
1

  ‹‹ HWND in QML      ListView contentY problem ››

You must log in to post a reply. Not a member yet? Register here!