如何设置索引缓冲区对象

Posted

技术标签:

【中文标题】如何设置索引缓冲区对象【英文标题】:How to setup Index Buffer Object 【发布时间】:2015-08-08 00:29:23 【问题描述】:

我正在尝试使用 lwjgl(java OpenGL 绑定)渲染基本模型。我试图用我记得的东西尽可能多地用我自己的知识来做到这一点。我创建了一个这样的 vbo:

    int verticesVBO = GL15.glGenBuffers ( );
    vboIDs.add ( verticesVBO );
    FloatBuffer verticesData = bufferFromData ( vertices );// Custom Method
    GL15.glBindBuffer ( GL15.GL_ARRAY_BUFFER , verticesVBO );
    GL15.glBufferData ( GL15.GL_ARRAY_BUFFER , verticesData , GL15.GL_STATIC_DRAW );
    GL20.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false, 0, 0);// Binds the vbo to the bound vao
    if(( error = GL11.glGetError()) != GL11.GL_NO_ERROR) System.err.println(GLU.gluErrorString(error));

我对索引缓冲区对象已经了解了这么多:

    int indicesVBO = GL15.glGenBuffers ( );
    vboIDs.add ( verticesVBO );
    IntBuffer indicesData = bufferFromData ( indices );
    GL15.glBindBuffer ( GL15.GL_ELEMENT_ARRAY_BUFFER , indicesVBO );
    GL15.glBufferData ( GL15.GL_ELEMENT_ARRAY_BUFFER , indicesData , GL15.GL_STATIC_DRAW );
    //Problem Here
    if(( error = GL11.glGetError()) != GL11.GL_NO_ERROR) System.err.println(GLU.gluErrorString(error));

我遇到的问题是我不知道将索引缓冲区绑定到 vao 的方法。对于包含顶点数据的 vbo,我知道使用 GL20.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false, 0, 0);,但我记得索引缓冲区的行为不同。这是一个学习过程,所以请以建设性的态度提出您的批评。

【问题讨论】:

【参考方案1】:

您需要做的就是在绑定 VAO 时绑定索引缓冲区。

见https://www.opengl.org/wiki/Buffer_Object#General_use:

GL_ELEMENT_ARRAY_BUFFER

gl*Draw*Elements*​形式的所有渲染函数都将使用指针字段作为与绑定到此目标的缓冲区对象开头的字节偏移量。用于索引渲染的索引将从缓冲区对象中获取。 请注意,此绑定目标是顶点数组对象状态的一部分,因此必须在此处绑定缓冲区之前绑定 VAO。

【讨论】:

那么如何指定绑定哪个属性列表呢?就像在执行包含法线或顶点数据的常规 vbo 时一样,您通常不使用GL20.glVertexAttribPointer() 中的第一个参数指定 vao 中的位置吗?例如GL20.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false, 0, 0); 将占据 vao 中的第一个位置。如何告诉 OpenGL 索引缓冲区应该绑定到哪个插槽? @FeatheredOrcian:没有你在讨论的东西(除了奇怪的扩展,只有 AMD 支持GL_AMD_interleaved_elements)。顶点流从同一个索引中提取每个属性。 @AndonM.Coleman 我从来没有做过任何严肃的 opengl 编程,但我几乎可以肯定你可以在 vao 的一个位置绑定顶点数据,在另一个位置绑定法线,在另一个位置绑定索引,在另一个位置绑定纹理坐标等. 我确信这就是vao的工作方式。如果这不是它们的工作方式,那么将多个 vbo 绑定到一个 vao 的意义何在? @FeatheredOrcian 索引缓冲区未绑定到属性。 @immibis 如果这是真的,那说明了很多

以上是关于如何设置索引缓冲区对象的主要内容,如果未能解决你的问题,请参考以下文章

我正在尝试在 opentk 中实现索引缓冲区对象,但不知道在绘图时如何实际使用它

OpenGL索引缓冲区对象元素顺序绘制不正确

OpenGL 顶点数组对象是存储顶点缓冲区名称和索引,还是只存储索引?

OBJ、缓冲区对象和面部索引

带有附加数据的 OpenGL 索引缓冲区对象

是否可以将索引缓冲区对象 (IBO) 与函数“glMultiDrawElements”一起使用?