将缓冲区合并为一个

时间:2015-01-02 10:14:56

标签: arrays pointers opengl vertex vertex-buffer

我有一个由几个条目组成的网格。 每个条目都包含它自己的面,顶点,法线,颜色和纹理坐标列表。

我是否可以遍历所有条目并使用glVertexAttribPointer来累积单个缓冲区对象中属性的数据,如下所示?:

glBindBuffer(vbo);
for(Entry* e : entries) {
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, e->vertices);
    ...
}

换句话说,对缓冲区glVertexAttribPointer的属性0重复调用vbo会重写之前指向的数据吗?

如果是,在为整个缓冲区调用glVertexAttribPointer之前,是否有任何有效的解决办法将所有顶点复制到一个连续的内存块中?

2 个答案:

答案 0 :(得分:2)

glVertexAttribPointer仅存储(对于每个属性)您提供给它的最后一个信息。因此,此方法无法附加缓冲区。

当您遇到像您这样的情况时,您有两种选择:

  1. 每个缓冲区的问题是单独的绘制调用
  2. 将所有缓冲区中的数据复制到一个缓冲区中,并为其发出一次绘制调用。请注意,在这种情况下,可能必须调整索引以指向组合缓冲区中的正确位置。

答案 1 :(得分:2)

glVertexAttribPointer()不会复制任何内容。它仅设置指定从哪里获取顶点数据的状态。如果您为同一属性重复调用它,则每个调用将替换先前的状态,最后一个调用将获胜。

从OpenGL 3.1开始,有一个glCopyBufferSubData()调用(man page),允许您将数据从一个缓冲区复制到另一个缓冲区。使用它,您可以为所有verctices分配一个具有足够空间的缓冲区,然后将较小的缓冲区复制到包含所有顶点的缓冲区中。

话虽如此,以这种方式使用它听起来并不是一个好主意。如果您希望所有顶点都在同一个缓冲区中,那么从一开始就将它们存储在缓冲区中会更容易,也更有效。

你绝对不应该在每次绘制调用中复制顶点数据。虽然减少绘制调用的数量是合乎需要的,但复制顶点数据的能力要高得多。