緩衝區有許多不同的用途,它能儲存頂點資料、畫素資料、紋理資料、著色器處理的輸入、或者不同著色器階段的輸出。
1. 建立緩衝區
我們可以一次性建立任意數量的緩衝區:
gluint buffers[n]; //n代表緩衝區數量
glgenbuffers(n, buffers);
執行此函式後,buffers陣列中就存放著n個緩衝區物件的識別符號(非0的無符號整數)。接下來就可以將這些緩衝區識別符號(如buffers[0])進行繫結來使用緩衝區。
在opengl中有許多不同的繫結點(binding point),每個繫結點有著不同的作用。我們可以將每個結合點或繫結點看做乙個在同一時刻只能結合乙個物件的槽。
繫結點如下:
gl_array_buffer:陣列緩衝區儲存顏色、位置、紋理座標等頂點屬性,或者其它自定義屬性
gl_copy_read_buffer:緩衝區用作通過glcopybuffersubdata進行複製的資料來源
gl_copy_write_buffer:緩衝區用作通過glcopybuffersubdata進行複製的目標
gl_element_array_buffer:索引陣列緩衝區用於儲存gldrawelements、gldrawrangeelements和gldrawelementsinstanced的索引
gl_pixel_pack_buffer:glreadpixels之類畫素包裝操作的目標緩衝區
gl_pixel_unpack_buffer:glteximagexd、gltexsubimagexd之類的紋理更新函式的源緩衝區
gl_texture_buffer:著色器可以通過紋理單元拾取來訪問的緩衝區
gl_transform_feedback_buffer:變換反饋頂點著色器寫入的緩衝區
gl_uniform_buffer:著色器訪問的uniform值
2. 繫結緩衝區
函式原型:glbindbuffer(glenum target, gluint buffer);
target引數為上面說到的繫結點,buffer引數為緩衝區物件的識別符號。
如果要解除繫結點的繫結,則再呼叫一次glbindbuffer引數,而引數buffer置為0即可。
另外,其它合法的緩衝區也可以繫結到同乙個繫結點上。
當使用完緩衝區後,我們需要呼叫gldeletebuffers(glsizei n, const gluint* buffers)函式對其進行清除。
3.填充緩衝區
即將資料傳遞到緩衝區,函式原型:
glbufferdata(glenum target, glsizeiptrarb size, const void *data, glenum usage);
其中glsizeiptrarb 型別等於ptrdiff_t。
target: 繫結點
size: 上傳資料大小
data: 資料。如果只是想分配指定大小的緩衝區,而不對它進行填充,則置為null
usage: 這個引數告訴opengl我們打算如何使用此緩衝區,一般來說為gl_dynamic_draw(緩衝區內容將經常會由應用程式進行更新,並且經常用於繪製或複製到其他影象)。其它的可選值還包括:
gl_stream_draw: 緩衝區內容將由應用程式進行一次設定,並且經常用於繪製
gl_stream_read:緩衝區的內容將作為一條opengl命令的輸出來進行一次設定,並且經常用於繪製
gl_stream_copy:緩衝區的內容將作為一條opengl命令的輸出來進行一次設定,並且不經常用於繪製或複製到其他影象
gl_static_draw:緩衝區內容將由應用程式進行一次設定,並且經常用於繪製或複製到其他影象
gl_static_read:緩衝區的內容將作為一條opengl命令的輸出來進行一次設定,並且由應用程式進行多次查詢
gl_static_copy:緩衝區的內容將作為一條opengl命令的輸出來進行一次設定,並且經常用於繪製或複製到其他影象
gl_dynamic_read:緩衝區的內容將作為一條opengl命令的輸出經常進行更新,並且由應用程式進行多次查詢
gl_dynamic_copy:緩衝區的內容將作為一條opengl命令的輸出經常進行更新,並且經常用於繪製或複製到其他影象
另外,我們可以使用glbuffersubdata函式對緩衝區的一部分進行更新。函式原型如下:
void glbuffersubdata(glenum target, intptr offset, sizeiptr size, const void *data);
這個函式不能更改緩衝區的使用方式,因為緩衝區記憶體已經被分配了。
4.pbo(pixel buffer object)
畫素緩衝區物件儲存在gpu中。pbo的繫結點為:
1. gl_pixel_pack_buffer:當乙個pbo繫結到這個目標時,任何讀取畫素的opengl操作都會從pbo中獲取他們的資料,包括glreadpixels、glgetteximage和glgetcompressedteximage。這樣的話,這些讀取畫素的操作就不必將從幀緩衝區或紋理中抽取的資料讀回到客戶端記憶體中。
2. gl_pixel_unpack_buffer:當繫結到此目標時,任何繪製畫素的opengl操作都會向乙個繫結的pbo中放入他們的資料。如glteximagexd、gltexsubimagexd、glcompressedteximagexd等。
pbo在處理需要經常訪問、修改或者更新畫素資料時有著巨大的優勢。它可以暫存gpu本地畫素資料,前提是需要先為他們分配儲存空間。它也經常用來儲存來自乙個渲染目標的2d影象、紋理或其它資料來源。
從緩衝區中讀取畫素資料
void glreadpixels(glint x, glint y, glsizei width, glsizei height, glenum format, glenum type, void *pixels);
此函式用於從當前啟用的讀取緩衝區的指定位置獲取畫素,然後將他們複製到cpu記憶體中。
使用緩衝區,可以避免當我們向客戶端記憶體進行寫入操作時,整個管線經常需要被清空而可能帶來的效能問題。
5.tbo(texbo)
乙個紋理主要包含兩個部分:紋理取樣狀態和包含紋理值得資料緩衝區。我們可以將乙個緩衝區物件繫結到gl_texture_buffer緩衝區中的乙個紋理繫結點。
tbo有兩個特性:
1.紋理緩衝區能直接填充來自其他渲染結果(如變換反饋、畫素讀取操作或頂點資料)的資料,這樣可以節省不少時間。
2.寬鬆的紋理大小限制。
我們可以通過下面的方法來建立、使用紋理緩衝區:
gluint texbo;
glgenbuffer(1, texbo);
glbindbuffer(gl_texture_buffer, texbo);
//上傳資料
glbufferdata(gl_texture_buffer, sizeof(float) * count, filedata, gl_dynamic_draw);
//繫結到乙個紋理單元
glactivetexture(gl_texture1);
glbindtexture(gl_texture_buffer, texbotexture);
//繫結
gltexbuffer(gl_texture_buffer, gl_r32f, texbo);
但是,紋理緩衝區不能在著色器中用普通的取樣器-sampler1d、sampler2d來進行訪問,而是使用samplerbuffer,取樣函式也相應地變為了texelfetch:
uniform samplerbuffer sampler;
void main()
OpenGL緩衝區物件
opengl 緩衝區物件 今天學習了一下緩衝區物件.opengl是按照客戶機 伺服器模式設計的,在opengl需要資料的時候,都必須把資料從客戶機內傳輸到伺服器。緩衝區物件,允許應用程式現實的指定把哪些資料儲存在圖形伺服器。1.建立緩衝區物件 glgenbuffers opengl分配n個當前未使用...
OpenGL緩衝區物件之FBO
在opengl渲染管線中幾何資料和紋理經過變換和一些測試處理,最終會被展示到螢幕上。opengl渲染管線的最終位置是在幀緩衝區中。幀緩衝區是一系列二維的畫素儲存陣列,包括了顏色緩衝區 深度緩衝區 模板緩衝區以及累積緩衝區。預設情況下opengl使用的是視窗系統提供的幀緩衝區。opengl的gl ar...
OpenGL緩衝區物件之VAO
vao vertex array object 是opengl用來處理頂點資料的乙個緩衝區物件,它不能單獨使用,都是結合vbo來一起使用的。vao是opengl coreprofile 引入的乙個特性。事實上在coreprofile中做頂點資料傳入時,必須使用vao方式。當我們使用vbo傳入頂點資料...