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

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

问题描述:

是否可以使用单个缓冲区来存储多种类型的数据? 或者我应该使用两个缓冲区,其中一个存储顶点数据,另一个存储索引数据?在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 
+0

https://www.opengl.org/wiki/Vertex_Specification_Best_Practices – 2014-10-31 10:05:29

是的,它的优良和用于交织的存储的基础。每个缓冲区只是其他命令可以指向的一部分内存。设置数据时甚至不需要将其绑定到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); 
+0

工程和我理解为什么。感谢您提供一个很好的答案,并且有一个很好的理由将这个索引放在开头。 – 2014-10-31 10:15:37

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

旧GL规格,直至并包括3.0,有这样一段话:由一个未使用的名称绑定到数组缓冲区和ELEMENT数组缓冲区创建

Buffer对象在形式上是等价的,但GL可以做出不同根据初始绑定选择存储实现。在某些情况下,性能将通过将索引和数组数据存储在单独的缓冲区对象中,并通过创建具有相应绑定点的缓冲区对象来优化。

与3.1规范开始,仅该段的最后一句仍然存在:

在某些情况下的性能将通过存储在单独的缓冲器的对象索引和阵列数据进行优化,并通过创建那些带有相应绑定点的缓冲区对象。

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

+0

并且很大程度上取决于驱动程序的实现(规范没有提到任何内容) – 2014-11-01 18:36:00