Using Legacy OpenGL calls with QT6
-
Hello, I'm new to Qt and am trying to import some older C++ openGL code. I'm currently using Qt 6.4. I've subclassed my OpenGL-using class to
QOpenGlFunctions
.Many of the
glFoo
calls "work" but the class also uses calls likeglEnableClientState
,glVertexPointer
,glNormalPointer
,glTexCoordPointer
,glDisableClientState
,glColor4fv
, &glMaterialfv
which come up with errors likeundefined reference to __imp_glTextCoordPointer
. Looking at the documentation these appear to no long be supported by "default" but it looks like they are supported using older versions ofQOpenGlFunctions
such asQOpenGlFunction_1_4
(https://doc-snapshots.qt.io/qt6-dev/qopenglfunctions-1-4.html).Trying to change my subclass from
QOpenGLFunctions
toQOpenGLFunctions_1_4
complains that really onlyQOpenGLFunctions_1_4_CoreBackend
andQOpenGLFunctions_1_4_DeprecatedBackend
exist but there appears to be no documentation on those and if I subclass to one of them I start seeing complaints about my constructor...How do I actually access the functions from these older versions of the class?
-
Hi and welcome to devnet,
If memory serves well, these classes are automatically generated out of the corresponding specifications.
Which error are you getting with them ?
Also, on which platform are you building your code ?
-
Thanks for the quick reply.
To my knowledge, I haven't explicitly defined what OpenGL spec I'm targeting. I supposed it's just using the newest. A 2 minutes Google search, just now, didn't give me the answer on how to define the targeted spec but I'll keep looking for that.
I'm on Windows 10 using Qt 6.4 with CMake 3.24.2, and GDB & G++ in MinGW 11.2.0, in Qt Creator 8.0.2. I'm building for Windows 10 right now (and want to later expand to Linux as well).
Thanks.
-
Sorry, there was a word missing (fixed now). I meant to ask which error are you getting ?
The specifications used comes from the Khronos group.
-
The errors all take the form
undefined reference to '__impglFoo'
glDrawElements
is a "supported" call. If you check QOpenGLFunctions you'll see it listed (but you won't seeglDisableClientState
)
glDisableClientState
is an "unsupported" call. While it is not in QOpenGLFunctions If you check QOpenGLFunctions_1_4 you'll see it (andglDrawElements
) listed.
but you see that both calls are somewhat recognized as they have tooltips and they don't, initially, throw an error. In fact you can find them in
gl.h
But the "older" set don't seem to have actualy functions to link against.
So, ultimately, I'm just trying to figure out how to specify that I want to use one of these older specifiations (I think).
Thanks for your time.
-
OpenGL 3.1 introduced profiles. Core profile does not support these old functions and Compatibility profile does.
So first you have to make sure you have a context in version either lower than 3.1 (which does not support profiles) or 3.1 and up set up to use Compatibility profile. AFAIK Qt does not support OpenGL < 3.1 anymore, so you only have the latter option.If you're not sure what context you have you can simply do
qDebug() << your_context
and it will print out all the parameters, or you can query individual fields of it e.g.your_conext->format()->profile()
. If your context is not set correctly the simplest way is to set it up like this before any OpenGL is initialized in your app:QSurfaceFormat fmt; fmt.setVersion(3,1); fmt.setProfile(QSurfaceFormat::CompatibilityProfile); fmt.setOptions(QSurfaceFormat::DeprecatedFunctions); QSurfaceFormat::setDefaultFormat(fmt);
When you have the correct context you can access the deprecated functions like this:
QOpenGLFunctions_1_4* funcs = QOpenGLVersionFunctionsFactory::get<QOpenGLFunctions_1_4>(context()); if(funcs) { //do OpenGL 1.4. stuff, for example funcs->glEnableClientState(GL_VERTEX_ARRAY); } else { // Not a valid context? }
-
As for your screenshots - gl.h is a vanilla OpenGL header provided by your toolchain (MinGW in your case).
You can't use the gl* functions from the gl.h header directly. Those are just function signatures that need to be dynamically resolved first from the implementation provided by your graphics card driver. That's why you're seeing the unresolved externals errors when you try to use them.Qt does that resolving for you, but, unlike the raw OpenGL header, it splits them into the Forward and Deprecated functions and puts them in QOpenGLFunctions and the QOpenGLFunctions_X_X classes. The easiest way to use the forward functions is to subclass QOpenGLFunctions, but to get the deprecated QOpenGLFunctions_X_X instance you go through a factory like I posted above.