好的,如果其他问答没有解释清楚的话,让我试着来解释一下。
问题确实在于你正在使用一个三角形条带。三角形条带有许多用途,其中使用它最重要的原因是为了减少存储顶点所需的数据量:
使用三角形条带的主要原因是减少创建一系列三角形所需的数据量。存储在内存中的顶点数从3N减少到N+2,其中N是要绘制的三角形数量。
(维基百科)
三角形条带通过简单地重用以前三角形的数据来实现这种神奇的属性。它从先前的三角形中取两个顶点和一个额外的顶点,这使得您可以在这组点上形成一个新的三角形。如果顶点都形成一个连续的表面,并且每个顶点作为第一个三角形和下一个三角形的一部分都有意义,那么这种方法非常有效。
例如,对于一系列顶点:
0: (0,0)
1: (0,1)
2: (1,0)
3: (1,1)
1---3
|\ |
| \ |
| \|
0---2
因此,三角形是由索引(0,1,2)和(1,2,3)形成的。
即使我们添加纹理,它仍然有效。假设纹理大小为四个图块,我们可能会得到:
0: (0,0) (0 , 0)
1: (0,1) (0 , 0.5)
2: (1,0) (0.5, 0)
3: (1,1) (0.5, 0.5)
4: (2,0) (1 , 0)
5: (2,1) (1 , 0.5)
1---3---5
|\ |\ |
| \ | \ |
| \| \|
0---2---4
-- triangle 0
0: (0,0) (0 , 0)
1: (0,1) (0 , 0.5)
2: (1,0) (0.5, 0)
-- triangle 1
3: (0,1) (0 , 0.5)
4: (1,0) (0.5, 0)
5: (1,1) (0.5, 0.5)
-- triangle 2
6: (1,0) (5 , 5)
7: (1,1) (5 , 5.5)
8: (2,0) (5.5, 5)
-- triangle 3
9: (1,1) (5 , 5.5)
10: (2,0) (5.5, 5)
11: (2,1) (5.5, 5.5)
t0
到t3
,第二个三角形的纹理坐标为u0
到u3
。现在:0: 0 t0
1: 1 t1
2: 2 t2
3: 1 t1
4: 2 t2
5: 3 t3
6: 2 u0
7: 3 u1
8: 4 u2
9: 3 u1
10: 4 u2
11: 5 u3
2
与纹理坐标t2
一起出现,而第二个三角形中与位置u0
一起出现。同样地,位置3
分别与t3
和u1
交互。这是因为顶点2是第一个三角形的第三个顶点,但是第二个三角形的第一个顶点,以此类推。
就是这样!现在你只需要编写代码来生成这样的布局,随意设置你的VBO(记住,用于位置的顶点属性可能位于完全不同的VBO中,以便于仅重写图块内容而无需重写图块本身),然后你就完成了。
请记住,正如我之前提到的,所有这些都仍然在一个绘制调用中绘制。整个VBO由GPU线性处理,速度尽可能快,并且应该会产生非常好的性能,稍高的内存使用量相对于我们正在处理的数据类型和典型GPU的内存大小而言是相当可以忽略的。
gl_VertexID
,那么做我之前提到的任何事情都会很困难。我的建议是简单地采用展开路线(记住,你不一定需要有交错的VBO,第二个顶点属性可以来自完全不同的另一个VBO),只有在你感觉需要时才探索其他选项。 - Bartek Banachewicz