Qt/3D brings Qt-style coding to 3D

For all you 3D and graphics hackers out there this will not be news:  writing OpenGL code is a pain.

Well, the Qt Graphics team is coming to save your sanity with the a new project called Qt/3D.

We teased about Qt/3D by putting a few of the foundations for it in Qt 4.6, which will be released very shortly. See the Qt/3D 4.6 features blog post for more details.

At some point Qt/3D will be available as part of Qt itself - exactly what sort of module or library we are not sure just yet - but for now you can try it out via Qt Labs!

With this post we're pleased to announce that Qt/3D will be available for experimental use via the new Qt/3D labs repo.

Old School OpenGL code gets the Qt Treatment

The trusty old QGLWidget got you past first base: a nice window set up with a OpenGL context ready to go.

But from there you're on your own with the OpenGL reference book, tearing your hair out writing code like

void My3DWidget::paintGL()
QColor clearColor(palette().color(backgroundRole()));
glClearColor(clearColor.redF(), clearColor.greenF(), clearColor.blueF(), clearColor.alphaF());
QColor color(170, 202, 0, 255);
glColor4f(color.redF(), color.greenF(), color.blueF(), color.alphaF());
static float vertices[] = {
60.0f,  10.0f,  0.0f,
110.0f, 110.0f, 0.0f,
10.0f,  110.0f, 0.0f
glVertexPointer(3, GL_FLOAT, 0, vertices);
glDrawArrays(GL_TRIANGLES, 0, 3);

just to paint a triangle on the screen.

But then if you want cross-platform code - something that you can try on your desktop, and then run on your device with OpenGL ES, it starts to look really horrible!

Macros everywhere to cope with the different function signatures and data types - not to mention shaders under ES 2.0 versus classic GL on the desktop, and a swath of other cross-platform difficulties.

With Qt/3D your code looks like this:

void My3DWidget::paintGL()
QGLPainter painter(this);
painter.setColor(QColor(170, 202, 0, 255));
QGLVertexArray vertices(QGL::Position, 3);
vertices.append(60.0f,  10.0f,  0.0f);
vertices.append(110.0f, 110.0f, 0.0f);
vertices.append(10.0f,  110.0f, 0.0f);
painter.draw(QGL::Triangles, 3);

And what's more it runs the same on your OpenGL/ES device and your desktop.  (Note that I have elided the view and model transform setup code from both examples above for the sake of space).

As mentioned in the previous blog post Qt/3D has been in the wings for some time now, and the eagle-eyed might have notice math classes springing up in Qt's GUI module.

These classes provide the basis for Qt/3D's cross platform geometry abstraction: QGLVertexArray. This nifty class also dovetails into the QGLBuffer class to take care of uploading your geometry to VBO's on the graphics adaptor, as well as coping with differences in platform on data member sizes.

Download the code from the labs repo and try out the examples - the code above comes from the tutorials directory, where you can find out more about writing your traditional OpenGL apps in the Qt cross-platform way.

Whats in Store with Qt/3D

There's more to come from Qt/3D over and above the Portability tools mentioned in the example above.

With Enablers are included encapsulation classes like QGLMaterialParameters to encapsulate OpenGL materials in a cross platform and Qt'ish way.

One of the nicest enablers is the QGLView class and its friends.  Doing your GL painting into a view looks pretty much exactly the same as with an OpenGL widget, but a few more things are taken care of for you - no need to set up tricky viewing and model transforms (which is one reason why I elided them from the code above).  But even better as a bonus you get a pan-rotate-zoom view window for free.   Its customizable using the QGLCamera class, and with QGLLightParameters you can quickly set up your own lights too.

Then there's Real 3D bringing basic but powerful geometry management, and model file import functionality. With this stuff we're just dipping our toes into the world of 3D to allow coding up of basic applications using Qt style containers, QObject based memory management, and the kinds of abstractions you've come to expect from Qt. If you're an Ogre programmer, or used to using Coin3D or CrystalSpace or other powerful 3D and modelling libraries - well, you'll still need them. We're not planning to go into competition with those established 3D toolkits.

Instead our aim is to deliver on the promise of Qt: do more with less.  It should be just as easy to use a 3D model file as it is to use a PNG file, and it should be just as easy to set up a cube with a texture on it as it is to create a Qt label. We call this component of Qt/3D Real 3D because it does start to provide functionality we're used to seeing in 3D toolkits. But we're working to be sure we do not go too far to go down this road, and thus to decide what will go in and what will left out - so please consider the stuff in our labs release as definite maybes.

QML and Qt/3D

There's a lot of buzz around Declarative UI and its associated language QML.

Qt/3D will work with Declarative UI by providing QML bindings so 3D functionality can be easily used from Declarative UI programs. There's a few demos of this in the source tree which can be tried out and you can see Henriks short video about QML and Qt/3D.

We'll expand on the exciting possibilities of QML and Qt/3D in later posts.

We hope you like what we're planning, and look forward to your feedback - keep tuned as there are more blog posts to follow, with some cool examples and things to try with Qt/3D.

Blog Topics: