[Qt-interest] custom widgets and OpenGL

Oliver.Knoll at comit.ch Oliver.Knoll at comit.ch
Fri Nov 12 11:04:02 CET 2010


Hi,

Welcome to the Qt development world :)

On 2010-11-12 Tyler Tyler Daniel wrote:

> I have have several ogl windows displaying simple scenes, and need to implement
> a manipulation widget with a few different active areas ("handles").

First off all, I have almost zero practical experience with the QGraphicsView, so my comments concern the QGLWidget approach.

>  1) recommendations for a basic approach?  I'm new to Qt and don't have a good
> mental picture yet of what all is available.

I can't tell you which is the "better" way. The QGraphicsScene approach offers you much more functionality than a simple QGLWidget.

Think of QGraphicsScene of a "container" for all sorts of graphic items - among them also QWidget based items.

Unfortunatelly I just read this thread here:

  http://www.qtcentre.org/threads/12309-Adding-QGLWidget-to-QGraphicsScene-problem

"Hi, guys. We don't directly support embedding of widgets that use Qt::WA_PaintOnScreen, such as QGLWidget, QX11EmbedContainer and QAxWidget. You can, however, set a QGLWidget as the viewport for QGraphicsView, try to embed the widget, and see what happens. If the QGLWidget uses QPainter to draw, it should work fine. But unfortunately it's not officially supported."

In other words, embedding a "pure QGLWidget" into a QGraphicsScene is not supported.

As a matter of fact, even the current Qt documentation states the same:

  http://doc.qt.nokia.com/4.7/qgraphicsscene.html#addWidget

"Note that widgets with the Qt::WA_PaintOnScreen widget attribute set and widgets that wrap an external application or controller are not supported. Examples are QGLWidget and QAxWidget."

HOWEVER, the entire QGraphicsScene (more specific: the corresponding QGraphicsView, see #setViewPort() method) CAN be painted onto a QGLWidget! So if you are fine with using the QPainter / QGraphicsScene API to draw your objects (which is then mapped by Qt to the appropriate OpenGL function calls), then you HAVE OpenGL support. Plus all the goodies from QGraphicsScene, such as managing the location of items, zooming the entire scene etc.

But apparently you can't use "raw" OpenGL functions yourself (UPDATE: that is actually wrong, see below ;), as you would in a simple QGLWidget. So if you have existing OpenGL rendering code, then QGLWidget is your only way to go.

>  2) anyone know of any reasons to not use a QGLWIdget (subclass) as a window?

Uhm... you HAVE to subclass QGLWidget, in order to re-implement the initializeGL(), updateGL() and resizeGL() methods, to actually get some meaningful rendering done ;)

> I've read that there have been problems with full-screen in the past.  In a simple
> test here on Win7 it seems to work ok if I have two monitors attached.  With only
> one monitor I get brief flickering to black when switching windows...

But I understand your question is more aiming at whether it is possible to have a single QGLWidget as the only (main) widget of your application? I don't see any reasons why that should not be possible without problems - any QWidget based widget can be the "top-level" widget, even a simle QPushButton widget.

And "it works when I have 2 monitors attached, but flickers when only one monitor attached" could also be a graphics driver issue, or a "double-buffer" / clear-background issue: QGLWidgets should not have the "autoFillBackground" property set to false, since they are responsible for drawing the entire widget area anyway - but by default that should be the case for QGLWidgets (autoFillBackground = false), see http://doc.trolltech.com/4.7/qwidget.html#autoFillBackground-prop

Also QGLWidgets have double-buffering enabled by default: http://doc.trolltech.com/4.7/qglformat.html#doubleBuffer so flickering could also be caused by "swapping" the buffers at the wrong moment (by an explicit glSwapBuffers in the code). But then again, you say the flickering only happens when changing window focus... hmm..

> 3) if I go the QGLWidget subclass route, would it be easy to add in Qt widgets /
> text rendering later by creating a QPainter, or something like that?

There is an example which shows you how to mix QPainter with GL calls:

  http://doc.qt.nokia.com/4.7/opengl-overpainting.html

The tricky part is to realise that both the "GL world" and "QPainter world" modifiy the model/view matrix stack.  So I think in this example they first do the OpenGL function calls, THEN do the QPainter calls (which are off course also mapped to GL functions). Carefully study the "Summary" below.

In theory it would also possible to really "mix" GL calls with QPainter calls in any order, therefore a method http://doc.qt.nokia.com/4.7/qpainter.html#beginNativePainting (and endNativePainting) has been added in Qt 4.6, or so I understand.

There was an article on "Qt Labs" about "Mixing QPainter and Native OpenGL": http://labs.qt.nokia.com/2010/01/06/qt-graphics-and-performance-opengl/ which goes a little bit more into depth.


Uhm... and just now I found this article which pretty much shows what you want, I guess. Apparently you CAN use "raw OpenGL commands" inside a QGraphicsView! Here is how:

  http://doc.trolltech.com/qq/qq26-openglcanvas.html


Here are some more pointers with regards to "QPainter QGLWidget" on "Qt Labs":
  http://labs.qt.nokia.com/?s=qpainter+qglwidget&x=0&y=0

So I guess now you have plenty of information (and yes, do have a look at the Qt Labs and "Qt Quarterly" articles, besides the already excellent Qt Documentation they provide very helpful "How To's" and "Behind the scenes" articles ;)


Good luck,
  Oliver
--
Oliver Knoll
Dipl. Informatik-Ing. ETH
COMIT AG - ++41 79 520 95 22






More information about the Qt-interest-old mailing list