繁体   English   中英

为什么不能单独创建和初始化OpenGl VAO?

[英]Why can't I create and initialize an OpenGl VAO separately?

我目前正在研究使用VAO(每个网格一个)的OpenGl 3.3应用程序。 当我分别创建和初始化我的VAO时,对glDrawElements任何调用glDrawElements导致程序立即退出,而不会出现任何错误消息。 但是,当我一起创建和初始化它们时,完全相同的glDrawElements调用成功。


单独的初始化代码:

Chunk::Chunk(){
  glGenVertexArrays(1, &m_vaoId);
  glBindVertexArray(m_vaoId);

  glGenBuffers(1, &m_vboId);
  glGenBuffers(1, &m_eboId);

  glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 4*sizeof(GLfloat), (GLvoid*)(0));
  glVertexAttribPointer(1, 1, GL_FLOAT, GL_FALSE, 4*sizeof(GLfloat), (GLvoid*)(1*sizeof(GLfloat)));
  glEnableVertexAttribArray(0);
  glEnableVertexAttribArray(1);
}


void Chunk::refreshMesh(){
  /*build data into vector<GLfloat> verticies and vector<GLuint> indices...*/

  //send data to GPU
  glBindVertexArray(m_vaoId);

  glBindBuffer(GL_ARRAY_BUFFER, m_vboId);
  glBufferData(GL_ARRAY_BUFFER, vertices.size()*sizeof(GLfloat), vertices.data(), GL_STATIC_DRAW);

  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_eboId);
  glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size()*sizeof(GLfloat), indices.data(), GL_STATIC_DRAW);
}

编译后的初始化代码:

void Chunk::refreshMesh(){
  /*build data into vector<GLfloat> verticies and vector<GLuint> indices...*/

  //send data to GPU
  glGenVertexArrays(1, &m_vaoId);
  glBindVertexArray(m_vaoId);

  glGenBuffers(1, &m_vboId);
  glBindBuffer(GL_ARRAY_BUFFER, m_vboId);
  glBufferData(GL_ARRAY_BUFFER, vertices.size()*sizeof(GLfloat), vertices.data(), GL_STATIC_DRAW);

  glGenBuffers(1, &m_eboId);
  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_eboId);
  glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size()*sizeof(GLfloat), indices.data(), GL_STATIC_DRAW);

  glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 4*sizeof(GLfloat), (GLvoid*)(0));
  glVertexAttribPointer(1, 1, GL_FLOAT, GL_FALSE, 4*sizeof(GLfloat), (GLvoid*)(1*sizeof(GLfloat)));
  glEnableVertexAttribArray(0);
  glEnableVertexAttribArray(1);
}

注意:我正在使用Ubuntu 16.04 LTS与g ++ 5.4.0 20160609(Ubuntu 5.4.0-6ubuntu1〜16.04.2)一起编译,运行1.13和SDL2 2.0.0。 我想进行单独的初始化,以允许在不创建新VAO的情况下定期更新网格数据,因为我想可以在任何实际GPU上处理有限数量的网格数据。

在发明VAO之前,(几乎)所有内容都保存在全局OpenGL状态下。 这与VAO略有不同,因为它们具有自己的状态。

您正在使用glVertexAttribPointer在缓冲区中设置指向属性的指针,但是,VAO状态不仅包含您传递给函数的值,还包含它们指向的缓冲区, GL_ARRAY_BUFFER当您绑定到GL_ARRAY_BUFFER的缓冲区时称为功能。 这允许这样的事情(伪代码):

glBindBuffer(GL_ARRAY_BUFFER, a);
glVertexAttribPointer(...);
glBindBuffer(GL_ARRAY_BUFFER, b);
glVertexAttribPointer(...);

这样,您将使用来自两个不同缓冲区的属性。 然后,您可以取消绑定缓冲区而忘记*它们,而无需为绘制而绑定它们。

TLDR:要解决您的问题,您需要在调用glVertexAttribPointer之前将要使用的缓冲区绑定到GL_ARRAY_BUFFER 您不需要每次都绑定缓冲区以进行绘制,因为VAO 不会使用当前绑定的缓冲区数组缓冲区进行绘制,而是使用设置了属性指针时绑定的缓冲区。

*:要更改或删除它们,您显然仍然需要它们的名称,因此不要严格意义上的“忘记”它们。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM