http://www.cppblog.com/kongque/archive/2010/08/26/124754.html

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函数。

至此,关于FBO的概念及其使用就算告一段落了。下面给出一个完整的例子,该例子是从国外一个网站上找到的,代码写得简单而漂亮,对FBO的演示也很完善。

FBO Demo

OpenGL中FBO的概念及其应用 [转]的更多相关文章

  1. OpenGL中glVertex、显示列表(glCallList)、顶点数组(Vertex array)、VBO及VAO区别

    OpenGL中glVertex.显示列表(glCallList).顶点数组(Vertex array).VBO及VAO区别 1.glVertex 最原始的设置顶点方法,在glBegin和glEnd之间 ...

  2. 从零开始学习OpenGL ES之一 – 基本概念

    我曾写过一些文章介绍iPhone OpenGL ES编程,但大部分针对的是已经至少懂得一些3D编程知识的人.作为起点,请下载我的OpenGL Xcode项目模板,而不要使用Apple提供的模板.你可以 ...

  3. OpenGL中的常用绘图的命令与效果(经验设置)

    1. 剔除多边形表面 在三维空间中,一个多边形虽然有两个面,但我们无法看见背面的那些多边形,而一些多边形虽然是正面的,但被其他多边形所遮挡.如果将无法看见的多边形和可见的多边形同等对待,无疑会降低我们 ...

  4. 如何使用OpenGL中的扩展

    如果你在Windows平台下开发OpenGL程序,那么系统中自带的OpenGL库就是1.1的,如果想使用1.2或者更高版本的OpenGL库,那么只能使用OpenGL扩展,在网上关于如何使用OpenGL ...

  5. OpenGL中的数据——Buffer

    OpenGL中主要包括了两种数据——Buffer和Texture. Buffer用于储存线性数无类型据块,可以看成普通的内存块,而Texture则用于储存多维数据,一般储存图像或者其他数据. Buff ...

  6. 关于opengl中的矩阵平移,矩阵旋转,推导过程理解 OpenGL计算机图形学的一些必要矩阵运算知识

    原文作者:aircraft 原文链接:https://www.cnblogs.com/DOMLX/p/12166896.html 为什么引入齐次坐标的变换矩阵可以表示平移呢? - Yu Mao的回答 ...

  7. CSharpGL(26)在opengl中实现控件布局/渲染文字

    CSharpGL(26)在opengl中实现控件布局/渲染文字 效果图 如图所示,可以将文字.坐标轴固定在窗口的一角. 下载 CSharpGL已在GitHub开源,欢迎对OpenGL有兴趣的同学加入( ...

  8. OpenGL中坐标系的理解(一)

    在OpenGL中,存在着至少存在着三种矩阵,对应着函数glMatrixMode()的三个参数:GL_MODELVIEW,GL_PROJECTION,GL_TEXTURE. 以下主要描述GL_MODEL ...

  9. CSharpGL(6)在OpenGL中绘制UI元素

    CSharpGL(6)在OpenGL中绘制UI元素 2016-08-13 由于CSharpGL一直在更新,现在这个教程已经不适用最新的代码了.CSharpGL源码中包含10多个独立的Demo,更适合入 ...

随机推荐

  1. UVa 1366 DP Martian Mining

    网上的题解几乎都是一样的: d(i, j, 0)表示前i行前j列,第(i, j)个格子向左运输能得到的最大值. d(i, j, 1)是第(i, j)个格子向上运输能得到的最大值. 但是有一个很关键的问 ...

  2. VMware Workstation 14 PRO 下安装Ubuntu 16.04 LTS教程

    一.准备好安装的VMware Workstation 14 PRO 1.VMware Workstation 14 PRO下载链接:http://rj.baidu.com/soft/detail/13 ...

  3. day05_04 数据类型-数值、布尔值、字符串简介

    数据运算 数据类型初识 数字 整数 int(integer) 整型 长整型 在python3里面已经不区分整型和长整型了,统一都叫整型 在32位机器上,整数的位数为32位,取值范围为-2**31-2* ...

  4. 缓存淘汰算法之LRU实现

    Java中最简单的LRU算法实现,就是利用 LinkedHashMap,覆写其中的removeEldestEntry(Map.Entry)方法即可 如果你去看LinkedHashMap的源码可知,LR ...

  5. iOS学习笔记49-Swift(九)访问控制

    一.Swift的访问控制 Swift中的访问控制模型基于模块和源文件这两个概念 模块指的是Framework或App bundle.在Swift中,可以用import关键字引入自己的工程. 源文件指的 ...

  6. CS231n笔记 Lecture 4 Introduction to Neural Networks

    这一讲主要介绍了神经网络,基本内容之前如果学习过Andrew的Machine learning应该也都有所了解了.不过这次听完这一讲后还是有了新的一些认识. 计算图 Computational gra ...

  7. 【Luogu】P2569股票交易(单调队列优化DP)

    题目链接 首先这题可以肯定的是朴素DP秒出.然后单调队列优化因为没接触过所以不会emmm 而且脑补没补出来 坐等四月省选倒数第一emmm 心态爆炸,偷懒放题解链接 #include<cstdio ...

  8. ACM程序设计选修课——Problem E:(ds:图)公路村村通(Prim)

    问题 E: (ds:图)公路村村通 时间限制: 1 Sec  内存限制: 128 MB 提交: 9  解决: 5 题目描述 现有村落间道路的统计数据表中,列出了有可能建设成标准公路的若干条道路的成本, ...

  9. javaweb-简单的验证码和算术验证码

    我们登陆网站时,每次都会填写一些验证码,这些验证码的作用:防止被恶意攻击,验证码上面的字母数字一般都是随机生成的,因此我们首先要写一个方法生成一个随机的字符串,这里就需要java里面的随机函数Rand ...

  10. BZOJ2527 [Poi2011]Meteors 【整体二分 + 树状数组】

    题目 Byteotian Interstellar Union有N个成员国.现在它发现了一颗新的星球,这颗星球的轨道被分为M份(第M份和第1份相邻),第i份上有第Ai个国家的太空站. 这个星球经常会下 ...