[英]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.