2011-03-23 85 views
11

我運行一個示例OpenGL代碼,我移植到OpenGL ES 2.0(實際上並沒有太多要做),但我不禁想知道glBufferData函數是什麼。最初來源是這樣的:OpenGL ES中的'glBufferData'是什麼?

glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 2 * 6, quad, GL_STATIC_DRAW); 
glEnableVertexAttribArray(0); 
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 2, (void *) 0); 

但我可以成功地簡化爲:

glEnableVertexAttribArray(0); 
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 2, quad); 

也就是說,我可以省略glBufferData功能只是在glVertexAttribPointer使用一個有效的指針成四陣列。

那麼,有誰能解釋glBufferData函數的功能嗎?從我所做的事情看,這似乎是多餘的,但這一定是因爲我嚴重缺乏API的知識。事實上,我嘗試閱讀khronos.org上的文檔,但這並沒有幫助我理解它的用法。

+1

除了答案中的內容之外,我相信你在這裏尋找的概念的名稱是一個頂點緩衝對象(VBO):http://www.opengl.org/wiki/Vertex_Buffer_Object – 2011-03-25 15:13:55

回答

16

如果您在多個幀中重複使用相同的數據,則使用glBufferData作爲設置/初始化的一部分將只將數據從CPU傳輸到GPU一次。而每個幀必須調用glVertexAttribPointer,因此使用它來傳輸數據會導致使用更多的總線帶寬。

如果您每幀更新屬性數組,那麼這種方式沒有多大優勢。

+0

Aha !我正在研究類似圖像處理API的東西,所以頂點不會改變(更不用說只有六個)。非常感謝!高度讚賞! – 2011-03-23 08:49:30

+4

問題不在於調用glVertexAttribPointer(實際上,儘管如此,仍然使用offset 0調用它)。關鍵的想法是,使用glBufferData可以在「快速內存」(即GPU可直接訪問的RAM)中創建數據的工作副本,而不必在內存域(即CPU→GPU)之間傳輸頂點屬性,每次調用glDrawElements或glDrawArrays。這也意味着您可以在複製到「快速」存儲器之後,用程序中的數據釋放存儲器。 – datenwolf 2011-03-23 08:55:40

+0

@datenwolf,謝謝! – 2011-03-23 09:00:16

5

這很奇怪。如果忽略glBufferData的工作原理相同,那麼要麼沒有綁定緩衝區,要麼在程序的前面有一個glBufferData調用。我很困惑,也許OpenGL ES有一些明顯不同的「特殊行爲」,但我已經檢查了規格,從我看到的,它和「普通」的OpenGL完全一樣。

如果沒有緩衝區被綁定(客戶端內存),繪圖(通過glDraw [Elements | Arrays])將從先前由glVertexAttribPointer提供的指針中讀取。它將從緩衝區讀取,如果綁定的話,將glVertexAttribPointer指針參數作爲偏移量處理到緩衝區中。從尚未初始化的緩衝區繪製顯然沒有定義。

glBufferData是做什麼的?

glBufferData至少做了兩件事,並且可選地做了第三件事。它分配緩衝區存儲並放置緩衝區的使用。或者,如果指針參數非空,它將用指向數據填充緩衝區。類似的glBufferSubData只是更新(可能是一個子範圍的)數據,它不會分配存儲或其他任何東西。

相關問題