美文网首页
七、变换

七、变换

作者: 凉夜lrs | 来源:发表于2020-10-26 18:27 被阅读0次

尽管我们现在已经知道了如何创建一个物体、着色、加入纹理,给它们一些细节的表现,但因为它们都还是静态的物体,无法实现旋转、平移和缩放。可以尝试着在每一帧改变物体的顶点并且重配置缓冲区从而使它们移动,但这太繁琐了,而且会消耗很多的处理时间。使用(多个)矩阵(Matrix)对象可以更好的变换(Transform)一个物体是一个更好的解决方案。

向量和矩阵的运算公式和数学性质可以看这里,写的很详细。https://www.khanacademy.org/math/algebra2/algebra-matrices

GLM

OpenGL可编程渲染管线没有自带任何的矩阵和向量运算(glTranslatef,glRotatef这些是固定管线的内容,GLAD core模式下无法使用)。想要抽象所有的数学细节,需要使用已经做好了的数学库,GLM就是一个专门为OpenGL量身定做的数学库,下载可以自行百度。

GLM是OpenGL Mathematics的缩写,它是一个只有头文件的库,也就是说只需包含对应的头文件就行了,不用链接和编译。需要的GLM的大多数功能都可以从下面这3个头文件中找到:

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>

GLM的旋转、平移和缩放:

glm::mat4 trans = glm::mat4(1.0f);
trans = glm::rotate(trans, glm::radians(90.0f), glm::vec3(0.0f, 0.0f, 1.0f));//角度转弧度
trans = glm::translate(trans, glm::vec3(0.5f, -0.5f, 0.0f));
trans = glm::scale(trans, glm::vec3(0.5, 0.5, 0.5));

GLM库从0.9.9版本起,默认会将矩阵类型初始化为一个零矩阵(所有元素均为0),而不是单位矩阵(对角元素为1,其它元素为0),所以定义时最好先初始化所有的矩阵。

在每个轴都缩放到0.5倍,然后平移,然后沿z轴旋转90度。GLM希望它的角度是弧度制的(Radian),所以使用glm::radians将角度转化为弧度。显示图形是在XY平面上的,所以需要把它绕着z轴旋转(也可以试试其他轴的效果)。因为我们把这个矩阵传递给了GLM的每个函数,GLM会自动将矩阵相乘,返回的结果是一个包括了多个变换的变换矩阵。

尽管在代码中先旋转再位移再缩放,实际的变换却是正好相反的,是先缩放再位移再旋转。

把矩阵传递给着色器

#version 330 core
layout (location = 0) in vec3 aPox;

uniform mat4 transform;
void main()
{
    gl_Position = transform * vec4(aPox, 1.0);
}

GLSL里有一个mat4类型。让其接收一个mat4的uniform变量,然后再用矩阵uniform乘以位置向量。

glUniformMatrix4fv(glGetUniformLocation(shader.shaderProgramId, "transform"), 1, GL_FALSE, glm::value_ptr(trans));

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

PS

旋转和位移这里很有意思,交换顺序的结果很哲学:

If we would first apply rotations then they'd resolve around the rotation origin (0,0,0), but
since the container is first translated, its rotation origin is no longer (0,0,0) making it
looks as if its circling around the origin of the scene.

相关文章

  • 七、变换

    尽管我们现在已经知道了如何创建一个物体、着色、加入纹理,给它们一些细节的表现,但因为它们都还是静态的物体,无法实现...

  • 傅里叶变换

    傅里叶变换 傅里叶变换的物理现象 七色光 当白色的光经过三菱镜的时候,就会分解成七色光。这就是一种傅里叶变换,将白...

  • 与汝相伴

    花香,没有鸟语, 阴霾,皆是朦胧, 时节如车轮般变换, 岁月像流水似更迭, 你数不清变换, 你觉不得更迭, 看着七...

  • 第七讲 S、Z变换及逆变换

  • Glide 系列(七) Glide图像变换

    前言 通过前面Glide系列文章的阅读,相信大家对Glide的核心流程及部分关键模块已经有了较为深入的了解,本节我...

  • Unity Shader 入门(七)顶点变换

    最近有点忙,所以好久都没写东西了,但Surface Shader入门系列还少个重要的部分没介绍——顶点变换。还是先...

  • Homography|单应性

    几何变换类型 保距变换 isometry 相似变换 similarity 仿射变换 affine 射影变换 pro...

  • 七夕略

    七夕 七夕的幻想 宁静安详 日月的黄昏,没有暗的天堂 转头空了荒凉 七夕 七夕的欢乐 魅力梦想 阴阳的变换,没有痛...

  • 数字信号处理 第二章作业

    第一题:第七问 :x(2n) 傅里叶变换答: x(2n)是x(n)的增采样,它的傅里叶变换应该是X(e^(j2w)...

  • 彩色电影

    在森林中 树叶变换色彩 昆虫变换翅膀 鸟变换羽毛 都像是 人在换衣裳 在河流中 鱼变换影子 水草变换舞步 河岸变换...

网友评论

      本文标题:七、变换

      本文链接:https://www.haomeiwen.com/subject/nsqzmktx.html