2016-11-13 81 views
-1

因此,讓我解釋一下我寫的代碼以及問題是如何出現的。使用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; 
} 

一切工作正常,我沒有錯誤。

顯然這不是正確的渲染方式,因爲雖然網格數據(又名頂點,索引)不會改變,但在每次繪圖調用中都會生成緩衝區。

回答

0

您需要爲每個網格生成不同的VAO VBO和EBO。 類似這樣的東西

calss Mesh{ 
std::vector<Vertex> vertices; 
std::vector<GLuint> indices; 
GLuint VAO, VBO, EBO; 
} 
+0

感謝您的回覆!我已經這樣做了,實際上我的Mesh類有這些數據成員。每次加載新模型時,都會創建一個新的Mesh對象,其中包含您提到的數據成員。 –