说明:如下的代码是参考: 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_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文件
#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文件 如下:
#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;
}
运行结果:
需要使用到的图像: