2012-05-11 34 views
2

我有一個錯誤,我花了相當一段時間來修復。 我不斷收到EXC_BAD_ACCESS和一個引用memmove錯誤,沒有任何進一步的描述,直到我評論以下行:爲什麼將GL_ELEMENT_ARRAY_BUFFER綁定到0會產生memmove錯誤?

[self loadShaders];

glGenVertexArraysOES(1, &_vao); 
glBindVertexArrayOES(_vao); 

// Vertex Buffer 
glGenBuffers(1, &_vertexBuffer); 
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); 
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW); 

glEnableVertexAttribArray(ATTRIB_VERTEX); 
glVertexAttribPointer(ATTRIB_VERTEX, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0); 

glEnableVertexAttribArray(ATTRIB_TEXTURE); 
glVertexAttribPointer(ATTRIB_TEXTURE, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*) (sizeof(float) * 7)); 

// Index Buffer 
glGenBuffers(1, &_indexBuffer); 
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer); 
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(Indices), Indices, GL_STATIC_DRAW); 

glBindBuffer(GL_ARRAY_BUFFER,0); 

////////// COMMENTED THIS ONE ////////////// 
//glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);// 
//////////////////////////////////////////// 

glBindVertexArrayOES(0); 

我想到了一個緩衝綁定到0意味着解除綁定,所以我真的無法理解怎麼會,使我的應用程序崩潰。

感謝您的信息!我只是不留在這個問題...

我的結構:

const Vertex Vertices[4] = { 
    {{0.75, -1, 0}, {1, 0, 0, 1},  {0.125, 0.833496}}, 
    {{0.75, 1, 0}, {0, 1, 0, 1},  {0.125, 1}}, 
    {{-0.75, 1, 0}, {0, 0, 1, 1},  {0,  1}}, 
    {{-0.75, -1, 0}, {0, 0, 0, 1}, {0,  0.833496}}, 
}; 

const GLushort Indices[6] = 
{ 
    0, 1, 2, 
    2, 3, 0 
}; 
+0

最有可能的問題是在您的代碼中的其他地方。評論這個調查只是讓問題以不同的方式表現出來。但看看你發佈的代碼 - 你確定Vertices結構至少有9個浮點成員?因爲我看到你只使用其中的5個,但給ATTRIB_TEXURE的偏移量爲7(其數據爲+2)。 –

+0

是的,我還認爲它是在別的地方,但只有這一行解決了這個問題,我真的不明白爲什麼,我已經發布了更新與我的結構。 thx – Pochi

回答

8

從你的代碼,它看起來如果此功能在一些初始化程序,在那裏你初始化屬性數據,它得到的存儲在綁定的VAO中,這樣在繪製時只需要綁定VAO。

甲VAO反過來封裝需要用於繪製維也納各組織,這是您的屬性(由gl(En/Dis)ableVertexAttribArray設定)的使能標誌,屬性來源和性質(與glVertexAttribPointer設置),當前綁定的索引緩衝器中的所有狀態(設置爲glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ...))。請注意,它不存儲當前綁定的頂點緩衝區,因爲此信息存儲在屬性狀態中。

所以會發生的是,您創建並綁定索引緩衝區,設置其數據,然後取消綁定它,而VAO仍然處於活動狀態。所以VAO狀態將存儲0GL_ELEMENT_ARRAY_BUFFER綁定。現在,當您與

glBindVertexArrayOES(_vao); 
glDrawElements(...); 

畫點什麼沒有必然緩衝區和glDrawElements失敗,因爲VAOs不與客戶端數組。您必須爲索引數據使用VBO或繪製非索引基元(使用glDrawArrays)。

亦不會

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer); 
glBindVertexArrayOES(_vao); 
glDrawElements(...); 

的工作,因爲綁定的索引緩存由VAO覆蓋時,獲取綁定(其索引緩存0)。如果你首先綁定VAO然後綁定索引緩衝區,它將會起作用,但這隻會繞過這個問題。

從概念上講,限制GL_ELEMENT_ARRAY_BUFFER是VAO狀態的一部分,因此您不應將其綁定到您的VAO初始化例程中的0(僅當您不需要任何索引數據時)。在使用VAO時,您也不能將客戶端數組用於索引或頂點數據。如果您不想繪製索引幾何圖形,只需使用glDrawArrays而不是glDrawElements,但無論如何索引緩衝區已過時。

+0

哦,我看到了,我不知道VAO也會將它作爲配置的一部分進行存儲。謝謝! – Pochi

+0

我甚至沒有考慮過它,並且即時編碼gl從此以後..很好的xplanation。非常helfull quesrion /答案 – PeeS

相關問題