qt使用opengl绘制矩形,三维摄像机

一. 内容简介

qt使用opengl绘制矩形,三维摄像机

二. 软件环境

2.1QT 5.14.1

QT编译器采用的是MSVC2017 64bit

2.2代码

链接:https://pan.baidu.com/s/1Fn6UpF0HLWD_mSSKe_36wA?pwd=1234 (矩形)
链接:https://pan.baidu.com/s/1PV4sYk_WgnhUiBhyyCy4iA?pwd=1234 (三维的)

三.主要流程

3.1 界面设置

qt中有直接支持opengl的窗口,但是这个没办法给他写代码,那就创建一个类,继承QOpenGLWidget类,然后再给窗口提升为创建的类,
在这里插入图片描述
需要重写三个虚函数,

#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

这个构造函数需要加上: QOpenGLWidget(parent),不然没办法出图

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);
}

然后就会出现图像了,窗口设置就好了
在这里插入图片描述

3.2 代码讲解

这里就分块讲解了,我只讲我学的时候里面比较难理解的点
第一步是先创建VAO,VBO,EBO。
VAO的作用就是记录缓存区里面的点怎么读,EBO会记录点的读取顺序的,VAO也会记住EBO的位置,方便后边读取,如果EBO解绑了,VAO就找不到EBO,但是VBO不会的,VBO随便解绑
VBO和EBO都是显卡中的一块显存,
GL_ARRAY_BUFFER,GL_ELEMENT_ARRAY_BUFFER是不同的缓存区,缓存区用来存放点的坐标,给缓存区绑定VBO,EBO就是,告诉相应的缓存区他们的数据应该往哪写入,
最后解绑那块,就是防止后续操作更改了已经设置好的状态,防止VAO状态改变,防止VBO,EBO中的数据被改写

    // 状态设置
    //创建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);

这块是设置着色器的代码,固定格式,里面也写了解析

    // 设置着色器
    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);

绘图

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);
}

在这里插入图片描述
在这里插入图片描述
析构函数

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

外部调用绘图的两种方式,
第一种,

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();
}

第二种是

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

3.3 三维三维摄像机,以后再更新

先放个图。代码在最上边,按钮有问题,凑合看吧
在这里插入图片描述

四.参考

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

猜你喜欢

转载自blog.csdn.net/qq_45179361/article/details/131026144
今日推荐