我已经阅读并看到了其他问题,这些问题通常都指向将顶点位置和颜色等交错到一个数组中的建议,因为这可以最大限度地减少从 cpu 发送到 gpu 的数据。
我不清楚的是 OpenGL 是如何做到这一点的,即使使用交错数组,您仍然必须对位置和颜色指针进行单独的 GL 调用。如果两个指针都使用同一个数组,只是设置为从该数组中的不同点开始,那么绘图调用是否不会复制数组两次,因为它是两个不同指针的对象?
我已经阅读并看到了其他问题,这些问题通常都指向将顶点位置和颜色等交错到一个数组中的建议,因为这可以最大限度地减少从 cpu 发送到 gpu 的数据。
我不清楚的是 OpenGL 是如何做到这一点的,即使使用交错数组,您仍然必须对位置和颜色指针进行单独的 GL 调用。如果两个指针都使用同一个数组,只是设置为从该数组中的不同点开始,那么绘图调用是否不会复制数组两次,因为它是两个不同指针的对象?
这主要是关于缓存。例如,假设我们有 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)。您可以在那里看到它如何只提供一次缓冲区,然后使用偏移量来有效地渲染。
我建议阅读:Vertex_Specification_Best_Practices
h4lc0n提供了很好的解释,但我想添加一些额外的信息:
您还可以为分离不同的属性提出论据。假设 GPU 不是一个接一个地处理一个顶点,而是并行处理一堆(例如 16 个)顶点,在执行顶点着色器时会得到类似的结果:
因此,您一次读取多个顶点的一个属性。从这个推理看来,交错属性实际上会损害性能。当然,这只有在带宽受限或由于某种原因无法隐藏内存延迟时才可见(例如,需要许多寄存器的复杂着色器将减少在给定时间可以运行的顶点数量) .