errorman

不积跬步,无以至千里

导航

learnopengl(7)变换

Posted on 2023-08-16 18:58  Clemens  阅读(22)  评论(0编辑  收藏  举报

一、基础知识

主要是一些向量和矩阵的计算方式。大学本科期间的线性代数里面的内容。坦白来讲,当时学线性代数,虽然考了个还不错的分数,但是实际这些向量、矩阵后面的意义是什么并不知道。只学会了一些基础的计算方法。

 

二、实践

使用GLM库。

我们在上一节的基础上,先将每个轴都缩放到0.5倍,再沿z轴旋转90度。

    // 定义矩阵,先缩放后旋转,注意代码顺序。
    glm::mat4 trans(1.0f);
    trans = glm::rotate(trans, glm::radians(90.0f), glm::vec3(0.0f, 0.0f, 1.0f));
    trans = glm::scale(trans, glm::vec3(0.5, 0.5, 0.5));

我们是先缩放,后旋转,为什么代码顺序是先旋转后缩放呢?

假设我们要进行变换的矩阵是A,进行缩放操作的矩阵是B,进行旋转操作的矩阵式C,最后的结果是D。

正确的计算顺序是 D = CBA.

我们如何将该矩阵传递给着色器呢?

我们修改顶点着色器程序,接收一个mat4的uniform变量,然后再用该mat4的矩阵乘位置。

顶点着色器的程序为:

#version 330 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);
}

我们把该uniform传递给着色器:

    unsigned int transformLoc = glGetUniformLocation(ourShader.ID, "transform");
    glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(trans));

我们首先查询uniform变量的地址,然后用有Matrix4fv后缀的glUniform函数把矩阵数据发送给着色器。

glUniformMatrix4fv第一个参数是uniform的位置值。第二个参数告诉OpenGL我们将要发送多少个矩阵,这里是1。第三个参数询问我们是否希望对我们的矩阵进行转置(Transpose),也就是说交换我们矩阵的行和列。OpenGL开发者通常使用一种内部矩阵布局,叫做列主序(Column-major Ordering)布局。GLM的默认布局就是列主序,所以并不需要转置矩阵,我们填GL_FALSE。最后一个参数是真正的矩阵数据,但是GLM并不是把它们的矩阵储存为OpenGL所希望接受的那种,因此我们要先用GLM的自带的函数value_ptr来变换这些数据。

最后的结果为: