OpenGL多维数组惩罚

时间:2012-07-06 22:09:11

标签: c# arrays opengl multidimensional-array

我一直在努力决定在VBO中为OpenGL存储信息的最佳方式。我一直在阅读有关如何将matricies存储为单维数组的原因,因为使用多维数组会降低性能。

我想知道,这是否扩展到在VBO中存储信息?将单个或多维数组中的顶点信息存储在VBO中更有意义吗?

在我得到一堆答案之前说这取决于我正在存储的内容,我特别谈论传统上考虑用于多维数组(地图,网格等等)的事情。

如果使用多维数组,我会看到什么类型的性能命中?

2 个答案:

答案 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];

正如您所看到的,所有尺寸都是静态的,数据是连续的。没有指针解引用,这使得处理数据更加简单,更重要的是允许操作的矢量化。这使得事情变得更加高效。