在OpenGL中为多组数据使用单个缓冲区对象

时间:2014-10-31 09:52:56

标签: opengl

是否可以使用单个缓冲区来存储多种类型的数据? 或者我应该使用两个缓冲区,其中一个存储顶点数据,另一个存储索引数据?

示例(使用单个缓冲区):

GLuint buffer;
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
// Buffer the Vertex Data
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer);
// Buffer the Index Data

2 个答案:

答案 0 :(得分:3)

是的,没关系,是交错存储的基础。每个缓冲区只是其他命令可以指向的一部分内存。在设置数据时,您甚至不需要将其绑定到GL_ELEMENT_ARRAY_BUFFER

您必须确保数据不重叠:

GLuint buffer;
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
//allocate the buffer, passing in null just allocates
glBufferData(GL_ARRAY_BUFFER, vertexSize+indexSize*sizeof(int), 0, GL_STATIC_DRAW);
// Buffer the Index Data at the start of the buffer
glBufferSubData(GL_ARRAY_BUFFER, 0, indexSize*sizeof(int), indexData);
// Buffer the Vertex Data right after that
glBufferSubData(GL_ARRAY_BUFFER, indexSize*sizeof(int), vertexSize, vertexData);

你需要偏移glVertexAttribPointer指针参数来指示它的起始位置。

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer);
glVertexAttribPointer(0, 3, GL_FLOAT, false, sizeof(vertex), (void*)(indexSize*sizeof(int)));
glVertexAttribPointer(1, 3, GL_FLOAT, false, sizeof(vertex), (void*)(indexSize*sizeof(int) + 3*sizeof(float)));
//...

并且在绘制时你需要传递适当的绘图偏移量(如果你先放置它,则为0,否则为你在相应的glBufferSubData调用中指定的偏移量)

glDrawElements(GL_TRIANGLES​, indexSize, GL_UNSIGNED_INT​, 0);

答案 1 :(得分:1)

将顶点属性和索引存储在同一缓冲区中是合法的。不过,规范总是有一些语言令人沮丧。

旧版GL规格(包括3.0)包含此段落:

  

通过将未使用的名称绑定到ARRAY BUFFER和ELEMENT ARRAY BUFFER创建的缓冲区对象在形式上是等效的,但GL可以基于初始绑定对存储实现做出不同的选择。在某些情况下,通过将索引和数组数据存储在单独的缓冲区对象中,并通过使用相应的绑定点创建这些缓冲区对象,可以优化性能。

从3.1规范开始,只有本段的最后一句仍然存在:

  

在某些情况下,通过将索引和数组数据存储在单独的缓冲区对象中,并通过使用相应的绑定点创建这些缓冲区对象,可以优化性能。

我不确定忽略此建议的性能差异是否很常见,但最新(4.5)规范中仍然存在这些差异。