Showing posts with label OpenGL. Show all posts
Showing posts with label OpenGL. Show all posts

Thursday, July 24, 2008

How to easily mix QWidgets and OpenGL

Around a month ago there was a post at Trolltech Labs Blogs about embedding widgets in QGLWidget. I had been wanting to do something like that for KGLLib, so I downloaded the demo and took a look. It worked fine, but the code didn't exactly fit my purposes.
The demo did all the OpenGL rendering in the QGraphicsScene subclass. Usually it is done in QGLWidget subclass and I wanted a solution which would be as transparent as possible. Thus the rendering had to stay in GLWidget.
The second problem was the events. The event handling could have been done in QGraphicsView or QGraphicsScene subclass. But if I already have a GLWidget using event handlers, I'd prefer them to continue working as before. So some kind of smart event forwarding was needed to send the events either to the gl widget or to the graphicsview, depending on whether any of the QGV widgets had focus.

I have now solved both problems and the result is a class called WidgetProxy. It takes a GLWidget as an argument and creates a QGraphicsView object, using the GL widget as viewport. The OpenGL rendering is done in your GLWidget as usual and QWidgets can be drawn onto the OpenGL scene. It also tries to do the right thing concerning events: mouse events are sent to whatever is behind the cursor (QGV widget if there is one behind the cursor, otherwise to the GL widget). Keyboard events are sent to whatever has the focus.

It's really easy to use: if you have a toplevel QGLWidget and want to add widgets into it, all you have to do is first create the WidgetProxy object:
WidgetProxy* proxy = new WidgetProxy(myGLWidget);
and then add some widgets:
QWidget* embeddedWindow = proxy->createWindow("Window title"); embeddedWindow->layout()->addWidget(new QLabel("This is an embedded widget!", embeddedWindow));
embeddedWindow->move(10, 10); proxy->addWidget(embeddedWindow);
If the GLWidget is not toplevel but in a layout then the only difference is that you have to add the proxy, not the GLWidget, into the layout.

You can even show() or hide() the GLWidget and it works as before since the WidgetProxy intercepts those events, showing or hiding the QGraphicsView instead.
The aim is to make it possible to have widgets in OpenGL with pretty much a single line of code - often the user of the GL widget doesn't even need to know about it.

The code is now part of my KGLLib, along with an example ("widgets"). KGLLib's code can be found in KDE's SVN, in trunk/playground/libs/kgllib/.

Tuesday, August 28, 2007

KDE OpenGL library?

Lately I've gotten the feeling that OpenGL is really going mainstream, including in KDE. We already have quite a few apps that are using it and it looks like more are coming.
However ATM many of those apps are reinventing the wheel by writing same generic code such as a texture class over and over again.

So I got the idea of creating some kind of KDE OpenGL library. It would have Qt-style API that KDE developers would be familiar with and would provide some common building blocks that would ease development of OpenGL apps. Right now I'm thinking texture and shader classes, maybe a camera class, some common functions, vector library (Eigen should be great for that) and perhaps an extension library (GLEW could be used). I don't want too many things though, it should still stay lightweight instead of becoming yet another fully featured 3d engine.
And it should be extensible. If your app needs e.g. cubemap textures, you should be able to write a CubemapTexture class that inherits from Texture class and provides necessary functionality. Such extensions could even be put into a common place so that other apps could copy them into their own source tree and use them without bloating the library.
The library probably needn't depend on KDE itself, just on Qt. This might make it interesting for pure Qt apps as well.

What do you think of that idea? Would you use such a library? Or know someone/something that might? Add your comments here.