In this recipe, we will learn about the pipeline of OpenGL and how to render a simple shape to the window. We will continue from the example project used in the previous recipe.
mainwindow.h
and add the following headers at the top of the source code:#include <QSurfaceFormat> #include <QOpenGLFunctions> #include <QtOpenGL> #include <GL/glu.h>
mainwindow.h
:private: QOpenGLContext* context; QOpenGLFunctions* openGLFunctions;
mainwindow.cpp
and set the surface format to compatibility profile. We also set the OpenGL version to 2.1 and create the OpenGL context using the format we just declared. Then, use the context we just created to access the OpenGL functions that are relevant only to the OpenGL version we have just set, by calling context->functions()
:MainWindow::MainWindow(QWidget *parent) { setSurfaceType(QWindow::OpenGLSurface); QSurfaceFormat format; format.setProfile(QSurfaceFormat::CompatibilityProfile); format.setVersion(2, 1); // OpenGL 2.1 setFormat(format); context = new QOpenGLContext; context->setFormat(format); context->create(); context->makeCurrent(this); openGLFunctions = context->functions(); }
paintGL()
function:void MainWindow::paintGL() { // Initialize clear color (cornflower blue) glClearColor(0.39f, 0.58f, 0.93f, 1.f); // Clear color buffer glClear(GL_COLOR_BUFFER_BIT); // Render quad glBegin(GL_QUADS); glVertex2f(-0.5f, -0.5f); glVertex2f(0.5f, -0.5f); glVertex2f(0.5f, 0.5f); glVertex2f(-0.5f, 0.5f); glEnd(); glFlush(); }
paintGL()
in the paintEvent()
function:void MainWindow::paintEvent(QPaintEvent *event)
{
paintGL();
}
We must set the OpenGL version to 2.1 and the surface format to compatibility profile so that we can access the fixed-function pipeline, which no longer exists in the newer version. Alternatively, you can set the surface format to QSurfaceFormat::CoreProfile
if you want to use OpenGL 3.x and above.
We called glClearColor()
and glClear(GL_COLOR_BUFFER_BIT)
to remove the previous render buffer
(or in layman's terms, the previous frame) and fill the entire canvas with the color we provided. We will repeat this step after an image has been rendered so that it clears the entire screen before we proceed to the next frame. We called glBegin(GL_QUAD)
to tell OpenGL we are about to draw a quad on the screen. After that, we provided the positions of all the vertices (or points) to OpenGL so that it will know how the quad should be positioned on the screen by calling glVertex2f()
four times, because a quad can only be constructed by connecting four different points. Then, we called glEnd()
to inform OpenGL that we are done with the quad.
Always call glFlush()
once you are done drawing images on screen so that OpenGL clears away all the unwanted information from the memory to give space to the next drawing.
Lastly, we must call paintGL()
in the paintEvent()
function, or else nothing will be drawn on the screen. Just like what we have learned in the previous chapters, all drawings happen within the paintEvent()
function, and it will only be called by Qt when it thinks it's necessary to refresh the screen. To force Qt to update the screen, call update()
manually.
3.22.71.106