GPU Programming: Frame Buffer Object (penjelasan)

Sample FBO application

Sample FBO application

Pada OpenGL rendering pipeline, geometry data dan textures diubah dan melewati beberapa test sebelum akhirnya di-render ke layar monitor sebagai 2D pixels. Tujuan akhir rendering dari OpenGL pipeline disebut dengan framebuffer. Framebuffer adalah kumpulan 2D array yang digunakan oleh OpenGL, seperti color buffers, depth buffer, stencil buffer, dan accumulation buffer. Pada dasarnya, OpenGL menggunakan framebuffer sebagai redering destination yang dibangun dan diatur oleh window system yang disebut dengan window-system-provided framebuffer.

OpenGL menyediakan GL_EXT_framebuffer_object sebagai sebuah interface untuk membangun non-displayable framebuffer objects (FBO) tambahan. Framebuffer ini disebut sebagai application-created framebuffer untuk membedakan dengan window-system-provided framebuffer. Dengan menggunakan FBO, aplikasi OpenGL dapat secara langung mengirim hasil rendering ke FBO, dan sepenuhnya dikendalikan oleh OpenGL.

Sama halnya dengan window-system-provided framebuffer, FBO mengandung kumpulan rendering  destination, seperti color, depth, dan stencil buffer (Accumulation buffer tidak terdapat di FBO). Buffer-buffer ini disebut dengan framebuffer-attachable images, yang merupakan 2D array of pixels yang dapat ditempatkan ke dalam framebuffer object. Multiple object dapat ditempatkan pada FBO.

connectivity between FBO, texture, and renderbuffer

connectivity between FBO, texture, and renderbuffer

Terdapat dua jenis framebuffer-attachable image, yakni texture image dan renderbuffer image. Jika sebuah texture object ditempatkan pada framebuffer, maka OpenGL menampilkan “render to texture”, dan jika renderbuffer object yang ditempatkan maka  OpenGL menampilkan “offscreen rendering”.
Renderbuffer object adalah jenis storage object baru pada GL_EXT_framebuffer_object. Ia digunakan sebagai rendering destination untuk 2D image selama proses rendering.

Pada FBO terdapat:
Multiple color attachment(GL_COLOR_ATTACHMENT0_EXT,.., GL_COLOR_ATTACHMENTn_EXT), sebuah depth attachment point (GL_DEPTH_ATTACHMENT_EXT) dan sebuah stencil attachment point (GL_STENCIL_ATTACHMENT_EXT). Jumlah color attachment tergantung implementasi, tetapi sedikitnya tiap FBO memiliki sebuah color attachment. Anda dapat menentukan jumlah color attachment dengan GL_MAX_COLOR_ATTACHMENTS_EXT, yang didukung oleh GPU. Alasana FBO memiliki multiple color attachment adalah memfasilitasi proses rendering color buffer ke beberapa tujuan dalam satu waktu. Multiple render targets(MRT) ini dapat dilakukan oleh GL_ARB_draw_buffers. FBO sendiri tidak memiliki image array di dalamnya, ia hanya memiliki multiple attachment points.

FBO menyediakan mekanisme switching yang efisien: detach the previous framebuffer-attachable image dari FBO, dan attach a new framebuffer-attachable image ke dalam FBO. Switching framebuffer-attachable images lebih cepat dibanding switching antar FBO. FBO juga menyediakan glFramebufferTexture2DEXT() untuk proses switching pada 2D texture objects, dan glFramebufferRenderbufferEXT() untuk proses switching pada renderbuffer objects.

Creating FBO
glGenFramebuffersEXT()

void glGenFramebuffersEXT(GLsizei n, GLuint* ids)
void glDeleteFramebuffersEXT(GLsizei n, const GLuint* ids)

glGenFramebuffersEXT() membutuhkan 2 parameter: yang pertama jumlah framebuffer yang akan dibangun, dan yang kedua adalah pointer yang berisi identifier. ID 0 berarti window-system-provided framebuffer. FBO dapat dihapus dengan memanggil glDeleteFramebuffersEXT().

glBindFramebufferEXT()

void glBindFramebufferEXT(GLenum target, GLuint id)

Parameter target seharusnya berisi GL_FRAMEBUFFER_EXT dan id berisi FBO identifier. Sekali FBO di-bind, maka segala operasi OpenGL akan bekerja pada FBO tersebut . ID 0 adalah window-system-provided framebuffer. Oleh karena itu, gunakan ID 0 untuk unbind dari FBO.

Renderbuffer Object
Sebagai tambahan, renderbuffer object dikenalkan sebagai offscreen rendering. Hal ini memungkinkan untuk menampilkan tampilan langsung ke renderbuffer object, malah dapat melakukan rendering ke texture object. Renderbuffer object digunakan untuk menyimpan OpenGL logical buffers yang tidak memiliki format texture, seperti stencil, dan depth buffer.

glGenRenderbuffersEXT()

void glGenRenderbuffersEXT(GLsizei n, GLuint* ids)
void glDeleteRenderbuffersEXT(GLsizei n, const Gluint* ids)

Sekali renderbuffer dibangun, ia memberikan nilai return sebuah positif integer bukan nol. ID 0 ditujukan untuk OpenGL.

glBindRenderbufferEXT()

void glBindRenderbufferEXT(GLenum target, GLuint id)

Parameter target diisi dengan GL_RENDERBUFFER_EXT untuk renderbuffer object.

glRenderbufferStorageEXT()

void glRenderbufferStorageEXT(GLenum target, GLenum internalFormat,
GLsizei width, GLsizei height)

Ketika renderbuffer object dibangun ia tidak memiliki alokasi memory untuk menyimpan data. Oleh karena itu, kita harus menyediakan alokasi memory dengan memanggil fungsi glRenderbufferStorageEXT(). Parameter target diisi dengan GL_RENDERBUFFER_EXT, dan parameter internalFormat diisi dengan color-renderable (GL_RGB, GL_RGBA, dll), depth-renderable(GL_DEPTH_COMPONENT), atau stencil-renderable (GL_STENCIL_INDEX). Lebar dan tinggi renderbuffer image dalam pixel ditempatkan pada parameter width dan height. width dan height harus kurang dari GL_MAX_RENDERBUFFER_SIZE_EXT, atau ia akan memberikan error pada GL_INVALID_VALUE.

glGetRenderbufferParameterivEXT()

void glGetRenderbufferParameterivEXT(GLenum target, GLenum param, GLint* value);

Anda juga dapat mengetahui berbagai parameter dari renderbuffer object yang sudah ada dengan memanggil fungsi ini. Parameter target diisi GL_RENDERBUFFER_EXT, dan parameter kedua diisi dengan nama parameter renderbuffer object, yakni pilihan di antara:
GL_RENDERBUFFER_WIDTH_EXT
GL_RENDERBUFFER_HEIGHT_EXT
GL_RENDERBUFFER_INTERNAL_FORMAT_EXT
GL_RENDERBUFFER_RED_SIZE_EXT
GL_RENDERBUFFER_GREEN_SIZE_EXT
GL_RENDERBUFFER_BLUE_SIZE_EXT
GL_RENDERBUFFER_ALPHA_SIZE_EXT
GL_RENDERBUFFER_DEPTH_SIZE_EXT
GL_RENDERBUFFER_STENCIL_SIZE_EXT

Parameter terakhir adalah pointer sebagai tempat menampung nilai parameter renderbuffer yang dipanggil.

Attaching images to FBO

FBO sendiri tidak memiliki image buffer di dalamnya. Malah, kita harus menempatkan framebuffer attachable images ( berupa texture atau renderbuffer objects) ke FBO. Mekanisme ini memungkinkan switch (detach dan attach) framebuffer-attachable images di dalam FBO. Ini lebih cepat dibanding switch antar FBO, dan lebih hemat dalam konsumsi memory. Sebagai contoh, sebuah texture dapat di tempatkan ke beberapa FBO sekaligus dan image storage-nya dapat di bagi-bagi untuk beberapa FBO.

glFramebufferTexture2DEXT()

glFramebufferTexture2DEXT(GLenum target,
GLenum attachmentPoint,
GLenum textureTarget,
GLuint textureId, GLint  level)

Parameter target berisi GL_FRAMEBUFFER_EXT, dan parameter kedua berisi attachment point tempat menghubungkan ke texture image, yakni dengan pilihan GL_COLOR_ATTACHMENT0_EXT, …, GL_COLOR_ATTACHMENTn_EXT, GL_DEPTH_ATTACHMENT_EXT atau GL_STENCIL_ATTACHMENT_EXT. Parameter ketiga berisi GL_TEXTURE_2D, dan keempat adalah identifier dari sebuah texture object. Parameter level adalah mipmap level dari texture yang akan ditempatkan. Bila textureId diisikan sebagai 0, maka texture image akan dikeluarkan dari FBO. Ketika sebuah texture object dihapus meskipun ia tengah berada di dalam FBO, maka secara otomatis ia akan dikeluarkan dari FBO yang sedang di-binding. Bila berada pada multiple FBO, maka tidak akan berpengaruh apapun pada FBO yang tidak di-binding.

glFramebufferRenderbufferEXT()

void glFramebufferRenderbufferEXT(GLenum target,
GLenum attachmentPoint,
GLenum renderbufferTarget,
GLuint renderbufferId)

Parameter pertama dan kedua sama dengan glFramebufferTexture2DEXT(), sedang parameter ketiga diisi dengan GL_RENDERBUFFER_EXT, dan yang terakhir diisi dengan renderbuffer identifier. Jika renderbufferId diisi dengan 0, maka renderbuffer image akan dikeluarkan dari FBO. Sifat-sifat seperti texture object juga berlaku pada renderbuffer object bila ia dihapus.

Checking FBO Status

Sekali attachable images ditempatkan ke dalam FBO, sebelum digunakan kita harus memastikan statusnya lengkap atau tidak lengkap. Hal ini dapat dilakukan dengan memanggil fungsi glCheckFramebufferStatusEXT(). Bila FBO tidak lengkap, maka perintah apapun akan gagal.

GLenum glCheckFramebufferStatusEXT(GLenum target)

Parameter target diisi dengan GL_FRAMEBUFFER_EXT. Fungsi tersebut akan memberikan nilai bukan nol setelah FBO dicek. Bila semua aturan dipenuhi, maka ia memberikan GL_FRAMEBUFFER_COMPETE_EXT. Sebaliknya, ia akan memberikan nilai error sesuai dengan aturan yang tidak dipenuhi.

Aturan kelengkapan FBO:

  1. Width dan height dari framebuffer-attachable image harus bukan nol.
  2. Jika image ditempatkan pada color attachment point, maka image harus memiliki color renderable. (GL_RGBA, GL_DEPTH_COMPONENT, GL_LUMINANCE, dll)
  3. Jika image ditempatkan pada GL_DEPTH_ATTACHMENT_EXT, maka image harus memiliki depth-renderable. (GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT24_EXT, dll)
  4. Jika image ditempatkan pada GL_STENCIL_ATTACHMENT_EXT, maka image harus memiliki stencil-renderable. (GL_STENCIL_INDEX, GL_STENCIL_INDEX8_EXT, dll)
  5. FBO sedikitnya memiliki satu image.
  6. Seluruh image yang ditempatkan pada FBO harus memiliki ukuran yang sama.
  7. Seluruh image yang ditempatkan pada color attachment point harus memiliki internal format yang sama.

Meskipun semua aturan diatas telah dipenuhi, adakalanya OpenGL driver tidak mendukung beberapa kombinasi internal format dan parameter. Bila OpenGL driver tidak mendukung maka fungsi glCheckFramebufferStatusEXT() akan memberikan nilai GL_FRAMEBUFFER_UNSUPPORTED_EXT.

referensi: song ho ahn

download sample code (VStudio2005): SampleFBO.rar, diperlukan library glut dan glew.

4 thoughts on “GPU Programming: Frame Buffer Object (penjelasan)”

  1. lam kenal nichhhh

    boleh tuch 3D di linux-nya…..ane blom pernah nyoba ngerasain……..krunnci gak ya……maklum baru pindah os dari produk bill gatellll

Leave a Reply

Your email address will not be published. Required fields are marked *