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

Fra*_*cio 9 c++ opengl graphics vbo

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

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

  1. 生成并绑定VBO和缓冲区数据
  2. 生成并绑定IBO和缓冲区数据
  3. Gen并绑定VAO
  4. 绑定与之前相同的VBO,在1中生成.
  5. 启用我需要的顶点属性数组并设置顶点属性指针
  6. 再次绑定IBO(不知道为什么)
  7. BindVertexArray回到0,这样我就不会搞砸我刚创建的VAO

根据我的理解,VAO将存储我启用的顶点属性数组的状态.它还将存储我绑定的VBO和IBO.由于我通过将顶点阵列绑定回0来"关闭"VAO上的所有操作,因此我确保没有其他代码会弄乱我的VAO.所以,如果这样可以,我需要呈现的是:

  1. 绑定VAO
  2. 绘制元素
  3. 解绑VAO(绑定为0)

这应该既可以存储AttribArray状态,也可以存储VBO和IBO.我的问题是:

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

B.是否真的VAO存储两者的VBO 国际文凭组织?我听说它只存储绑定的最后一个缓冲区,这意味着我必须像这样渲染:

  1. 绑定VAO
  2. 绑定VBO
  3. 绘制元素
  4. 解开VAO

但这没有任何意义,为什么在不存储缓冲区对象时使用VAO?它不会像绑定VBO和IBO一样,然后在不绑定V​​AO的情况下绘制元素吗?

提前谢谢你的帮助.

代码如下:

初始化

// 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);
Run Code Online (Sandbox Code Playgroud)

画画

glBindVertexArray(m_vao);
glDrawElements(GL_TRIANGLES,size,GL_UNSIGNED_SHORT,reinterpret_cast<const GLvoid*>(0));
glBindVertexArray(0);
Run Code Online (Sandbox Code Playgroud)

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

  1. Gen并绑定VAO
  2. Gen并绑定IBO和BufferData
  3. Gen并绑定VBO和BufferData
  4. 我需要的EnableVertexAttribArrays并设置VertexAttribPointers
  5. 取消绑定VAO(绑定到0)

似乎更干净,但我不知道结果是否相同,特别是因为步骤4和5之间缺乏IBO绑定.

rad*_*al7 8

解决你的问题:

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

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

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

是.VAO可以存储单个IBO和至少16个VBO的绑定信息.

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

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

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

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

  1. Gen并绑定VAO
  2. Gen并绑定IBO和BufferData
  3. Gen并绑定VBO和BufferData
  4. 我需要的EnableVertexAttribArrays并设置VertexAttribPointers
  5. 取消绑定VAO(绑定到0)

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

真的,这是VAO的全部要点,收集所有那些绑定和顶点属性关联,这样你就可以做一次所有的管道,然后再点击即可.