簡體   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