zoukankan      html  css  js  c++  java
  • OpenGL FBO

    FBO一个最常见的应用就是:渲染到纹理(render to texture),通过这项技术可以实现发光效果,环境映射,阴影映射等很炫的效果。

    OpenGL中的Frame Buffer Object(FBO)扩展,被推荐用于把数据渲染到纹理对像。相对于其它同类技术,如数据拷贝或交换缓冲区等,使用FBO技术会更高效并且更容易实现。

    在OpenGL渲染管线中,几何数据和纹理最终都是以2d像素绘制到屏幕上。最后一步的渲染目标在OpenGL渲染管线中被称为帧缓存(frame buffer)。帧缓存是颜色缓存、深度缓存、模板缓存、累积缓存的集合。默认情况下, OpenGL使用的帧缓存是由窗体系统创建和管理的。

    在OpenGL扩展中,GL_EXT_framebuffer_object扩展提供了一个创建额外帧缓存对象(FBO)的接口。这个帧缓存的创建和控制完全是由OpenGL完成的,有别于窗体系统创建的默认的帧缓存。与系统默认的帧缓存类似,一个FBO也是颜色缓存、深度缓存、模板缓存的集合(FBO不包括累积缓存),然后OpenGL程序就可以把渲染重定向到FBO中。

    这里有一个新的概念需要注意,那就是renderbuffer object。这个对象是通过GL_EXT_framebuffer_object扩展创建。它被用来在渲染过程中为一个2D图像提供渲染目标。

    下图展示了FBO和renderbuffer object与texture object之间的关系。从图中我们可以看出:多个renderbuffer object和texture object可以通过挂接点挂接到FBO上。需要主要的是FBO并没有实际存储数据的地方,它只是一个数据的壳,它只有挂接点。



    一个FBO对象包含多个颜色挂接点和一个深度挂接点以及一个模板挂接点。不同的显卡支持的颜色挂接点的数目是不同的,可以通过查询GL_MAX_COLOR_ATTACHMENTS_EXT获取支持的最大的挂接点的数目。支持多个颜色挂接点的原因是FBO可以在同一时间内将颜色缓存渲染到多个目标中去,这种能力被称为MRT(multiple render targets)。通过GL_ARB_draw_buffers扩展可以实现该功能。

    帧缓冲提供了一种有效的切换机制,使得挂接和卸载一个可挂接的图像非常之迅速。FBO使用glFramebufferTexture2DEXT()来进行texturebuffer对象的切换,使用glFramebufferRenderbufferEXT()来进行renderbuffer对象的切换。

    让我们看一下其使用过程:
    1.FBO对象的创建与销毁
    void glGenFramebuffersEXT(GLsizei n, GLuint* ids);
    void glDeleteFramebuffersEXT(GLsizei n, const GLuint* ids);
    第一个参数是要创建的FBO的个数,第二个保存创建的FBO的ID。

    2.一旦FBO对象创建完毕,即要进行绑定
    void glBindFramebufferEXT(GLenum target, GLuint id);
    第一个参数必须是GL_FRAMEBUFFER_EXT
    第二个参数是第一步创建FBO对象中获取的id号,该id号是一个非0值,因为系统默认的FBO的id号是0,所以如果你想取消FBO的绑定,将id等于0作为id参数传递给该函数即可。

    3.创建Renderbuffer Object
    void glGenRenderbuffersEXT(GLsizei n, GLuint* ids);
    void glDeleteRenderbuffersEXT(GLsizei n, const GLuint* ids);

    4.同样的,Renderbuffer Object创建好之后,要记得绑定。
    void glBindRenderbufferEXT(GLenum target, GLuint id)

    5.确定Renderbuffer Object的数据格式和尺寸。
      这一步很重要,因为我们只是创建了Renderbuffer Object,还没有为它提供一个存储数据的地方,也没有指定其存储数据的地方存储什么格式的数据,所以接下来就要做这个事情了。
    void glRenderbufferStorageEXT(GLenum target, GLenum internalFormat, GLsizei width, GLsizei height);
    第一个参数必须是GL_RENDERBUFFER_EXT
    第二个参数可以是可渲染的颜色格式,如(GL_RGB, GL_RGBA, etc.),可渲染的深度格式(GL_DEPTH_COMPONENT)或者是可渲染的模板格式(GL_STENCIL_INDEX)。
    最后两个参数就是以像素为单位指定数据所要占用内存的大小。

    这里需要注意两点:
    1。 指定的内存区域的宽和高应该都小于GL_MAX_RENDERBUFFER_SIZE_EXT,否则将产生GL_INVALID_VALUE错误。
    2。 所有的texture object也好,renderbuffer object也好,其宽和高都是严格一致的。

    6.指定挂接的对象
    glFramebufferTexture2DEXT函数挂接一个texture图像到FBO
    glFramebufferRenderbufferEXT函数挂接一个Renderbuffer图像到FBO

    7.检测FBO状态
    该挂接的对象都挂接好了,在使用FBO之前,必须要检查FBO的状态是否处于完成状态。如果FBO处于未完成状态,那么绘制操作就会失败。如何获取FBO的完成状态呢?使用
    glCheckFramebufferStatusEXT函数。


  • 相关阅读:
    26 转义符 re模块 方法 random模块 collection模块的Counter方法
    25 正则表达式
    24 from 模块 import 名字
    24 from 模块 import 名字
    24 from 模块 import 名字
    23 析构方法 items系列 hash方法 eq方法
    21 isinstance issubclass 反射 _str_ _new_ _len_ _call_
    20 属性, 类方法, 静态方法. python2与python3的区别.
    python(1)
    python之字符串格式化
  • 原文地址:https://www.cnblogs.com/dragon2012/p/2860446.html
Copyright © 2011-2022 走看看