如何用 GLM 做 C++ 图形数学:vec、mat 与四元数完整上手指南
【免费下载链接】glmOpenGL Mathematics (GLM)项目地址: https://gitcode.com/gh_mirrors/gl/glm
GLM(OpenGL Mathematics)是一个 header only 的 C++ 图形数学库,把 GLSL 规范里的向量、矩阵、四元数函数用相同的命名搬到了 C++ 一侧。如果你要写渲染器、3D 工具或物理模拟,又不想自己推导矩阵乘法和归一化,它是直接可用的现成方案。
一句话定位
GLM 的定位是“用 GLSL 的写法,在 C++ 里用”:会读着色器的人可以直接上主机端写数学代码。与通用线性代数库不同,它不追求 SVD、稀疏矩阵这类通用能力,而是专注于 GLSL 规范定义的那套类型和函数,再叠加一层扩展体系——矩阵变换、四元数、数据打包、噪声、随机数等。
五分钟用 GLM 图形数学跑起来 🧰
引入方式很轻:CMake 里find_package(glm CONFIG REQUIRED)之后链接glm::glm-header-only(纯头文件)或glm::glm(库模式);用 vcpkg 的话直接vcpkg install glm。源码可以从 https://gitcode.com/gh_mirrors/gl/glm 克隆下来自己构建。
装好之后,一个函数就能拿到第一张 MVP 相机矩阵,只需包含glm/ext/matrix_clip_space.hpp和glm/ext/matrix_transform.hpp:
glm::mat4 view(float dist, float yaw, float pitch) { glm::mat4 P = glm::perspective(glm::pi<float>() * 0.25f, 4.0f / 3.0f, 0.1f, 100.0f); glm::mat4 V = glm::translate(glm::mat4(1.0f), {0.0f, 0.0f, -dist}); V = glm::rotate(glm::rotate(V, pitch, {1.0f, 0.0f, 0.0f}), yaw, {0.0f, 1.0f, 0.0f}); return P * V; }glm::perspective、glm::rotate这些函数名和 GLSL 里的写法一一对应,头文件拆分在 glm/ext/ 目录下,用到哪个包含哪个。
能力拆解:三个常见场景 🧮
用 GLM 矩阵函数搭建 MVP 相机链路
自己写渲染器时,4x4 矩阵乘法、列主序布局、透视投影公式都得手工实现,还得对照 OpenGL 的 clip space 约定验证。GLM 把这些拆成独立的 clip space 与 transform 扩展头文件,直接包含即用。上面的例子是完整相机矩阵;如果需要无限远平面处理,扩展里还提供了infinitePerspectiveRH和infinitePerspectiveLH两个函数。
用四元数做平滑旋转与合成
旋转插值如果自己做,得处理球面线性插值、轴角表示,还要防万向锁。用 GLM 的话,glm::angleAxis从轴角建一个旋转,glm::slerp在两个四元数之间平滑过渡,需要拼进 MVP 链路时再用 glm::mat4_cast 转成矩阵:
#include <glm/gtc/quaternion.hpp> glm::quat q = glm::angleAxis(glm::radians(45.0f), {0.0f, 1.0f, 0.0f}); glm::mat4 M = glm::mat4_cast(q); glm::quat mid = glm::slerp(q, glm::quat(1.0f, 0.0f, 0.0f, 0.0f), 0.5f);1.0.2 版本还补充了 packed/aligned 两种 quat 类型,前者省内存,后者给 SIMD 场景用,可按内存布局需求挑选。
用结构化绑定拆开 vec3 的分量
把向量分量逐个传给函数时,以前得手写.x、.y、.z。1.0.2 新增的GLM_GTX_structured_bindings扩展让 C++17 结构化绑定直接作用于 vec、mat、quat 类型:
#define GLM_ENABLE_EXPERIMENTAL #include <glm/gtx/structured_bindings.hpp> glm::vec3 p{1.0f, 2.0f, 3.0f}; auto [x, y, z] = p;GTX 系列属于实验性扩展,使用前必须定义GLM_ENABLE_EXPERIMENTAL,接口将来可能变动。同一系列里的glm/gtx/iteration.hpp还能让向量参与 range-for 遍历。
工程化细节 ⚙️
- 编译器要求:需要 C++17 编译器;官方支持列表为 GCC 8+、Clang 6+、Apple Clang 6.0+、Visual C++ 2019+、CUDA 9.0+(实验性),更老的 C++ 标准可以用 1.0 分支。
- 构建安装:
cmake -DGLM_BUILD_TESTS=OFF -B build .后执行cmake --build build -- install;加-DBUILD_SHARED_LIBS=ON产出动态库。 - 不想装包也可以用 CMake 的 FetchContent 拉取源码随工程一起构建。
- 单元测试默认不构建,需要显式加
-DGLM_BUILD_TESTS=ON。 - SIMD intrinsics 默认关闭,定义
GLM_FORCE_INTRINSICS开启;默认配置下函数保持 constexpr 友好。 - 跨版本迁移:1.0.2 修复过四元数 rotate 的方向问题,1.0.3 又把该修复回退,跨这两个版本升级时要核对旋转方向的用例;1.0.3 还修正了 vec4 到 vec3 的转换,依赖旧行为的代码注意检查。
选型参考 ⚖️
- 对比Eigen:Eigen 是更重的通用线性代数库,覆盖稀疏矩阵、各类分解。如果你的核心需求是与 GLSL 命名一一对应、主机端和着色器写同一套 vec/mat 操作,GLM 更直接。
- 对比CML:CML 同样面向游戏和图形场景,GLM 的扩展体系、编译器覆盖(含 NEON 路径)和测试规模更完整,单测分布在 test/ 下的 core、ext、gtc、gtx 四个子目录。
- 不必选它的场景:通用数值计算、稀疏线性代数这类需求,或者团队已有引擎内建数学库且不需要 GLSL 风格命名。
收尾 📮
如果你在写 C++ 图形或模拟代码、希望主机端数学和着色器同名同构,GLM 就是现成答案。完整的手册见仓库内的 manual.md,API 参考文档在doc/api/目录。
【免费下载链接】glmOpenGL Mathematics (GLM)项目地址: https://gitcode.com/gh_mirrors/gl/glm
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考