2013-11-20 37 views
2

我有一些哈斯克爾/ OpenGLRaw代碼,不會是這樣的:我應該在每次繪製中移除頂點緩衝區對象嗎?

verticesPtr <- newArray ... 
glVertexPointer 3 gl_DOUBLE 0 verticesPtr 

buffersPtr <- malloc 
glGenBuffers 1 buffersPtr 
buffer <- peek buffersPtr 

glBindBuffer gl_ARRAY_BUFFER buffer 
glBufferData gl_ARRAY_BUFFER 4 verticesPtr gl_STREAM_DRAW 

glDrawArrays gl_LINE_STRIP 0 4 
glDeleteBuffers 1 buffersPtr 

我有一個關於這個代碼的兩個問題:

  1. 我從draw回調中調用此。這完全否定了將我的頂點數據存儲在服務器中的有用性嗎?
  2. 如果我應該將此代碼放在draw之外,我應該將gl_STREAM_DRAW命令更改爲更靜態的東西嗎?
+3

存儲使用雙精度將根本不利於你的頂點位置。驅動程序將把它們轉換爲單精度,所以你基本上只是在浪費內存。至於將頂點數據存儲在服務器中,考慮到在繪圖後立即刪除數據存儲,我幾乎不會稱之爲「存儲」:)至少,請將緩衝區保持在某個地方並使用'glBufferSubData(...) '更新它,而不是每次調用這個函數時分配和銷燬它。 –

+0

@ AndonM.Coleman:他正在使用Haskell,並保留一個緩衝區來修改與該語言的成語有點相似的行爲。是的,有可變類型,但有一個可變緩衝區,然後用於使用glBufferSubData進行更新。很顯然,在Haskell中,你會希望VBO本身被表示爲更高級別的類型。無論是內部可變的狀態還是寫入時複製的方式,新的VBO在更改時都是從舊的VBO派生的(這總是一個GL_STATIC_DRAW訪問)。 – datenwolf

+1

Haskell OpenGL綁定開發人員還致力於一系列更高級別的函數和類型,這些函數和類型在Haskell成語後面以乾淨,功能良好的方式呈現OpenGL。我建議看看他們是如何做到的。 – datenwolf

回答

2
  1. 是的,你以這種方式使用它們扔大部分緩衝區對象的好處了。很可能,它仍然會比glBegin/glEnd更快,因爲驅動程序會同時知道所有數據,而不是增量式的,但不能保證速度會更快,而且對於小緩衝區大小可能會更慢,這是由於創建和銷燬緩衝區對象的開銷。

  2. 是的,如glBufferData API docs中所述,您應該避免使用STREAM_DRAW,除非緩衝區在每一幀或接近每幀都發生變化。我個人的經驗法則是:

    • 變化只在偶爾 - >STATIC
    • 經常更改,但不經常比保持不變 - >DYNAMIC
    • 更改往往比它保持相同的 - >STREAM
+0

訪問模式不需要經驗法則。它準確地指定了哪種情況下使用哪種模式。 – datenwolf

+0

@datenwolf是真的,但是它指定緩衝區在被修改之前被訪問多少次。恕我直言,它更直觀地以相反的方式來思考它;作爲緩衝器被更新的幀的數量與幀的總數量之間的比率。 – bcrist

相關問題