Difference in opengl speed between Qt 4/5 and Opengl API

10,267

Solution 1

I have read all the questions on SO that i could find about qt 4 and 5 opengl. This one came the closest OpenGL vs QOpenGL/QtOpenGL in Qt 5: differences and limitations? , I have no idea why it was closed because its a great question. The only aspect I see it missing is the speed difference.

To be a little more specific, I need to use physx, tcp/ip communication, and large numbers of quickly updating vertices and meshes. The goal is to do this as close as realtime as possible. Things like rendering is not a concern, but any bit of overhead from qt is damaging. (Everything is in 3D with C++)

There are multiple questions in your question.

"Raw" OpenGL vs "Qt" OpenGL

This question is ill posed, in that there's no such thing as "Qt OpenGL". OpenGL is the standard owned and published by Khronos. Qt just uses it.

What Qt can do for you is helping your application manage several things.

Window/context creation

Have you ever tried creating an OpenGL context under Win32? It requires a bunch of boilerplade code (see here or here), which involves creating a temporary context to check for WGL capabilities, then creating the actual context in the end...

Have you ever tried creating an OpenGL context under X11? It requires a bunch of boilerplade code (see here), which involves checking for GLX_ARB_create_context presence and then use it to create the context, or fall back to a GLX 1.3 code path and...

Have you ever tried creating an OpenGL context under Mac OS X?

Have you ever tried creating an OpenGL context under Android?

Have you ever tried creating an OpenGL context under QNX?

Have you ever tried creating an OpenGL context under DirectFB/EGLFS?

Oh, wait. Here it comes Qt:

class Window : public QWindow {
    QOpenGLContext *context;
public:
    Window() {
        QSurfaceFormat format;
        format.setVersion(3,3);
        format.setProfile(QSurfaceFormat::CoreProfile);

        setSurfaceType(OpenGLSurface);
        setFormat(format);
        create();

        context = new QOpenGLContext;
        context->setFormat(format);
        context->create();
    }
...

Yup, that's all. That creates a (toplevel) OpenGL window and a 3.3 Core Profile context. Combine it with a QTimer and you have a viable renderer. Which of course will work on all the above platforms: Win32, Mac, X11, Linux/EGLFS, QNX, iOS, Android.


Is there an overhead you have to pay for all of this? Yes, of course. But that's absolutely negligible; and you pay for it only once, i.e. when you create the window and the context.

The real heavy stuff comes from the OpenGL drawing itself, which is totally under your control: you make the context current on the window and start issuing raw OpenGL commands. Qt is not in the way there. The only moment when Qt and OpenGL will meet again will be at swap buffers time; but that's an operation that has virtually no cost.

So: Qt does not add any measurable overhead.

Window management

Of course, bundled with the above comes the fact that you can f.i. handle keyboard and mouse input with identical code across any of those platforms. Or resize the window. Or make it fullscreen. Or close it.

OpenGL helpers

Qt doesn't "just" offer a way to create an OpenGL surface and context (and the related operations: set as current, swap buffers, etc.). It goes (much) further, and offers a whole array of helper classes and functions:

  • QMatrix4x4 is a... 4x4 matrix. Which has all the nice functions you need in an OpenGL program: lookAt(), ortho(), perspective(), normalMatrix(), and so on.
  • QOpenGLContext::hasExtension and QOpenGLContext::getProcAddress are platform independent ways of resolving OpenGL entry points.
  • QOpenGLContext::versionFunctions returns an object containing all the OpenGL entry point for a given version/profile already resolved.
  • QOpenGLBuffer wraps a buffer object.
  • QOpenGLVertexArrayObject wraps a vertex array object (and has a RAII helper to bind and unbind the VAO).
  • QOpenGLTexture wraps a texture object.
  • QOpenGLFrameBufferObject wraps a frame buffer object.
  • QOpenGLShader and QOpenGLShaderProgram wrap shaders and shader programs, offering convenience methods for f.i. setting a QMatrix4x4 as a uniform variable. So, you can calculate the MVP for a given mesh on the CPU using the methods mentioned above, then set it as uniform.
  • QOpenGLDebugLogger wraps GL_KHR_debug for debugging your OpenGL applications.
  • and another bunch of stuff I don't remember right now.

Is there an overhead? Yes, but once again it is minimal, and it does not involve how you use those objects in your OpenGL code. If your OpenGL code is fast and well structured, you'll find those helpers useful to manage it, and they won't make it run any slower.

(Example of "useful to manage it": QOpenGLVertexArrayObject will let you use a VAO on OpenGL 3.0, or on any Desktop OpenGL version where the GL_ARB_vertex_array_object extension is present, or on OpenGL ES2 if GL_OES_vertex_array_object is present. You don't need to resolve the right set of functions depending on the runtime. Qt will do that for you and provide the same APIs for creating, binding, releasing and destroying a VAO).

Is everything that good? No. I must be honest here, there are bits and bolts which would benefit from some love.

For instance, QOpenGLFrameBufferObject has a limited API, not supporting f.i. any amount of color attachments. QOpenGLBuffer would need some work for supporting more buffer types / binding targets. There's still no support for program pipelines. There's still no support for uniform buffers.

On the other hand, you have things such as QOpenGLTexture, which supports quite recent features such as immutable storage and texture views.

Does that mean you can't use those features? Of course you can. Just go back to raw OpenGL code if you need features Qt doesn't give you right now. Or, consider contributing those features to Qt!

Qt

Of course, once you go the Qt path, you have Qt. Which means, in the QtCore and QtGui libraries alone:

  • event loops
  • timers
  • signals and slots
  • threads
  • Unicode strings + i18n
  • containers
  • regular expressions
  • file handling
  • plugin loading
  • settings
  • mimetypes
  • input handling
  • image I/O
  • 2d imperative painting using a raster engine
  • JSON
  • XML
  • and another bunch of stuff I don't remember right now.

Of course, all of the above is cross platform.

By the way, Qt also has:

  • QtWidgets for cross platform 2d widgets
  • QtSql for DB access
  • QtNetwork for TCP/UDP/SSL sockets, as well as a high level HTTP/FTP engine
  • QtTest for unit tests
  • QtWebkit for embedding webkit
  • and another bunch of stuff I don't remember right now

OpenGL in Qt 4 vs 5

Are there any huge differences between how OpenGL is handled in Qt 4 vs Qt 5? Not really...

In Qt 4 the class to use to do OpenGL rendering was QGLWidget. It lived in the QtOpenGL module (and not in QtGui -- remember that in Qt 4 widgets lived in QtGui too). Also, what's actually a subset of the Qt 5 OpenGL helpers I listed above was available there under a QGLFoo name (f.i. QGLBuffer instead of QOpenGLBuffer).

In Qt 5 the QtOpenGL module is still there to keep old applications work. But:

  • QtGui and QtWidgets were split. QtGui now contains the low level bits to handle WM, creating GL contexts and surfaces, 2d painting, and basically the stuff I listed above. QtWidgets instead contains the widgets themselves.

  • QtOpenGL still contains the QGL* classes, but now links to QtWidgets (as it contains QGLWidget). This means that using QGLWidget means you'll link to a somehow big library even if you're not using widgets at all (because f.i. your app is pure OpenGL).

  • As I've shown before, QtGui is enough for creating a toplevel OpenGL window. But what if you want to embed it in a widgets-based application? Then you can still use QGLWidget or embed the QWindow via QWidget::createWindowContainer. Apart from QGLWidget, you shouldn't be using any other QtOpenGL (i.e. QGL) class. Use the counterparts in QtGui (i.e. QOpenGL classes).

  • All the above QOpenGL* classes are in QtGui, not in QtOpenGL; and they are more than the QGL* counterparts (e.g. there's no QGLVertexArrayObject), they have more features (e.g. QOpenGLShader supports geometry and tessellation shaders, QGLShader doesn't), and in general the ones to use (as they will see bugfixes and improvements, the QGL* ones won't).

  • Given that now QtGui offers OpenGL support, it would be natural to expect a QGLWidget replacement appearing directly into QtWidgets. And indeed it will, hopefully in 5.4 (the preparatory work is going into 5.3; but unfortunately the feature itself will miss the feature freeze).


Is there any reason for expecting a huge performance difference between Qt 4 and Qt 5? No. I expect your GL code to perform exactly the same. In the end Qt is not really getting in your way.

Desktop GL / ES 2

You can compile Qt 5 with either "Desktop GL" or "ES 2" support via a configure time switch. It obviously will change which headers QtGui will use when compiling, and what libraries it will link to (libGL or libGLES2, etc.). It will also change the default surface format: the above QWindow code will create a nice OpenGL ES2 surface (and probably fail the context creation since there's no OpenGL ES 3.3, oh well).

But you get the point: with the same code you can also support ES2.

The problem (in my opinion) is that it will also change some other more subtle stuff: for instance QOpenGLShader will insert some macros such as

#define highp
#define mediump
#define lowp

before all your shaders if you're using Desktop GL. The reason is that it allows you to reuse the same shaders in ES2 and Desktop GL, which lacks the precision qualifiers; hence they get erased via macros that expand to nothing.

I think these small things aren't really a gain. Maybe they reduce maintainance for very small and simple shaders (and programs made by only a vertex and afragment shader). It would have been better if Qt hand't tried to be so smart.

But your Desktop GL code path might be using more shader stages; or just in general be using features not available on ES2. Ultimately, it will significantly diverge from your ES2 code path. (Just think that in 3.3 Core you must use VAOs, while ES2 on its own doesn't eve know what a VAO is.)

Personal rant: I hate, hate, hate the fact that ES2 is not like an OpenGL profile or so, and instead sits on its own. And one must basically have a diverged code base just to make ES2 happy. Bah bah bah.

Windows

Enter the World of Pain! also known as the OpenGL driver status under Windows.

Basically, anyone but NVIDIA ships broken OpenGL drivers on Windows.

At least, "out of the box". Upgrading the drivers usually works, but you aren't always in the position of asking the users to upgrade their drivers. They're end users, not pro-gamers. Maybe they don't even have administrator privileges.

This is a problem for OpenGL applications, and especially for one of Qt's strongest tools: Qt Quick 2. Qt tries to work around this problem by using ANGLE, which is a OpenGL ES2 -> Direct3D translation layer. So, under Windows, you have the choice between

  • a Desktop OpenGL build
  • an OpenGL ES2 build via ANGLE

The choices are not equal -- ES2 of course means forgetting about doing any serious Modern GL. But apart from that, reasons for going one way or the other are available here.

Qt Quick 2

This is important and I think deserves a point on its own.

But first let's clarify things: do you need to use Qt Quick 2 to build an OpenGL application under Qt? NO, NO, and NO. Qt Quick 2 is a totally independent technology which also leverages OpenGL for rendering. As such, you can ignore it and just build your OpenGL application.

But what's Qt Quick 2 exactly? It's a library built on top of the QML language, a declarative language born for creating dynamic UIs (and now used for build systems... oh well).

Keep in mind the distinction: QML is the language, Qt Quick 2 is a library with a set of visual items (and C++ APIs for creating your own) which you program in QML.

It happens that Qt Quick 2 uses OpenGL to draw those visual items. This guarantees nice 60 FPS tear-free results, very low CPU usage, all kind of shader-based eye-candy, and so on.

So what? Well, you might be interested at giving it a kick. For instance, the API allows it to be superimposed to any pure OpenGL content you draw. So you could think of using Qt Quick 2 for handing the more traditional UI bits -- buttons, sliders, etc., while you keep control of the rendering of the main content.

Or, you can just ignore the fact it exists and keep playing with OpenGL.

Solution 2

I think that there is a lot of misunderstanding in your question and in the comments it received. The root of the problem is the very loose use of the term "Qt".

Qt is a big cross-platform application development framework. It combines features offered by many stand-alone frameworks. It offers a lot of functionality that is entirely non-gui-related. Namely cross-platform containers, threads, variants, meta object system with introspection, timers, networking, scripting using either qtscript or javascript (via qml), xml, json, state machines, and others. Qt is used for writing web services, for example, without a single line of UI code anywhere.

When it comes to user interface, Qt offers you four UI toolkits. It is entirely your choice which toolkit one you end up using. You can also mix-and-match all of them - you can have parts of your UI implemented in one toolkit, parts in another. Everything depends on your requirements.

I presume that by "Qt5" you mean Qt Quick 2, an implementation of a scene graph and UI toolkit using QML as the description/scripting platform. If all you need is a 2D, scenegraph-based toolkit, then Qt Quick 2 is a good choice. It does not offer any 3D functionality, so for 3D features you're on your own. Qt won't get in your way - in fact, it will help you, since it provides a portable wrapper API for OpenGL that hides some platform differences in getting access to OpenGL. It also provides ANGLE, a bundled implementation of OpenGL on top of Direct3D. This lets you develop in OpenGL while still targeting Direct3D on Windows.

For TCP/IP and general non-ui functionality, you should be using Qt - it makes life very easy. For 3D, you'll be using OpenGL directly via Qt-provided wrappers. You can then choose between OpenGL and ANGLE builds of Qt to decide whether you use the platform OpenGL driver directly, or whether you're using OpenGL implemented on top of DirectX (ANGLE). Since you use physx, you already have good nvidia drivers, and a decent implementation of OpenGL, so not using ANGLE is preferred. That's how I see it.

Share:
10,267

Related videos on Youtube

user-2147482637
Author by

user-2147482637

Interested in programming with python. Looking to learn more about robots, math, and programming

Updated on June 06, 2022

Comments

  • user-2147482637
    user-2147482637 almost 2 years

    I have read all the questions on SO that i could find about qt 4 and 5 opengl. This one came the closest OpenGL vs QOpenGL/QtOpenGL in Qt 5: differences and limitations? , I have no idea why it was closed because its a great question. The only aspect I see it missing is the speed difference.

    I have also read this https://qt-project.org/forums/viewthread/22921 which had a similar question, but as the back and forth about 4 vs 5, mostly discussing new features.

    My question is, is using the built in methods of QT5 faster than making a custom widget using the opengl API directly? If I am concerned about performance, is using QT a bad choice and there

    EDIT:

    To be a little more specific, I need to use physx, tcp/ip communication, and large numbers of quickly updating vertices and meshes. The goal is to do this as close as realtime as possible. Things like rendering is not a concern, but any bit of overhead from qt is damaging. (Everything is in 3D with C++)

    • Kuba hasn't forgotten Monica
      Kuba hasn't forgotten Monica about 10 years
      @user1095108 Anything visual using QML is part of Qt Quick, not QML, so please use those terms correctly. Also you're using the term "Qt" quite loosely so that your comments are not helpful. When you talk about "Qt", you're talking specifically about Qt Quick 2, not about Qt in general. It is of course perfectly valid to use Qt with bare-naked OpenGL or Direct3D code. Qt offers a lot more besides just the visuals.
    • user1095108
      user1095108 about 10 years
      @KubaOber If you want to be pedantic, at least you need to make sure, that you've got it right. Why do the docs: qt-project.org/doc/qt-4.8/qdeclarativeelements.html talk about QML elements, if they were part of Qt Quick (according to you) and not QML and I wasn't saying anything about the "validity" of using Qt alongside DX or GL, just that it is not necessarily easy, as a great many questions on this topic testify. File a documentation bug, but ooooh, these never get fixed. For anything out of the ordinary (and is a TreeView out of the ordinary, really?) you'll have problems.
  • user1095108
    user1095108 about 10 years
    Such huge choice and one buggier than the next. Bundled ANGLE is not being provided anymore as of Qt5.2, you can install it separately as a standalone .DLL. Simply put, you just talk and talk about the greatness of Qt. For gods sake, some things need to be implemented by the developer. So what, if there are 4 toolkits, if they don't provide what you need. You try to implement it yourself and you get bogged down into undocumented/poorly documented parts of Qt. Even what should be documented properly often isn't and you have to go source diving.
  • user1095108
    user1095108 about 10 years
    And for all these buggy goodies, you'll pay by having to link with huge DLLs or .sos. One does see beyond the hype eventually.
  • peppe
    peppe about 10 years
    "Huge" by what metric? QtCore and QtGui together are 10-12MB in release mode on Linux/AMD64. And as I said they provide much, much more than an OpenGL wrapper.
  • Kuba hasn't forgotten Monica
    Kuba hasn't forgotten Monica about 10 years
    @user1095108 If you write raw openGL, you end up reimplementing those goodies yourself, and there's no reason to expect they'll be any less "buggy" than Qt. Qt comes with a rather extensive test suite, that includes testing for performance regressions. Many people use those goodies, and major bugs get squished rather quickly.
  • Kuba hasn't forgotten Monica
    Kuba hasn't forgotten Monica about 10 years
    @user1095108 Peppe's is the right ballpark. For me, a small Windows 7 application, compiled statically, with LTCG and RTTI under MSVC2012, using Qt5.2's core, gui and widgets modules weighs in at about 10MB, or 4.5MB after UPX compression. This is a complete, stand-alone application that doesn't depend on any DLLs other than those that come with stock Windows itself. It's about 1.5MB more than the same code compiled with Qt 4.8. I wouldn't call it huge.
  • Kuba hasn't forgotten Monica
    Kuba hasn't forgotten Monica about 10 years
    @user1095108 Since I use 5.2 with bundled ANGLE, you're demonstrably wrong. At least with Qt you start with well tested code, even if it's undocumented :) A lot of work went into Qt, nobody's going to reimplement major parts of it in an afternoon - not even major parts of a single module.
  • Kuba hasn't forgotten Monica
    Kuba hasn't forgotten Monica about 10 years
    @user1095108 Qt is a joint effort. I'm sure it'd be widely appreciated if you would address what you perceive as documentation shortcomings by submitting patches to gerrit. The signup is trivial, you should be up and running in a couple of minutes. Qt's documentation is exemplary when you look at the industry, but it still could be much better, there's no doubt about it.
  • Kuba hasn't forgotten Monica
    Kuba hasn't forgotten Monica about 10 years
    @user1095108 Given that Qt implements a lot of platform-specific functionality that by itself is very poorly documented, I find that merely using Qt is like indirectly getting better documentation for the underlying platform functionality.
  • user1095108
    user1095108 about 10 years
    @KubaOber If the last 3 comments weren't all written by you, I would have believed you sooner. But my experience is, that Qt only serves you to a point and no further. If your requirements are not that high, it might be ok. Otherwise, I don't see why my code would be more bugged, or less, than Qts. The major bugs in Qt are not squashed for a long time, according to my experiences.
  • peppe
    peppe about 10 years
    Your comment is not constructive. You're still not bringing any technical arguments or factual evidence to support your points. The ones you brought ("huge DLL", "buggy") were so blatantly false that were easily disproven. Why should we then believe that you're reliable and "your experience" tell the truth?