【GLM】GLM库简介

1.GLM仓库简介

GLM(OpenGL Mathematics)是一个专为OpenGL图形编程设计的C++数学库,它基于OpenGL Shading Language(GLSL)规范。以下是GLM库的一些关键特点和功能:

  1. 基于GLSL规范:GLM的设计灵感来源于GLSL,这意味着它与OpenGL标准紧密结合,提供了高效且可靠的计算能力。
  2. 矩阵变换和四元数:GLM支持各种矩阵变换操作,包括平移、旋转和缩放。此外,它还提供了四元数支持,这对于处理3D旋转非常有用。
  3. 数据打包和随机数生成:除了基本的数学函数外,GLM还提供了用于数据打包和解包、生成随机数的功能。
  4. 扩展性:基于GLSL扩展约定的扩展系统使得GLM能够根据需要进行扩展,满足各种特殊需求。
  5. 互操作性:尽管与OpenGL紧密集成,但GLM也确保与其他第三方库和SDK的互操作性,使得与其他工具或库的集成变得相对容易。
  6. 广泛的应用场景:无论是软件渲染、图像处理、物理模拟还是需要简单方便的数学库的其他开发上下文,GLM都是一个优秀的选择。
  7. 易于学习和使用:GLM的类和函数设计得非常直观,易于使用,且与OpenGL完美集成。如果你熟悉GLSL,那么在使用GLM时将能够快速上手。
  8. 性能优化:GLM作为一款针对C语言设计的高性能二维与三维数学库,其内部设计和实现都充分考虑了性能优化的需求。为了确保在图形编程中的高效运行,GLM采取了多项策略来提升计算速度和资源利用效率。
  9. 平台独立性:GLM库是平台独立的,可以在任何支持C++的平台上使用,包括Windows, Linux, macOS等。
  10. 源代码可用:GLM是一个开源项目,其源代码和文档可以在GitHub上找到,允许开发者自定义编译,满足特定要求。

GLM库通过提供丰富的数学工具和函数,极大地简化了复杂图形运算的过程,使得开发者能够专注于创意设计而非底层数学计算。

GLM仓库是一个只有头文件的仓库,如果想使用GLM库只需包含它的头文件路径就可以:

仓库地址:https://github.com/g-truc/glm.git

2.GLM库核心API与功能

2.1 基本组成

  • 标量类型(Scalar types):提供基本的数学类型,如 floatdouble等。
  • 向量类型(Vector types):支持不同维度的向量,如 vec2vec3vec4
  • 矩阵类型(Matrix types):提供多种矩阵类型,如 mat2mat3mat4
  • 四元数类型(Quaternion types):支持四元数,如 quatdquat(单精度和双精度)。

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);

参数说明

  1. 一个glm::mat4类型的矩阵,通常是单位矩阵,表示初始的变换矩阵。
  2. 一个表示旋转角度的 float 类型的值,这个值需要以弧度为单位,可以通过glm::radians函数将角度转换为弧度。
  3. 一个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场景中相机视图矩阵的常用工具,它简化了从世界坐标到观察坐标的转换过程

posted @ 2024-11-26 21:00  Emma1111  阅读(163)  评论(0编辑  收藏  举报