为什么仍然有许多波前 obj 文件包含一个面中的 4 个顶点?
Why there are still many wavefront obj files containing 4 vertices in one face?
今天,我开始实现一个wavefront obj loader,问题是我不知道为什么尽管OpenGL不再支持,但互联网上有这么多包含4个顶点的obj文件GL_QUADS 并弃用它的使用。
有什么解决方法吗?我的意思是,每次我尝试使用 GL_TRIANGLE_FAN 或 GL_TRIANGLE_STRIP 绘制包含 4 个顶点的面时,它都会显示悲惨的结果。所以最后我别无选择,只能在每张脸上发出绘图命令,正如你所知,它显示出糟糕的表现。我想绘制它在每个组或平滑组上只发出一个命令。
有什么想法吗?
如果您有一个建模程序可以 open/export 像 Maya 或 Blender 这样的 objs,我建议您在那里打开模型,triangulating 它使用适当的菜单选项, 然后重新导出它。
如果您无权访问其中任何一个,编写一个程序来读取 obj 数据、对其进行三角剖分并将其写入文件应该相对简单。您需要对 obj 格式有更深入的了解,但不需要任何额外的软件。
因为OBJ是一种与OpenGL完全无关的文件格式
OBJ 文件中的面语句可以包含任意数量的顶点,而不仅仅是 3 个或 4 个。它们包含超过 4 个并不罕见。因此,如果您希望能够读取合理多样的 OBJ 文件,您需要准备好读取每个面的任意数量的顶点。
这确实没有增加多少难度。除非您使用算法来分析连通性并构建网格,否则无论如何您都会为每个面声明一个单独的三角形,即使对于每个面只有 3 个顶点的文件也是如此。所以在那种情况下,你为每个面创建一个三角形,并用原始类型 GL_TRIANGLES
.
绘制它们
因此,每个面超过 3 个顶点的所有变化是每个面生成多个三角形。对于具有 n
个顶点的面,您将需要 n - 2
个三角形。我对这个问题的回答更详细地解释了这是如何完成的:Converting quadriladerals in an OBJ file into triangles?.
另一种选择是将每个面都视为三角形扇形,并使用 GL_TRIANGLE_FAN
基元类型渲染它们。凸多边形(如果文件中的面是非凸多边形,所有这些都会分解)始终可以绘制为三角形扇形,同时保持顶点完全按照其原始顺序。要将每个面视为一个单独的三角形扇形,您可以使用自 OpenGL 3.1 以来可用的原始重启功能,使用如下调用:
glEnable(GL_PRIMITIVE_RESTART);
glPrimitiveRestartIndex(...);
很容易看出 OBJ 不针对 OpenGL 渲染。更麻烦的方面是 OBJ 对位置、法线和纹理坐标使用单独的索引,而 OpenGL 仅支持用于所有顶点属性的一组索引。这往往会给编写解析器的人带来更多困难。参见此处的示例:OpenGL - Index buffers difficulties.
今天,我开始实现一个wavefront obj loader,问题是我不知道为什么尽管OpenGL不再支持,但互联网上有这么多包含4个顶点的obj文件GL_QUADS 并弃用它的使用。
有什么解决方法吗?我的意思是,每次我尝试使用 GL_TRIANGLE_FAN 或 GL_TRIANGLE_STRIP 绘制包含 4 个顶点的面时,它都会显示悲惨的结果。所以最后我别无选择,只能在每张脸上发出绘图命令,正如你所知,它显示出糟糕的表现。我想绘制它在每个组或平滑组上只发出一个命令。
有什么想法吗?
如果您有一个建模程序可以 open/export 像 Maya 或 Blender 这样的 objs,我建议您在那里打开模型,triangulating 它使用适当的菜单选项, 然后重新导出它。
如果您无权访问其中任何一个,编写一个程序来读取 obj 数据、对其进行三角剖分并将其写入文件应该相对简单。您需要对 obj 格式有更深入的了解,但不需要任何额外的软件。
因为OBJ是一种与OpenGL完全无关的文件格式
OBJ 文件中的面语句可以包含任意数量的顶点,而不仅仅是 3 个或 4 个。它们包含超过 4 个并不罕见。因此,如果您希望能够读取合理多样的 OBJ 文件,您需要准备好读取每个面的任意数量的顶点。
这确实没有增加多少难度。除非您使用算法来分析连通性并构建网格,否则无论如何您都会为每个面声明一个单独的三角形,即使对于每个面只有 3 个顶点的文件也是如此。所以在那种情况下,你为每个面创建一个三角形,并用原始类型 GL_TRIANGLES
.
因此,每个面超过 3 个顶点的所有变化是每个面生成多个三角形。对于具有 n
个顶点的面,您将需要 n - 2
个三角形。我对这个问题的回答更详细地解释了这是如何完成的:Converting quadriladerals in an OBJ file into triangles?.
另一种选择是将每个面都视为三角形扇形,并使用 GL_TRIANGLE_FAN
基元类型渲染它们。凸多边形(如果文件中的面是非凸多边形,所有这些都会分解)始终可以绘制为三角形扇形,同时保持顶点完全按照其原始顺序。要将每个面视为一个单独的三角形扇形,您可以使用自 OpenGL 3.1 以来可用的原始重启功能,使用如下调用:
glEnable(GL_PRIMITIVE_RESTART);
glPrimitiveRestartIndex(...);
很容易看出 OBJ 不针对 OpenGL 渲染。更麻烦的方面是 OBJ 对位置、法线和纹理坐标使用单独的索引,而 OpenGL 仅支持用于所有顶点属性的一组索引。这往往会给编写解析器的人带来更多困难。参见此处的示例:OpenGL - Index buffers difficulties.