2025 年 3 月 2 日,介绍了 Wavefront OBJ 格式(https://en.wikipedia.org/wiki...),它是 3D 几何的面向行的文本格式,受建模软件广泛支持,易于解析和生成。文中展示了一个用 C 编写的健壮的部分 OBJ 解析器,无硬编码限制,从头开始编写,不是真正关于 OBJ,而是演示一些以前可能从未见过的技术。
- 需求:要求对任何输入(有效或无效)无未定义行为,无越界访问和有符号溢出,输入未验证,只关注顶点、法向量和带法向量的三角形面(
v
、vn
、f
元素),模型可能有相对索引,解析器不能忽略行顺序且需处理负索引。 - 基础函数:使用竞技场进行内存管理,避免空终止字符串,定义了一系列字符串处理函数,如
span
、equals
、trimleft
、trimright
、substring
、cut
等,方便处理字符串。 - 读取输入:打算将整个模型加载到内存,使用简单的竞技场使全文件加载容易,无需处理逐行输入,还提到在使用大内存竞技场时可能会触发内存不足错误或遇到平台 bug。
- 解析数据:实践中渲染系统将计数限制在 32 位范围,所以 OBJ 解析器中顶点和法向量索引为 32 位整数,解析函数
parseint
用于解析有符号整数,parsefloat
用于解析浮点数(可处理指数符号),parsevert
用于解析顶点,parseface
用于解析面(处理相对索引)。 - 整合模型:模型由顶点、法向量和索引数组组成,解析器分两步遍历 OBJ 源,第一步计数,第二步填充数组,解析后的模型可能不一致,需进一步转换为更有用的表示形式。
- 转换:用旧版 OpenGL 1.1 的
glInterleavedArrays
函数将模型转换为GL_N3F_V3F
表示形式,每个顶点是一个法向量和一个位置,每个面是三个这样的元素,通过验证面的索引范围并复制有效面来完成转换。展示了转换后的suzanne.obj
和bmw.obj
在 OpenGL 中的渲染效果。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。