Accelerate your widgets with OpenGL

Posted by sroedal on June 27, 2008 · 11 comments

To breathe some new life into the graphics dojo, here’s an example of how to put widgets on top of an OpenGL scene using QGraphicsView. By leveraging the synergy (tounge in cheek) of the OpenGL module and graphics view’s in 4.4 new widget capabilities, the long lacking feature of putting widgets in OpenGL becomes possible. All that’s needed is to set a QGLWidget as viewport on the graphics view, override QGraphicsScene::drawBackground() to do the OpenGL rendering, and add widgets and other graphics items to the graphics scene as usual. The result can be seen in the screenshot below, which shows a simple obj-model viewer application written in just a couple of hundred lines of code:

Widgets on top of an OpenGL scene

The source code is available by “svn checkout svn://labs.trolltech.com/svn/graphics/dojo/modelviewer”. Have fun!

Update (8 Feb 2010): Latest version of source code with some new patches is available at http://qt.gitorious.org/qt-labs/modelviewer

QShare(this)

Possibly related posts:

  1. Hitching Qt/Embedded to a framebuffer OpenGL ES (2) abstraction
  2. Alien widgets on Mac

11 comments

1 Jay Cralley June 27, 2008 at 3:26 pm
 

Hi,

This looks and sounds great. But I would like to know how good is the performance of this versus drawing the OpenGL scene to a PBuffer or FBO and then copying it to the background?

Jay

2 sroedal June 27, 2008 at 3:45 pm
 

Using an FBO or pbuffer will probably be quite a bit slower, since you then need to do a read-back from graphics memory. In this example all the rendering is done in OpenGL, both the 3d model and the widgets on top. Plus, using QGraphicsItem’s cache mode combined with QtOpenGL’s implicit texture caching means that unless the widgets are updating they are cached as textures, thus only one texture needs to be drawn per widget. So you can actually get really good performance with this approach.

3 guardian June 27, 2008 at 4:01 pm
 

i just tested it under ubuntu hardy, compiz enabled, intel gma 950 card
it works but i get flickering, just so you know :)

4 Thomas June 29, 2008 at 3:31 pm
 

I think there is a good chance that the flickering is an ubuntu and/or compiz bug, and not a Qt problem as such:

https://wiki.ubuntu.com/RedirectedDirectRendering

5 David Johnson July 3, 2008 at 12:04 am
 

I think it’s a video driver “bug”. That’s what TT support told me. You need hardware accelerated XRender for acceptable results, and there are several video drivers that don’t have that. I wish there were a way to “gracefully downgrade” the feature, but there’s none that I can find. So I avoid the feature whenever possible because I don’t have any control over my users’ hardware.

6 tru July 9, 2008 at 6:17 pm
 

Running Qt4.4 on osx leopard I get this backtrace:

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_PROTECTION_FAILURE at address: 0×00000000
0×00000000 in ?? ()
(gdb) bt
#0 0×00000000 in ?? ()
#1 0x0009a8bf in QOpenGLPaintEnginePrivate::composite ()
#2 0x0009aeef in QOpenGLPaintEnginePrivate::composite ()
#3 0x000a26cc in QOpenGLPaintEnginePrivate::drawFastRect ()
#4 0x000a2bcf in QOpenGLPaintEngine::drawRects ()
#5 0x00a88c50 in QPainter::drawRects ()
#6 0x00f0e552 in QGraphicsRectItem::paint ()
#7 0x00f28eba in _q_paintItem ()
#8 0x00f2a3ac in QGraphicsScenePrivate::drawItemHelper ()
#9 0x00f2bdff in QGraphicsScene::drawItems ()
#10 0x00f3f024 in QGraphicsView::drawItems ()
#11 0x00f46ad8 in QGraphicsView::paintEvent ()
#12 0x009d8968 in QWidget::event ()
#13 0x00d42385 in QFrame::event ()
#14 0x00dc825f in QAbstractScrollArea::viewportEvent ()
#15 0x00f4aa22 in QGraphicsView::viewportEvent ()
#16 0x00dcb225 in QAbstractScrollAreaFilter::eventFilter ()
#17 0x003368e7 in QCoreApplicationPrivate::sendThroughObjectEventFilters ()
#18 0x009962e6 in QApplicationPrivate::notify_helper ()
#19 0x0099cffc in QApplication::notify ()
#20 0×00336691 in QCoreApplication::notifyInternal ()
#21 0x00a04246 in QWidgetPrivate::qt_widget_event ()
#22 0x962fc763 in DispatchEventToHandlers ()
#23 0x962fbb9d in SendEventToEventTargetInternal ()
#24 0x962fba02 in SendEventToEventTargetWithOptions ()
#25 0x9631f421 in HIView::SendDraw ()
#26 0x9631ef0e in HIView::RecursiveDrawComposited ()
#27 0x9631f072 in HIView::RecursiveDrawComposited ()
#28 0x9631f072 in HIView::RecursiveDrawComposited ()
#29 0x9631f072 in HIView::RecursiveDrawComposited ()
#30 0x9631e30c in HIView::DrawComposited ()
#31 0x9631e01f in HIView::Draw ()
#32 0x9631df6f in HIView::Render ()
#33 0x9631d895 in WindowData::PrepareForVisibility ()
#34 0x9631d019 in _ShowHideWindows ()
#35 0x9631cef6 in ShowHide ()
#36 0x00a01879 in QWidgetPrivate::show_sys ()
#37 0x009db5f7 in QWidgetPrivate::show_helper ()
#38 0x009de423 in QWidget::setVisible ()
#39 0x000073f0 in QWidget::show (this=0xbffff858) at qwidget.h:470
#40 0x0000717f in main (argc=1, argv=0xbffff8f4) at main.cpp:52

7 tru July 9, 2008 at 6:21 pm
 

Hi, I just tried this with Qt4.4 on Leopard. I got a crash, the backtrace is posted here: http://3e196cfc3da9f024.paste.se/

8 Anssi July 10, 2008 at 12:08 pm
 

Hi,

Thanks for great post!

Have you test GLSL/Cg with GraphicsView?
I tried to put QWebView -widget into GraphicsView using GL-rendering, but results were not really good.
It was slow and ugly. Maybe I did something wrong.. should make some more tests to verify.

9 sroedal July 10, 2008 at 2:05 pm
 

tru: That sounds like an issue that should be fixed in 4.4.1, could you perhaps try the snapshots?

Anssi: using GLSL or Cg with graphicsview should be possible as long as you have an OpenGL viewport, though there’s currently no official way of combining fragment/vertex shaders with QPainter drawing. With native OpenGL commands it ought to work just fine. If you want to use a QWebView in a graphicsview with a QGLWidget viewport you could try setting the cache mode of the proxy widget item to DeviceCoordinateCache to force the widget to be drawn into a pixmap before being drawn on the QGLWidget. If you want to animate the item ItemCoordinateCache might be a faster option as long as the web view isn’t updating too often.

10 paco July 17, 2008 at 2:21 pm
 

Im dying to get this example’s source code, but the svn checkout isnt working for me (svn co svn://lab.trolltech.com/svn/graphics/dojo/modelviewer mv). is ther ea way I can get it? pretty please?

to psandoval@gmail.com

Thanks in advance!!

11 sroedal July 18, 2008 at 8:31 am
 

paco: mailed it to you

Comments on this entry are closed.

Previous post:

Next post: