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

运行结果:

需要使用到的图像:

相关推荐
xiaowu08019 分钟前
策略模式-不同的鸭子的案例
开发语言·c#·策略模式
edjxj44 分钟前
Qt图片资源导入
开发语言·qt
qq_25929724731 小时前
QT-事件
开发语言·qt
专注VB编程开发20年1 小时前
CSS 的命名方式像是 PowerShell 的动词-名词结构,缺乏面向对象的层级关系
开发语言·后端·rust
古译汉书1 小时前
嵌入式铁头山羊stm32-ADC实现定时器触发的注入序列的单通道转换-Day26
开发语言·数据结构·stm32·单片机·嵌入式硬件·算法
DreamLife☼1 小时前
Qt 中的 Q_OBJECT 宏详解 —— 从源码到底层机制的全面剖析
qt·信号·qml·q_object··rtti·运行时类型信息
计算机毕业设计木哥2 小时前
计算机毕设选题:基于Python+Django的B站数据分析系统的设计与实现【源码+文档+调试】
java·开发语言·后端·python·spark·django·课程设计
陈陈爱java2 小时前
Spring八股文
开发语言·javascript·数据库
歪歪1002 小时前
qt creator新手入门以及结合sql server数据库开发
c语言·开发语言·后端·qt·数据库开发
@大迁世界2 小时前
用 popover=“hint“ 打造友好的 HTML 提示:一招让界面更“懂人”
开发语言·前端·javascript·css·html