转换(Transformations),主要是指位移(Translate),缩放(Scaling),旋转(Rotation)三种,opengl实现这三种转换,主要是经过矩阵的运算来实现的。在这里就会涉及到必定的矩阵、向量的运算了。html
opengl没有提供现成的矩阵、向量运算的库,这个须要咱们本身引入第三方的库,在教程中做者是使用到了GLM库,能够在这里下载。git
由于矩阵运算并不知足交换律,因此在这里进行转换的矩阵操做对于运算顺序有要求,须要先缩放(Scaling),再旋转(Rotation),最后再位移(Rotation)。而实际书写过程可能又是这样的顺序:T * R * S,在代码中调用顺序是 T、R、S, 在这里须要注意一下。咱们理解/读矩阵组合运算的式子,应该是从右到左的顺序。github
glm提供现成的位移、缩放、旋转的矩阵运算方法,分别为glm::translate、glm::scale、glm::rotation,假如咱们在这里须要实现一个缩放、旋转、位移的组合操做,咱们的代码大概是这样的:spa
// 转换矩阵 glm::mat4 trans = glm::mat4(1.0f); // 位移 x轴移动0.5单位,y轴移动-0.5单位 trans = glm::translate(trans, glm::vec3(0.5f, -0.5f, 0.0f)); // 旋转 绕y轴旋转45度 trans = glm::rotation(trans, glm::radians(45.0f), glm::vec3(0.0f, 1.0f, 0.0f)); // 缩放 0.5 trans = glm::scale(trans, glm::vec3(0.5f, 0.5f, 0.5f));
这是一个组合运算的过程,最终获得一个转换后的矩阵。再将转换好的矩阵传给顶点着色器,就能看到最终的转换效果了。顶点着色器接收转换后的矩阵:.net
#version 330 core layout (location = 0) in vec3 aPos; layout (location = 1) in vec3 aColor; layout (location = 2) in vec2 aCoord; out vec3 oColor; out vec2 oCoord; uniform mat4 u_transform; void main() gl_Position = u_transform * vec4(aPos, 1.0f); oColor = aColor; oCoord = aCoord; }
GLSL内部也有对应的mat4类型的变量,用来存储传递过来的转换矩阵数据,再将这个乘以顶点坐标,既能够获得转换后的坐标信息。code
赋值uniform部分对应的调整为orm
glUniformMatrix4fv(location, 1, GL_FALSE, glm::value_ptr(trans));
参数1为uniform变量的位置索引,参数4就是咱们要传递过来的矩阵数据,glm使用value_ptr方法将glm存储的矩阵格式转换为GLSL使用的格式。htm
对应的代码在这里。blog