因此,讓我解釋一下我寫的代碼以及問題是如何出現的。使用glDrawElements繪製3D網格時的奇怪行爲
我做了一個簡單的OpenGL應用程序,它讀取.obj文件並呈現它。
我讀取文件並將頂點和索引數據放在兩個矢量中:std::vector vertices<Vertex>
和std::vector indices<GLuint>
。頂點是一個結構我構建了:
struct Vertex{
glm::vec3 Position;
glm::vec3 Normal;
}
所以現在可以假設我有閱讀.OBJ,並用它的數據填補上述載體。之後,使用下面的代碼,在渲染網格之前設置我的緩衝區。
void Mesh::setupBuffers()
{
glGenVertexArrays(1,&VAO);
glGenBuffers(1,&VBO);
glGenBuffers(1,&EBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER,VBO);
glBufferData(GL_ARRAY_BUFFER,vertices.size()*sizeof(MyVertex),&vertices[0],GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,indices.size()*sizeof(GLuint),&indices[0],GL_STATIC_DRAW);
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,sizeof(MyVertex),(GLvoid*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1,3,GL_FLOAT,GL_FALSE,sizeof(MyVertex),(GLvoid*)offsetof(MyVertex,Normal));
glEnableVertexAttribArray(1);
glBindVertexArray(0);
}
請注意,上面的代碼只被調用一次,即我加載一個新的.obj後。
最後渲染我用的是網:
void Mesh::Draw()
{
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES,indices.size(),GL_UNSIGNED_INT,0);
glBindVertexArray(0);
GLenum error = glGetError();
if(error) std::cout << error << std::endl;
}
繪製函數被調用每一個渲染迭代。
問題出現時,我已經呈現第一個模型,並希望繪製另一個。可以說,通過按下'a'按鈕,正在加載另一個模型(通過清除和填充上面相同的頂點和索引向量),調用setupBuffer()並且程序進入渲染循環。 這樣,網格將不會被吸引,我得到錯誤1282
我發現,如果我不是調用setupBuffer()在每一個渲染迭代,即:
void Mesh::Draw()
{
setupBuffers();
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES,indices.size(),GL_UNSIGNED_INT,0);
glBindVertexArray(0);
GLenum error = glGetError();
if(error) std::cout << error << std::endl;
}
一切工作正常,我沒有錯誤。
顯然這不是正確的渲染方式,因爲雖然網格數據(又名頂點,索引)不會改變,但在每次繪圖調用中都會生成緩衝區。
感謝您的回覆!我已經這樣做了,實際上我的Mesh類有這些數據成員。每次加載新模型時,都會創建一個新的Mesh對象,其中包含您提到的數據成員。 –