Windows doesn't provide the prototypes of any OpenGL function introduced after OpenGL 1.1. You must resolve the pointers to those functions at runtime (via GetProcAddress
-- or better QOpenGLContext::getProcAddress
, see below).
Qt offers excellent enablers to ease this job:
QOpenGLShader
andQOpenGLShaderProgram
allow you manage your shaders, shader programs, and their uniforms. QOpenGLShaderProgram provides nice overloads allowing you to seamlessly passQVector<N>D
orQMatrix<N>x<N>
classes:QMatrix4x4 modelMatrix = model->transform(); QMatrix4x4 modelViewMatrix = camera->viewMatrix() * modelMatrix; QMatrix4x4 modelViewProjMatrix = camera->projMatrix() * modelViewMatrix; ... program->setUniform("mv", modelViewmatrix); program->setUniform("mvp", modelViewProjMatrix);
QOpenGLContext::getProcAddress()
is a platform-independent function resolver (useful in combination withQOpenGLContext::hasExtension()
to load extension-specific functions)QOpenGLContext::functions()
returns a QOpenGLFunctions object (owned by the context), which offers as public API the common subset between OpenGL 2 (+FBO) / OpenGL ES 2.¹ It will resolve the pointers behind the scenes for you, so all you have to do is callingfunctions->glUniform4f(...);
QOpenGLContext::versionFunctions<VERSION>()
will return aQAbstractOpenGLFunctions
subclass, namely, the one matching theVERSION
template parameter (or NULL if the request can't be satisfied):QOpenGLFunctions_3_3_Core *functions = 0; functions = context->versionFunctions<QOpenGLFunctions_3_3_Core>(); if (!functions) error(); // context doesn't support the requested version+profile functions->initializeOpenGLFunctions(context); functions->glSamplerParameterf(...); // OpenGL 3.3 API functions->glPatchParameteri(...); // COMPILE TIME ERROR, this is OpenGL 4.0 API
As an alternative way, you can make your "drawing" classes /inherit/ from
QOpenGLFunctionsX
. You can initalize them as usual, but this way you can keep your code like:class DrawThings : public QObject, protected QOpenGLFunctions_2_1 { explicit DrawThings(QObject *parent = 0) { ... } bool initialize(QOpenGLContext *context) { return initializeOpenGLFunctions(context); } void draw() { Q_ASSERT(isInitialized()); // works, it's calling the one in the QOpenGLFunctions_2_1 scope... glUniform4f(...); } }
¹ There are also "matching" classes in the QtOpenGL
module, i.e. QGLContext
and QGLFunctions
. If possible, avoid using QtOpenGL
in new code, as it's going to be deprecated in a couple of releases in favour of the QOpenGL*
classes.