C 语言中健壮的波前 OBJ 模型解析

2025 年 3 月 2 日,介绍了 Wavefront OBJ 格式(https://en.wikipedia.org/wiki...),它是 3D 几何的面向行的文本格式,受建模软件广泛支持,易于解析和生成。文中展示了一个用 C 编写的健壮的部分 OBJ 解析器,无硬编码限制,从头开始编写,不是真正关于 OBJ,而是演示一些以前可能从未见过的技术。

  • 需求:要求对任何输入(有效或无效)无未定义行为,无越界访问和有符号溢出,输入未验证,只关注顶点、法向量和带法向量的三角形面(vvnf元素),模型可能有相对索引,解析器不能忽略行顺序且需处理负索引。
  • 基础函数:使用竞技场进行内存管理,避免空终止字符串,定义了一系列字符串处理函数,如spanequalstrimlefttrimrightsubstringcut等,方便处理字符串。
  • 读取输入:打算将整个模型加载到内存,使用简单的竞技场使全文件加载容易,无需处理逐行输入,还提到在使用大内存竞技场时可能会触发内存不足错误或遇到平台 bug。
  • 解析数据:实践中渲染系统将计数限制在 32 位范围,所以 OBJ 解析器中顶点和法向量索引为 32 位整数,解析函数parseint用于解析有符号整数,parsefloat用于解析浮点数(可处理指数符号),parsevert用于解析顶点,parseface用于解析面(处理相对索引)。
  • 整合模型:模型由顶点、法向量和索引数组组成,解析器分两步遍历 OBJ 源,第一步计数,第二步填充数组,解析后的模型可能不一致,需进一步转换为更有用的表示形式。
  • 转换:用旧版 OpenGL 1.1 的glInterleavedArrays函数将模型转换为GL_N3F_V3F表示形式,每个顶点是一个法向量和一个位置,每个面是三个这样的元素,通过验证面的索引范围并复制有效面来完成转换。展示了转换后的suzanne.objbmw.obj在 OpenGL 中的渲染效果。
阅读 5
0 条评论