【Qt+OpenGL】绘制旋转正方体

说明:如下的代码是参考: https://blog.csdn.net/github_18974657/article/details/122533506

感觉他写的很好,我这些代码是为了方便自己看的。

.h文件

cpp 复制代码
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QOpenGLWidget>
#include <QOpenGLExtraFunctions>
#include <QOpenGLVertexArrayObject>
#include <QOpenGLBuffer>
#include <QOpenGLShaderProgram>
#include <QOpenGLTexture>

namespace Ui {
class Widget;
}

class Widget : public QOpenGLWidget, public QOpenGLExtraFunctions
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

    virtual void initializeGL();
    virtual void resizeGL(int w, int h);
    virtual void paintGL();


    void timerEvent(QTimerEvent *event);

private:
    Ui::Widget *ui;

    QOpenGLVertexArrayObject m_vao;
    QOpenGLBuffer m_vbo;

    QOpenGLShaderProgram *m_program = nullptr;
    QOpenGLTexture *m_texture  = nullptr;

    QMatrix4x4 m_projection;
    QMatrix4x4 m_view;
    QMatrix4x4 m_model;

    int m_angle;

};

#endif // WIDGET_H

.cpp文件

cpp 复制代码
#include "widget.h"
#include "ui_widget.h"
#include <QDebug>

Widget::Widget(QWidget *parent) :
    QOpenGLWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    auto newFormat = this->format();
    newFormat.setSamples(16);
    this->setFormat(newFormat);

    startTimer(1000 / 60);
}

Widget::~Widget()
{
    delete ui;
}

void Widget::initializeGL()
{
    //qDebug() << "initializeGL";
    initializeOpenGLFunctions();
    glEnable(GL_DEPTH_TEST);
    glClearColor(0, 0.5, 0.7, 1);

    m_vao.create();
    m_vbo.create();

    m_program = new QOpenGLShaderProgram();
    m_program->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/vertex_shader.glsl");
    m_program->addShaderFromSourceFile(QOpenGLShader::Fragment, ":/fragment_shader.glsl");
    m_program->link();

    //m_texture = new QOpenGLTexture(QImage(":/image/2.png").mirrored());
    m_texture = new QOpenGLTexture(QImage(":/image/2.png"));
    //m_texture = new QOpenGLTexture(QImage(":/image/1.jpeg"));


    // 顶点缓存中前三个是顶点坐标, 后两个是纹理坐标, 一个顶点由5个float值组成
    float vertex[] = {
    //顶点						纹理
    // 1
        -1,  1,  1,		0.50, 0.25,	// 左上
        -1, -1,  1,		0.50, 0.50,	// 左下
         1, -1,  1,		0.75, 0.50,	// 右下
         1,  1,  1,		0.75, 0.25,  // 右上
    // 6
         1,  1, -1,		0.00, 0.25,	// 左上
         1, -1, -1,		0.00, 0.50,	// 左下
        -1, -1, -1,		0.25, 0.50,	// 右下
        -1,  1, -1,		0.25, 0.25,	// 右上
    // 2
         1,	 1,  1,		0.75, 0.25,  // 左上
         1,	-1,  1,		0.75, 0.50,	// 左下
         1,	-1, -1,		1.00, 0.50,	// 右下
         1,	 1, -1,		1.00, 0.25,	// 右上
    // 5
        -1,  1, -1,		0.25, 0.25,	// 左上
        -1, -1, -1,		0.25, 0.50,	// 左下
        -1, -1,  1,		0.50, 0.50,	// 右下
        -1,  1,  1,		0.50, 0.25,	// 右上
    // 3
        -1,  1, -1,		0.00, 0.00,	// 左上
        -1,  1,  1,		0.00, 0.25,	// 左下
         1,  1,  1,		0.25, 0.25,  // 右下
         1,  1, -1,		0.25, 0.00,	// 右上
    // 4
        -1, -1,  1,		0.00, 0.50,  // 左上
        -1, -1, -1,		0.00, 0.75,	// 左下
         1, -1, -1,		0.25, 0.75,	// 右下
         1, -1,  1,		0.25, 0.50,	// 右上
    };

    m_vao.bind();
    m_vbo.bind();

    m_vbo.allocate(vertex, sizeof(vertex));

    m_program->bind();
//    m_program->setAttributeBuffer("vPos", GL_FLOAT, 0, 3, 0);
//    m_program->enableAttributeArray("vPos");

    // 绑定顶点坐标信息, 从0 * sizeof(float)字节开始读取3个float, 因为一个顶点有5个float数据, 所以下一个数据需要偏移5 * sizeof(float)个字节
    m_program->setAttributeBuffer("vPos", GL_FLOAT, 0 * sizeof(float), 3, 5 * sizeof(float));
    m_program->enableAttributeArray("vPos");
    // 绑定纹理坐标信息, 从3 * sizeof(float)字节开始读取2个float, 因为一个顶点有5个float数据, 所以下一个数据需要偏移5 * sizeof(float)个字节
    m_program->setAttributeBuffer("vTexture", GL_FLOAT, 3 * sizeof(float), 2, 5 * sizeof(float));
    m_program->enableAttributeArray("vTexture");


    m_program->release();
    m_vao.release();
}

void Widget::resizeGL(int w, int h)
{
    //qDebug() << "resizeGL";

    m_projection.setToIdentity();
    m_projection.perspective(60, (float)w / h, 0.001, 1000);

    m_view.setToIdentity();
    m_view.lookAt(QVector3D(3, 3, 3), QVector3D(0, 0, 0), QVector3D(0, 1, 0));

    m_model.setToIdentity();
    m_model.rotate(m_angle, 0, 0, 1);

}

void Widget::paintGL()
{
    //qDebug() << "paintGL";

    glEnable(GL_CULL_FACE);

    m_texture->bind();
    m_vao.bind();
    m_program->bind();

    // 绑定变换矩阵
    m_program->setUniformValue("projection", m_projection);
    m_program->setUniformValue("view", m_view);
    m_program->setUniformValue("model", m_model);

    //glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

    // 绘制
    for (int i = 0; i < 6; ++i)
    {
        glDrawArrays(GL_TRIANGLE_FAN, i * 4, 4);
    }

    m_vao.release();
    m_program->release();
    m_texture->release();
}

void Widget::timerEvent(QTimerEvent *event)
{
    m_angle += 1;
    if (m_angle >= 360)
        m_angle = 0;
    m_model.setToIdentity();
    m_model.rotate(m_angle, 0, 1, 0);
    repaint();
}

fragment_shader.glsl文件 如下:

cpp 复制代码
#version 330 core
in vec2 oTexture;
uniform sampler2D uTexture;
void main()
{
    gl_FragColor = texture2D(uTexture, oTexture);
}

vertex_shader.glsl 文件如下:

cpp 复制代码
#version 330 core
in vec3 vPos;
in vec2 vTexture;
out vec2 oTexture;
uniform mat4 projection;
uniform mat4 view;
uniform mat4 model;
void main()
{
    gl_Position = projection * view * model * vec4(vPos, 1.0);
    oTexture = vTexture;
}

运行结果:

需要使用到的图像:

相关推荐
智算菩萨1 小时前
【Python图像处理】2 数字图像基础与Python图像表示
开发语言·图像处理·python
Jasmine_llq2 小时前
《B3840 [GESP202306 二级] 找素数》
开发语言·c++·试除法·顺序输入输出算法·素数判定算法·枚举遍历算法·布尔标记算法
梁山好汉(Ls_man)2 小时前
鸿蒙_ArkTS解决Duplicate function implementation错误
开发语言·华为·typescript·harmonyos·鸿蒙
xiaoshuaishuai82 小时前
Git二分法定位Bug
开发语言·python
so2F32hj22 小时前
一款Go语言Gin框架DDD脚手架,适合快速搭建项目
开发语言·golang·gin
LJianK13 小时前
Java中的类、普通类,抽象类,接口的区别
java·开发语言
Dev7z3 小时前
基于MATLAB的5G物理层文本传输系统仿真与性能分析
开发语言·5g·matlab
小智社群3 小时前
贝壳获取小区的名称
开发语言·前端·javascript
lsx2024063 小时前
Python3 OS模块详解
开发语言
LiLiYuan.3 小时前
【Java线程 vs 虚拟机线程】
java·开发语言