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