2013-04-04 170 views
21

我設置了一個頂點緩衝OpenGL中,像這樣的:什麼是修改OpenGL頂點緩衝區的正確方法?

int vboVertexHandle = glGenBuffers(); 
glBindBuffer(GL_ARRAY_BUFFER, vboVertexHandle); 
glBufferData(GL_ARRAY_BUFFER, vertexData, GL_DYNAMIC_DRAW); 

以後,如果我想添加或刪除頂點「vertexData」,什麼是做到這一點的正確方法?它甚至有可能嗎?我假設我不能直接修改陣列而不重新發送給GPU。

如果我修改vertexData陣列,然後再調用這個:

glBindBuffer(GL_ARRAY_BUFFER, vboVertexHandle); 
glBufferData(GL_ARRAY_BUFFER, vertexData, GL_DYNAMIC_DRAW); 

... ...將是覆蓋舊的緩存與我的新的數據?或者我也必須刪除舊的?有沒有更好的辦法?

回答

23

當您調用glBufferData時,將設置任何OpenGL緩衝區對象的大小。也就是說,OpenGL將分配您在glBufferData(未在OP中列出)的第二個參數中指定的內存量。實際上,如果你打電話,例如glBufferData(GL_ARRAY_BUFFER, bufferSize, NULL, GL_DYNAMIC_DRAW); OpenGL將創建一個bufferSize字節的未初始化數據的緩衝區

您可以使用glBufferSubData,glMapBuffer或任何其他用於傳遞數據的例程來加載任意數量的數據(最大爲緩衝區大小)。調整緩衝區大小的唯一方法是使用相同緩衝區ID(從glGenBuffers返回的值)以新大小調用glBufferData。也就是說,你總是可以在緩衝區中使用數據的子集(這將類似於刪除頂點),如果使用glDrawElements進行渲染,則可以隨機訪問緩衝區中的元素。將頂點添加到緩衝區需要分配更大的緩衝區,然後您需要重新加載緩衝區中的所有數據。

+0

難道你不是故意在第一段末尾說「未初始化的數據」嗎? – Ancurio 2013-08-05 00:45:56

+0

@Ancurio的確我是。感謝您的更正。 – radical7 2013-08-05 14:58:51

4

http://www.opengl.org/wiki/GLAPI/glBufferData

glBufferData創建用於當前綁定到目標緩衝對象的新數據存儲。任何預先存在的數據存儲都將被刪除。

這說明了一個調用glBufferData將「重新分配」數據,緩衝區將有一個新的大小。所有的舊數據都將丟失。如果您只想寫入緩衝區的一部分,請改爲使用glBufferSubData

http://www.opengl.org/wiki/GLAPI/glBufferSubData

編輯:glBufferSubData只有當你要替換的數據;改爲調整緩衝區大小,您必須撥打glBufferData

此外,您不必先破壞緩衝區並生成一個新緩衝區。記住GLuint只是OpenGL的一個'指針'。這不是實際的存儲空間,因此重複使用相同的「指針」是完全正確的(如果您當然沒有刪除它)。