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. selenium2.53用45以下的火狐别太高

    selenium2.53用45以下的火狐别太高在高的火狐需要selenium3

  2. 零基础学习 Python 之前期准备

    写在之前 从今天开始,我将开始新的篇章 -- 零基础学习 Python,在这里我将从最基本的 Python 写起,然后再慢慢涉及到高阶以及具体应用方面.我是完全自学的 Python,所以很是明白自学对 ...

  3. pat 1037

    如果你是哈利·波特迷,你会知道魔法世界有它自己的货币系统 —— 就如海格告诉哈利的:“十七个银西可(Sickle)兑一个加隆(Galleon),二十九个纳特(Knut)兑一个西可,很容易.”现在,给定 ...

  4. 九度oj 题目1085:求root(N, k) 清华2010年机试题目

    题目描述: N<k时,root(N,k) = N,否则,root(N,k) = root(N',k).N'为N的k进制表示的各位数字之和.输入x,y,k,输出root(x^y,k)的值 (这里^ ...

  5. 找不到css 路径问题

    今天进入一个网页的时候,一直报找不到css的错误,但是我的路径原来是正确的 后来找网络控制台,发现路径上多了一个listCommodity,是我controller里面的跳到这个页面的路径 然后我在& ...

  6. BZOJ 4816 [Sdoi2017]数字表格 ——莫比乌斯反演

    大力反演出奇迹. 然后xjb维护. 毕竟T1 #include <map> #include <ctime> #include <cmath> #include & ...

  7. (C++一本通)最少转弯问题 (经典搜索)

    题目描述 给出一张地图,这张地图被分为n×m(n,m<=100)个方块,任何一个方块不是平地就是高山.平地可以通过,高山则不能.现在你处在地图的(x1,y1)这块平地,问:你至少需要拐几个弯才能 ...

  8. windows.open 以post的方式传递参数

    今天看到有篇文章寫到 windows.open 可以post方式傳遞參數,就趕緊照作看看,結果是可行的,感謝撰寫這篇文章的作者~ /** * window.open with post method  ...

  9. .net IntPtr ==interoperable pointer

    调用system.runtime.interopservice,可以用dllimport; API函数主要在“kernel32.dll”.“user32.dll”.“GDI32.dll”, kerne ...

  10. vue.js源码学习分享(六)

    /* */ /* globals MutationObserver *///全局变化观察者 // can we use __proto__?//我们能用__proto__吗? var hasProto ...