OPENGL学习笔记之七

来源:互联网 发布:淘宝店铺销售策划方案 编辑:程序博客网 时间:2024/05/21 06:34

OPENGL学习笔记之七

2017/11/6

阅读材料来自learnopengl.com以及learnopengl-cn.github.io

本节属于基础线性代数内容,只挑重点记录

1.使用(多个)矩阵(Matrix)对象可以更好的变换(Transform)一个物体。

向量最基本的定义就是一个方向。或者更正式的说,向量有一个方向(Direction)和大小(Magnitude,也叫做强度或长度)。

标量(Scalar)只是一个数字(或者说是仅有一个分量的向量)。
简单来说,标量就是用它的值缩放(Scale)矩阵的所有元素(译注:注意Scalar是由Scale + -ar演变过来的)

点乘是通过将对应分量逐个相乘,然后再把所得积相加来计算。通过点乘获得向量夹角或夹角余弦值。

叉乘只在3D空间中有定义,它需要两个不平行向量作为输入,生成一个正交于两个输入向量的第三个向量。如果输入的两个向量也是正交的,那么叉乘之后将会产生3个互相正交的向量。

2.齐次坐标(Homogeneous Coordinates)
向量的w分量也叫齐次坐标。想要从齐次向量得到3D向量,我们可以把x、y和z坐标分别除以w坐标。我们通常不会注意这个问题,因为w分量通常是1.0。使用齐次坐标有几点好处:它允许我们在3D向量上进行位移(如果没有w分量我们是不能位移向量的),而且下一章我们会用w值创建3D视觉效果。
如果一个向量的齐次坐标是0,这个坐标就是方向向量(Direction Vector),因为w坐标是0,这个向量就不能位移(译注:这也就是我们说的不能位移一个方向)。

3.旋转
大多数旋转函数需要用弧度制的角,但幸运的是角度制的角也可以很容易地转化为弧度制的:
弧度转角度:角度 = 弧度 * (180.0f / PI)
角度转弧度:弧度 = 角度 * (PI / 180.0f)
PI约等于3.14159265359。

这里写图片描述

利用旋转矩阵我们可以把我们的位置向量沿一个单位轴进行旋转。也可以把多个矩阵结合起来,比如先沿着x轴旋转再沿着y轴旋转。但是这会很快导致一个问题——万向节死锁(Gimbal Lock)。我们不会讨论它的细节,但是一个更好的解决方案是沿着任意轴比如(0.662, 0.2, 0.7222)(注意这是个单位向量)旋转,而不是使用一系列旋转矩阵的组合。这样一个(超级麻烦的)矩阵是存在的,见下面这个公式,(Rx,Ry,Rz)代表任意旋转轴:

这里写图片描述

即使这样一个矩阵也不能完全解决万向节死锁问题(尽管会极大地避免)。避免万向节死锁的真正解决方案是使用四元数(Quaternion),它不仅安全,而且计算更加友好。

4.GLM
GLM是OpenGL Mathematics的缩写,它是一个只有头文件的库,也就是说我们只需包含对应的头文件就行了,不用链接和编译。GLM可以在它们的网站(我们这里使用的版本为0.9.5,建议去GitHub)上下载。把头文件的根目录复制到你的includes文件夹,然后你就可以使用这个库了。
我们需要的GLM的大多数功能都可以从下面这3个头文件中找到:

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

创建变换矩阵:

glm::mat4 trans;trans = glm::rotate(trans, glm::radians(90.0f), glm::vec3(0.0, 0.0, 1.0));trans = glm::scale(trans, glm::vec3(0.5, 0.5, 0.5)); 

这里注意,在原教程中 glm::radians(90.0f)不如直接90参数来的彻底,可能函数有优化!

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

原创粉丝点击