opengl緩衝區對象

轉自 http://iqnix.blog.163.com/blog/static/21721982014228115223718/


一:爲什麼要有opengl緩衝區對象
前面的頂點數組使得幾何圖元的顯示方便了很多,但是如果每次都要向OPENGL發送一大塊數據,而這數據其實並沒有修改過,那麼傳輸就是冗餘的。所以這裏添加了緩衝區對象,將頂點數組存儲在服務器端的緩衝區對象中。


二:如何創建和使用緩衝區對象
1.創建緩衝區對象
    glGenBuffers():OpenGL分配n個當前未使用的名稱(非 0),表示緩衝區對象。
    原型 : void glGenBuffers(GLsizei n,GLuint *buffers);
    GLboolean glIsBuffer(GLuint buffer):判斷一個標識符是否是當前使用的緩衝區對象的標識符。


  2.激活緩衝區對象
    激活緩衝區對象,首先需要對他進行綁定。綁定緩衝區對象表示選擇未來的操作將影響到哪個緩衝區    對象。
    glBindBuffer(GLenum target ,GLuint buffer): 指定了當前的活動緩衝區對象 。


  3.用數據分配和初始化緩衝區對象
     一旦綁定了一個緩衝區對象,就需要保留空間以存儲數據。
    void glBufferData(GLenum target,GLsizeiptr size,const GLvoid * data,GLenum usage );
    功能是分配size個存儲單位的OpenGL服務器內存,用於存儲頂點數據或索引。以前有與當前緩衝區對象相關聯的數據將刪除。
    glBufferData()首先在OpenGL拂去其中分配內存以存儲數據。如果成功分配,data!=NULL,size個單位就會從客戶機內存複製到這個對象中。如果data=NULL,爲數據保留適當的空間,但不會初始化。


4.更新緩衝區對象的數據值
    方法一:假設已經在用用程序的一個緩衝區中準備了相同類型的數據,glBufferSubData()將用我們提供的數據替換被綁定的緩衝區對象的一些數據子集。
            void glBufferSubData(GLenum target,GLuint offset,GLsizei size,const GLvoid *data); 用data 指向的數據更新 與target 相關聯的當前綁定緩衝區對象中從offset開始的size個字節數據。
             
    方法二:允許靈活的選擇需要更新的數據。
            GLvoid *glMapBuffer(GLenum target,GLuenum access):返回一個指向緩衝區對象的指針,可以在這個緩衝區對象中寫入新值及更新之後,再調用GLboolean glUnMapBuffer(GLenum target)表示已經完成了對數據的更新,取消對這個緩衝區的映射。如果只需要更新所需範圍內的數據值,也可調用GLvoid *glMapBuffwerRange(GLenum target,GLintptr offset,GLsizeiptr length,GLbitfield access)


   5.在緩衝區對象之間複製數據
     void glCopyBufferSubData(readbuffer,writebuffer,resdoffset,writeoffset,size);
     把數據從與readbuffer相關聯的緩衝區對象複製到綁定到writebuffer的緩衝區對象。


   6. 清除緩衝區對象
      glDeleteBuffer(GLsizei n,const GLuint *buffers):刪除n個緩衝區對象。被刪除的當前緩衝區對象的所有綁定都重置爲零。如果一個緩衝區對象是在綁定時刪除的,這個對象的所有綁定都重置爲默認的緩衝區對象。


   7.使用緩衝區對象來存儲頂點數組數據
      需要以下步驟:
       (1)生成緩衝區對象標識符;
       (2)綁定緩衝區對象,確定是存儲頂點數據還是索引;
       (3)請求數據的存儲空間,並對數據元素進行初始化;
       (4)指定相對於緩衝區起始位置的偏移量;
       (5)綁定適當的緩衝區對象,用於渲染;
       (6)使用適當的頂點數組渲染函數進行渲染,比如glDrawArrays()
      如果想初始化多個緩衝區對象,就需要爲每個緩衝區對象重複以上。頂點數組數據的所有格式都適用於緩衝區對象。


轉自:http://blog.csdn.net/bugrunner/article/details/5356781


OpenGL的緩衝對象提供了一種高效的數據操作及吞吐方式,這此操作涉及整個渲染管線的多個環節,用來提高OpenGL的實現效率。常見的緩衝對象有:頂點緩衝對象(VBO)、像素緩衝對象(PBO)和幀緩衝對象(FBO),各種緩衝對象的操作方式及應用場合不盡相同,但主要都是在關係到內存與顯存之間需進行數據傳輸與交互時而進行的優化操作,因爲內存與顯存之間的數據交互在當前的硬件渲染架構下是必須的,但效率卻又受限於PCI的傳輸速度。緩衝區對象的作用就是讓這種數據交互操作在一種最優的方式下進行,使所有的操作從Client到顯存之間的距離儘可能地縮短,從而提高效率。

Vertex Buffer Object:

1.      在Client與Server之間快速地操作幾何頂點數據,能夠很快地對頂點數據進行更新等操作。這裏頂點數據的實質可以根據具體需要以其它數據填充。

2.      開闢的實際數據空間的位置不確定,根據VBO的屬性及CPU調用的次數,由顯存逐漸向內存轉移。

 

Pixel Buffer Object:

1.      在Client與Server之間快速地操作各類像素數據

2.      高效並不在於傳輸更快,而在於與硬件相關的異步調用方式,調用之後CPU即返回執行其它操作(使用DMA方式的傳輸、由OpenGL直接控制)

3.      在單個PBO情況下並不能得到很好的效果,畢竟傳輸過程仍然存在(但速度可能變快,比如顯存內部的數據傳輸),但其異步性就提供了雙PBO實現的可能性,用雙PBO來進行加速。

4.      PBO關聯的實際數據空間位置不確定,主要由PBO的屬性及OpenGL來確定。

 

Frame Buffer Object:

1.      提供了一個與FrameBuffer同類型的離屏渲染操作對象,可直接控制管線最終數據的去向。

2.      分配的空間是在顯存之中,因此用FBO來對顯存進行涉及GPU運算的交互操作效率較高。

3.      主要用於顯存內部數據的轉化、交互、操作的場合?

 

整個過程可用如下圖所示:

 

OpenGL Buffer Object Sample 

注意:所有的Buffer Object都只是一個中間的管理平臺,與實際的空間相分離。其中,除了FBO所關聯的數據空間在顯存之外,PBO和VBO所關聯的數據空間位置均不一定(system memory, shared memory, AGP, Video Memory均有可能)

 

關於更加詳細的Buffer Object使用方法可以參見:

《OpenGL Super Bible》(chapter11, chapter18)

http://www.songho.ca/opengl/gl_vbo.html

http://www.songho.ca/opengl/gl_pbo.html

http://www.songho.ca/opengl/gl_fbo.html


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章