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

运行结果:

需要使用到的图像:

相关推荐
这周也會开心2 小时前
JDK1.8新增语法
java·开发语言
心随雨下2 小时前
TypeScript泛型开发常见错误解析
java·开发语言·typescript
郝学胜-神的一滴3 小时前
现代OpenGL窗口管理:GLFW从入门到实战
开发语言·c++·程序人生·图形渲染·个人开发
谁刺我心3 小时前
C++三种智能指针unique、shared、weak
开发语言·c++
AGANCUDA3 小时前
qt使用osg显示pcd点云的例子
开发语言·qt
2301_815686453 小时前
extern
java·开发语言
q***56384 小时前
Java进阶-SPI机制
java·开发语言
合作小小程序员小小店4 小时前
桌面开发,在线%物品代送,代接管理%系统,基于vs2022,c#,winform,sql server数据。
开发语言·数据库·sql·microsoft·c#
g***B7384 小时前
Rust在网络中的Tokio
开发语言·网络·rust
寻找华年的锦瑟4 小时前
Qt-侧边栏布局
开发语言·qt