在 OpenGL 中,为什么除非我再次重新指定顶点属性,否则我的缓冲区对象不会绘制?

In OpenGL why won't my buffer object draw unless I respecify the vertex attributes again?

本文关键字:我的 缓冲区 对象 绘制 属性 新指定 为什么 OpenGL 非我 顶点      更新时间:2023-10-16

我认为VAO(顶点数组对象)应该像顶点属性一样存储状态。当我创建VBO时,我指定我的顶点属性:

glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)nullptr);
glEnableVertexAttribArray(0);
// And so on

如果我绑定了另一个VBO,我必须调用GlverTexAttribPointer和GlenableVertexattribarray三次,这是每次切换VBO时。我只有一个VAO,我从不更改它。有什么不对?我只使用一个顶点布局,我不明白VAO在每次切换时都会失去此信息时会做什么。每个VAO只有一个VBO吗?

如果您不想在调用gldraw*函数之前对glvertexattribpointer进行重新分配,那么您需要几种vaos,而不仅仅是一个。我认为您正在混淆VBO和VAO是什么。VBO只是包含数据的惰性记忆。VAO包含OpenGL绘制网格所需的所有信息,其中包括:
- 引用包含您的顶点数据(通常命名为vbo)的缓冲对象
- 对包含顶点索引的缓冲对象的引用(如果您使用的是gldrawelements*)
- 您将要使用的不同顶点属性的索引及其在包含顶点数据的缓冲对象中的布局(使用GlenableVertexAttribarray和GlverTexAttribPointer指定)

基本上,对于每个网格,您需要绘制您需要准备相应的VAO:

// at scene preparation time
glBindVertexArray(vaoA); // the following functions will only affect vaoA
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer_of_meshA);
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_of_meshA);
foreach attrib of meshA
  glEnableVertexAttribArray(***);
  glVertexAttribPointer(***)
glBindVertexArray(0)
glBindVertexArray(vaoB); // the following functions will only affect vaoB
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer_of_meshB);
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_of_meshB);
foreach attrib of meshB
  glEnableVertexAttribArray(***);
  glVertexAttribPointer(***)
glBindVertexArray(0)
//And now at render time:
void render()
{
   glBindVertexArray(vaoA);
   glDrawElements(***);
   glBindVertexArray(vaoB);
   glDrawElements(***);
}

有关更多信息,请检查:https://www.opengl.org/wiki/vertex_specification

相关文章: