Using OpenGL with QT Creator

David Godfrey
7 min readJun 28, 2022

--

WARNING: To understand this article, it is necessary to have previous knowledge of C, C++, QT, QT Creator, OpenGL, 3D Graphics, Object Oriented Programming, Haute Couture, French Cuisine, Quantum Physics, … and if you know all that, maybe you no longer have to read this.

CONTENTS

It is well known that QT comes with OpenGL stacks installed, so it will not be very difficult (always considering our personal scale of “difficult”) to use the OpenGL library, within our QT programs.

To begin I will say that I am going to use QT Creator 3.4.2 on top of QT 5.5.0, with the Visual C++ compiler, on Windows, and as a last detail, “insignificant”, I must say that I am not an expert in QT, so I am not responsible for material or psychological damage, and as always corrections are welcome.

To start, let’s go from the beginning, sure there are twisted ways to use OpenGL in QT (to see the twisted ways to use OpenGL in QT click here, if the link is not active, I still can’t find these twisted ways), but here I am going to follow the “standard” method, so to speak, which is the one that I have seen being used the most.

This method consists of using the QGLWidget class (or its almost forgotten brother QOpenGLWidget), which is already prepared to handle OpenGL graphical output, and it is quite helpful because one of the main problems of the OpenGL graphical library is that it does not have a canvas to draw on, and QGLWidget gives you just that. It’s also good to remember that QGLWidget is just like the QWidget class (if that helps at all) only it comes prepared to draw using OpenGL, although it can use QPainter too, if we ask it nicely.

Using QGLWidget is simple, just derive a class to use as an OpenGL drawing screen and then implement the necessary methods. How is this done? Well, we are going to follow the following recipe, as an exercise:

Create Project

Create a new project of type “Qt Widget Application”. Don’t forget that we are using QT Creator (I reserve my opinion on this IDE).

The name that we are going to choose for the project is «MiOpenGL». Leave all other values ​​as default.

Adding the Evil References

Who said that QT makes your life easier? No gentlemen, there are many things that we must do by hand.

Add the references to “opengl” and to the “opengl32.lib” library, in the MiOpenGL.pro project file, at the indicated points:

If we forget these references, we’ll get the diabolical non-descriptive errors “LNK-0666 — Error in some reference I have no idea about, so you’re dead###”

And the most annoying thing, it is mandatory, I repeat MANDATORY, to do a “QMake”, after modifying the MiOpenGL.pro file.

To see if everything goes well so far, it is recommended to run the program to see if there are any errors.

Create a QGLWidget class

In the context menu of the project, select “>Add New…>C++>C++ Class”, to add a new class, which we will call “GLWidget”:

The other options, leave them by default. The content of the class should be like this:

// — — — — — — — — — — — glwidget.h — — — — — — — — — — 
#ifndef GLWIDGET_H
#define GLWIDGET_H
#include <QGLWidget>
class GLWidget : public QGLWidget
{
Q_OBJECT
public:
explicit GLWidget(QWidget *parent = 0);
signals:
public slots:
};
#endif // GLWIDGET_H
// — — — — — — — — — — — — glwidget.cpp — — — — — — — —
#include “glwidget.h”
GLWidget::GLWidget(QWidget *parent) : QGLWidget(parent)
{
}

This content is not generated directly from QT Creator, so it has to be corrected by hand. The idea is to inherit from QGLWidget, rather than QWidget.

Shaping QGLWidget

Once we have the class, we need to implement the virtual methods (if you have no idea what this means, there is a lot of information on the Web) of QGLWidget, in the declaration:

protected:
void initializeGL();
void resizeGL(int w, int h);
void paintGL();

And in the implementation we will do the simplest of implementations:

void GLWidget::initializeGL()
{
glClearColor(0, 0, 1, 1); //define blue color as background color
}
void GLWidget::resizeGL(int w, int h)
{
}
void GLWidget::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT);
}

These 3 methods are the minimum that need to be implemented from QGLWidget, in our class, to be able to display graphics using OpenGL.

The names are descriptive so they do not deserve further explanation. It is enough for us to know that the initializeGL() method will be called only once when starting our program, while the paintGL() method is called repeatedly each time the image is requested to be drawn. In our example, the only thing that is done in paintGL() is to clear the background using the color defined with glClearColor(), which in our case is blue, since the parameters are of type RGB, with the last parameter representing the opacity .

In summary, what we have done so far is create a class derived from QGLWidget, and we have customized it so that it draws what we want, but that’s it. Nothing is drawn yet, because our class is a structure without a visual part, a mannequin without a face.

Give me a Widget and I’ll draw in 3D

Now that we have implemented an elementary class from QGLWidget, we need to give it a screen, so that it can be seen.

We will obtain this, using a control (a Widget) where it can be drawn. Look how coincidences are, there is precisely one in QT Creator, which adapts well. It’s called “Widget”.

What we have to do is drag a «Widget» control to our form and size it, as it is most convenient for us:

Now we have a control that can display our graphics on the screen, but it’s a simple Widget, and it has nothing to do with our GLWidget class. What needs to be done is what is called “promoting” our Widget so that it inherits the functionalities of our GLWidget class, instead of keeping the functionalities of a simple Widget.

To do this, what we must do is select our control or Widget in the form and select the “Promote to…” option:

In this form, we must write the name of our GLWidget class, then press the “Add” button, mark the item from the top list and finally press the “Promote” button:

After carrying out this “promotion”, our Widget evolves to now be a GLWidget and follow our commands.

You can see that now our Widget control appears as a GLWidget object in the objects panel.

To verify that we have not screwed up, we can run our program, and we must see a form with a blue box in the center:

Now yes, let’s draw

Truth be told, so far we have not drawn anything, we have only cleaned the canvas. That’s great, and shows that we’re on the right track, now we can show off our drawing skills by adding additional OpenGL instructions.

The place to do that is, as you guessed it, in the paintGL() method of our GLWidget class. I’m not going to explain the OpenGL drawing functions here, I’ll just use the ones needed to draw a simple triangle:

void GLWidget::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1,0,0);
glBegin(GL_TRIANGLES);
glVertex3f(-0.6 ,0.3, 0);
glVertex3f(-0.9, -0.3, 0);
glVertex3f(-0.3 , -0.3, 0);
glEnd();
}

With these instructions, and a bit of geometry, we are saying that we want to draw a red triangle on the screen. Now, if we have done things right, we should be able to obtain the following result:

It may be necessary to adjust the size of the window, or the coordinates to achieve this masterpiece.

Well that’s it. This article is just the beginning to get started with OpenGL and QT. From here you can make the program more complicated to obtain better results, but do not forget that every good program requires a good design, after all, even the pyramids of Egypt were designed (it was not started by laying stone by stone), And that was several thousand years ago.

--

--