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

运行结果:

需要使用到的图像:

相关推荐
blasit17 小时前
笔记:Qt C++建立子线程做一个socket TCP常连接通信
c++·qt·tcp/ip
郑州光合科技余经理6 天前
代码展示:PHP搭建海外版外卖系统源码解析
java·开发语言·前端·后端·系统架构·uni-app·php
feifeigo1236 天前
matlab画图工具
开发语言·matlab
dustcell.6 天前
haproxy七层代理
java·开发语言·前端
norlan_jame6 天前
C-PHY与D-PHY差异
c语言·开发语言
多恩Stone6 天前
【C++入门扫盲1】C++ 与 Python:类型、编译器/解释器与 CPU 的关系
开发语言·c++·人工智能·python·算法·3d·aigc
QQ4022054966 天前
Python+django+vue3预制菜半成品配菜平台
开发语言·python·django
遥遥江上月6 天前
Node.js + Stagehand + Python 部署
开发语言·python·node.js
m0_531237176 天前
C语言-数组练习进阶
c语言·开发语言·算法
Railshiqian6 天前
给android源码下的模拟器添加两个后排屏的修改
android·开发语言·javascript