OpenGL ES 3.0之Fragment buffer objects(FBO)詳解(一)


   片段操作圖

  

 

  這篇文章將介紹從寫入幀緩沖和讀取幀緩沖的方式。

  Buffers(緩沖)

  OpenGL ES支持三種緩沖:

  OpenGL ES

  •• Color buffer顏色緩沖

  •• Depth buffer深度緩沖

  •• Stencil buffer模板緩沖

  創建緩沖區

  OpenGL ES 是一個交互式的渲染系統,假設每幀的開始,你希望初始化所有緩沖區中數據的默認值。調用glClear 函數來清除緩沖區內容,參數mask 指定清除的緩沖區。

  

你可能不要求清除每一個緩沖區,不在同時清除它們。但如果你想同時清除所有的緩沖區,只調用一次glClear 可以獲得更好的性能。

  

  

  

 如果你的幀緩沖區中有多個繪制緩沖,你也可以清除指定的緩沖區,如下:

  

  為減少調用函數的次數,你可以同時清除深度和模板緩沖區內容,如下:

  

  使用掩碼來控制寫入緩沖區

  一般你可以控制對緩沖區的操作,哪部分可以寫,哪部分不可寫。在顏色緩沖區中,glColorMask 指定顏色緩沖區的組成里那部分可被更新。如果mask 被設為GL_FALSE,這個組成部分不能更新,默認值是GL_TRUE。對於深度同樣

  

  

  

  

  讀取和寫入像素到幀緩沖區

  

  

  

  多渲染目標MRTs

  MRTs允許應用程序同時渲染多個顏色緩沖區。下面是流程

  1.創建幀緩沖對象framebuffer objects,使用

  glGenFramebuffers ( 1, &fbo );創建幀緩沖對象
  glBindFramebuffer ( GL_FRAMEBUFFER, fbo );綁定為當前使用的幀緩沖對象。

  

  2.創建紋理對象

  glGenTextures(4,textureId);創建

  glBindTexture ( GL_TEXTURE_2D, textureId );綁定
  glTexImage2D ( GL_TEXTURE_2D, 0, GL_RGBA,
          textureWidth, textureHeight,
  0, GL_RGBA, GL_UNSIGNED_BYTE, NULL );
  // Set the filtering mode
  glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
  GL_NEAREST );
  glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
GL_NEAREST );

  

  3.幀緩沖對象綁定相關的紋理。

  glFramebufferTexture2D ( GL_DRAW_FRAMEBUFFER,
               GL_COLOR_ATTACHMENT0,
               GL_TEXTURE_2D,
               textureId, 0 );

  

   4.指定渲染的附加顏色

  glDrawBuffers(GLsizei n, const GLenum* bufs)

  

例如你可以使用4種顏色輸出建立一個FBO對象

  

const GLenum attachments[4] = { GL_COLOR_ATTACHMENT0,
                                                   GL_COLOR_ATTACHMENT1,
                                                   GL_COLOR_ATTACHMENT2,
                                                   GL_COLOR_ATTACHMENT3
                                                   };
glDrawBuffers ( 4, attachments );

通過GL_MAX_COLOR_ATTACHMENTS你可以查詢支持最多的顏色數,支持最小的數目是4.

 

  5.聲明和使用着色器的輸出

layout(location = 0) out vec4 fragData0;
layout(location = 1) out vec4 fragData1;
layout(location = 2) out vec4 fragData2;
layout(location = 3) out vec4 fragData3;

 

完整代碼

  

int InitFBO ( ESContext *esContext )
{
   UserData *userData = esContext->userData;
   int i;
   GLint defaultFramebuffer = 0;
   const GLenum attachments[4] = 
   { 
      GL_COLOR_ATTACHMENT0,
      GL_COLOR_ATTACHMENT1,
      GL_COLOR_ATTACHMENT2,
      GL_COLOR_ATTACHMENT3 
   };

   glGetIntegerv ( GL_FRAMEBUFFER_BINDING, &defaultFramebuffer );

   // Setup fbo
   glGenFramebuffers ( 1, &userData->fbo );
   glBindFramebuffer ( GL_FRAMEBUFFER, userData->fbo );

   // Setup four output buffers and attach to fbo
   userData->textureHeight = userData->textureWidth = 400;
   glGenTextures ( 4, &userData->colorTexId[0] );
   for (i = 0; i < 4; ++i)
   {
      glBindTexture ( GL_TEXTURE_2D, userData->colorTexId[i] );

      glTexImage2D ( GL_TEXTURE_2D, 0, GL_RGBA, 
                     userData->textureWidth, userData->textureHeight, 
                     0, GL_RGBA, GL_UNSIGNED_BYTE, NULL );

      // Set the filtering mode
      glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
      glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );

      glFramebufferTexture2D ( GL_DRAW_FRAMEBUFFER, attachments[i], 
                               GL_TEXTURE_2D, userData->colorTexId[i], 0 );
   }

   glDrawBuffers ( 4, attachments );

   if ( GL_FRAMEBUFFER_COMPLETE != glCheckFramebufferStatus ( GL_FRAMEBUFFER ) )
   {
      return FALSE;
   }

   // Restore the original framebuffer
   glBindFramebuffer ( GL_FRAMEBUFFER, defaultFramebuffer );

   return TRUE;
}

 

fsh代碼

   

#version 300 es
precision mediump float;
layout(location = 0) out vec4 fragData0;
layout(location = 1) out vec4 fragData1;
layout(location = 2) out vec4 fragData2;
layout(location = 3) out vec4 fragData3;
void main()
{
    // first buffer will contain red color
    fragData0 = vec4 ( 1, 0, 0, 1 );
    // second buffer will contain green color
    fragData1 = vec4 ( 0, 1, 0, 1 );
    // third buffer will contain blue color
    fragData2 = vec4 ( 0, 0, 1, 1 );
    // fourth buffer will contain gray color
    fragData3 = vec4 ( 0.5, 0.5, 0.5, 1 );
}

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM