OpenGL with Qt 5.6
-
I used to work with Qt 5.1.1 and OpenGL used to work fine.
Now I've installed Qt 5.6 and it seems like it is not straightforward the OpenGL application as 5.1.1 is.
The GL functions (even including it with #include <QOpenGLFunctions> returns "undefined reference". Maybe because it is a very new version, I'm not finding anything to help me out on that.
The main question is: How do proceed for using OpenGL with Qt 5.6 version? Any of GL functions works.
I see in some Qt Manual examples that initializeOpenGLFunctions() makes it work, but this statement is not recognized by my code (I've tried to #include lots of things).
The code is the most basic:
glwidget.h:
#ifndef GLWIDGET_H #define GLWIDGET_H #include <QGLWidget> class GLWidget : public QGLWidget { Q_OBJECT public: explicit GLWidget(QWidget *parent = 0); void initializeGL(); void paintGL(); void resizeGL(int w, int h); }; #endif // GLWIDGET_H
mainwindow.h:
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); private: Ui::MainWindow *ui; }; #endif // MAINWINDOW_H
glwidget.cpp:
#include "glwidget.h" #include <QWidget> #include <QOpenGLFunctions> GLWidget::GLWidget(QWidget *parent) : QGLWidget(parent) { } void GLWidget::initializeGL() { glClearColor(1,1,0,1); } void GLWidget::paintGL() { } void GLWidget::resizeGL(int w, int h) { }
main.cpp:
#include "mainwindow.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); }
mainwindow.cpp:
#include "mainwindow.h" #include "ui_mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); } MainWindow::~MainWindow() { delete ui; } test.pro: QT += core gui opengl greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TARGET = Test TEMPLATE = app SOURCES += main.cpp\ mainwindow.cpp \ glwidget.cpp HEADERS += mainwindow.h \ glwidget.h FORMS += mainwindow.ui
-
I did not work with OpengGL with Qt 5.6 .
But QGLWidget was marked as obsolete a while ago and new widget - QOpenGLWidget was introduced.
It should have being working, Are you capable to run examples using QGLWidget ?
If not, make sure correct libraries are picked up. -
Thanks for your reply, Alex.
Actually, there is no such explanations about using QOpenGLWidget for those users of earlier versions (5.1.1). I'm not a newbie, neither a advanced user, but the OpenGL usage in this new version is too much obscure. What happened with those OpenGL Functions like a simple glLoadIdentity()? No reference at all. There is no way to use it anymore.
In my point of view, the latest the version the most user friendly (at least it should). It is very commom to have a newest version that jeopardize the learnings/procedures/methodologies the user developed along his work.
I confess that I'm almost concluding that the best thing to be done is to go back to previous versions in order to maintain the hard learnings we achieved.
-
Hi and welcome to devnet,
Like @alex_malyu suggested you should grab one of the small example to get you started.
The QOpenGLXXX classes aren't doing something really new, they are just closer to what Modern OpenGL is i.e. the Programmable Pipeline which might be a bit less intuitive than the old Fixed Pipeline.
-
QOpenGLFunctions
is a class exposing OpenGL functions. As with any other class to access its members you need an instance of it.
So you can simply do it like this:#include <QOpenGLFunctions> class GLWidget : public QGLWidget { QOpenGLFunctions foo; ...
then initialize it and use:
void GLWidget::initializeGL() { foo.initializeOpenGLFunctions(); foo.glXXXX(); ...
If you want to avoid the
foo.
part, you can use inheritence like this:#include <QOpenGLFunctions> class GLWidget : public QGLWidget, public QOpenGLFunctions { ...
and then you can call the functions directly:
void GLWidget::initializeGL() { initializeOpenGLFunctions(); glXXXX(); ...
As others mentioned you should switch to
QOpenGL*
going forward. TheQGL*
classes are obsolete and should not be used in new code. They will be removed at some point.
As to the missing functions - Qt's OpenGL support is based around OpenGL ES 2.0 and above (and equivalent desktop OpenGL version). Fixed pipeline functions likeglLoadIdentity
,glBegin/glEnd
are in every possible way obsolete. They map poorly to modern hardware and are no longer developed. No new code should use them. They are removed from a core profile of OpenGL 3.0 and up.
If they were accessible to you in Qt 5.5 then I'm guessing it's because something includedgl.h
into global scope. This should not happen in general and, if anything, a glitch was fixed. Qt moves forward. Fixed function pipeline is legacy. If you need to use it for legacy code you need to create a Compatibility OpenGL profile that exposes them and ingludegl.h
on your own.
I'll just repeat - don't do that in new code. -
@Chris-Kawa said:
happen in general and, if anything, a glitch was fi
Many thanks SGaist and Chris!
Your advices are very helpful. I need to be updated about those issues and new (at least for me :( ) features we have nowadays.
Just to let you know, I changed to QOpenGLFunctions_3_0 and those fixed pipeline functions were available. However, I already saw that GLU also has (seems to) no compatibility with OpenGL ES 2.0. I felt I were in the wrong way...
Now I want to get back to school to learn about these features. All suggestions are welcome.
I'll do as Chris said for learning about too.
Kind Regards
-
QOpenGLFunctions_3_0
(and up) expose fixed pipeline because it's still part of the compatibility profile. For new code consider using core profile.
Btw. GLU is also obsolete. It's nineties technology not updated for over a decade. -
QOpenGLFunctions_3_0
(and up) expose fixed pipeline because it's still part of the compatibility profile. For new code consider using core profile.
Btw. GLU is also obsolete. It's nineties technology not updated for over a decade.Curious reading this, so what's the replacement for e.g. gluProject/gluOrtho2D/gluTess* ?
-
Fixed function pipeline does not always translate directly to the new ways.
For examplegluOrtho
sets the projection matrix (it's basically callingglOrtho
with z near and far set to -1/1). In core profile there's no single projection matrix to set. Projection matrix is usually an attribute in some of the vertex shaders and OpenGL no longer manages where it comes from. You can code it yourself or use existing libraries to construct the matrix e.g.QMatrix4x4
,glm::mat4
or whatever your preferred 3D math library is. They provide a lot more than GLU or vanilla GL ever did.
Similar withgluProject
- OpenGL no longer manages that. You can use your own implementation or a library e.g.glm::project
.
gluTess*
stuff does software tessellation - that's horribly inefficient and performance wise suitable only for small sets of data. There's hardware tessellation these days and dedicated programmable shader stages (though they don't provide 1:1 functionality with gluTess*). -
Fixed function pipeline does not always translate directly to the new ways.
For examplegluOrtho
sets the projection matrix (it's basically callingglOrtho
with z near and far set to -1/1). In core profile there's no single projection matrix to set. Projection matrix is usually an attribute in some of the vertex shaders and OpenGL no longer manages where it comes from. You can code it yourself or use existing libraries to construct the matrix e.g.QMatrix4x4
,glm::mat4
or whatever your preferred 3D math library is. They provide a lot more than GLU or vanilla GL ever did.
Similar withgluProject
- OpenGL no longer manages that. You can use your own implementation or a library e.g.glm::project
.
gluTess*
stuff does software tessellation - that's horribly inefficient and performance wise suitable only for small sets of data. There's hardware tessellation these days and dedicated programmable shader stages (though they don't provide 1:1 functionality with gluTess*).Thanks, this is very informative. Is all this available for OpenGL 2.1 and beyond (still need to support users back to this version)?
-
Programmable pipeline (shaders) was introduced in OpenGL 2.0 so you can (and should) jump over to it.
Tessellation is core in OpenGL 4.X and with extensions in 3.2 (ARB_tessellation_shader) so that's more restrictive.
You could probably achieve some sort of tessellation with geometry shaders, which are available core in 3.2 and with extensions (ARB_geometry_shader4) in OpenGL 2.0.