当前位置: 首页 > news >正文

songho——OpenGL的帧缓冲

http://www.songho.ca/opengl/gl_fbo.html

纵览:
在OpengL的渲染管线中,几何数据和纹理被变换,被传送到几个不同的测试,最终作为2D像素渲染到屏幕上。最后一个渲染目的地是OpenGL管线,它称为帧缓冲。帧缓冲一个一组2D数组、或者是存储空间的集合。颜色缓冲、深度缓冲、模板缓冲,还有累计缓冲。默认情况下,OpenGL使用帧缓冲作为最终的渲染目的地,这个目的地,是通过窗口系统来创建、管理。这个默认的帧缓冲叫做窗口-系统提供的帧缓冲。

OpenGL的扩展,GL_ARB_framebuffer_object提供一个接口,来创建额外的未展示的帧缓冲对象。这个帧缓冲对象叫做应用-创建的帧缓冲,它区别于默认的窗口-系统-提供的帧缓冲。通过使用帧缓冲对象,OpengL应用可以重定向渲染输出到应用创建的帧缓冲对象,而不是传统的窗口-系统提供的帧缓冲,这个完全由OpengL控制。

和窗口-系统-提供的帧缓冲一样,FBO对象是渲染目标:颜色、深度、末班缓冲的集合。注意到累计缓冲不在FBO中定义。这写FBO中逻辑的缓冲叫做帧缓冲——附件图片,它们是被关联到帧缓冲对象的2D数组的像素。

这里有两个类型的帧缓冲-附件图片:纹理图片和渲染缓冲对象。如果纹理对象的图片附加到帧缓冲,OpenGL执行的是渲染到纹理。如果是渲染缓冲对象的图片关联到帧缓冲,OpenGL执行的是离屏渲染。

顺便说一句,渲染缓冲对象是新类型的存储对象,通过GL_ARB_framebuffer_object扩展定义。这个被用于简单的2D图片的渲染目标。

下面一张图展示帧缓冲对象、纹理对象和渲染缓冲对象的联系。多个纹理对象和渲染缓冲对象可以被附加到帧缓冲对象,通过附件点进行附件。

在这里插入图片描述

这里有多个颜色附着点:
GL_COLOR_ATTACHMENT0,…, GL_COLOR_ATTACHMENTn)
一个深度附着点GL_DEPTH_ATTACHMENT,一个模板缓冲附着点GL_STENCIL_ATTACHMENT,在帧缓冲对象中。

颜色附着点的个数和实现是独立的,但是每个FBO都至少有一个颜色附着点。你可以查看附着点的个数GL_MAX_COLOR_ATTACHMENTS,这个是图形显卡支持的。FBO有多个颜色附着点,是允许渲染颜色缓冲同时渲染到多个目标。这个就是多重渲染目标(MRT),他可以通过GL_ARB_draw_buffers实现。注意帧缓冲对象本身没有任何的图片存储空间,它只有多个附件附着点。、

帧缓冲对象提供有效的切换机制。从前一个帧缓冲附着图片,附加到新的帧缓冲附着点的图片。在帧缓冲附着的图片之间做切换比在帧缓冲对象之间切换要快。FBO提供glFramebufferTexture2D在2D纹理对象之间做切换,glFramebufferRenderbuffer在渲染对象之间做切换。

创建一个帧缓冲对象
创建一个帧缓冲对象和创建顶点缓冲对象类似:

glGenFramebuffers()
void glGenFramebuffers(GLsizei n, GLuint* ids)
void glDeleteFramebuffers(GLsizei n, const GLuint* ids)

glGenFramebuffers需要两个参数:第一个是帧缓冲的个数,dirge参数是指向2D存储空间的ID,或者是多个ID数组。它的返回是未使用的帧缓冲对象的IDs。ID=0是默认的帧缓冲,这个是窗口-系统提供的帧缓冲。

同时,FBO可以通过glDeleteFramebuffers删除。

一旦FBO被创建,它必须在使用之前绑定。

void glBindFramebuffer(GLenum target, GLuint id)

第一个参数是目标,应该是`GL_FRAMEBUFFER,第二个是帧缓冲对象的ID。一旦FBO被绑定,所有的OpenGL操作会影响到当前绑定到的帧缓冲对象。ID=0的对象,是窗口-系统提供的预留的帧缓冲。因此,为了解绑当前的帧缓冲,使用ID为0,作为参数:glBindFramebuffer。

渲染缓冲对象
除此之外,渲染缓冲对象是被新引入的离屏渲染。它允许直接渲染场景到渲染缓冲对象,而不是渲染到纹理贴图对象。渲染缓冲对象是一个简单的存储数据的对象,包含一个简单的图片,里面有内部的格式。它用于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其他对象一样,你需要使用它之前,把它绑定的到当前的渲染缓冲对象。目标应该是GL_RENDERBUFFER,它是针对渲染缓冲对象的。

glRenderbufferStorage()
void glRenderbufferStorage(GLenum  target,
                           GLenum  internalFormat,
                           GLsizei width,
                           GLsizei height)

当渲染缓冲对象呗创建,它没有任何的数据存储,所以我们需要分配一个内存空间给它。这个可以通过
glRenderbufferStorage指定。第一个参数是GL_RENDERBUFFER。第二个参数是颜色渲染值,如GL_RGB, GL_RGBA等,或者是GL_DEPTH_COMPONENT,或者是模板渲染格式GL_STENCIL_INDEX。渲染缓冲对象图片的像素宽度和高度。

宽度和高度需要小于GL_MAX_RENDERBUFFER_SIZE,否则会产生GL_INVALID_VALUE错误。

glGetRenderbufferParameteriv()
void glGetRenderbufferParameteriv(GLenum target,
                                  GLenum param,
                                  GLint* value)

你对于当前绑定的渲染缓冲对象,还需要多个参数。目标应该是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共享。

Attaching a 2D texture image to FBO
glFramebufferTexture2D(GLenum target,
                       GLenum attachmentPoint,
                       GLenum textureTarget,
                       GLuint textureId,
                       GLint  level)

glFramebufferTexture2D把2D纹理绑定到FBO。第一个参数是GL_FRAMEBUFFER,第二个参数是附着点,它连接了纹理图片。一个帧缓冲对象有多个附着点,(GL_COLOR_ATTACHMENT0, …, GL_COLOR_ATTACHMENTn),
GL_DEPTH_ATTACHMENT和GL_STENCIL_ATTACHMENT。第三个参数,纹理目标,他多数情况是GL_TEXTURE_2D。第四个参数是纹理对象的标识符。最后一个是纹理对象的mipmap等级。

如果textureID参数被设置为0,接着,纹理图片从FBO解绑。如果纹理对象被删除了,它依然绑定到FBO。结合,纹理图片将会自动从当前绑定的FBO解绑。但是,如果它被附加到多个FBO,如果被删除了,则只会从绑定的FBO解除,但是不会从其他的未绑定的FBO对象解绑。

Attaching a Renderbuffer image to FBO
void glFramebufferRenderbuffer(GLenum target,
                               GLenum attachmentPoint,
                               GLenum renderbufferTarget,
                               GLuint renderbufferId)

一个渲染缓冲对象可以通过glFramebufferRenderbuffer来附加。第一个参数和第二个参数和glFramebufferTexture2D一样。第三个参数必须是GL_RENDERBUFFER,最后一个参数是渲染缓冲对象的ID。

如果渲染缓冲id设置为0,这个渲染缓冲对象从FBO的附着点上解绑。如果渲染缓冲对象从附加到FBO上删除,它就不自动从FBO上解绑。但是,他不会从其他的未绑定的FBO上解绑。

相关文章:

  • while 循环 及 and or not
  • songho——OpenGL的顶点缓冲对象
  • OGL(教程35)——延迟渲染1——代码结构梳理
  • 安装MySQL_安装Navicat_启动数据库服务
  • android studio查看android手机日志
  • Python02(Linux命令)
  • luaforwindws安装与调用方式
  • vs添加链接文件
  • httpclient
  • 继成ScriptableObject的静态类对象竟然没有销毁
  • 国内镜像站
  • unity地形
  • Excel催化剂开源第5波-任务窗格在OFFICE2013中新建文档不能同步显示问题解决
  • shader 顶点属性——颜色
  • unity shader projector使用
  • android高仿小视频、应用锁、3种存储库、QQ小红点动画、仿支付宝图表等源码...
  • bearychat的java client
  • ES6之路之模块详解
  • JavaScript 是如何工作的:WebRTC 和对等网络的机制!
  • JavaScript学习总结——原型
  • Promise面试题2实现异步串行执行
  • python学习笔记-类对象的信息
  • Rancher-k8s加速安装文档
  • React-flux杂记
  • SOFAMosn配置模型
  • ⭐ Unity 开发bug —— 打包后shader失效或者bug (我这里用Shader做两张图片的合并发现了问题)
  • 基于阿里云移动推送的移动应用推送模式最佳实践
  • 简单基于spring的redis配置(单机和集群模式)
  • 前端知识点整理(待续)
  • 如何学习JavaEE,项目又该如何做?
  • 实现简单的正则表达式引擎
  • 小程序开发中的那些坑
  • 移动端 h5开发相关内容总结(三)
  • 原创:新手布局福音!微信小程序使用flex的一些基础样式属性(一)
  • ​ssh-keyscan命令--Linux命令应用大词典729个命令解读
  • #define
  • #stm32驱动外设模块总结w5500模块
  • #大学#套接字
  • #控制台大学课堂点名问题_课堂随机点名
  • (007)XHTML文档之标题——h1~h6
  • (1)常见O(n^2)排序算法解析
  • (31)对象的克隆
  • (阿里云万网)-域名注册购买实名流程
  • (每日持续更新)信息系统项目管理(第四版)(高级项目管理)考试重点整理第3章 信息系统治理(一)
  • (十七)devops持续集成开发——使用jenkins流水线pipeline方式发布一个微服务项目
  • (十一)图像的罗伯特梯度锐化
  • (五)大数据实战——使用模板虚拟机实现hadoop集群虚拟机克隆及网络相关配置
  • (转)setTimeout 和 setInterval 的区别
  • *p=a是把a的值赋给p,p=a是把a的地址赋给p。
  • .NET CORE 2.0发布后没有 VIEWS视图页面文件
  • .net 打包工具_pyinstaller打包的exe太大?你需要站在巨人的肩膀上-VC++才是王道
  • .net 反编译_.net反编译的相关问题
  • .Net8 Blazor 尝鲜
  • .net的socket示例
  • @KafkaListener注解详解(一)| 常用参数详解