OpenGL之FBO(Frame Buffer Object)和多次离屏渲染

2023-05-16

第一次听到离屏渲染的时候觉得很高级,遥不可及,直到后来做高斯模糊的时候,需要通过两次处理来节省性能,一直玩一次渲染处理的我这时候才认识FBO,继而明白了离屏渲染,今天抽个空做个记录。

一、FBO怎么用

由于我玩纹理比较多,所以就通过纹理来介绍FBO的用法吧,对纹理不熟可以看看我之前文章。至于FBO是什么这种概念,可以百度下,到处都是,我就不写了。

FBO其实就是帧缓存对象,有时候渲染一次结束,需要保存处理的结果,当作下一次处理的输入时,我们就可以把上一次的处理纹理保存到帧缓存中,给下一个着色器输入即可。

1.FBO的创建和绑定

先上代码:

glGenFramebuffers(1, &FBO[0]); //和其他buffer类似的创建
	glGenTextures(1, &uTexture[2]); //再创建个纹理对象
	glBindTexture(GL_TEXTURE_2D, uTexture[2]); //绑定纹理,接下来设置纹理的默认参数
	//    为当前绑定的纹理对象设置环绕、过滤方式
	//    将纹理包装设置为GL_REPEAT(默认包装方法)
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
	//    设置纹理过滤参数
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, SCR_WIDTH, SCR_HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); //此处尺寸设置要是窗口大小,很重要,也可以自己尝试别的尺寸,看效果
 
	glBindFramebuffer(GL_FRAMEBUFFER, FBO[0]); //绑定FBO
	glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, uTexture[2], 0);//将纹理绑到FBO上
 
	glBindTexture(GL_TEXTURE_2D, 0);//解绑纹理对象
	glBindFramebuffer(GL_FRAMEBUFFER, 0);//解绑FBO

从上面可以看到我们为FBO绑定了一张空有尺寸无内容的纹理,为什么呢?因为我们用帧缓存是去存处理后的纹理的,所以绑定个啥样的都不重要,但尺寸要对!

2.FBO的使用

同样还是代码,在渲染时这么写:

glUseProgram(programObject[3]); // 使用着色器,假设我这里是第3号着色器
        glBindVertexArray(VAOId[0]); // 使用VAO信息
		glActiveTexture(GL_TEXTURE1); //激活纹理单元
		glBindTexture(GL_TEXTURE_2D, uTexture[0]);//设定纹理对象,0号纹理
		glUniform1i(glGetUniformLocation(programObject[3], "uTexture1"), 1);//将0号纹理绑定到shader中的纹理变量
		glBindFramebuffer(GL_FRAMEBUFFER, FBO[0]); //绑定FBO开始操作
		glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);//绘制
        glBindFramebuffer(GL_FRAMEBUFFER, 0);//解绑FBO

从上述可以看出,跟普通使用着色器绘制相比就多了两行代码,绑定FBO和解绑,有了这两行代码,着色器处理后的结果将不会显示在窗口了,而是保存到FBO绑定的纹理对象上,比如上面绑定的2号纹理对象。离屏渲染也就是这么回事。

那么怎么使用这个FBO保存的纹理呢?怎么多次离屏渲染呢?看接下来的代码:

glUseProgram(programObject[1]); // 使用着色器
		glActiveTexture(GL_TEXTURE0); //激活纹理单元
		glBindTexture(GL_TEXTURE_2D, uTexture[2]);//绑定FBO[0]绑定的纹理对象
        glUniform1i(glGetUniformLocation(programObject[1], "uTexture1"), 0);//将纹理绑定到shader中的纹理变量
        glBindFramebuffer(GL_FRAMEBUFFER, FBO[1]); //绑定第二个FBO对象
		glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
		glBindFramebuffer(GL_FRAMEBUFFER, 0);//解绑
 
		glUseProgram(programObject[0]); // 使用着色器
		glActiveTexture(GL_TEXTURE1);
		glBindTexture(GL_TEXTURE_2D, uTexture[1]); //绑定FBO[1]绑定的纹理对象,假设为1号
		glUniform1i(glGetUniformLocation(programObject[0], "uTexture1"), 1);//将0号纹理绑定到shader中的纹理变量
		glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);

上面代码先是使用了第一个FBO绑定的纹理,再是用第二个FBO对象去保存第二步着色器处理的纹理,再给第三步着色器使用,这样就利用两次离屏渲染实现了3次处理,当然我们还可以进行三次,四次的离屏渲染,以此类推。

二、总结

前期我也遇到了很多不知名问题,很是崩溃,但是逐行去理解代码之后,问题一一解决,沉下气静下心来理解代码很容易就通畅了。希望有问题可以提出来,非常感谢!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

OpenGL之FBO(Frame Buffer Object)和多次离屏渲染 的相关文章

随机推荐

  • 字符串及处理之三: 使用TCHAR系列方案

    使用TCHAR系列方案编写程序 TCHAR是一种字符串类型 xff0c 它让你在以MBCS和UNNICODE来build程序时可以使用同样的代码 xff0c 不需要使用繁琐的宏定义来包含你的代码 TCHAR的引入 xff0c 主要是在Tch
  • Chrome解决“github.com拒绝了我们的访问请求”

    目录 1 网站查询特定IP 2 host文件修改 3 刷新DNS 如果你在Chrome访问github com时出现以下错误 xff1a 本博主之前的Chrome和Edge都无法访问github官网 xff0c 然后就来到了万能的C站找到了
  • STC12C5A60S2_LCD1602驱动

    文章目录 LCD1602 HLCD1602 cmain c LCD1602 H 代码如下 xff1a span class token macro property span class token directive hash span
  • 猿创征文|机器学习实战(8)——随机森林

    目录 1 随机森林 2 极端随机树 3 特征重要性 4 提升法 4 1 AdaBoost 4 2 梯度提升 机器学习实战 xff08 7 xff09 中我们已经提到 xff0c 随机森林是决策树的集成 xff0c 通常用bagging方法训
  • 总结2014——迷茫以及迷茫过后的坚持

    首先 xff0c 借用一句话和大家共勉 xff1a 少一些功利主义的追求 xff0c 多一些不为什么的坚持 xff01 xff01 不知不觉15年也快过了1个月了 xff0c 还是想着要为14年做一下总结 xff1a 记录一下自己的历程 今
  • 汇编总结:lea指令

    ea指令变种 按大小分类 leaw 2个字节 leal 4个字节 leaq 8个字节 lea的用法 leaq a b c d rax 首先lea指令是mov指令的变种 xff0c 据说 xff0c lea指令是x86体系结构中 xff0c
  • CMake语法—选项(option)

    CMake语法 选项 xff08 option xff09 1 选项 1 1 定义 1 2 说明 variable 选项名help text 描述 解释 备注value 选项初始化值 xff08 除ON而外全为OFF xff09 2 应用注
  • C++工程:总结 CMake 添加第三方库依赖方式git submodule、 find_library、FetchContent、CPM等

    CMake 已经成为了C 43 43 工程管理的主流方式 xff0c 功能非常强大 xff0c 现在大多数的 C 43 43 库都已经支持CMake xff0c 下面以 jsoncpp 为例 xff0c 介绍几种引入第三方库的方式 1 代码
  • 医学图像——DCMTK、VTK、ITK、RTK、SimpleITK

    1 引言 https github com SINTEFMedtek ITK VTK xff0c 相关童鞋应该很熟悉的 xff0c 而CTK是一个较新的界面库 xff0c 主要用于方便前面两个 TK的界面设计 xff0c 当然也可以作为通用
  • C++中的volatile

    volatile的本意是 易变的 volatile关键字是一种类型修饰符 xff0c 用它声明的类型变量表示可以被某些编译器未知的因素更改 xff0c 比如操作系统 硬件或者其它线程等 遇到这个关键字声明的变量 xff0c 编译器对访问该变
  • 3DTiles】关于GeometricError几何度量误差

    在 3DTiles 的官方文档中详细介绍了关于几何度量误差 Geometric Error 的一些理念和内涵 xff0c 概括来说可以翻译为如下定义 xff1a 几何度量误差 xff0c Geometric Error xff0c 简称 G
  • glPixelStorei 详解 包括像素传输

    3 glPixelStore 像glPixelStorei GL PACK ALIGNMENT 1 这样的调用 xff0c 通常会用于像素传输 PACK UNPACK 的场合 尤其是导入纹理 glTexImage2D 的时候 xff1a C
  • ESLint 简介

    ESLint简介 ESLint是一个用来识别 ECMAScript 并且按照规则给出报告的代码检测工具 xff0c 使用它可以避免低级错误和统一代码的风格 如果每次在代码提交之前都进行一次eslint代码检查 xff0c 就不会因为某个字段
  • IOS VasSonic 粗略见解

    因为项目需求需要在本地缓存html页面 xff0c 优化用户体验 了解到VasSonic 百度了下源码解析但是没有发现IOS的所以只有自己慢慢摸索了 一 类的简单关系 1 SonicEngine 引擎类 代理为 UIWebViewContr
  • axios的详细讲解

    一 axios的特性 axios 是一个基于Promise 用于浏览器和 nodejs 的 HTTP 客户端 xff0c 简单的理解就是ajax的封装 特性 xff1a 从浏览器中创建 XMLHttpRequests从 node js 创建
  • 无人机飞控算法-姿态估计-欧拉角-旋转矩阵-四元数

    无人机飞控算法 姿态估计 此系列记录了我理解的卡尔曼滤波从0到1的过程 xff0c 从姿态估计到位置估计 xff0c 我们从核心点一个个出发 xff0c 并结合实际模块的应用来一一揭开卡尔曼滤波的神秘面纱 提示 xff1a 在系列文章中 x
  • BMP格式详解

    介绍 数字图像在外存储器设备中的存储形式是图像文件 xff0c 图像必须按照某个已知的 公认的数据存储顺序和结构进行存储 xff0c 才能使不同的程序对图像文件顺利进行打开或存盘操作 xff0c 实现数据共享 图像数据在文件中的存储顺序和结
  • WinHex使用方法详解

    WinHex是由X Ways软件技术公司 xff08 官方网站http www x ways net xff09 开发的一款专业的磁盘编辑工具 xff0c 该工具文如其名 xff0c 是在Windows下运行的十六进制 xff08 hex
  • three.js流动线

    效果 xff1a 先看最基本的 function initThree el options options 61 options const t 61 this appInstance 61 this const width 61 el o
  • OpenGL之FBO(Frame Buffer Object)和多次离屏渲染

    第一次听到离屏渲染的时候觉得很高级 xff0c 遥不可及 xff0c 直到后来做高斯模糊的时候 xff0c 需要通过两次处理来节省性能 xff0c 一直玩一次渲染处理的我这时候才认识FBO xff0c 继而明白了离屏渲染 xff0c 今天抽