先看效果:
顶点着色器:
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec2 aTextureCoord;
out vec3 outColor;
out vec2 textureCoord;
//矩阵必须初始化,初始化单位矩阵,否则GLSL语言中默认矩阵是0矩阵
uniform mat4 trans = mat4(1.0);
uniform mat4 model = mat4(1.0);
uniform mat4 view = mat4(1.0);
uniform mat4 projection = mat4(1.0);
void main(){
gl_Position = projection * view * model * vec4(aPos, 1.0);
textureCoord = aTextureCoord;
}
片段着色器
#version 330 core
out vec4 fragColor;
in vec3 outColor;//从顶点着色器中传过来的颜色
in vec2 textureCoord;
uniform sampler2D textureImg;
void main(){
fragColor = texture(textureImg, textureCoord);
}
#pragma once
#include <QOpenGLWindow>
#include <QOpenGLExtraFunctions>
#include <QDebug>
#include <QOpenGLTexture>
#include <QElapsedTimer>
#include <QOpenGLShader>
#include <QOpenGLShaderProgram>
class RotateCubeWnd : public QOpenGLWindow{
Q_OBJECT
public:
RotateCubeWnd();
~RotateCubeWnd();
protected:
void initializeGL()override;
void paintGL()override;
private slots:
void slotTimeOut();
private:
GLuint _VBO, _VAO;
class QOpenGLFunctions_3_3_Core* _openGLCore;
QOpenGLShaderProgram _shaderProgram;//着色器程序,所里系统所有的着色器
class QOpenGLTexture *_texture1;
QMatrix4x4 view, model, projection;
class QTimer* _timer = nullptr;
double _angle = 30.0;
};
#include "RotateCubeWnd.h"
#include <QKeyEvent>
#include <QMouseEvent>
#include <QWheelEvent>
#include <QTimer>
#include <QOpenGLFunctions_3_3_Core>
RotateCubeWnd::RotateCubeWnd(){
_timer = new QTimer;
_timer->start(20);
connect(_timer, SIGNAL(timeout()), this, SLOT(slotTimeOut()));
}
RotateCubeWnd::~RotateCubeWnd(){
}
void RotateCubeWnd::initializeGL() {
_openGLCore = QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_3_3_Core>();
//开启深度测试
_openGLCore->glEnable(GL_DEPTH_TEST);
_openGLCore->glDepthFunc(GL_LESS);
GLfloat vertexData[] = {
// X Y Z U V
// 下
-1.0f,-1.0f,-1.0f, 0.0f, 0.0f,
1.0f,-1.0f,-1.0f, 1.0f, 0.0f,
-1.0f,-1.0f, 1.0f, 0.0f, 1.0f,
1.0f,-1.0f,-1.0f, 1.0f, 0.0f,
1.0f,-1.0f, 1.0f, 1.0f, 1.0f,
-1.0f,-1.0f, 1.0f, 0.0f, 1.0f,
// 上
-1.0f, 1.0f,-1.0f, 0.0f, 0.0f,
-1.0f, 1.0f, 1.0f, 0.0f, 1.0f,
1.0f, 1.0f,-1.0f, 1.0f, 0.0f,
1.0f, 1.0f,-1.0f, 1.0f, 0.0f,
-1.0f, 1.0f, 1.0f, 0.0f, 1.0f,
1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
// 前
-1.0f,-1.0f, 1.0f, 1.0f, 0.0f,
1.0f,-1.0f, 1.0f, 0.0f, 0.0f,
-1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
1.0f,-1.0f, 1.0f, 0.0f, 0.0f,
1.0f, 1.0f, 1.0f, 0.0f, 1.0f,
-1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
// 后
-1.0f,-1.0f,-1.0f, 0.0f, 0.0f,
-1.0f, 1.0f,-1.0f, 0.0f, 1.0f,
1.0f,-1.0f,-1.0f, 1.0f, 0.0f,
1.0f,-1.0f,-1.0f, 1.0f, 0.0f,
-1.0f, 1.0f,-1.0f, 0.0f, 1.0f,
1.0f, 1.0f,-1.0f, 1.0f, 1.0f,
// 左
-1.0f,-1.0f, 1.0f, 0.0f, 1.0f,
-1.0f, 1.0f,-1.0f, 1.0f, 0.0f,
-1.0f,-1.0f,-1.0f, 0.0f, 0.0f,
-1.0f,-1.0f, 1.0f, 0.0f, 1.0f,
-1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
-1.0f, 1.0f,-1.0f, 1.0f, 0.0f,
// 右
1.0f,-1.0f, 1.0f, 1.0f, 1.0f,
1.0f,-1.0f,-1.0f, 1.0f, 0.0f,
1.0f, 1.0f,-1.0f, 0.0f, 0.0f,
1.0f,-1.0f, 1.0f, 1.0f, 1.0f,
1.0f, 1.0f,-1.0f, 0.0f, 0.0f,
1.0f, 1.0f, 1.0f, 0.0f, 1.0f
};
_openGLCore->glGenVertexArrays(1, &_VAO);
_openGLCore->glGenBuffers(1, &_VBO);
_openGLCore->glBindVertexArray(_VAO);
_openGLCore->glBindBuffer(GL_ARRAY_BUFFER, _VBO);
_openGLCore->glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), vertexData, GL_STATIC_DRAW);
// 位置属性
_openGLCore->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
_openGLCore->glEnableVertexAttribArray(0);
// 坐标属性
_openGLCore->glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
_openGLCore->glEnableVertexAttribArray(1);
//垂直镜像mirrored
_texture1 = new QOpenGLTexture(QImage("E:/Projects/QtGuiTest/OPenGLApp/RotateCube/a.jpg").mirrored());
if (!_texture1->isCreated()) {
qDebug() << "Failed to load texture";
}
_texture1->setWrapMode(QOpenGLTexture::DirectionS, QOpenGLTexture::Repeat);
_texture1->setWrapMode(QOpenGLTexture::DirectionT, QOpenGLTexture::Repeat);
_texture1->setMinificationFilter(QOpenGLTexture::Linear);
_texture1->setMagnificationFilter(QOpenGLTexture::Linear);
_shaderProgram.addShaderFromSourceFile(QOpenGLShader::Vertex, "E:/Projects/QtGuiTest/OPenGLApp/RotateCube/RotateCube.vert");
_shaderProgram.addShaderFromSourceFile(QOpenGLShader::Fragment, "E:/Projects/QtGuiTest/OPenGLApp/RotateCube/RotateCube.frag");
_shaderProgram.link();
_shaderProgram.bind();
_shaderProgram.setUniformValue("textureImg", 0);
view.lookAt(QVector3D(3.0, 3.0,-3.0), QVector3D(0.0, 0.0, 0.0), QVector3D(0.0, 1.0, 0.0));
projection.perspective(45.0, width() / height(), 0.1, 100);
model.scale(0.5);
}
void RotateCubeWnd::paintGL() {
_openGLCore->glClearColor(0.4f, 0.4f, 0.4f, 1.0f);
_openGLCore->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
_openGLCore->glActiveTexture(GL_TEXTURE0);
_texture1->bind();
_shaderProgram.bind();
//每次旋转都是在当前位置的基础上旋转,第一次旋转30度,以后每次旋转1度
model.rotate(_angle, QVector3D(1.0, 0.0, 0.0));
_shaderProgram.setUniformValue("model", model);
_shaderProgram.setUniformValue("view", view);
_shaderProgram.setUniformValue("projection", projection);
/*
立方体6个面,每个面有2个三角形,每个三角形有3个顶点,所以需要绘制的顶点数是:6 × 2 × 3 = 36
*/
_openGLCore->glDrawArrays(GL_TRIANGLES, 0, 36);
}
void RotateCubeWnd::slotTimeOut() {
_angle = 1.0;
update();
}
使用的图片
aaa