Qt uses opengl to draw rectangles, 3D cameras

1. Introduction

Qt uses opengl to draw rectangles, 3D cameras

2. Software environment

2.1QT 5.14.1

The QT compiler uses MSVC2017 64bit

2.2 Code

Link: https://pan.baidu.com/s/1Fn6UpF0HLWD_mSSKe_36wA?pwd=1234 (rectangular)
Link: https://pan.baidu.com/s/1PV4sYk_WgnhUiBhyyCy4iA?pwd=1234 (three-dimensional)

3. Main process

3.1 Interface settings

There is a window that directly supports opengl in qt, but there is no way to write code for it, then create a class, inherit the QOpenGLWidget class, and then upgrade the window to the created class, you need to rewrite
insert image description here
three virtual functions,

#ifndef QQQOPENGLWIDGET_H
#define QQQOPENGLWIDGET_H

#include <QOpenGLWidget>
#include <QOpenGLFunctions_3_3_Core>

class QQQOpenGLWidget : public QOpenGLWidget,QOpenGLFunctions_3_3_Core
{
    
    
    Q_OBJECT
public:
    explicit QQQOpenGLWidget(QWidget *parent = nullptr);
protected:
    virtual void initializeGL();
    virtual void resizeGL(int w, int h);
    virtual void paintGL();
};
#endif // QQQOPENGLWIDGET_H

This constructor needs to add: QOpenGLWidget(parent), otherwise there is no way to draw

QQQOpenGLWidget::QQQOpenGLWidget(QWidget *parent) : QOpenGLWidget(parent)
{
    
    

}
void QQQOpenGLWidget::initializeGL() {
    
    
	// 这个是都要加的初始化一下,不然程序指针都是空的,调用显卡的函数
	initializeOpenGLFunctions();
}
void QQQOpenGLWidget::resizeGL(int w, int h)
{
    
    

}
void QQQOpenGLWidget::paintGL()
{
    
    
    glClearColor(0.2f,0.3f,0.3f,1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
}

Then the image will appear, and the window settings will be fine.
insert image description here

3.2 Code explanation

Here I will explain it in blocks, and I will only talk about the points that were difficult to understand when I was learning.
The first step is to create VAO, VBO, and EBO first.
The function of VAO is to record how to read the points in the buffer area. EBO will record the reading order of points, and VAO will also remember the location of EBO, which is convenient for later reading. If EBO is unbound, VAO cannot find EBO. But VBO will not, VBO can be unbound casually
VBO and EBO are a piece of video memory in the graphics card,
GL_ARRAY_BUFFER, GL_ELEMENT_ARRAY_BUFFER are different buffer areas, the buffer area is used to store the coordinates of the point, bind VBO to the buffer area, EBO is, tell Where should their data be written in the corresponding buffer area, and
finally unbind that block, which is to prevent subsequent operations from changing the already set state, preventing VAO state changes, and preventing data in VBO and EBO from being rewritten

    // 状态设置
    //创建VBO和VAO对象,并赋予ID
    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);
    glGenBuffers(1, &EBO);

    //绑定VBO和VAO对象
    glBindVertexArray(VAO);

    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

    //告知显卡如何解析缓冲里的属性值
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
    //开启VAO管理的第一个属性值
    glEnableVertexAttribArray(0);

    // 这个是状态设置完成
    // VAO会记录EBO的绑定状态,而不会记录VBO的,如果EBO提前解绑,就会找不到EBO
    glBindVertexArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

This is the code for setting the shader, fixed format, and the analysis is also written in it

    // 设置着色器
    unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
    glCompileShader(vertexShader);
    // 设置片段着色器
    unsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
    glCompileShader(fragmentShader);

    shaderProgram = glCreateProgram();
    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);
    glLinkProgram(shaderProgram);

    // glPolygonMode 是一个用于控制多边形的绘制模式的函数。它可以设置多边形的绘制模式,包括填充模式、线框模式和点模式。
    // glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);

    // 删除着色器对象的主要原因是释放内存和资源。当你将着色器对象链接到程序对象后,它们的内容已经被复制到了程序对象中,并且不再需要单独的着色器对象来执行渲染。
    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);

drawing

void QQQOpenGLWidget::paintGL()
{
    
    
    glClearColor(0.2f,0.3f,0.3f,1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    // 设定着色器
    glUseProgram(shaderProgram);
    // VAO初始化状态
    glBindVertexArray(VAO);
    // glDrawArrays(GL_TRIANGLES, 0, 3);
    // 重复绘图也不会被覆盖的,都是在一个上面的
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
}

insert image description here
insert image description here
destructor

    // 获取当前状态
    makeCurrent();
    // 1是个数
    glDeleteVertexArrays(1,&VAO);
    glDeleteBuffers(1,&VBO);
    glDeleteBuffers(1,&EBO);
    glDeleteProgram(shaderProgram);
    // 退出当前状态
    doneCurrent();

There are two ways to call drawing externally,
the first one,

void QQQOpenGLWidget::draw()
{
    
    
    // 获取当前状态
    makeCurrent();
    glClearColor(0.2f,0.3f,0.3f,1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    // 设定着色器
    glUseProgram(shaderProgram);
    // VAO初始化状态
    glBindVertexArray(VAO);
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
    // 退出当前状态
    doneCurrent();
}

The second is

    // 会调用paintGL(),进行重绘
    update();

3.3 3D 3D camera, to be updated later

Put a picture first. The code is at the top, there is a problem with the button, let’s take a look
insert image description here

Four. Reference

https://ke.qq.com/webcourse/3999604/104150693#taid=12078191069693812&vid=3701925924839353164

Guess you like

Origin blog.csdn.net/qq_45179361/article/details/131026144