OpenGL帧缓存对象(FBO:Frame Buffer Object)(转载)
原文地址http://www.songho.ca/opengl/gl_fbo.html
但有改动。
OpenGL Frame BufferObject(FBO)
Overview:
在OpenGL渲染管线中,几何数据和纹理经过多次转化和多次测试,最后以二维像素的形式显示在屏幕上。OpenGL管线的最终渲染目的地被称作帧缓存(framebuffer)。帧缓冲是一些二维数组和OpenG所使用的存储区的集合:颜色缓存、深度缓存、模板缓存和累计缓存。默认情况下,OpenGL将帧缓冲区作为渲染最终目的地。此帧缓冲区完全由window系统生成和管理。这个默认的帧缓存被称作“window系统生成”(window-system-provided)的帧缓冲区。
在OpenGL扩展中,GL_ARB_framebuffer_object提供了一种创建额外的非显示的帧缓冲区对象的接口。此种帧缓冲区被称为"由程序创建的帧缓冲区(application-created framebuffer)"。这是为了区分window系统默认创建的帧缓冲区对象。通过使用帧缓存对象(FBO),OpenGL可以将显示输出重定向到程序帧缓存对象,而不是传统的“window系统生成”帧缓存。而且,它完全受OpenGL控制。
相似于window系统提供的帧缓存,一个FBO也包含一些存储颜色、深度和模板数据的区域。(注意:没有累积缓存)我们把FBO中这些逻辑缓存称之为“帧缓存关联图像”,它们是一些能够和一个帧缓存对象关联起来的二维像素数组。
有两种类型的“帧缓存关联图像”:纹理图像(texture images)和渲染缓存图像(renderbuffer images)。如果纹理对象的图像数据关联到帧缓存,OpenGL执行的是“渲染到纹理”(render to texture)操作。如果渲染缓存的图像数据关联到帧缓存,OpenGL执行的是离线渲染(offscreen rendering)。
这里要提到的是,渲染缓存对象是在GL_ARB_framebuffer_object 扩展中定义的一种新的存储类型。在渲染过程中它被用作存储单幅二维图像。下面这幅图显示了帧缓存对象、纹理对象和渲染缓存对象之间的联系。多多个纹理对象或者渲染缓存对象能够通过关联点关联到一个帧缓存对象上。
下面这幅图显示了帧缓冲区对象与纹理对象、渲染缓冲区对象的关系。多个纹理对象或多个渲染缓冲区对象,可通过连接点(attachment points)连接到帧缓冲区对象上。
在一个帧缓存对象中有多个颜色关联点(GL_COLOR_ATTACHMENT0_EXT,...,GL_COLOR_ATTACHMENTn_EXT),一个深度关联点(GL_DEPTH_ATTACHMENT_EXT),和一个模板关联点(GL_STENCIL_ATTACHMENT_EXT)。每个FBO中至少有一个颜色关联点,其数目与实体显卡相关。可以通过GL_MAX_COLOR_ATTACHMENTS_EXT来查询颜色关联点的最大数目。FBO有多个颜色关联点的原因是可以将颜色对象同时渲染到多个目标上。这种“多渲染目标”(multiple rendertargets,MRT)可以通过GL_ARB_draw_buffers扩展实现。需要注意的是:FBO本身并没有任何图像存储区,只有多个关联点。
帧缓冲区对象提供了高效的切换机制:从帧缓冲区对象中断开先前的帧缓冲区关联图像,连接一个新的帧缓冲区关联图像到帧缓冲区对象上。切换帧缓冲区关联图像比切换帧缓冲区对象快多了。帧缓冲区对象提供了glFramebufferTexture2D()来切换2D纹理对象,glFramebufferRenderbuffer()来切换渲染缓冲区对象。
创建FBO
创建FBO和产生VBO类似。
glGenFramebuffers()
void glGenFramebuffers(GLsizei n, GLuint* ids)
void glDeleteFramebuffers(GLsizei n, const GLuint* ids)
glGenFramebuffers()需要两个参数:第一个是要创建的帧缓存的数目,第二个是指向存储一个或者多个ID的变量或数组的指针。它返回未使用的FBO的ID。ID为0表示默认帧缓存,即window系统提供的帧缓存。
当FBO不再被使用时,FBO可以通过调用glDeleteFramebuffers()来删除。
glBindFramebuffer()
一旦一个FBO被创建,在使用它之前必须绑定。
void glBindFramebuffer(GLenum target, GLuint id)
第一个参数target应该是GL_FRAMEBUFFER,第二个参数是FBO的ID号。一旦FBO被绑定,之后的所有的OpenGL操作都会对当前所绑定的FBO造成影响。ID号为0表示缺省帧缓存,即默认的window提供的帧缓存。因此,在glBindFramebuffer()中将ID号设置为0可以解绑定当前FBO。
渲染缓存对象(Renderbuffer Object)
另外,渲染缓存是为离线渲染而新引进的。它允许将一个场景直接渲染到一个渲染缓存对象中,而不是渲染到纹理对象中。渲染缓存对象是用于存储单幅图像的数据存储区域。该图像按照一种可渲染的内部格式存储。它用于存储没有相关纹理格式的OpenGL逻辑缓存,比如模板缓存或者深度缓存。
glGenRenderbuffers()
void glGenRenderbuffers(GLsizei n, GLuint* ids)
void glDeleteRenderbuffers(GLsizei n, const Gluint* ids)
一旦一个渲染缓存被创建,它返回一个非零的正整数。ID为0是OpenGL保留值。
glBindRenderbuffer()
void glBindRenderbuffer(GLenum target, GLuint id)
和OpenGL中其他对象一样,在引用渲染缓存之前必须绑定当前渲染缓存对象。他target参数应该是GL_RENDERBUFFER。
glRenderbufferStorage()
void glRenderbufferStorage(GLenum target, GLenum internalFormat,
GLsizei width, GLsizei height)
当一个渲染缓存被创建,它没有任何数据存储区域,所以我们还要为他分配空间。这可以通过用glRenderbufferStorage()实现。第一个参数必须是GL_RENDERBUFFER。第二个参数可以是用于颜色的(GL_RGB,GL_RGBA,etc.),用于深度的(GL_DEPTH_COMPONENT),或者是用于模板的格式(GL_STENCIL_INDEX)。Width和height是渲染缓存图像的像素维度。
width和height必须比GL_MAX_RENDERBUFFER_SIZE_EXT小,否则将会产生GL_UNVALID_VALUE错误。
glGetRenderbufferParameteriv()
void glGetRenderbufferParameteriv(GLenum target, GLenum param,GLint* value);
我们也可以得到当前绑定的渲染缓存对象的一些参数。Target应该是GL_RENDERBUFFER,第二个参数是所要得到的参数名字。最后一个是指向存储返回值的整型量的指针。渲染缓存的变量名有如下:
GL_RENDERBUFFER_WIDTH
GL_RENDERBUFFER_HEIGHT
GL_RENDERBUFFER_INTERNAL_FORMAT
GL_RENDERBUFFER_RED_SIZE
GL_RENDERBUFFER_GREEN_SIZE
GL_RENDERBUFFER_BLUE_SIZE
GL_RENDERBUFFER_ALPHA_SIZE
GL_RENDERBUFFER_DEPTH_SIZE
GL_RENDERBUFFER_STENCIL_SIZE
将图像和FBO关联
FBO本身没有图像存储区。我们必须帧缓存关联图像(纹理或渲染对象)关联到FBO。这种机制允许FBO快速地切换(分离和关联)帧缓存关联图像。切换帧缓存关联图像比在FBO之间切换要快得多。而且,它节省了不必要的数据拷贝和内存消耗。比如,一个纹理可以被关联到多个FBO上,图像存储区可以被多个FBO共享。
把2D纹理图像关联到FBO
glFramebufferTexture2D(GLenum target,
GLenumattachmentPoint,
GLenum textureTarget,
GLuint textureId,
GLint level)
glFramebufferTexture2D()把一幅纹理图像关联到一个FBO。第一个参数一定是GL_FRAMEBUFFER_,第二个参数是关联纹理图像的关联点。一个帧缓冲区对象可以有多个颜色关联点(GL_COLOR_ATTACHMENT0, ..., GL_COLOR_ATTACHMENTn),L_DEPTH_ATTACHMENT, 和GL_STENCIL_ATTACHMENT。第三个参数textureTarget在多数情况下是GL_TEXTURE_2D。第四个参数是纹理对象的ID号。最后一个参数是要被关联的纹理的mipmap等级
如果参数textureId被设置为0,那么纹理图像将会被从FBO分离。如果纹理对象在依然关联在FBO上时被删除,那么纹理对象将会自动从当前帮的FBO上分离。然而,如果它被关联到多个FBO上然后被删除,那么它将只被从绑定的FBO上分离,而不会被从其他非绑定的FBO上分离。
把渲染缓存对象关联到FBO
void glFramebufferRenderbuffer(GLenum target,
GLenum attachmentPoint,
GLenum renderbufferTarget,
GLuint renderbufferId)
通过调用glFramebufferRenderbuffer()可以关联渲染缓存图像。前两个参数和glFramebufferTexture2D()一样。第三个参数只能是GL_RENDERBUFFER,最后一个参数是渲染缓存对象的ID号。
如果参数renderbufferId被设置为0,渲染缓存图像将会从FBO的关联点分离。如果渲染缓存图像在依然关联在FBO上时被删除,那么纹理对象将会自动从当前绑定的FBO上分离,而不会从其他非绑定的FBO上分离。
检查FBO状态
一旦关联图像(纹理和渲染缓存)被关联到FBO上,在执行FBO的操作之前,你必须检查FBO的状态:完整或不完整。这可以通过调用glCheckFramebufferStatusEXT()来检查其状态。如果帧缓冲区状态是不完整的,那么任何绘制命令(glBegin(),glCopyTexImage2D()等等)都会失败。
GLenum glCheckFramebufferStatus(GLenum target)
glCheckFramebufferStatus()检查当前帧缓存的关联图像和帧缓存参数。这个函数不能在glBegin()/glEnd()之间调用。Target参数必须为GL_FRAMEBUFFER。它返回一个非零值。如果所有要求和准则都满足,它返回GL_FRAMEBUFFER_COMPLETE。否则,返回一个相关错误代码告诉我们哪条准则没有满足。
FBO完整性准则有:
(1)帧缓存关联图像的宽度和高度必须非零。
(2)如果一幅图像被关联到一个颜色关联点,那么这幅图像必须有颜色可渲染的内部格式(GL_RGBA, GL_DEPTH_COMPONENT, GL_LUMINANCE, etc)。
(3)如果一幅被图像关联到GL_DEPTH_ATTACHMENT,那么这幅图像必须有深度可渲染的内部格式(GL_DEPTH_COMPONENT,GL_DEPTH_COMPONENT24, etc)。
(4)如果一幅被图像关联到GL_STENCIL_ATTACHMENT,那么这幅图像必须有模板可渲染的内部格式(GL_STENCIL_INDEX,GL_STENCIL_INDEX8, etc)。
(5)FBO至少有一幅图像关联。
(6)被关联到FBO的缩影图像必须有相同的宽度和高度。
(7)被关联到颜色关联点上的所有图像必须有相同的内部格式。
注意:即使以上所有条件都满足,你的OpenGL驱动也可能不支持某些格式和参数的组合。如果一种特别的实现不被OpenGL驱动支持,那么glCheckFramebufferStatus()返回GL_FRAMEBUFFER_UNSUPPORTED。
OpenGL帧缓存对象(FBO:Frame Buffer Object)(转载)的更多相关文章
- 【OpenGL】OpenGL帧缓存对象(FBO:Frame Buffer Object) 【转】
http://blog.csdn.net/xiajun07061225/article/details/7283929/ OpenGL Frame BufferObject(FBO) Overview ...
- OpenGL帧缓存对象(FBO:Frame Buffer Object)
http://blog.csdn.net/dreamcs/article/details/7691690 转http://blog.csdn.net/xiajun07061225/article/de ...
- OpenGL帧缓存对象(FBO:Frame Buffer Object) 【转】
http://blog.csdn.net/dreamcs/article/details/7691690 原文地址http://www.songho.ca/opengl/gl_fbo.html 但有改 ...
- OpenGL 顶点缓存对象
顶点缓存对象(Vertex Buffer Object,简称 VBO),允许开发者根据情况把顶点数据放到显存中. 如果不用 VBO,用 glVertexPointer / glNormalPointe ...
- WebGL简易教程(十三):帧缓存对象(离屏渲染)
目录 1. 概述 2. 示例 2.1. 着色器部分 2.2. 初始化/准备工作 2.2.1. 着色器切换 2.2.2. 帧缓冲区 2.3. 绘制函数 2.3.1. 初始化顶点数组 2.3.2. 传递非 ...
- 现代3D图形编程学习--opengl使用不同的缓存对象(译者添加)
现代3D图形编程学习系列翻译地址 http://www.cnblogs.com/grass-and-moon/category/920962.html opengl使用不同的缓存对象 在设置颜色一章中 ...
- OpenGL顶点缓冲区对象(VBO)
转载 http://blog.csdn.net/dreamcs/article/details/7702701 创建VBO GL_ARB_vertex_buffer_object 扩展可 ...
- 顶点缓存对象(VBO)
创建VBO 绘制VBO 更新VBO 实例 GL_ARB_vertex_buffer_object扩展致力于提供顶点数组与显示列表的优势来提升OpenGL效率,同时避免它们实现上的不足.顶点缓存对象(V ...
- 顶点缓存对象(VBO)【转】
http://www.cnblogs.com/hefee/p/3824300.html 顶点缓存对象(VBO) 创建VBO 绘制VBO 更新VBO 实例 GL_ARB_vertex_buffer_ob ...
随机推荐
- jQuery 人脸识别插件,支持图片和视频
jQuery Face Detection 是一款人脸检测插件,能够检测到图片,视频和画布中的人脸坐标.它跟踪人脸并输出人脸模型的坐标位置为一个数组.我们相信,面部识别技术能够给我们的 Web 应用带 ...
- RabbitMQ常用命令行
打印了一些rabbitmq服务状态信息,包括内存,硬盘,和使用erlong的版本信息rabbitmqctl -q status 各个参数说明:http://www.rabbitmq.com/man/r ...
- WIN10下java8的开发环境配置与第一个java程序
一.开发环境配置 1.在官网上下载jdk-8u111-windows-x64.exe 2.运行安装包,可以自定义安装路径 3.进入环境变量设置: 计算机右键-->属性-->高级系统设置-- ...
- select中文字垂直居中解决办法
我们知道select标签在各个浏览器中的属性和各浏览器的支持各有些不同,从而造成select选择框在各浏览器的显示有不同,下面我们通过对主要 外形CSS属性的支持,打造全兼容select. 我对sel ...
- CentOS最常用命令及快捷键整理
CentOS最常用命令及快捷键整理 整理了Linux常用命令及快捷键. 常用命令: 文件和目录: # cd /home 进入 '/home' 目录 # ...
- word20161217
p-node / p 节点 package / 程序包 packet / 数据包 packet assembler/disassembler, PAD / 分组拆装器 packet header / ...
- 一些有趣的Javascript技巧
整理一些刷题时学会的小技巧…… 目录: 即大于0又小于0的变量 String.split() 与 正则表达式 缓存的几种方法 初始化一个数组 即大于0又小于0的变量 问题: 设计一个变量val,使得以 ...
- oracle 学习笔记(一)
1. 数据库原理 1.1. 数据库简介 1.1.1. 文件存储 对数据的存储需求一直存在.保存数据的方式,经历了手工管理.文件管理等阶段,直至数据库管理阶段. 文件存储方式保存数据的弊端: 缺乏对数据 ...
- httpie 取代 curl
接口测试有人喜欢postman(for windows or mac) 如果长期用linux工作,可能更喜欢命令的方式,比如curl最近深入了解了下django-rest-framwork,他们推荐了 ...
- python3 黑板客爬虫闯关游戏(四)
这关较第三关难度增加许多,主要多了并发编程 密码一共有100位,分布在13页,每页打开的时间在15秒左右,所以理所当然的想到要用并发,但是后来发现同IP访问间隔时间不能小于8秒,不然会返回404,所以 ...