关于FBO(FrameBuffer Object)的一些理解

  先来整理下本人对FBO的理解。FBO是FrameBuffer Object的首字母简称。翻译过来就是帧缓冲区的意思。根据我的理解,OpenGL作为图形API,可以看做是画笔,帧缓冲区可以比作画布。我们使用OpenGL在帧缓冲区上“作画”(渲染)。

  首先,我们需要建立OpenGL Context,即获得一套“作画”的工具。以Win32 OpenGL为例,我们需要如下流程去建立一个标准的OpenGL Context:

  1、创建一个窗口类(WNDCLASS/WNDCLASSEX)。

  2、注册窗口类(RegisterClass)。

  3、调用CreateWindow/CreateWindowEx创建新窗口,返回窗口句柄 HWND。

  4、创建设备描述符PIXELFORMATDESCRIPTOR pfd。该结构体中包含即将要创建的OpenGL context的各种信息,包括是否支持双缓冲区、像素位数、Z-buffer位数等各种缓冲区位宽。

  5、获取新生成窗口的Device Context句柄HDC hDC,通过调用GetDC(HWND)获得。

  6、调用ChoosePixelFormat(hDC,&pfd)选择合适的像素格式,如果成功,返回像素格式的索引GLuint nPixelFormat。

  7、利用上一步的结果调用SetPixelFormat(hDC,nPixelFormat,&pfd),设置像素格式。

  8、调用wglCreateContext(hDC)获得 OpenGL Context 句柄 HGLRC hRC;

  9、设置上一步获得的OpenGL Context为当前的Context,通过调用wglMakeCurrent(hDC,hRC);

  不总结不知道,一总结发现一步一步下来,步骤还是挺多的。要注意的一点是,上述9步中大部分函数调用是为了生成/申请相关窗口或者句柄,为了提高程序的鲁棒性,需要及时检查返回值的有效性。

  注意:在上述第4步中,我们在设备描述符中通过参数设置了各个缓冲区的位宽。位宽为0当然就是没有这个缓冲区的意思啦。



  在建立了OpenGL渲染环境之后,相当于获得了一只画笔,而此时我们有一块默认的画布,即我们的屏幕,default framebuffer。我们渲染的目的地就是我们的屏幕,我们画出来的东西,会显示在屏幕上。这个default framebuffer 是与一系列缓冲区相关联的(具体有哪些缓冲区,多少位的缓冲区,是建立OpenGL Context的时候用户自定义的。一般来讲,必要的是颜色缓冲区,深度缓冲区。模板缓冲区、累加缓冲区这俩哥们儿可选。)。我们需要颜色缓冲区来存储我们渲染物体的颜色,需要深度缓冲区来进行深度测试,等等。具体的渲染过程是如何进行的,就是OpenGL Render Pipeline的东西了。在此不细表。

  之后随着新需求的出现和OpenGL的发展,off-screen render技术出现了,即离屏渲染(离线渲染)。我去,off-screen render,离线渲染,乍一听好牛逼的样子,其实很简单。我们把物体直接渲染到屏幕上,就是“在线渲染”。同理,我们把物体渲染到别的地方,不渲染到屏幕上,那不就是“离线渲染”了么。 那我们不渲染到屏幕,渲染到哪儿去呢?

  OpenGL 从某版本之后,引入了Framebuffer Object。 XXXX Object,我们见过很多了,像Vertex Buffer Object, Vertex Array Object。这次的Framebuffer Object是什么东西呢?

  根据本人的理解,FBO(Framebuffer Object)就是OpenGL模拟default framebuffer的功能和结构创建的一种可以作为“画布”使用的Object。也就是说,你生成一个FBO,根据你的渲染需要,捯饬捯饬,然后把你想渲染的东西渲染到你刚生成的这个FBO里面,而不是直接渲染到屏幕上,就是这个样子。Default framebuffer 有很多支撑渲染行为的缓冲区,FBO也可以有,但是要你手动去生成、设置和绑定。

  值得注意的是FBO的角色更像是一个管理者,管理着所有支撑渲染的RenderBuffers和Textures,OpenGL没有为FBO分配内存空间去存储渲染所需的几何、像素数据等。但是,FBO有很多Attachment Point,顾名思义,我们把真正起作用的、具有实际内存空间占用的Renderbuffer和Texutures依附在FBO上,FBO起到管理的作用。这点跟VAO有点类似,是一批量“状态”的集合。VAO的事情我觉得有必要再整理下思路,但是此处暂且按下不表。

  最近爱上了Viso作图,如下:

   

  

  貌似不能插pdf,只能插图片。不清晰,此处有pdf: http://files.cnblogs.com/chandler00x/FBO.pdf

  下面简单说下两种情况的用法:

  下面这段代码说明如何将Renderbuffer与FBO绑定。

 1 GLuint hFbo,hTex,hDepth,hColor;
 2
 3     glGenFramebuffers(1,&hFbo);
 4     glBindFramebuffer(GL_FRAMEBUFFER,hFbo);
 5
 6     glGenRenderbuffers(1,&hDepth);
 7     glBindRenderbuffer(GL_RENDERBUFFER,hDepth);
 8
 9     //为当前的Renderbuffer分配空间,格式为GL_DEPTH_COMPONENT,顾名思义
10     //这个Renderbuffer肯定是与depth test相关的。
11     glRenderbufferStorage(GL_RENDERBUFFER,GL_DEPTH_COMPONENT,m_width,m_height);
12
13     //将当前的Renderbuffer与Framebuffer Object的GL_DEPTH_ATTACHMENT的连接点
14     //连接起来。再顾名思义,肯定是与Depth test相关的。
15     glFramebufferRenderbuffer(GL_FRAMEBUFFER,GL_DEPTH_ATTACHMENT,GL_RENDERBUFFER,hDepth);
16
17     glGenRenderbuffers(1,&hColor);
18     glBindRenderbuffer(GL_RENDERBUFFER,hColor);
19
20     //为当前的Renderbuffer分配空间,格式为GL_RGBA
21     glRenderbufferStorage(GL_RENDERBUFFER,GL_RGBA,m_width,m_height);
22
23     //与FBO的GL_COLOR_ATTACHMENT0连接起来。
24     glFramebufferRenderbuffer(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,GL_RENDERBUFFER,hColor);
25
26     //检查Framebuffer的完整性,十分必要!!!!!
27     //十分必要!!!!!
28     GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
29     if( status != GL_FRAMEBUFFER_COMPLETE)
30         printf("Framebuffer incomplete!\n");
31     else
32         printf("Framebuffer complete!\n");

  下面这段代码说明如何将Texture与FBO绑定。

 1 GLuint hFbo,hTex,hDepth,hColor;
 2
 3     glGenFramebuffers(1,&hFbo);
 4     glBindFramebuffer(GL_FRAMEBUFFER,hFbo);
 5
 6     glGenRenderbuffers(1,&hDepth);
 7     glBindRenderbuffer(GL_RENDERBUFFER,hDepth);
 8
 9     //为当前的Renderbuffer分配空间,格式为GL_DEPTH_COMPONENT,顾名思义
10     //这个Renderbuffer肯定是与depth test相关的。
11     glRenderbufferStorage(GL_RENDERBUFFER,GL_DEPTH_COMPONENT,m_width,m_height);
12
13     //将当前的Renderbuffer与Framebuffer Object的GL_DEPTH_ATTACHMENT的连接点
14     //连接起来。再顾名思义,肯定是与Depth test相关的。
15     glFramebufferRenderbuffer(GL_FRAMEBUFFER,GL_DEPTH_ATTACHMENT,GL_RENDERBUFFER,hDepth);
16
17     glActiveTexture(GL_TEXTURE0);
18     glGenTextures(1,&hTex);
19     glBindTexture(GL_TEXTURE_2D,hTex);
20
21     //为纹理分配空间。
22     glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,m_width,m_height,0,GL_RGBA,GL_UNSIGNED_BYTE,NULL);
23
24     //与FBO的GL_COLOR_ATTACHMENT0绑定,Color。。color。。
25     glFramebufferTexture2D(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,GL_TEXTURE_2D,hTex,0);
26
27
28     //检查Framebuffer的完整性,十分必要!!!!!
29     //十分必要!!!!!
30     GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
31     if( status != GL_FRAMEBUFFER_COMPLETE)
32         printf("Framebuffer incomplete!\n");
33     else
34         printf("Framebuffer complete!\n");

关于FBO(FrameBuffer Object)的一些理解

时间: 2024-10-14 14:10:00

关于FBO(FrameBuffer Object)的一些理解的相关文章

关于OpenGL Framebuffer Object、glReadPixels与离屏渲染

最近写论文需要用到离屏渲染(主要是因为模型太大普通窗口绘制根本做不了),于是翻阅了红宝书查了下相关api和用法.中文版的红宝书可读性有点差,很多地方翻译地晦涩,但好歹读起来比较快,主要相关章节为第8章和第10章(可以连带把第9章读完以后写GLSL会顺利成章).貌似superbible可读性更强,但红宝书讲得也差不多了就没再继续看. 由于红宝书过于学术,想动手还是最好查查网上的资料,于是把一些还可以的资料列一下. 关于FBO: OpenGL中的FBO对象(含源码) OpenGL的帧缓冲对象和浮点纹

File类--System.out.print(Object obj)的理解

一.File 类(java.io) 概述:Java中使用File类来表示文件或者文件夹对象!     抽象路径名:描述文件或文件夹时,使用的路径符号,就是一个对象的字符串表示形式,如"c:\\";     绝对路径:绝对位置开始的路径;     相对路径:相对位置开始的路径; 构造方法:     File(String pathname)     File(String parent, String child)     File(File parent, String child)

ArrayList集合--关于System.out.print(Object obj);的理解

1.ArrayList集合中常用的方法 ArrayList<Student> stuArrayList = new ArrayList<>(); //定义一个集合对象 stuArrayList.add():    //添加元素 stuArrayList.add(index, e):    //在某个位置添加元素,但不覆盖原元素 stuArrayList.get(index):    //获取某位置的元素 stuArrayList.size():    //获取集合长度 stuArr

Java DTO(data transfer object)的理解

首先明白springboot每层 model层 model层即数据库实体层,也被称为entity层,pojo层. 一般数据库一张表对应一个实体类,类属性同表字段一一对应. Model层是数据层: TableName是对数据表实体的映射: Criteria传输前台数据 DTO 传输类间数据 dao层 dao层即数据持久层,也被称为mapper层. dao层的作用为访问数据库,向数据库发送sql语句,完成数据的增删改查任务. service层 service层即业务逻辑层. service层的作用为

var, function, object, parameter怎么理解?

var是用来存放data value的(container).data type包括number, string, array, math, date等(其中string, array, math, date都是object). function是a block of code,优势:通过不同的arguments(和parameters一个意思)来实现code reuse. object是用来存放多个values,并以name: value/property: property value出现:

selenium Object Page 设计模式理解及实现!

Page Object模式是Selenium中的一种测试设计模式,主要是将每一个页面设计为一个Class,其中包含页面中需要测试的元素(按钮,输入框,标题 等),这样在Selenium测试页面中可以通过调用页面类来获取页面元素,这样巧妙的避免了当页面元素id或者位置变化时,需要改测试页面代码的情况. 当页面元素id变化时,只需要更改测试页Class中页面的属性即可. 获取页面中元素的属性可以通过id,class或者XPath获取,在id唯一的情况下,可以使用id获取页面元素,否则可以使用XPat

Python的object和type理解

1.节选自Python Documentation 3.5.2的部分解释 Objects are Python's abstraction for data. All data in a Python program is represented by objects or by relations between objects. (In a sense, and in conformance to Von Neumann's model of a "stored program comput

Object对象深入理解及通用接口

Object对象 java.lang.Object java.lang包在使用的时候无需显示导入,编译时由编译器自动导入.Object类是类层次结构的根,Java中所有的类都继承自这个类. equals() public boolean equals(Object obj) { return (this == obj); } 我们可以看出,Object类的默认实现是比较对象的引用是否指向同一个对象. 对于对象引用,==比较对象引用是否指向同一个对象.对于基本类型,比较实际内容. public c

Selective Search for Object Recognition(理解)

0 - 背景 在目标检测任务中,我们希望输入一副图像,输出目标所在的位置以及目标的类别.最常用的算法是滑动窗口方法,但滑动窗口其实相当于穷举图像中的所有子图像,其效率低且精度也受限.该论文提出一种新的生成目标检测框的方法selective search. 1 - 算法流程 step 0:生成区域集R step 1:计算区域集R中每个相邻区域的相似度S step 2:找出最相似的两个区域,将其合并成新区域添加到R中 step 3:从S中移除所有与step 2中相关的区域 step 4:计算新集与所