当前位置: 代码迷 >> Iphone >> OpenGL ES 3.0之Fragment buffer objects(FBO)详解(1)
  详细解决方案

OpenGL ES 3.0之Fragment buffer objects(FBO)详解(1)

热度:678   发布时间:2016-04-25 05:29:05.0
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 esprecision 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 );}

 

 

 

  相关解决方案