我正在使用OpenGL ES来显示从Blender导出的一些对象。 Blender提供顶点列表,面部索引列表和2d纹理坐标列表。在Blender中,我通常相信OpenGL,纹理坐标映射到索引数组中描述的每个顶点。
我想我有两个问题:
我是given to understand(参见“应用纹理”部分),在OpenGL ES中,纹理坐标仅映射到顶点缓冲区,而不是索引缓冲区。是这种情况还是有一种方法将纹理合作数据绑定到索引缓冲区呢?
如果上述情况属实,那么使用索引缓冲区有什么好处吗?毕竟要正确映射纹理,需要使用索引缓冲区保存的所有冗余写出顶点缓冲区。是否仍然可以获得性能提升,或者纹理数据的索引缓冲区是多余的?
答案 0 :(得分:11)
1)我理解在OpenGL ES中,纹理坐标只映射到顶点缓冲区,而不是索引缓冲区。
右边,纹理坐标是相对于顶点数据(缓冲或cpu空间)非索引数据。索引机制与纹理无关。
假设你有这个顶点数组,由3个顶点组成(每个3个组件):
float vdata[] = {x0,y0,z0, x1,y1,z1, x2,y2,z2};
和这个texcoord数组,由3个坐标(每个2个分量)组成:
float tdata[] = {u0,v0, u1,v1, u2,v2};
将此数据声明为OpenGL时,将顶点0(x0,y0,z0)与纹理坐标0(u0,v0)相关联,将顶点1与纹理坐标1相关联,依此类推。最后它会映射你的三角形由3个顶点/ 3个纹理坐标组成的纹理部分对应。
这是传统的OpenGL图片,但是对于四顶点多边形。
(来源:glprogramming.com)
索引数据(缓冲与否)是一种使用间接指定顶点而不是按顺序指定顶点的方法。在我之前的例子中,如果我想渲染三角形两次,我会指定一个像这样的索引数组:
unsigned int idata[] = {0,1,2, 0,1,2};
因此,为了响应1),索引数据独立于texcoords或其他顶点属性,如颜色,法线等,因此没有理由愿意将texcoords绑定到索引数据。
2)毕竟要正确地映射纹理,我们需要写出顶点缓冲区,其中包含将使用索引缓冲区保存的所有冗余。是否仍然可以获得性能提升,或者纹理数据的索引缓冲区是多余的?
通常,索引网格是一种在重用相同顶点时消除冗余的方法,因此内存占用成本较低。在大多数情况下,我认为有很多裁员。
当然,如果你拍摄一个3D立方体,没有顶点共享相同的texcoords或法线,但这不是一个代表性的模型!我相信游戏/ CAD应用程序中的大多数网格都是连续的表面,有很多顶点冗余,并且有很多索引。
其次,当具有索引时,GPU可以使用前/后顶点缓存来加速渲染。 关于内存带宽,索引几乎是免费的,因为图形驱动程序将它们放在pci-express内存(DMA)中,因此不会占用视频内存带宽。
总而言之,即使你没有重复的顶点,我也不认为使用索引缓冲区的表演是一个糟糕的东西,但通常你应该检查不同的OpenGL实现并使你的自己的测试。