c++ glm库使用 c++如何用glm进行3d数学计算

酷宇大大_7566

酷宇大大_7566

2026-03-20

979人浏览

原创

glm初始化应避免花括号聚合初始化,优先用显式构造函数如glm::vec3(1.0f, 2.0f, 3.0f);变换顺序需按s→r→t左乘链式书写;perspective默认输出负z需匹配opengl深度测试;头文件需正确配置c++标准与include路径。

c++ glm库使用 c++如何用glm进行3d数学计算

glm::vec3 和 glm::mat4 的初始化为什么总出错

常见错误是直接用花括号初始化但忽略 GLM 的默认构造行为。比如 glm::vec3 v = {1, 2, 3}; 在 C++17 前可能调用错误构造函数,导致值未定义;C++17 后虽支持聚合初始化,但 GLM 默认禁用隐式转换,glm::vec3(1, 2, 3) 才是安全写法。

  • 用显式构造函数:优先写 glm::vec3(1.0f, 2.0f, 3.0f),不依赖初始化列表
  • 避免混合类型:glm::vec3(1, 2, 3) 是 int,GLM 内部按 float 处理但会触发隐式转换警告,加 f 后缀更稳
  • 矩阵初始化同理:glm::mat4 m(1.0f); 得单位阵,glm::mat4(0.0f) 得零阵,别用 {} 初始化 mat4

glm::rotate / glm::translate / glm::scale 的顺序为什么和直觉相反

GLM 的变换函数返回的是「左乘矩阵」,而人脑习惯「先平移再旋转」的顺序,实际代码中必须反着写:旋转矩阵要写在平移之后,才能让物体绕自身轴转。本质是矩阵乘法不可交换,M = T * R * S 表示先缩放、再旋转、最后平移(模型空间→世界空间)。

  • 正确链式写法:glm::mat4 model = glm::translate(glm::mat4(1.0f), pos) * glm::rotate(glm::mat4(1.0f), angle, axis) * glm::scale(glm::mat4(1.0f), scale);
  • 别写成 rotate * translate,那会让旋转中心偏移到原点以外的位置
  • 如果用 glm::gtx::transform,注意它提供的是右乘风格函数(已弃用),别混用

glm::perspective 返回的矩阵为什么让 z 值变负、深度测试失败

GLM 默认使用 OpenGL 的右手坐标系 + NDC z 范围 [-1, 1],glm::perspective 生成的投影矩阵会把摄像机前方的 z 映射为负值。如果你用的是 Vulkan 或 Metal,默认 NDC z 是 [0, 1],或者你手动翻转了深度比较方向(如 GL_GREATER),就会出现全黑或剔除异常。

C++ Code Review Master
C++ Code Review Master

组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。

下载
  • 检查深度缓冲配置:OpenGL 下确保 glDepthFunc(GL_LESS),且清除值为 1.0f
  • Vulkan 用户需改用 glm::perspectiveLH_ZO(左手+零到一)或手动调整近远平面符号
  • 调试时打印 proj[2][2] 和 proj[3][2]:若前者为正、后者为负,大概率是近/远平面传反了(near > far)

#include 编译报错找不到头文件或 constexpr 问题

GLM 是纯头文件库,但没正确设置 include path 或 C++ 标准版本,就会报 glm::vec3 未声明或 constexpr 不支持。尤其在较老编译器(如 GCC 7 或 MSVC 2015)上,GLM 0.9.9+ 默认启用 C++14 特性,容易崩。

  • 确认包含路径:CMake 中加 target_include_directories(your_target PRIVATE ${GLM_INCLUDE_DIR}),不是 glm/ 子目录
  • 显式指定标准:set(CMAKE_CXX_STANDARD 14) 或更高,GLM 0.9.9.8 起最低要求 C++14
  • 避免宏污染:不要在包含 GLM 前定义 GLM_FORCE_RADIANS 等,应统一在 glm/glm.hpp 前定义,或用编译选项 -DGLM_FORCE_RADIANS

最常被忽略的是:GLM 的矩阵向量乘法默认按列主序,但如果你手写 shader 并用了 row_major,CPU 和 GPU 的内存布局就对不上——这时候得用 glm::transpose() 或改用 glm::column_major 模式。这个坑不打日志根本看不出。

C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!

相关文章

c++速学教程(入门到精通)
c++速学教程(入门到精通)

c++怎么学习?c++怎么入门?c++在哪学?c++怎么学才快?不用担心,这里为大家提供了c++速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

c++

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
css中float用法
css中float用法

css中float属性允许元素脱离文档流并沿其父元素边缘排列,用于创建并排列、对齐文本图像、浮动菜单边栏和重叠元素。想了解更多float的相关内容,可以阅读本专题下面的文章。

2024.04.28

6007

8

C++中int、float和double的区别
C++中int、float和double的区别

本专题整合了c++中int和double的区别,阅读专题下面的文章了解更多详细内容。

2025.10.23

684

4

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.02

5799

3

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.08.29

2865

6

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

2025.08.29

3628

10

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

2025.08.29

2565

10

FrankenPHP集成Laravel详细教程
FrankenPHP集成Laravel详细教程

本专题提供FrankenPHP集成Laravel的详细配置指南,全面解析运行原理、开发环境搭建、Caddyfile配置、Octane工作模式、数据库连接、队列任务、定时任务和生产环境优化,解决部署过程中常见的报错与兼容性问题。

2026.10.08

0

20

LLVM自定义Pass怎么写
LLVM自定义Pass怎么写

本专题聚焦LLVM自定义Pass开发,整理Pass类结构、run()方法、PreservedAnalyses、CMake构建、插件注册、-load-pass-plugin加载和测试用例编写流程。

2026.09.30

120

10

LLVM RISC-V参数配置教程
LLVM RISC-V参数配置教程

本专题介绍LLVM对RISC-V基础ISA和扩展的支持方式,涵盖RV32、RV64、标准扩展、实验性扩展、厂商扩展、-menable-experimental-extensions和版本差异。

2026.09.30

100

14

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Conan 2 Essentials 免费课程
Conan 2 Essentials 免费课程

共0课时 | 0人学习

CMake 与 Conan 集成实践
CMake 与 Conan 集成实践

共0课时 | 0人学习

Conan 2 高级依赖模型介绍
Conan 2 高级依赖模型介绍

共0课时 | 0人学习