5

我已经阅读并看到了其他问题,这些问题通常都指向将顶点位置和颜色等交错到一个数组中的建议,因为这可以最大限度地减少从 cpu 发送到 gpu 的数据。

我不清楚的是 OpenGL 是如何做到这一点的,即使使用交错数组,您仍然必须对位置和颜色指针进行单独的 GL 调用。如果两个指针都使用同一个数组,只是设置为从该数组中的不同点开始,那么绘图调用是否不会复制数组两次,因为它是两个不同指针的对象?

4

3 回答 3

6

这主要是关于缓存。例如,假设我们有 4 个顶点和 4 种颜色。您可以通过这种方式提供信息(对不起,我不记得确切的函数名称)

glVertexPointer(..., vertex);
glColorPointer(..., colors);

它在内部所做的是读取顶点 [0],然后应用颜色 [0],然后再次使用颜色 [1] 应用顶点 [1]。如您所见,例如,如果 vertex 的长度为 20 兆字节,那么 vertex[0] 和 colors[0] 将至少相距 20 兆字节。

现在,另一方面,如果您提供像 { vertex0, color0, vertex1, color1, etc.} 这样的结构,将会有很多缓存命中,因为 vertex0 和 color0 是在一起的,vertex1 和 color1 也是如此。

希望这有助于回答问题

编辑:在第二次阅读时,我可能没有回答这个问题。您可能想知道 OpenGL 是如何知道从该结构中读取哪些值的?就像我之前说的那样,使用 { vertex, color, vertex, color } 这样的结构,你告诉 OpenGL 顶点在位置 0,偏移量为 2(所以下一个将在位置 2,然后是 4,等等)和颜色从位置 1 开始,偏移量也为 2(所以位置 1,然后是 3,等等)。

另外:如果您想要一个更实际的示例,请查看此链接http://www.lwjgl.org/wiki/index.php?title=Using_Vertex_Buffer_Objects_(VBO)。您可以在那里看到它如何只提供一次缓冲区,然后使用偏移量来有效地渲染。

于 2013-01-26T09:13:02.967 回答
4

我建议阅读:Vertex_Specification_Best_Practices

h4lc0n提供了很好的解释,但我想添加一些额外的信息:

  • 当您的数据经常更改时,交错数据实际上会损害性能。例如,当您更改点精灵的位置时,您会更新 POS,但 COLOR 和 TEXCOORD 通常是相同的。然后,当数据交错时,您必须“触摸”其他数据。在这种情况下,最好有一个 VBO 仅用于 POS(或通常用于经常变化的数据),而第二个 VBO 用于恒定数据。
  • 对 VBO 布局给出严格的规则并不容易,因为它是特定于供应商/驱动程序的。您的用法也可能与其他人不同。一般来说,需要为您的特定测试用例做一些基准测试
于 2013-01-26T12:08:26.647 回答
0

您还可以为分离不同的属性提出论据。假设 GPU 不是一个接一个地处理一个顶点,而是并行处理一堆(例如 16 个)顶点,在执行顶点着色器时会得到类似的结果:

  • 读取所有 16 个顶点的属性 A
  • 执行一些计算
  • 读取所有 16 个顶点的属性 B
  • 执行更多计算
  • ……

因此,您一次读取多个顶点的一个属性。从这个推理看来,交错属性实际上会损害性能。当然,这只有在带宽受限或由于某种原因无法隐藏内存延迟时才可见(例如,需要许多寄存器的复杂着色器将减少在给定时间可以运行的顶点数量) .

于 2013-01-26T12:34:13.053 回答