OpenGL Framebuffer Object (FBO)
来源:互联网 发布:火狐javascript void 0 编辑:程序博客网 时间:2024/05/22 14:11
在OpenGL中, OpenGL Context有一个默认的FBO用来绘制图像, 但是我们也可以创建新的用户定义的Framebuffers, 这样我们可以绘制到自定义的framebuffer, 而不会影响到窗口系统。
关键词定义
- Image: 本文中, Image是包含像素的二维数组,这些像素具有特定的存储格式。
- Layered Image: 具有某一特定尺寸和格式的一套images, 对应于texture的某一个mipmap level. (注意 layered image不是一个人在战斗,而是一整套的images!)
- Texture: 表示一系列的images的集合。所有的image具有相同的格式, 但是尺寸不一样(不同的mipmap level). Texture 可以绑定(bind)到 shaders.
- Renderbuffer: 包含一个image, 不可以绑定(bind)到shaders, 只能附着(attach)到FBO.
- Framebuffer-attachable image: 可附着到FBO的image
- Framebuffer-attachable layered image: 可附着到FBO的layered image.
- Attachment point: FBO中一个署名的附着点,可用来附着(attach) framebuffer-attachable image 和 framebuffer-attachable layered image. 对于附着(attach)的image,要求具有特定的格式。
- Attach: 附着是表示将两个物体连系起来, 和绑定(bind) 是不一样的。 一个物体被绑定(bind)到context, 但是物体与物体则是相互附着(attach).
绑定FBO
和其它 OpenGL object一样,FBO有以下的相关函数:
void glGenFramebuffers(GLsizei n, GLuint* framebuffers);void glDeleteFramebuffers(GLsizei n, GLuint* framebuffers);void glBindFramebuffer(GLenum target, GLuint framebuffer);
其中的
target
参数可以是:- GL_FRAMEBUFFER
- GL_READ_FRAMEBUFFER
- GL_DRAW_FRAMEBUFFER
GL_READ_FRAMEBUFFER:当
target
设置为GL_READ_FRAMEBUFFER时,framebuffer
参数所指代的FBO变成读操作的目标,如glReadPixels
,glCopyTexImage2D
,glCopyTexSubImage2D
.
GL_DRAW_FRAMEBUFFER: 当target 设置为 GL_DRAW_FRAMEBUFFER是,framebuffer
指代的FBO变成绘制操作的目标, 如glDrawArrays
,glDrawElements
等等。
GL_FRAMEBUFFER: 此时读操作和绘制操作都在此FBO上进行。参数
framebuffer
framebuffer
的值是一个非负整数,0预留给由窗口系统提供的默认FBO. 当将参数设置为0时,目标还原到初始状态,即窗口系统提供的默认FBO.
一个FBO绑定到OpenGL context会一直有效,直到另一个FBO被绑定或者glDeleteFramebuffers
被调用。
FBO attachment point
FBO有下列attachment points:
- GL_COLOR_ATTACHMENT
i
: attachment points的数量跟实现相关, 最少需要8个, 所以i
至少可以取0-7范围以内的值, 附着的image必须具有可绘制的格式(color-renderable formats). 所有压缩格式都是不可绘制的,因此不可以附着到FBO. - GL_DEPTH_ATTACHMENT:只能附着具有depth格式的image, 附着的image被称为FBO的depth buffer.
- GL_STENCIL_ATTACHMENT:只能附着具有stencil格式的image, 附着的image被称为FBO的stencil buffer.
- GL_DEPTH_STENCIL_ATTACHMENT:附着的image既是FBO的depth buffer 又是 stencil buffer. 被附着的image格式应该是a packed depth-stencil internal format.
texture 类型简要回顾
1D texture
1D texture可以看成包含的image的高度为12D texture
2D texture是最好理解的了,包含2D image3D texture
3D texture的每一个mipmap level就包含一套2D image. 如果用xy来表示image 平面,那么z 轴就是表示image的数量的维度,每一个整数就表示一个layered image. 因此,3D texture 中的每一张image都可以通过一个mipmap level 和一个 layer定位。cubemap
包含一个立方体的六个平面,因此cubemap包含6张image, 因此每一张image可以通过mipmap level和平面定位。1D array texture
每一个mipmap level包含一套2D image(高度为1),数量等于数组的维度, 每一张image由一个mipmap level 和数组索性(array index) 定位。2D array texture
和3D texture类似, 只要将z的值换成数组索引就可以。 每一张image 可以通过一个 mipmap level 和一个数组索引定位。 不同的是,数组大小不会随着mipmap层次的下降而改变。Buffer texture
类似于1D texture, 只是它只包含一张image, 可以通过mipmap level 0 表示。
Attaching texture image
当我们需要将texture内部的某一张image 附着到FBO时,我们可以使用以下方法:
void glFramebufferTexture1D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);void glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); void glFramebufferTextureLayer(GLenum target, GLeunm attachment, GLuint texture, GLint level, GLint layer);
target
参数和glBindFramebuffer
一样,但是这里GL_FRAMEBUFFER和GL_DRAW_FRAMEBUFFER等同。attachment
参数则是上面提到的attachment point.textarget
当attach 非cubemap时,textarget
可以是 GL_TEXTURE_1D, GL_TEXTURE_2D_MULTISAMPLE 等等, 当attach的是cubemap, 必须使用glFramebufferTexture2D
函数,textarget
必须是GL_TEXTURE_CUBE_MAP_POSITIVE_X/Y/Z, GL_TEXTURE_CUBE_MAP_NEGATIVE_X/Y/Z.texture
参数是需要附着的texture
名称, 当texture
为 0时, 表示解除该attachment point的附着物。
注意,由于texture
具有多个image, 因此必须明确指定需要attach的image.
Attaching renderbuffers
在创建好renderbuffer之后,你就可以将它attach到FBO:
void glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
renderbuffertarget
必须是 GL_RENDERBUFFERrenderbuffer
: renderbuffer object name
Attaching layered image
上面讲了layered image对应于texture的某个mipmap level上的所有images, 当然像1D texture, 2D texture, 它们一个mipmap level 上只有一张image, 但是像 3D texture, 2D array texture, cubemap等等,一个mipmap level上面可是有很多的images的。 我们可以将整个mipmap level附着到某一个attachment point:
void glFramebufferTexture(GLenum target, GLenum attachment, GLuint texture, GLint level);
Framebuffer completeness
每一个attachment point都要求附着到它上面的image具有特定的格式, 但是当你将一个不符合要求的image 附着上来,并不会马上产生错误信息,而是要等到你使用FBO的时候错误才会显现出来。 当然除了image格式不符合要求, image的尺寸也有可能不符合条件, 因此, 我们需要一些手段来帮助我们检查FBO的完整度。
一个有效的FBO被称为”完整的Framebuffer” (“framebuffer complete”),检查FBO完整度,可以调用:
GLenum glCheckFramebufferStatus(GLenum target);
调用它并不是必需的,但是使用一个非完整的FBO会产生错误,因此在使用前检查FBO的完整度是一个好的习惯。当FBO完整时返回值是 GL_FRAMEBUFFER_COMPLETE, 否则就有问题。
Framebuffer blits
Framebuffer blits 可以高效的将一个framebuffer(GL_READ_FRAMEBUFFER)的某块矩形区域拷贝到另外一个framebuffer(GL_DRAW_FRAMEBUFFER).
void glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
srcX0, srcY0, srcX1, srcY1
: 指定GL_READ_FRAMEBUFFER的源矩形区域。dstX0, dstY0, dstX1, dstY1
: 指定GL_DRAW_FRAMEBUFFER的目标矩形区域。mask
: 指定拷贝操作的按位‘或’掩码, GL_COLOR_BUFFER_BIT, GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT, GL_DEPTH_STENCIL_ATTACHMENT.filter
: 当拷贝需要缩放时, 指定插值算法,GL_NEAREST 或 GL_LINEAR.
我们注意到mask掩码有一个GL_COLOR_BUFFER_BIT,但是我们FBO的color buffer attachment point却是多个, 到底拷贝哪个buffer,抑或是拷贝所有的color buffers? 答案是只拷贝一个buffer, 默认值在single-buffer configuration时 是 GL_FRONT, 在double-buffer configuration时 是 GL_BACK.
那么假如我们的GL_READ_FRAMEBUFFER是一个自定义FBO,显然我们必须要指定目标color buffer,这时我们使用函数:
void glReadBuffer(GLenum mode);
mode
: GL_FRONT_LEFT, GL_FRONT_RIGHT, GL_BACK_LEFT, GL_BACK_RIGHT, GL_FRONT, GL_BACK, GL_LEFT, GL_RIGHT, GL_COLOR_ATTACHMENTi
.
glReadBuffer
隐式的指定GL_READ_FRAMEBUFFER的color buffer, OpenGL还提供另外一个函数来显示的指定FBO:
void glNamedFramebufferReadBuffer( GLuint framebuffer, GLenum mode);
除了影响glBlitFramebuffer
, glReadBuffer
还影响所有的可从color buffer 读数据的操作, 比如:glReadPixels
, glCopyTexImage1D
, glCopyTexImage2D
, glCopyTexSubImage1D
, glCopyTexSubImage2D
, glCopyTextSubImage3D
…
- OpenGL Framebuffer Object (FBO)
- Framebuffer Object, FBO
- OpenGL FrameBuffer Object OpenGL中的FBO对象 OpenGL函数思考-glGenTextures
- OpenGLES demo - 13. Framebuffer Object FBO
- OpenGL Frame Buffer Object (FBO)
- OpenGL FrameBuffer Object 101
- OpenGL FrameBuffer Object
- OpenGL FrameBuffer Object
- OpenGL.FrameBuffer Object
- OpenGL.FrameBuffer Object
- OpenGL Frame Buffer Object (FBO)【转】
- [转]OpenGL Frame Buffer Object (FBO)
- 【OpenGL】OpenGL帧缓存对象(FBO:Frame Buffer Object)
- 【OpenGL】OpenGL帧缓存对象(FBO:Frame Buffer Object)
- Opengl FBO
- OpenGL FBO
- OpenGL - FBO
- 关于OpenGL中FrameBuffer Object的使用
- 点方法并不需要@property
- MySql 创建表的时候保留大小写状态
- 【codeforces #295(div 1)】ABC题解
- Android volley 解析(四)之缓存篇
- Android Studio导入GitHub上的项目常见问题(以图片轮播开源项目为实例)
- OpenGL Framebuffer Object (FBO)
- Mysql物理查询技术
- 双队列实现队列中元素排序
- cout流的重载
- AFNetworking NSURLErrorDomain error -1012
- Windows Phone 8.1添加后台任务运行条件(可添加多个)
- Qt元对象系统
- strcpy函数的实现
- 精通正则表达式(1)