1

I am trying desperately to understand the architecture of OpenGL support in Qt5.

My current problem is this: I have some existing OpenGL code (desktop, not OpenGL ES) that uses some OpenGL extensions, including glGenBuffersARB. Outside Qt5 getting access to the functions for extensions like this is trivial, for example by using GLEW I could simply do this:

glewInit();

And everything would just magically work as expected, and I could start to use glGenBuffersARB straight away. If I was ever worried, I could throw in a call to glewIsSupported to be sure it was supported.

But in Qt5 there is a warning that GLEW and QOpenGLFunctions don't play well together (copied from qopenglfunctions.h):

#ifdef __GLEW_H__
#if defined(Q_CC_GNU)
#warning qopenglfunctions.h is not compatible with GLEW, GLEW defines will be undefined
#warning To use GLEW with Qt, do not include <qopengl.h> or <QOpenGLFunctions> after glew.h
#endif
#endif

So let's say that I for the sake of this question and to satisfy the curiosity ditch GLEW completely and rely solely on Qt5 for a pure Qt5 approach. How would I get my existing OpenGL code that relies on glGenBuffersARB to work without manually binding each and every extension function manually?

NOTE: I know I can follow tips in this answer and do this:

auto functions = context->versionFunctions<QOpenGLFunctions_3_3_Core>();
if (!functions) error();
functions->initializeOpenGLFunctions();
functions->glGenBuffersARB(...);

But then I would have to prefix every single line of existing OpenGL code with functions-> which I would rather not do.

Community
  • 1
  • 1
Mr. Developerdude
  • 9,118
  • 10
  • 57
  • 95
  • 3
    FYI: Don't ever use `glGenBuffersARB`. `glGenBuffers` has been core OpenGL for nearly *fifteen years*. – Nicol Bolas Sep 21 '16 at 23:54
  • I just realized that, sorry it was a really bad example, but I think the question is still good. Just imagine I was talking about another extension that is relevant today! (that is the extension that my existing OpenGL code uses). – Mr. Developerdude Sep 21 '16 at 23:59

2 Answers2

3

But then I would have to prefix every single line of existing OpenGL code with functions-> which I would rather not do.

You could of course use QOpenGLContext::getProcAddress to load the function pointers yourself. But the only interface that Qt provides that handles function loading for you is the QOpenGLFunctions_* one. Not only that, they don't really cover extensions.

You could use Qt's OpenGL wrapper classes like QOpenGLBuffer and so forth. But those are a lowest-common-denominator sort of thing. They don't wrap everything you could do with buffers using modern OpenGL. And again, they don't cover extensions; only stuff that's core functionality.

And there's plenty of OpenGL not wrapped by such objects, so it's not exactly a comprehensive solution.

Better to stick with a proper OpenGL Loading Library.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • 1
    It's technically incorrect to say that wrappers `QOpenGLBuffer` is a lowest-common-denominator. While not supporting *all* the possible buffer object features, it actually checks for extensions, so for instance it supports ranged maps. (Then, it also has other fundamental problems). QOpenGLTexture supports immutable storage, texture views and similar. – peppe Sep 24 '16 at 14:32
  • About extensions, there's actually the QtOpenGLExtensions library (`QT += openglextensions`), that you can use just like `QOpenGLFunctions`. Like `auto f = new QOpenGLExtension_KHR_debug; f->initializeOpenGLFunctions(); f->glDebugMessage...`. I've no idea why it's not documented, likely a bug (since it's autogenerated). – peppe Sep 24 '16 at 14:38
1

The way to have GL functions be available to the class in Qt5, without needing to use a helper, is to make your GL class derive from a subclass of QAbstractOpenGLFunctions. For example your header file might look something like this:

#include <QOpenGLFunctions_1_1>
class MyGLClass : protected QOpenGLFunctions_1_1
{
    ...
}

Then in your initialize method you need to initialize the OpenGL functions like so:

void MyGLClass::initialize()
{
    if (!initializeOpenGLFunctions()) {
        qFatal("initializeOpenGLFunctions failed");
    }
}
Barry Rogerson
  • 598
  • 2
  • 15