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

Posted

技术标签:

【中文标题】在OpenGL中,除非我再次重新指定顶点属性,否则为啥我的缓冲区对象不会绘制?【英文标题】:In OpenGL why won't my buffer object draw unless I respecify the vertex attributes again?在OpenGL中,除非我再次重新指定顶点属性,否则为什么我的缓冲区对象不会绘制? 【发布时间】:2016-12-02 23:10:14 【问题描述】:

我认为 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?

【问题讨论】:

【参考方案1】:

如果您不想在调用 glDraw* 函数之前重新指定 glVertexAttribPointer,那么您需要多个 VAO 而不仅仅是一个。我认为您混淆了 VBO 和 VAO 是什么。 VBO 只是一块包含数据的惰性内存。 VAO 包含 OpenGL 绘制网格所需的所有信息,包括: - 对包含顶点数据的 Buffer 对象的引用(通常称为 VBO) - 对包含顶点索引的 Buffer 对象的引用(如果您使用 glDrawElements*) - 您将要使用的不同顶点属性的索引及其在包含顶点数据的 Buffer 对象中的布局(使用 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

【讨论】:

以上是关于在OpenGL中,除非我再次重新指定顶点属性,否则为啥我的缓冲区对象不会绘制?的主要内容,如果未能解决你的问题,请参考以下文章

openGL之API学习(一六六)glVertexAttrib*函数

openGL之API学习(一六七)默认着色器 顶点属性索引 别名索引

我的OpenGL学习进阶之旅顶点属性顶点数组

我的OpenGL学习进阶之旅顶点属性顶点数组

为啥要为一个属性指定不同的顶点格式?

OpenGL顶点属性未启用