说明:如下的代码是参考: https://blog.csdn.net/github_18974657/article/details/122533506
感觉他写的很好,我这些代码是为了方便自己看的。
.h文件
#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_OBJECTpublic: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文件
#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, // 右上// 61, 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, // 右上// 21, 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文件 如下:
#version 330 core
in vec2 oTexture;
uniform sampler2D uTexture;
void main()
{gl_FragColor = texture2D(uTexture, oTexture);
}
vertex_shader.glsl 文件如下:
#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;
}
运行结果:
需要使用到的图像: