一般而言,改变物体的位置时,需要改变每一帧所有顶点的坐标,计算量巨大
可以将每一个顶点用向量值表示,使用位移矩阵,缩放矩阵,旋转矩阵对顶点进行操作。
顶点着色器:
#version 330 core
layout(location = 0) in vec3 aPos;
layout(location = 1) in vec3 aColor;
layout(location = 2) in vec2 aTexCord;
out vec3 ourColor;
out vec2 TexCord;
uniform mat4 theMatrix;
void main(){
gl_Position = theMatrix*vec4(aPos.x, aPos.y, aPos.z, 1.0f);
ourColor=aColor;
TexCord=vec2(aTexCord.s,aTexCord.t);
}
片段着色器
#version 330 core
out vec4 FragColor;
in vec3 ourColor;
in vec2 TexCord;
uniform sampler2D textureWall;
uniform sampler2D textureSmile;
uniform sampler2D textureSmall;
uniform float ratio;
void main(){
FragColor = mix(texture(textureWall,TexCord),
texture(textureSmile,TexCord),ratio);
}
核心代码:
void MatrixGlWgt::initializeGL() {
initializeOpenGLFunctions();
//创建VBO和VAO对象,并赋予ID
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
//绑定VBO和VAO对象
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
//为当前绑定到target的缓冲区对象创建一个新的数据存储。
//如果data不是NULL,则使用来自此指针的数据初始化数据存储
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
//告知显卡如何解析缓冲里的属性值
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
//开启VAO管理的第一个属性值
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
glEnableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, 0);
bool success;
shaderProgram.addShaderFromSourceFile(QOpenGLShader::Vertex, "shaders/shapes.vert");
shaderProgram.addShaderFromSourceFile(QOpenGLShader::Fragment, "shaders/shapes.frag");
success = shaderProgram.link();
if (!success)
qDebug() << "ERR:" << shaderProgram.log();
glGenBuffers(1, &EBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
textureWall = new QOpenGLTexture(QImage("images/wall.jpg").mirrored());
textureSmile = new QOpenGLTexture(QImage("images/awesomeface.png").mirrored());
textureSmall = new QOpenGLTexture(QImage("images/small.png").mirrored());
shaderProgram.bind();
shaderProgram.setUniformValue("textureWall", 0);
shaderProgram.setUniformValue("textureSmile", 1);
shaderProgram.setUniformValue("textureSmall", 2);
textureSmall->generateMipMaps();
textureSmile->bind(1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glBindVertexArray(0);
}
void MatrixGlWgt::resizeGL(int w, int h) {
Q_UNUSED(w); Q_UNUSED(h);
}
void MatrixGlWgt::paintGL() {
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
shaderProgram.bind();
shaderProgram.setUniformValue("ratio", ratio);
shaderProgram.setUniformValue("theMatrix", matrix);
glBindVertexArray(VAO);
textureWall->bind(0);
textureSmile->bind(1);
textureSmall->bind(2);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, NULL);
}
void MatrixGlWgt::on_timeout() {
matrix.setToIdentity();
unsigned int time = QTime::currentTime().msec();
matrix.translate(0.5, 0, 0);
matrix.rotate(time, 0.0f, 0.0f, 1.0f);
update();
}
坐标信息:
float vertices[] = {
// positions // colors // texture coords
0.3f, 0.3f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, // top right
0.3f, -0.3f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // bottom right
-0.3f, -0.3f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, // bottom left
-0.3f, 0.3f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f // top left
};
unsigned int indices[] = { // note that we start from 0!
0, 1, 3, // first triangle
1, 2, 3 // second triangle
};