OpenGL緩衝區物件之FBO

2021-07-24 10:55:40 字數 4817 閱讀 9442

在opengl渲染管線中幾何資料和紋理經過變換和一些測試處理,最終會被展示到螢幕上。opengl渲染管線的最終位置是在幀緩衝區中。幀緩衝區是一系列二維的畫素儲存陣列,包括了顏色緩衝區、深度緩衝區、模板緩衝區以及累積緩衝區。預設情況下opengl使用的是視窗系統提供的幀緩衝區。

opengl的gl_arb_framebuffer_object這個擴充套件提供了一種方式來建立額外的幀緩衝區物件(fbo)。使用幀緩衝區物件,opengl可以將原先繪製到視窗提供的幀緩衝區重定向到fbo之中。

和視窗提供的幀緩衝區類似,fbo提供了一系列的緩衝區,包括顏色緩衝區、深度緩衝區和模板緩衝區(需要注意的是fbo中並沒有提供累積緩衝區)這些邏輯的緩衝區在fbo中被稱為 framebuffer-attachable images說明它們是可以繫結到fbo的二維畫素陣列。

fbo中有兩類繫結的物件:紋理影象(texture images)和渲染影象(renderbuffer images)。如果紋理物件繫結到fbo,那麼opengl就會執行渲染到紋理(render to texture)的操作,如果渲染物件繫結到fbo,那麼opengl會執行離屏渲染(offscreen rendering)

fbo可以理解為包含了許多掛接點的乙個物件,它自身並不儲存影象相關的資料,他提供了一種可以快速切換外部紋理物件和渲染物件掛接點的方式,在fbo中必然包含乙個深度緩衝區掛接點和乙個模板緩衝區掛接點,同時還包含許多顏色緩衝區掛節點(具體多少個受opengl實現的影響,可以通過gl_max_color_attachments使用glget查詢),fbo的這些掛接點用來掛接紋理物件和渲染物件,這兩類物件中才真正儲存了需要被顯示的資料。fbo提供了一種快速有效的方法掛接或者解綁這些外部的物件,對於紋理物件使用glframebuffertexture2d,對於渲染物件使用glframebufferrenderbuffer建立fbo的方式類似於建立vbo,使用glgenframebuffers

void glgenframebuffers( 

glsizei n,

gluint *ids);

n:建立的幀緩衝區物件的數量

ids:儲存建立幀緩衝區物件id的陣列或者變數

其中,id為0有特殊的含義,表示視窗系統提供的幀緩衝區(預設)

fbo不在使用之後使用gldeleteframebuffers刪除該fbo

建立fbo之後,在使用之前需要繫結它,使用glbindframebuffers

void glbindframebuffer(glenum target, gluint id)
target:繫結的目標,該引數必須設定為 gl_framebuffer

id:由glgenframebuffers建立的id

渲染物件是用來繫結的緩衝區物件fbo上做離屏渲染的。它可以讓場景直接渲染到這個物件中(而不是到視窗系統中顯示),建立它的方法與建立fbo有點類似:

void glgenrenderbuffers(glsizei n, gluint* ids) 建立

void gldeleterenderbuffers(glsizei n, const gluint* ids) 刪除

void glbindrenderbuffer(glenum target, gluint id) 繫結

繫結完成之後,需要為渲染物件開闢一塊空間,使用下面函式完成:

void glrenderbufferstorage(glenum target,

glenum internalformat,

glsizei width,

glsizei height);

target:指定目標,必須設定為gl_renderbuffer

internalformat:設定影象格式(參考《opengl影象格式》)

width和height:設定渲染物件的長和寬(大小必須小於 gl_max_renderbuffer_size)

可以使用glgetrenderbufferparameteriv函式來獲取當前繫結的渲染物件

void glgetrenderbufferparameteriv(glenum target,

glenum param,

glint* value)

target:引數必須是gl_renderbuffer

param:取值如下(根據查詢的不同選擇相應的值)

gl_renderbuffer_width

gl_renderbuffer_height

gl_renderbuffer_internal_format

gl_renderbuffer_red_size

gl_renderbuffer_green_size

gl_renderbuffer_blue_size

gl_renderbuffer_alpha_size

gl_renderbuffer_depth_size

gl_renderbuffer_stencil_size

fbo本身並不包含任何影象儲存空間,它需要掛接紋理物件或者渲染物件到fbo,掛接影象物件到fbo使用下面的方式:

2.3.1 掛接2d紋理到fbo

glframebuffertexture2d

(glenum target,

glenum attachmentpoint,

glenum texturetarget,

gluint textureid,

glint level)

target:掛接的目標,必須指定為 gl_framebuffer

attachmentpoint:掛接點位,取值:gl_color_attachment0到gl_color_attachmentn,gl_depth_attachment,gl_stencil_attachment

對應著上圖中顏色緩衝區點位和深度以及模板緩衝區點位

texturetarget:設定為二維紋理(gl_texture_2d)

textureid:紋理物件的id值(如果設定為0,那麼紋理物件從fbo點位上解綁)

level:mipmap的層級

2.3.2 掛接渲染物件到fbo

void glframebufferrenderbuffer(glenum target,

glenum attachmentpoint,

glenum renderbuffertarget,

gluint renderbufferid)

第乙個和第二個引數與掛接到紋理一樣,第三個引數必須設定為gl_renderbuffer,第四個引數是渲染物件的id值。(如果設定為0,那麼該渲染物件從當前點位上解綁)

當掛接完成之後,我們在執行fbo下面的操作之前,必須檢查一下fbo的狀態,使用以下的函式:

glenum glcheckframebufferstatus(glenum target)
target:取值必須是gl_framebuffer,當返回gl_framebuffer_complete時,表示所有狀態都正常,否則返回錯誤資訊。

#pragma comment(lib, "glew32.lib")

#pragma comment(lib, "freeglut.lib")

#include

#include

#include

int windowwidth = 0;

int windowheight = 0;

const

int texwidth = 512;

const

int texheight = 512;

bool leftmousedown = false;

float mou***, mousey;

float cameraanglex, cameraangley;

float xrot, yrot;

gluint textureid;

gluint framebufferid;

gluint renderbufferid;

void drawcube()

void changesize(int w, int h)

void setuprc()

glenable(gl_depth_test);

glenable(gl_texture_2d);

}void renderscene(void)

void mousefunccb(int button, int state, int x, int y)

else

if (state == glut_up)

}}void mousemotionfunccb(int x, int y)

glutpostredisplay();

}void timerfunccb(int value)

int main(int argc, char* argv)

setuprc();

glutmainloop();

return

0;}

該程式演示了使用fbo作「渲染到紋理」的技術,將茶壺場景作為視窗場景的紋理,執行的效果圖如下所示:

OpenGL緩衝區物件

opengl 緩衝區物件 今天學習了一下緩衝區物件.opengl是按照客戶機 伺服器模式設計的,在opengl需要資料的時候,都必須把資料從客戶機內傳輸到伺服器。緩衝區物件,允許應用程式現實的指定把哪些資料儲存在圖形伺服器。1.建立緩衝區物件 glgenbuffers opengl分配n個當前未使用...

OpenGL緩衝區物件之VAO

vao vertex array object 是opengl用來處理頂點資料的乙個緩衝區物件,它不能單獨使用,都是結合vbo來一起使用的。vao是opengl coreprofile 引入的乙個特性。事實上在coreprofile中做頂點資料傳入時,必須使用vao方式。當我們使用vbo傳入頂點資料...

OpenGL緩衝區物件之EBO

ebo element buffer object,也叫ibo index buffer object 索引緩衝區物件,這個緩衝區主要用來儲存頂點的索引資訊。考慮這樣一種情況,我們需要繪製乙個立方體 在指定頂點座標的時候,可以使用以下的乙個陣列 glfloat vertices 可以看到事實上整個立...