【GLM】GLM库简介
1.GLM仓库简介
GLM(OpenGL Mathematics)是一个专为OpenGL图形编程设计的C++数学库,它基于OpenGL Shading Language(GLSL)规范。以下是GLM库的一些关键特点和功能:
- 基于GLSL规范:GLM的设计灵感来源于GLSL,这意味着它与OpenGL标准紧密结合,提供了高效且可靠的计算能力。
- 矩阵变换和四元数:GLM支持各种矩阵变换操作,包括平移、旋转和缩放。此外,它还提供了四元数支持,这对于处理3D旋转非常有用。
- 数据打包和随机数生成:除了基本的数学函数外,GLM还提供了用于数据打包和解包、生成随机数的功能。
- 扩展性:基于GLSL扩展约定的扩展系统使得GLM能够根据需要进行扩展,满足各种特殊需求。
- 互操作性:尽管与OpenGL紧密集成,但GLM也确保与其他第三方库和SDK的互操作性,使得与其他工具或库的集成变得相对容易。
- 广泛的应用场景:无论是软件渲染、图像处理、物理模拟还是需要简单方便的数学库的其他开发上下文,GLM都是一个优秀的选择。
- 易于学习和使用:GLM的类和函数设计得非常直观,易于使用,且与OpenGL完美集成。如果你熟悉GLSL,那么在使用GLM时将能够快速上手。
- 性能优化:GLM作为一款针对C语言设计的高性能二维与三维数学库,其内部设计和实现都充分考虑了性能优化的需求。为了确保在图形编程中的高效运行,GLM采取了多项策略来提升计算速度和资源利用效率。
- 平台独立性:GLM库是平台独立的,可以在任何支持C++的平台上使用,包括Windows, Linux, macOS等。
- 源代码可用:GLM是一个开源项目,其源代码和文档可以在GitHub上找到,允许开发者自定义编译,满足特定要求。
GLM库通过提供丰富的数学工具和函数,极大地简化了复杂图形运算的过程,使得开发者能够专注于创意设计而非底层数学计算。
GLM仓库是一个只有头文件的仓库,如果想使用GLM库只需包含它的头文件路径就可以:
仓库地址:https://github.com/g-truc/glm.git
2.GLM库核心API与功能
2.1 基本组成
- 标量类型(Scalar types):提供基本的数学类型,如
float
、double
等。 - 向量类型(Vector types):支持不同维度的向量,如
vec2
、vec3
、vec4
。 - 矩阵类型(Matrix types):提供多种矩阵类型,如
mat2
、mat3
、mat4
。 - 四元数类型(Quaternion types):支持四元数,如
quat
和dquat
(单精度和双精度)。
2.2 函数与操作
- 向量操作(Vector functions):包括向量加法、减法、标量乘法等基本操作。
- 矩阵操作(Matrix functions):包括矩阵乘法、转置、逆矩阵等
- 四元数操作(Quaternion functions):包括四元数的归一化、共轭、旋转等操作。
2.3 扩展
GLM提供了许多扩展模块,这些模块可以通过包含对应的特定的头文件来使用:
- GLM_GTC_bitfield:位字段操作。
- GLM_GTC_color_space:颜色空间转换。
- GLM_GTC_constants:常数,如π和ε。
- GLM_GTC_matrix_inverse:矩阵求逆。
- GLM_GTC_matrix_transform:矩阵变换,如旋转、平移。
- GLM_GTC_noise:噪声函数。
- GLM_GTC_packing:数据打包和解包。
- GLM_GTC_quaternion:四元数操作。
- GLM_GTC_random:随机数生成。
2.4 OpenGL互操作性
GLM提供了与OpenGL函数直接互操作的功能,如:
- glm::value_ptr():返回矩阵的指针,可以用于OpenGL的glUniformMatrix函数
- glm::perspective():创建透视投影矩阵
2.5 配置和自定义
GLM允许通过预处理器指令进行配置和自定义,例如:
- GLM_FORCE_MESSAGES:开启或关闭消息输出。
- GLM_FORCE_INLINE:强制内联函数。
- GLM_FORCE_PRECISION:设置默认的精度。
3.LearnOpenGL中所使用的API
3.1 glm::rotate
glm::rotate用于创建一个旋转变换矩阵,这个函数接受三个参数
函数原型 :
glm::mat4 rotate(glm::mat4 const& m, float angle, glm::vec3 const& axis);
参数说明 :
- 一个glm::mat4类型的矩阵,通常是单位矩阵,表示初始的变换矩阵。
- 一个表示旋转角度的 float 类型的值,这个值需要以弧度为单位,可以通过glm::radians函数将角度转换为弧度。
- 一个glm::vec3类型的向量,表示旋转轴。
使用示例 :
// 初始化一个单位矩阵
glm::mat4 trans = glm::mat4(1.0f);
// 将角度转换为弧度,并沿Z轴旋转90度
trans = glm::rotate(trans, glm::radians(90.0f), glm::vec3(0.0, 0.0, 1.0));
使用glm::rotate生成的变换矩阵可以与物体的其他变换矩阵(如位移、缩放)相乘,以实现复杂的变换效果。这些变换矩阵最终需要传递给着色器,以便在渲染时应用这些变换。
3.2 glm::translate
glm::translate 是 OpenGL Mathematics(GLM)库中的一个函数,它用于创建一个平移变换矩阵。这个函数可以对一个给定的矩阵应用平移变换,通常用于在三维空间中移动物体。
函数原型 :
glm::mat4 translate(glm::mat4 const& m, glm::vec3 const& v);
参数说明 :
1.m:一个glm::mat4类型的矩阵,表示初始的变换矩阵,通常是一个单位矩阵或者已经包含其他变换(如旋转、缩放)的矩阵
2.v :一个glm::vec3类型的向量,表示平移的向量,其中v.x、v.y和v.z分别对应于X、Y和Z轴上的平移距离
使用实例 :
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp> // 包含glm::translate
int main() {
// 初始化一个单位矩阵
glm::mat4 model = glm::mat4(1.0f);
// 平移向量,将物体沿X轴移动5个单位,沿Y轴移动3个单位
glm::vec3 translation(5.0f, 3.0f, 0.0f);
// 应用平移变换
model = glm::translate(model, translation);
// model 现在包含了平移变换,可以传递给着色器
// ....
return 0;
}
生成的model矩阵可以与视图矩阵和投影矩阵一起用于计算模型的最终位置,这些矩阵最终需要传递给着色器,以便在渲染时应用这些变换。
3.3 glm::perspective
glm::perspective是 OpenGL Mathematics(GLM)库中的一个函数,用于创建一个透视投影矩阵。这个矩阵可以用来模拟相机的视角,将三维空间中的物体投影到二维屏幕上。
函数原型:
glm::mat4 perspective(float fovy, float aspect, float near, float far);
参数说明 :
1.fovy:一个float类型的值,表示垂直向上的视场角度,以弧度为单位。这个值通常由客户根据需要设置,比如glm::radians(45.0f)表示45度的市场角
2.aspect:一个float类型的值,表示投影矩阵的宽高比,即屏幕或视口的宽度与高度的比值。这个值通常是视口的宽度除以高度
3.near:一个float类型的值,表示近剪裁面的距离。所有在near距离内的物体都不会被渲染
4.far:一个float类型的值,表示远剪裁面的距离,所有在far距离外的物体都不会被渲染
使用实例 :
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp> // 包含glm::perspective
int main() {
// 设置视场角度为45度,转换为弧度
float fov = glm::radians(45.0f);
// 设置宽高比,假设视口大小为800x600
float aspectRatio = 800.0f / 600.0f;
// 设置近剪裁面和远剪裁面的距离
float nearPlane = 0.1f;
float farPlane = 100.0f;
// 创建透视投影矩阵
glm::mat4 projection = glm::perspective(fov, aspectRatio, nearPlane, farPlane);
// projection 矩阵现在可以用于设置投影矩阵
return 0;
}
这个透视投影矩阵通常在渲染循环的开始处设置一次,用于确定相机的视角和裁剪空间。在OpenGL中,这个矩阵可以通过 glUniformMatrix4fv 函数传递给着色器。
3.4 glm::ortho
glm::ortho用于创建一个正交投影矩阵。正交投影矩阵与透视投影矩阵不同,它不模拟相机的视角,而是提供了一个二维的投影,其中所有物体都按照它们的真实大小显示,不论它们距离观察者的距离如何。这在很多情况下非常有用,比如在创建用户界面(UI)或者进行2D游戏开发时。
函数原型 :
glm::mat4 ortho(float left, float right, float bottom, float top, float near, float far);
参数说明 :
1.left:表示视口的左边界
2.right:表示视口右边界
3.bottom:表示视口底边界
4.top:表示视口顶边界
5.near:表示视口近边界
6.fat:表示视口远边界
使用实例 :
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp> // 包含glm::ortho
int main() {
// 设置视口的边界
float left = -1.0f;
float right = 1.0f;
float bottom = -1.0f;
float top = 1.0f;
float nearPlane = -1.0f;
float farPlane = 1.0f;
// 创建正交投影矩阵
glm::mat4 projection = glm::ortho(left, right, bottom, top, nearPlane, farPlane);
// projection 矩阵现在可以用于设置投影矩阵
return 0;
}
这个正交投影矩阵通常用于2D渲染或者当需要一个不依赖于深度的投影时。在OpenGL中,这个矩阵可以通过 glUniformMatrix4fv 函数传递给着色器。
3.5 glm::lookAt
glm::lookAt用于创建要个观察矩阵(View Matrix),该矩阵描述了从一个特定位置观察一个目标点的场景。这个函数的目的是构建一个将世界坐标转换到观察坐标的矩阵,使得相机可以"看向"一个特定的方向。
glm::lookAt的工作原理是:
1.计算相机的方向向量(从eye指向center)。
2.使用up向量和方向向量计算相机的右向量和上向量。
3.构建一个矩阵,该矩阵将世界坐标转换到相机坐标系中,其中相机位于原点,相机的前方沿着负Z轴,上方沿着Y轴。
函数原型:
glm::mat4 glm::lookAt(const glm::vec3& eye, const glm::vec3& center, const glm::vec3& up);
参数说明:
- eye : 表示相机的位置向量
- center: 表示相机"看向"的目标点位置向量
- up:表示相机的"上"方向向量,通常用于定义相机的旋转和倾斜
使用实例:
glm::vec3 cameraPos(0.0f, 0.0f, 3.0f); // 相机位置
glm::vec3 cameraTarget(0.0f, 0.0f, 0.0f); // 目标点位置
glm::vec3 cameraUp(0.0f, 1.0f, 0.0f); // 上方向量
glm::mat4 viewMatrix = glm::lookAt(cameraPos, cameraTarget, cameraUp);
以上代码创建了一个观察矩阵viewMatrix,它将世界坐标转换为一个cameraPos为原点,cameraTarget为前方,cameraUp为上方的相机坐标系中。
glm::lookAt 函数是构建3D场景中相机视图矩阵的常用工具,它简化了从世界坐标到观察坐标的转换过程