3 个索引缓冲区

Posted

技术标签:

【中文标题】3 个索引缓冲区【英文标题】:3 index buffers 【发布时间】:2011-02-11 09:02:16 【问题描述】:

因此,在 D3D 和 OpenGL 中,都可以从索引缓冲区中进行绘制。

然而,OBJ 文件格式做了一些奇怪的事情。它指定了一堆顶点,如:

v -21.499660 6.424470 4.069845 v -25.117170 6.418100 4.068025 v -21.663851 8.282170 4.069585 v -21.651890 6.420180 4.068675 v -25.128481 8.281520 4.069585

然后它指定了一堆法线,比如..

vn 0.196004 0.558984 0.805680 vn -0.009523 0.210194 -0.977613 vn -0.147787 0.380832 -0.912757 越南 0.822108 0.567581 0.044617 vn 0.597037 0.057507 -0.800150 vn 0.809312 -0.045432 0.585619

然后它指定一堆tex坐标

VT 0.1225 0.5636 VT 0.6221 0.1111 VT 0.4865 0.8888 VT 0.2862 0.2586 VT 0.5865 0.2568 VT 0.1862 0.2166

然后它在模型上指定“面孔”,例如:

f 1/2/5 2/3/7 8/2/6 f 5/9/7 6/3/8 5/2/1

v/t/n 第一个数字是顶点数组的索引,第二个是 tex 坐标数组的索引,第三个是法线数组的索引。

因此,在尝试使用顶点缓冲区进行渲染时,

在 OpenGL 中,我可以使用 glVertexPointerglNormalPointerglTexCoordPointer 分别设置指向每个顶点、法线和纹理坐标数组的指针。但是当涉及到使用 glDrawElements 进行绘图时,我可以仅指定 ONE 组索引,即访问顶点时应使用的索引。

好的,然后呢?我还有 3 组索引要访问。

在 d3d 中几乎相同 - 我可以设置 3 个流:一个用于顶点,一个用于 texcoords,一个用于法线,但是在使用 IDirect3DDevice9::DrawIndexedPrimitive 时,我仍然只能指定 ONE 索引缓冲区,它将索引到顶点数组。

那么,是否可能为每个顶点、texcoord 和普通缓冲区(d3d 或 opengl!)使用不同的索引数组从顶点缓冲区中绘制,或者我必须创建单个交错数组然后访问它?

【问题讨论】:

Rendering meshes with multiple indices的可能重复 【参考方案1】:

你真正想要做的(从 D3D 方面说,抱歉,我不知道 OpenGL)是将 OBJ 加载到自定义顶点格式的数组中——这样你就有了一个结构体索引、顶点、法线和 tex 坐标,你可以使用一个 DrawIndexedPrimtive 来渲染它。

我在这里误解了您的问题定义吗?我认为您需要提供更多细节——您不应该需要多个索引缓冲区来呈现单个 OBJ 文件(除非您故意对它进行批处理)。如果是这种情况,即您故意对它进行批处理,那么您应该查看 DrawIndexedPrimitive 的参数,这些参数允许您在 VB 中指定要使用的偏移量。

【讨论】:

我需要多个索引缓冲区的原因是顶点、法线和 texcoords 实际上在人脸规范中以“不同的速率”进行索引。在f 1/3/5 2/8/1 4/2/2 中,第一个顶点使用顶点数组的索引 1、tex 数组的索引 3 和法线数组的索引 5。 是的——您需要将 OBJ 数据加载到自定义结构中才能在 D3D 中正确呈现。此过程的一部分需要复制顶点以正确引用面格式。 DirectX SDK 中包含一个示例(取决于您使用的版本)。它可以在 \Samples\C++\Direct3D10\MeshFromOBJ10 中找到 @JoshuaAtkins 那是一个查看实现的好地方,出于懒惰,我使用了几个 for 循环。【参考方案2】:

OBJ 并非旨在映射到 OpenGL 或 DirectX。

你说的都是真的,不,不可能使用每个属性的索引。

您必须将 OBJ 表示转换为每个顶点仅使用一个索引的东西(可能在此过程中复制一些顶点数据)。

【讨论】:

那么,作为后续,我可以假设一个 obj 文件永远不会中途切换顶点格式吗? @bobobobo:好吧,我已经很久没有处理 OBJ 文件了,但我认为有些奇怪的情况是纹理只应用于模型的一部分。结果,我认为只有部分顶点具有相应的纹理坐标。不过那是大约 10 年前的事了,所以不要相信我。 哈哈。你现在处理什么? @bobobobo:我的部分背景在篱笆的另一边,在GL的实现中。我之前写过客户端代码。 @bobobobo 你不能假设它不会中途切换顶点格式。事实上,在去年夏天(2012 年)使用 Lightwave,我导出了一个 OBJ/MTL,它使用 f pos/tex/norm 的不同组合来指定不同面的顶点属性(尽管每个单独的面都有一致的格式),所以不要也不希望在“新”OBJ 中表现良好。

以上是关于3 个索引缓冲区的主要内容,如果未能解决你的问题,请参考以下文章

OBJ、缓冲区对象和面部索引

从单个顶点缓冲区渲染多个图形

索引以及索引缓冲区

在 GLSL 顶点着色器中,您可以访问索引缓冲区中顶点的索引,而不仅仅是顶点缓冲区吗?

C++ DirectX 11 从第二个顶点缓冲区渲染问题

VAO 绘制错误的索引缓冲区