在了解矩阵的变换之后,我们就可以开始对图形进行变换。这里使用的变换图形是之前绘制出来的笑脸箱子。欢迎光临我的个人网站Orient一起讨论学习。这里是我的GitHub,如果您喜欢,不妨点个
star
。☺
数学库包
首先我们需要引入专门为OpenGL量身定做的数学库——GLM(OpenGL Mathematics)
我们可以从它的网站上下载。
GLM的网站可能需要通过VPN访问,如果你无法访问,你可以点击这里进行下载。如果你使用的是Visual Studio 2017 ,那么在你搭建完开发环境后,你可以直接引入GLM的相关头文件
我们需要引入以下3个头文件:
#include
#include
#include
变换
uniform
在变换之前,我们需要修改顶点着色器,让其接收一个 mat4
的 uniform
变量,然后在用矩阵 uniform
乘以位置向量:
#version 430 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec2 aTexCoord;
out vec2 TexCoord;
uniform mat4 transform;
void main()
{
gl_Position = transform * vec4(aPos, 1.0f);
TexCoord = vec2(aTexCoord.x, 1.0 - aTexCoord.y);
}
变换矩阵
首先我们把箱子逆时针旋转90度(沿着Z轴旋转),然后缩放0.5倍。我们需要创建变换矩阵:
glm::mat4 transfrom
transform = glm::rotate(transform, glm::radians(90.0f), glm::vec3(0.0, 0.0, 1.0));
transform = glm::scal(transform, glm::vec3(0.5, 0.5, 0.5));
可以看到,变换顺序和程序编写顺序刚好相反。在程序中,我们先写出旋转变换,然后再写缩放变换
glm::rotate
函数是旋转函数。GLM希望旋转的角度是弧度制,所以使用了 glm::radians
对角度进行转换。同时我们的纹理是在 XY 平面上,所以我们把它绕着Z轴
(0.0, 0.0, 1.0)
进行旋转。
glm::scal
函数是缩放函数,我们需要将纹理图像对应的轴缩放 (0.5, 0.5, 0.5)
倍。
把变换矩阵传递给着色器
unsigned int transformLoc = glGetUniformLocation(ourShader.ID, "transform");
glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(trans));
首先用 glGetUniformLocation
函数查询了 uniform
变量地址。
然后用 glUniformMatrix4fv
函数把矩阵数据发送给着色器。
第一个参数是 uniform
的位置值;
第二个参数告诉OpenGL发送的矩阵个数,这里是1;
第三个参数确定是否进行矩阵置换(交换行和列)。GLM中不需要,所以设置为 GL_FALSE
;
第四个参数是矩阵数据,但GLM并不是把矩阵存储为OpenGL期望接受的格式,因此这里用 glm::value_ptr
函数变换数据。
以上完成了纹理图像的缩放旋转
接下来我们让纹理图像随着时间变换而不断旋转
我们只需要将变换矩阵更改成如下形式即可:
glm::mat4 transform;
transform = glm::translate(transform, glm::vec3(0.5f, -0.5f, 0.0f));
transform = glm::rotate(transform, (float)glfwGetTime(), glm::vec3(0.0f, 0.0f, 1.0f));
glm::translate
函数是位移函数,将纹理图像位移了 (0.5, -0.5, 0.0)
个单位,将纹理图像位移到了屏幕的右下角。
我们把旋转函数的第二个参数改成了 glfwGetTime()
,因此纹理图像旋转的弧度是随着运行时间的增加而不断增加的。
运行效果如下:
本文的代码可在这里找到,如果对您有所帮助,不妨点个赞。☺