fbo多个color buffer绘制

http://www.cnblogs.com/cloudseawang/archive/2008/12/07/1349661.html

FBO: frame buffer object主要用来render-to-texture,进行off-screen rendering.

以下是使用步骤:

1,初始化glewInit(),然后检测 GPU是否支持GL_EXT_FRAMEBUFFER_OBJECT扩展

2,创建FBO ,

GLuint fbo, color;
// Create an FBO
glGenFramebuffersEXT(1, &fbo);
// Create color texture
glGenTextures(1, &color);
glBindTexture(GL_TEXTURE_2D, color);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0,
GL_RGBA, GL_UNSIGNED_BYTE, NULL);

glGenerateMipmapEXT(GL_TEXTURE_2D);//生成mipmap
// Bind the FBO and attach color texture to it
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, color, 0);

对于一个fbo,可以绑定多个GL_COLOR_ATTACHMENT(I)_EXT,即可以有多个color

查询当前设备颜色绑定点的最大值:

[cpp] view plain copy
  1. <span style="font-family:Microsoft YaHei;font-size:14px;">GLuint maxbuffers;  
  2. glGetIntergeri(GL_MAX_COLOR_ATTACHMENTS, &maxbuffers);</span>  

对于深度缓存:使用32位float纹理

 Gluint depth,

  glGenTextures(1, &detph);

 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, depth);
  glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP);
  glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP);
  glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_DEPTH_COMPONENT32F_NV,
   widht, height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);

 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_TEXTURE_RECTANGLE_EXT,depth, 0);

 对于stencil buffer,目前是和depth buffer绑定在一起的,需要支持GL_EXT_PACKED_DEPTH_STENCIL extension扩展。

其定义方式如下:

 Gluint depthStencil;

glGenTextures(1, &detphStencil);

glBindTexture(GL_TEXTURE_2D, depthStencil);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8_EXT, widht, height, 0,
GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, NULL);

glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
GL_TEXTURE_2D, depthStencil,0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT,
GL_TEXTURE_2D, depthStencil,0);

对于depth, stencil buffer绑定的纹理,不支持mipmap.

另外也可以使用renderbuffer与fbo绑定。

 注意:fbo里如果不指定要写depth buffer,stencil buffer,仅仅enable depth test, 并不会写depth buffer!

3,使用fbo ,使用前一定要 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);

返回到主frambebuffer只需要

glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);

 

4,对于绑定多个color buffer,如果指定渲染到其中某一个buffer,则用glDrawBuffer

// Render to color0
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
glDrawBuffer(GL_ COLOR_ATTACHMENT0_EXT);
// Render to color1
glDrawBuffer(GL_ COLOR_ATTACHMENT1_EXT);

5, 如果一次渲染多个color buffer,则是Mulitple rendering target (MRT)。如果要指定渲染的起始buffer,则用glDrawBuffers

glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
glDrawBuffers(GL_ COLOR_ATTACHMENT(I)_EXT);

查询可以一次同时写入缓冲区的个数:

[cpp] view plain copy
  1. <span style="font-family:Microsoft YaHei;font-size:14px;">GLuint maxbuffers;  
  2. glGetIntergeri(GL_MAX_DRAW_BUFFERS, &maxbuffers);</span>  

因而,如果我们已经把两个纹理分别绑定到绑定点0和1,现在我们想同时渲染输出到这两个纹理上,我们就可以按以下代码来写:

   
   
   
   
[cpp] view plain copy
  1. <span style="font-family:Microsoft YaHei;font-size:14px;">GLenum buffers[] = { GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT };  
  2. glDrawBuffers(2, buffers);</span>  

当上面的函数正确运行之后,OpenGL 便建立了一个双颜色缓冲渲染输出的环境

6,读取fbo渲染的内容,有两种办法

定义输出图像:

  unsigned char output_image = new unsigned char[ width*height];

a,   直接读buffer, 

    glReadBuffer(GL_ COLOR_ATTACHMENT(I)_EXT)

     glReadPixels( 0,  0,width,height, GL_RGB,  GL_FLOAT,output_image);

b, 读绑定的texture ,color是绑定的纹理
  glBindTexture(GL_TEXTURE_RECTANGLE_ARB,color);
  glGetTexImage(GL_TEXTURE_RECTANGLE_ARB,0,GL_DEPTH_COMPONENT,GL_UNSIGNED_BYTE,output_image);

 7,delete FBO

glDeleteFramebuffersEXT(1,&fbo);

RBO和FBO To Texture区别:

  • when you want to make OpenGL do depth/stencil tests, but don't care about the actual values in the buffer, you will make a depth/stencil renderbuffer (no need to use textures if don't care about the values - and you can't for stencil). 
    (Same if you don't care about the values in the color-buffer (perhaps you only need depth values))
  • when you need to process the values of a buffer on the CPU (not the GPU) you should use a renderbuffer instead of a texture
    (faster and easier than using a texture)
  • if you want build-in AA on the color-buffer, you have no choice but to use a renderbuffer
  • 你可能感兴趣的:(fbo多个color buffer绘制)