OpenGL中FBO的概念及其應用

來源:互聯網
上載者:User

OpenGL中FBO的概念及其應用

 

【本帖轉自 http://www.cppblog.com/kongque/archive/2010/08/26/124754.html】

 

FBO一個最常見的應用就是:渲染到紋理(render to texture),通過這項技術可以實現光暈效果,環境映射,陰影映射等很炫的效果。

OpenGL中的Frame Buffer Object(FBO)擴充,被推薦用於把資料渲染到紋理對像。相對於其它同類技術,如資料拷貝或交換緩衝區等,使用FBO技術會更高效並且更容易實現。

在OpenGL渲染管線中,幾何資料和紋理最終都是以2d像素繪製到螢幕上。最後一步的渲染目標在OpenGL渲染管線中被稱為幀緩衝(frame buffer)。幀緩衝是顏色緩衝、深度緩衝、模板緩衝、累積緩衝的集合。預設情況下, OpenGL使用的幀緩衝是由表單系統建立和管理的。

在OpenGL擴充中,GL_EXT_framebuffer_object擴充提供了一個建立額外幀緩衝對象(FBO)的介面。這個幀緩衝的建立和控制完全是由OpenGL完成的,有別於表單系統建立的預設的幀緩衝。與系統預設的幀緩衝類似,一個FBO也是顏色緩衝、深度緩衝、模板緩衝的集合(FBO不包括累積緩衝),然後OpenGL程式就可以把渲染重新導向到FBO中。

這裡有一個新的概念需要注意,那就是renderbuffer object。這個對象是通過GL_EXT_framebuffer_object擴充建立。它被用來在渲染過程中為一個2D映像提供渲染目標。

展示了FBO和renderbuffer object與texture object之間的關係。我們可以看出:多個renderbuffer object和texture object可以通過掛接點掛接到FBO上。需要主要的是FBO並沒有實際儲存資料的地方,它只是一個資料的殼,它只有掛接點。

一個FBO對象包含多個顏色掛接點和一個深度掛接點以及一個模板掛接點。不同的顯卡支援的顏色掛接點的數目是不同的,可以通過查詢GL_MAX_COLOR_ATTACHMENTS_EXT擷取支援的最大的掛接點的數目。支援多個顏色掛接點的原因是FBO可以在同一時間內將顏色緩衝渲染到多個目標中去,這種能力被稱為MRT(multiple render targets)。通過GL_ARB_draw_buffers擴充可以實現該功能。

幀緩衝提供了一種有效切換機制,使得掛接和卸載一個可掛接的映像非常之迅速。FBO使用glFramebufferTexture2DEXT()來進行texturebuffer對象的切換,使用glFramebufferRenderbufferEXT()來進行renderbuffer對象的切換。

讓我們看一下其使用過程:
1.FBO對象的建立與銷毀
void glGenFramebuffersEXT(GLsizei n, GLuint* ids);
void glDeleteFramebuffersEXT(GLsizei n, const GLuint* ids);
第一個參數是要建立的FBO的個數,第二個儲存建立的FBO的ID。

2.一旦FBO對象建立完畢,即要進行綁定
void glBindFramebufferEXT(GLenum target, GLuint id);
第一個參數必須是GL_FRAMEBUFFER_EXT
第二個參數是第一步建立FBO對象中擷取的id號,該id號是一個非0值,因為系統預設的FBO的id號是0,所以如果你想取消FBO的綁定,將id等於0作為id參數傳遞給該函數即可。

3.建立Renderbuffer Object
void glGenRenderbuffersEXT(GLsizei n, GLuint* ids);
void glDeleteRenderbuffersEXT(GLsizei n, const GLuint* ids);

4.同樣的,Renderbuffer Object建立好之後,要記得綁定。
void glBindRenderbufferEXT(GLenum target, GLuint id)

5.確定Renderbuffer Object的資料格式和尺寸。
  這一步很重要,因為我們只是建立了Renderbuffer Object,還沒有為它提供一個儲存資料的地方,也沒有指定其儲存資料的地方儲存什麼格式的資料,所以接下來就要做這個事情了。
void glRenderbufferStorageEXT(GLenum target, GLenum internalFormat, GLsizei width, GLsizei height);
第一個參數必須是GL_RENDERBUFFER_EXT
第二個參數可以是可渲染的顏色格式,如(GL_RGB, GL_RGBA, etc.),可渲染的深度格式(GL_DEPTH_COMPONENT)或者是可渲染的模板格式(GL_STENCIL_INDEX)。
最後兩個參數就是以像素為單位指定資料所要佔用記憶體的大小。

這裡需要注意兩點:
1。 指定的記憶體地區的寬和高應該都小於GL_MAX_RENDERBUFFER_SIZE_EXT,否則將產生GL_INVALID_VALUE錯誤。
2。 所有的texture object也好,renderbuffer object也好,其寬和高都是嚴格一致的。

6.指定掛接的對象
glFramebufferTexture2DEXT函數掛接一個texture映像到FBO
glFramebufferRenderbufferEXT函數掛接一個Renderbuffer映像到FBO

7.檢測FBO狀態
該掛接的對象都掛接好了,在使用FBO之前,必須要檢查FBO的狀態是否處於完成狀態。如果FBO處於未完成狀態,那麼繪製操作就會失敗。如何擷取FBO的完成狀態呢?使用
glCheckFramebufferStatusEXT函數。

至此,關於FBO的概念及其使用就算告一段落了。下面給出一個完整的例子,該例子是從國外一個網站上找到的,代碼寫得簡單而漂亮,對FBO的示範也很完善。

FBO Demo

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.