一般而言,改变物体的位置时,需要改变每一帧所有顶点的坐标,计算量巨大
可以将每一个顶点用向量值表示,使用位移矩阵,缩放矩阵,旋转矩阵对顶点进行操作。
顶点着色器:
#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对象,并赋予IDglGenVertexArrays(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 coords0.3f, 0.3f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, // top right0.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 triangle1, 2, 3 // second triangle
};