VAO是否记得EBO / IBO(元素或指数)和VBO?

时间:2013-06-27 00:28:29

标签: c++ opengl graphics vbo

我的代码正常运行,但这可能是巧合,我不想稍后再讨论一个bug,所以我尽量保持它的清洁:

我执行以下操作来初始化网格:

  1. Gen并绑定VBO和缓冲区数据
  2. Gen并绑定IBO和缓冲区数据
  3. Gen并绑定VAO
  4. 与以前绑定相同的VBO,在1中生成。
  5. 启用我需要的顶点属性数组并设置顶点属性指针
  6. 再次绑定IBO(不知道原因)
  7. BindVertexArray回到0,这样我就不会搞砸我刚创建的VAO
  8. 根据我的理解,VAO将存储我启用的顶点属性数组的状态。它还将存储我绑定的VBO和IBO。由于我通过将顶点阵列绑定回0来“关闭”VAO上的所有操作,因此我确保没有其他代码会弄乱我的VAO。所以如果这样可以,我需要渲染的是:

    1. BIND VAO
    2. 绘制元素
    3. 取消绑定VAO(绑定为0)
    4. 这应该同时存储AttribArray状态以及VBO和IBO。我的问题是:

      A. 我设置VertexAttribPointers后是否需要绑定IBO?如果是这样,为什么?

      B。 VAO真的存储两者 VBO IBO?我听说它只存储绑定的 last 缓冲区,这意味着我必须像这样渲染:

      1. BIND VAO
      2. Bind VBO
      3. 绘制元素
      4. Unbind VAO
      5. 但这没有任何意义,为什么在不存储缓冲区对象的情况下使用VAO?它不会像绑定VBO和IBO一样,然后在没有绑定VAO的情况下绘制元素吗?

        提前感谢您的帮助。

        代码如下:

        初始化

        // generate VBO
        glGenBuffers(1, &m_vbo);
        glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
        glBufferData(GL_ARRAY_BUFFER, m_vertices.size()*sizeof(GLfloat), m_vertices.data(), GL_STATIC_DRAW);
        
        // generate IBO
        glGenBuffers(1, &m_ibo);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ibo);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_indices.size()*sizeof(unsigned short), m_indices.data(), GL_STATIC_DRAW);
        
        // generate VAO
        glGenVertexArrays(1, &m_vao);
        glBindVertexArray(m_vao);
        glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
        
        // set the vertex attribute pointer
        glEnableVertexAttribArray(0);
        glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,vertexSize,reinterpret_cast<const GLvoid*>(0));         
        
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ibo);
        glBindVertexArray(0);
        

        图纸

        glBindVertexArray(m_vao);
        glDrawElements(GL_TRIANGLES,size,GL_UNSIGNED_SHORT,reinterpret_cast<const GLvoid*>(0));
        glBindVertexArray(0);
        

        另外,如果我这样说是不是更清洁:

        1. Gen并绑定VAO
        2. Gen并绑定IBO和BufferData
        3. Gen并绑定VBO和BufferData
        4. 我需要的EnableVertexAttribArrays并设置VertexAttribPointers
        5. 取消绑定VAO(绑定到0)
        6. 似乎更干净,但我不知道结果是否相同,特别是因为步骤4和5之间缺乏IBO绑定。

1 个答案:

答案 0 :(得分:8)

解决您的问题:

  

A. 我设置VertexAttribPointers后是否需要绑定IBO?如果是这样,为什么?

没有。您可以先绑定元素数组(术语中的IBO),然后再执行顶点属性,但一般来说,它们是VAO中的单独绑定。例如,您可以绑定您的IBO以及几个VBO,并使用IBO中的数据使用glDrawElements(和变体)进行渲染,或仅使用顺序顶点使用glDrawArrays(和变体)进行渲染VBO中的数据 - 渲染命令确定是否使用IBO。

  

B。 VAO是否真的存储了VBO和IBO?

是。 VAO可以存储单个IBO的绑定信息,以及至少16个VBO。

  

我听说它只存储绑定的 last 缓冲区,这意味着我必须像这样渲染:

     

绑定VAO
  绑定VBO
  绘制元素
  解开VAO

正如您在原始帖子中推测的那样,此声明不正确,并且您所包含的VBO的绑定是不必要的。 VAO可以存储依赖于实现的最大值(至少为16个)VBO,每个VBO都可以绑定到顶点属性。

  

另外,如果我这样说是不是更清洁:

     
      
  1. Gen并绑定VAO
  2.   
  3. Gen并绑定IBO和BufferData
  4.   
  5. Gen并绑定VBO和BufferData
  6.   
  7. 我需要的EnableVertexAttribArrays并设置VertexAttribPointers
  8.   
  9. 解除绑定VAO(绑定到0)
  10.   

是。正如您所指出的那样,只允许您在三个命令中绑定,渲染和清理。

真的,这就是VAO的全部意义,收集所有那些绑定和顶点属性关联,这样你就可以做一次所有的管道,然后再开火了。