重用顶点属性缓冲区作为索引缓冲区?

时间:2016-03-05 23:54:06

标签: opengl

我可以使用我初始化的VBO:

GLuint bufferID;
glGenBuffers(1,&BufferID);
glBindBuffer(GL_ARRAY_BUFFER,bufferID);
glBufferData(GL_ARRAY_BUFFER,nBytes,indexData,GL_DYNAMIC_DRAW);

作为索引缓冲区,如下所示:

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,bufferID);
/* ... set up vertex attributes, NOT using bufferID in the process ... */
glDrawElements(...); 

我想将缓冲区主要用作属性缓冲区,偶尔也用作索引缓冲区(但不能同时使用)。

2 个答案:

答案 0 :(得分:1)

GL中没有任何内容阻止您进行此类操作,上面的代码是合法的GL。您可以将每个缓冲区绑定到每个缓冲区绑定目标(您甚至可以同时将相同的缓冲区绑定到不同的目标,因此,如果属性和索引数据来自同一缓冲区,则甚至可以)。但是,GL实现可能会根据观察到的应用程序行为进行一些优化,因此如果您突然使用这种方法更改现有缓冲区对象的使用情况,或者将其用于两件事情,则最终可能会出现次优性能马上。

<强>更新

将{缓冲区对象的概念引入OpenGL的ARB_vertex_buffer_object extension spec在“问题”部分提到了这个主题:

  

此扩展是否应支持允许顶点索引存储在缓冲区对象中?

     

决议:是的。它很容易和干净地添加           添加索引缓冲区对象的绑定点。以来           我们的重载指针的方法适用于GL中的任何指针,           与其他API不同,不需要定义其他API           * _element_array extensions。

     

请注意,预计实现可能会有所不同           存储类型要求有效存储索引和           顶点。例如,某些系统可能更喜欢AGP中的索引           视频内存中的内存和顶点,反之亦然;或者,在           不支持索引数据DMA的系统,索引数据必须           存储在(可缓存的)系统内存中以供接受           性能。因此,强烈建议应用程序           将模型的顶点和索引数据放在不同的缓冲区中           协助司机选择最有效的地点。

但是,某些实现可能更喜欢将索引缓冲区保留在系统RAM中的原因似乎已经过时了。

答案 1 :(得分:1)

虽然完全合法,但有时不鼓励将属性数据和索引数据放在同一个缓冲区中。我怀疑这主要是基于规范文档中的一个段落(例如OpenGL 3.3规范的第49页,在“2.9.7缓冲区对象中的数组索引”一节的末尾):

  

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

虽然看起来似乎有可能对性能有害,但我很有兴趣在实际平台上看到基准测试结果。属性数据和索引数据同时使用,并具有相同的访问操作(CPU写入或来自临时存储的blit,用于使用数据填充缓冲区,在渲染期间读取GPU)。所以我想不出一个很好的理由,为什么他们需要区别对待。

我能想到的唯一区别是索引数据总是按顺序读取,而索引渲染期间属性数据是无序读取的。因此,在两种情况下都可以应用不同的缓存属性来调整访问权限。