opengl 中默認會爲我們創建一個幀緩衝,以後的顏色深度模板等信息會保存在裏面。
一 什麼是幀緩衝
以下摘抄自著名的wiki:
A framebuffer (frame buffer, or sometimes framestore) is a portion of random-access memory (RAM)[1] containing a bitmap that drives a video display. It is a memory buffer containing a complete frame of data.[2] Modern video cards contain framebuffer circuitry in their cores. This circuitry converts an in-memory bitmap into a video signal that can be displayed on a computer monitor。
所謂幀緩衝就是一個包含了位圖能夠驅動顯卡顯示的位於RAM中的一塊內存區域。它包含了完整的幀數據。現代的顯卡在其核心中包含幀緩衝電路。這個電路將內存位圖轉換成可以在計算機顯示器上顯示的視頻信號
二 幀緩衝能做什麼
通過創建幀緩衝我們可以自己創建需要的顏色顯示,最主要的實現效果是後處理。後處理可以實現,hdr,bloom,模糊,鏡頭光暈,體積光等。
三 幀緩衝的使用方法
流程:
創建緩衝 ->創建附件(紋理、緩衝對象)->附加到幀緩衝上->執行着色渲染->切換緩衝區->綁定到另外一個幀緩衝區。
OpenGL實現:幀緩衝可以同時附加紋理附件和緩衝對象附件來處理顏色深度等信息代碼如下:
GLuint NewframeBuffer;
glGenFramebuffers(1, &NewframeBuffer);
//綁定幀緩衝
glBindFramebuffer(GL_FRAMEBUFFER, NewframeBuffer);
//創建綁定到幀緩衝上的紋理附件
GLuint NewTextureColorBuffer;
//創建貼圖
glGenTextures(1, &NewTextureColorBuffer);
//綁定紋理貼圖
glBindTexture(GL_TEXTURE_2D, NewTextureColorBuffer);
//生成貼圖的格式
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 800, 600, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
//圖片近距離使用線性過濾
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
//遠距離使用線性過濾
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_LINEAR);
//把貼圖附加到爲幀緩衝附件
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, NewTextureColorBuffer, 0);
//創建綁定到幀緩衝的緩衝渲染緩衝附件(包含深度和模板信息等)
GLuint newRbo;
glGenRenderbuffers(1, &newRbo);
//綁定渲染緩衝對象
glBindRenderbuffer(GL_RENDERBUFFER, newRbo);
//設置渲染對象的數據格式(深度值使用24位保存,模板值使用8位)
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 800, 600);
//設置幀緩衝 (渲染對象)附件
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, newRbo);
幀緩衝附件形式有兩種紋理附件和緩衝對象。
紋理附件
當把一個紋理附加到幀緩衝的時候,所有的渲染指令將會寫入到這個紋理中。使用紋理的優點是,所有渲染操作的結果將會被儲存在一個紋理圖像中,我們之後可以在着色器中很方便地使用它。
緩衝對象
渲染緩衝對象(Renderbuffer Object)和紋理圖像一樣,即一系列的字節、整數、像素等。渲染緩衝對象附加的好處是,它會將數據儲存爲OpenGL原生的渲染格式,它是爲離屏渲染到幀緩衝優化過的。渲染緩衝對象直接將所有的渲染數據儲存到它的緩衝中,不會做任何針對紋理格式的轉換,讓它變爲一個更快的可寫儲存介質。然而,渲染緩衝對象通常都是隻寫的,所以你不能讀取它們(比如使用紋理訪問)。當然你仍然還是能夠使用glReadPixels來讀取它,這會從當前綁定的幀緩衝,而不是附件本身,可以在每個渲染迭代最後使用的glfwSwapBuffers,也可以通過渲染緩衝對象實現:只需要寫入一個渲染緩衝圖像,並在最後交換到另外一個渲染緩衝就可以。
四 幀緩衝需要注意什麼
想使用幀緩衝的信息:創建或者切換到另外一個幀緩衝然後把要使用的幀緩衝的附件綁定給當該緩衝就可以了, 比如上面代碼中想使用NewTextureColorBuffer 可以用 glBindTexture(GL_TEXTURE_2D, NewTextureColorBuffer);