Qt OpenGL creates an OpenGL window

In this tutorial, we will create an OpenGL object in the Qt Creator environment, it will display an empty OpenGL window, you can switch between windowed and full-screen mode, press ESC to exit, it will be the basic framework of our subsequent applications.

There are still many differences between writing OpenGL in Qt and writing in VC. Friends who are not familiar with the Qt mechanism, please get a general understanding of the Qt mechanism first, and then read the tutorial.

The effect when the program is running is as follows:


Enter the tutorial below:

Create a new empty Qt project, the project name is myOpenGL, and then add a new C++ class to the project, the class name is MyGLWidget, the base class is QGLWidget, and the type information selects "inherited from QWidget". After the addition is complete, open the project file myOpenGL.pro and complete the code as follows:

CSDN QT technology stack outline: Qt development necessary technology stack learning route and materials

 1 TARGET = myOpenGL
 2 TEMPLATE = app
 4 HEADERS += \
 5     myglwidget.h
 7 SOURCES += \
 8     main.cpp \
 9     myglwidget.cpp
11 QT       += core gui
13 greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
15 QT       += opengl

Then save the file. Open the myglwidget.h file below, and complete the class declaration as follows:

 1 #ifndef MYGLWIDGET_H
 2 #define MYGLWIDGET_H
 4 #include <QWidget>
 5 #include <QGLWidget>
 7 class MyGLWidget : public QGLWidget
 8 {
 9     Q_OBJECT
10 public:
11     explicit MyGLWidget(QWidget *parent = 0);
12     ~MyGLWidget();
14 protected:
15     //Redefinition of 3 pure virtual functions
16     void initializeGL();
17     void resizeGL(int w, int h);
18     void paintGL();
20     void keyPressEvent(QKeyEvent *event);           //Handle keyboard press events
22 private:
23     bool fullscreen;                                //Whether to display in full screen
24 };
26 #endif // MYGLWIDGET_H

Then go to the myglwidget.cpp file to first include #include<GL/glu.h>, #include<QKeyEvent> header file, and then add the definition of the function in the class:

 1 MyGLWidget::MyGLWidget(QWidget *parent) :
 2     QGLWidget(parent)
 3 {
 4     fullscreen = false;
 5 }
 7 MyGLWidget::~MyGLWidget()
 8 {
10 }

The constructor only needs to initialize the fullscreen, and the destructor does not need to do anything for the time being.

Here is the definition of initializeGL():

 1 void MyGLWidget::initializeGL()                         //Start all the settings for OpenGL here
 2 {
 3     glClearColor(0.0, 0.0, 0.0, 0.0);                   //black background
 4     glShadeModel(GL_SMOOTH);                            //enable shadow smoothing
 6     glClearDepth(1.0);                                  //set depth buffer
 7     glEnable(GL_DEPTH_TEST);                            //Enable depth testing
 8     glDepthFunc(GL_LEQUAL);                             //Type of depth testing done
 9     glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);  //Tell the system to correct for perspective
10 }

The glClearColor() function is used to set the color used when clearing the screen. The 4 parameters are used to set the red, green, blue color components and Alpha value respectively. Their value range is 0.0~1.0, and the 4 parameters here are all 0.0 , representing pure black. I then set shadow smoothing, which allows for more subtlety in the colors and lighting.

The next three lines have to do with the depth buffer. Think of the depth buffer as a layer behind the screen. The depth buffer keeps track of how deep objects go into the screen. Our program in this section does not actually use the depth buffer, but almost all OpenGL programs that display 3D scenes on the screen use the depth buffer. Its order determines which object is drawn first. This prevents a square behind a circle from being drawn in front of the circle. The depth buffer is a very important part of OpenGL. In the end we want to make the best possible perspective correction. This affects performance very slightly, but makes perspective views look a little better.

Here is the definition of resizeGL():

 1 void MyGLWidget::resizeGL(int w, int h)                 //Reset the size of the OpenGL window
 2 {
 3     glViewport(0, 0, (GLint)w, (GLint)h);               //reset current viewport
 4     glMatrixMode(GL_PROJECTION);                        //Choose a projection matrix
 5     glLoadIdentity();                                   //reset projection matrix
 6     //Set the size of the viewport
 7     gluPerspective(45.0, (GLfloat)w/(GLfloat)h, 0.1, 100.0);
 8     glMatrixMode(GL_MODELVIEW);                         //Select model observation matrix
 9     glLoadIdentity();                                   //Reset model observation matrix
10 }

The glViewport() function is used to set the size of the viewport. Use glMatrixMode() to set the projection matrix, which is used to add perspective to the scene, and then use glLoadIdentity() to reset the projection matrix, so that the projection matrix can be restored to its initial state. gluPerspective() is used to set the perspective projection matrix. Here, the viewing angle is set to 45°, the aspect ratio is the aspect ratio of the window, the nearest position is 0.1, and the farthest position is 100. These two values ​​​​are the depth that can be drawn in the scene critical value. As you can imagine, objects closer to our eyes appear larger, while objects farther away appear smaller. Finally the modelview matrix is ​​set and reset.

Here is the definition of paintGL():

1 void MyGLWidget::paintGL()                              //Start all drawing from here
2 {
3     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //Clear screen and depth buffer
4     glLoadIdentity();                                   //Reset the current model view matrix
5 }

The paintGL() function contains all the drawing code, and anything you want to display on the screen will appear in this code. In each tutorial in the future, code will be added to this function to achieve the purpose of drawing.

Finally, the definition of the keyboard event processing function KeyPressEvent(), since this has little to do with OpenGL, I will not explain too much:

 1 void MyGLWidget::keyPressEvent(QKeyEvent *event)
 2 {
 3     switch (event->key()) 
 4     {
 5     //F1 is the switching key for full screen and normal screen
 6     case Qt::Key_F1:
 7         fullscreen = !fullscreen;
 8         if (fullscreen)
 9         {
10             showFullScreen();
11         }
12         else
13         {
14             showNormal();
15         }
16         updateGL();
17         break;
18     //ESC is the escape key
19     case Qt::Key_Escape:
20         close();
21     }
22 }

Finally, add the main.cpp file to the project and change the content as follows:

 1 #include <QApplication>
 2 #include "myglwidget.h"
 4 int main(int argc, char *argv[])
 5 {
 6     QApplication app(argc, argv);
 8     MyGLWidget w;
 9     w.resize(400, 300);
10     w.show();
12     return app.exec();
13 }

Now you can run the program to see the effect!

The benefits of this article, free to receive Qt development learning materials package, technical video, including (C++ language foundation, introduction to Qt programming, QT signal and slot mechanism, QT interface development-image drawing, QT network, QT database programming, QT project combat, QT embedded development, Quick module, etc.) ↓↓↓↓↓↓See below↓↓Click on the bottom of the article to receive the fee↓↓

Tags: C++ Qt5 Qt6

Posted by ben2005 on Sat, 03 Dec 2022 11:31:18 +1030