为什么 blender .obj 文件中 vt 和 v 元素的数量不同?

Why does the number of vt and v elements in a blender .obj file differ?

已按照教程的说明进行操作 https://www.youtube.com/watch?v=yc0b5GcYl3U (How To Unwrap A UV Sphere In Blender)我成功地在搅拌机程序中生成了一个带纹理的球体。

现在我想在我的 openGL C++ 程序中使用它。为此,我按照教程 http://en.wikibooks.org/wiki/OpenGL_Programming/Modern_OpenGL_Tutorial_Load_OBJexported 将球体保存为 .obj 文件(使用教程中所述的三角测量导出选项)并高兴地发现了很多 'v'、'vt',结果中有 'f' 行。

然而,解析文件我发现预期结构的 642 个顶点 (v)、561 'texture vertices' (vt)[ 和 1216 个元素行 (f) 'f a/at b/bt c/ct'].

令我困惑的是:我对 openGL 的天真理解告诉我,纹理对象上的每个点在 space(顶点)和纹理(UV 点)中都有一个站点。因此,我真的希望 vs 和 vts 的数量匹配。但他们没有:642!=561。怎么可能?

A wavefront obj 文件通过为纹理坐标 (vt)、顶点 (v) 和法线 (vn) 提供索引来构建面 (f)。如果多个人脸共享数据,他们简单地使用相同的索引而不是复制 vt、v 或 vn 数据。

因为 OBJ 和 OpenGL 使用不同的 "vertex" 定义,并以不同方式处理索引。

在下面的解释中,我将顶点的坐标称为v OBJ格式记录中的值,"positions"。

OBJ

OBJ vertex/index 模型的主要特点是它对不同的顶点属性(位置、法线、纹理坐标)使用单独的索引。

这意味着您可以拥有不同大小的独立位置和纹理坐标列表。该文件只需要列出每个唯一位置一次,每个唯一纹理坐标对一次。

然后通过指定 3 索引定义顶点:位置、纹理坐标和法线各一个。

OpenGL

另一方面,OpenGL 使用一组索引,它引用完整的顶点。

顶点由其位置、纹理坐标和法线定义。因此,位置、纹理坐标和法线的每个独特 组合 都需要一个顶点。

转化

当您读取 OBJ 文件进行 OpenGL 渲染时,您需要为位置、纹理坐标和法线的每个 唯一组合 创建一个顶点。由于它们由 f 记录中的索引引用,因此您需要为在这些 f 记录中找到的每个唯一索引三元组创建一个 OpenGL 顶点。对于这些顶点中的每一个,您使用从 OBJ 文件中读取的给定索引处的位置、纹理坐标和法线。

我在这里的旧答案包含伪代码来说明这个过程:OpenGL - Index buffers difficulties