• frame buffer object (fbo)整理


    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

    对于深度缓存:使用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);

    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
  • 相关阅读:
    [MySQL] InnoDB三大特性之 插入缓冲
    字节对齐《c和指针》笔记包含位域结构体的内存对齐(32bit,GCC)
    反编译想到的代码安全问题
    剪切\编辑歌曲软件
    照片行【生活随笔】井冈山之行
    埃里克食品浅谈垃圾食品
    C++ 堆排序实现
    SQLite数据库
    全光网络的前世今生
    hdu1201(从出生长18岁经过多少天)
  • 原文地址:https://www.cnblogs.com/cloudseawang/p/1349661.html
  • Copyright © 2020-2023  润新知