我一直在尝试确定在 VBO 中为 OpenGL 存储信息的最佳方式。由于使用多维数组的性能损失,我一直在阅读有关如何将矩阵存储为单维数组的信息。
我想知道,这是否扩展到在 VBO 中存储信息?将顶点信息存储在单维或多维数组中的 VBO 中是否更有意义?
在我得到一堆答案说这取决于我存储的内容之前,我特意谈论的是传统上考虑用于多维数组(地图、网格等)的东西。
如果有的话,我会通过使用多维数组来查看什么类型的性能影响?
我一直在尝试确定在 VBO 中为 OpenGL 存储信息的最佳方式。由于使用多维数组的性能损失,我一直在阅读有关如何将矩阵存储为单维数组的信息。
我想知道,这是否扩展到在 VBO 中存储信息?将顶点信息存储在单维或多维数组中的 VBO 中是否更有意义?
在我得到一堆答案说这取决于我存储的内容之前,我特意谈论的是传统上考虑用于多维数组(地图、网格等)的东西。
如果有的话,我会通过使用多维数组来查看什么类型的性能影响?
这个问题是无效的,因为它没有意义。缓冲区对象是由 OpenGL 存储和管理的内存块。它不是 C# 数组或 C# 多维数组。这是您将数据传输到其中的一块内存。
您放入缓冲区对象的顶点数据必须符合glVertexAttribPointer
允许的条件。如何在 C# 中实现这一点取决于您和您使用的任何 API。
由于使用多维数组的性能损失,存储为单维数组。
我认为您的困惑源于关于多维数组以及如何表示它们的术语差异。
在 C 中,数组是通过指针解引用来访问的:
int arr[10];
arr[5] <--> *(arr+5)
事实上,索引运算符o[i]
完全等价于*(o+i)
and 你实际上也可以写i[o]
,因为它产生相同的表达式。所以索引运算符执行指针算术和取消引用。这对 C multidim 数组意味着什么:
int marr[10][10];
int (*row)[10] = marr[5] <--> *(marr + 5);
mrow[5] = *(mrow + 5) <--> marr[5][5];
您可以根据需要将其扩展到任意多个维度。因此,在 C 中,多维数组会经历多个指针取消引用,这也可能意味着数据在内存中不是连续的,并且在 face 中的每一行可能具有不同的大小。这就是他们效率低下的原因。C 这样做是为了允许动态分配列指针和行。
然而,另一种存储多维数组的方法是平面存储模型。即,您只需将所有元素连接成一个单一的值字符串。并且通过引入你知道的尺寸,在哪里剪断这个字符串来重新排列它。
int fmarr[10*20*30];
int at1_2_3 = fmarr[1*30*20 + 2*20 + 3];
如您所见,所有大小都是静态的,并且数据是连续的。没有指针解引用,这使得处理数据更加简单,更重要的是允许操作向量化。这使事情变得更加高效。