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

QT之OpenGL帧缓冲

QT之OpenGL帧缓冲

  • 1. 概述
    • 1.1 帧缓冲的创建与删除
    • 1.2 帧缓冲的数据来源
      • 1.2.1 数据源与帧缓冲的关系
      • 1.2.2 纹理Attachment
      • 1.2.3 渲染缓冲对象Attachment
      • 1.2.4 两者的区别
      • 1.2.5 关于两者的使用场景
  • 2. Demo
  • 3. 后期处理
  • 4. 参考

1. 概述

OpenGL管线的最终渲染目的地被称作帧缓冲(framebuffer),它由用于写入颜色值的颜色缓冲、用于写入深度信息的深度缓冲和允许根据一些条件丢弃特定片段的模板缓冲组合而成,它被储存在内存中。

1.1 帧缓冲的创建与删除

  • 创建

    unsigned int fbo;
    /*
    第一个是要创建的帧缓存的数目
    第二个是指向存储一个或者多个ID的变量或数组的指针
    默认帧缓冲的id是0
    */
    glGenFramebuffers(1, &fbo);
    
  • 绑定激活

    /*
    GL_READ_FRAMEBUFFER : 绑定到GL_READ_FRAMEBUFFER的帧缓冲将会使用在所有像是glReadPixels的读取操作中
    GL_DRAW_FRAMEBUFFER : 而绑定到GL_DRAW_FRAMEBUFFER的帧缓冲将会被用作渲染、清除等写入操作的目标
    GL_FRAMEBUFFER : 通常都会使用GL_FRAMEBUFFER,绑定到两个上
    */
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    
  • 删除

    glDeleteFramebuffers(1, &fbo);
    
  • OpenGL允许自定义帧缓冲,一个完整帧缓冲需要满足以下条件

    • 附加至少一个缓冲(颜色、深度或模板缓冲)
    • 至少有一个颜色attachment
    • 所有的attachment都必须是完整的(保存在内存)
    • 每个缓冲都应有相同的样本数
  • 完整性检查

    if(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE)
    

1.2 帧缓冲的数据来源

在这里插入图片描述

1.2.1 数据源与帧缓冲的关系

  • 只是用纹理Attachment
    在这里插入图片描述

  • 只是用渲染缓冲对象Attachment
    在这里插入图片描述

  • 纹理Attachment与渲染缓冲对象Attachment结合使用
    在这里插入图片描述

注:

  • GL_COLOR_ATTACHMENT的数量可以通过GL_MAX_COLOR_ATTACHMENTS获取
  • 一个帧缓冲至少要有一个颜色缓冲Attachment
  • 这里的Attachment仅仅是一个附着点,并不是将数据拷贝到FBO中
  • FBO提供了一种高效的切换机制,将前面帧缓冲关联的图形从FBO分离,然后把心的帧缓冲图像关联到FBO在帧缓冲关联图像之间切换比在FBO之间切换要快的多。 切换函数如下:
    // 切换纹理图像
    glFramebufferTexture2D();
    // 切换渲染缓冲区
    glFramebufferRenderbuffer();
    

1.2.2 纹理Attachment

把一个纹理附加附加到缓冲区的时候,所有的渲染指令都将会写入到这个纹理中,就像他是一个普通的颜色/深度或模板缓冲一样。使用纹理的优点是,所有渲染操作的结果将会被存储在一个纹理图像中,可以很方便的在着色器中只是用。

  • 纹理创建
    unsigned int texture;
    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, texture);/*
    这里的data部分设置为NULL,表示仅仅分配了内存而没有进行数据填充。纹理的填充会在渲染到帧缓冲之后进行如果想将屏幕渲染到一个更小或更大的纹理上,需要(在渲染到帧缓冲之前)再次调用glViewport,使用纹理的新维度作为参数,否则只有一小部分的纹理或屏幕会被渲染到这个纹理上
    */
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 800, 600, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);// 设置纹理过滤方式 压缩 采用线性采样
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    // 设置纹理过滤方式 放大 采用线性采样
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    
  • 附加到帧缓冲
    /*
    target:帧缓冲的目标(绘制、读取或者两者皆有)
    attachment:我们想要附加的附件类型。当前我们正在附加一个颜色附件。注意最后的0意味着我们可以附加多个颜色附件。我们将在之后的教程中提到。
    textarget:你希望附加的纹理类型
    texture:要附加的纹理本身
    level:多级渐远纹理的级别。我们将它保留为0。
    */
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
    /*除了颜色附件之外,还可以附加一个深度和模板缓冲纹理到帧缓冲对象中。要附加深度缓冲,需要将附件类型设置为GL_DEPTH_ATTACHMENT。注意纹理的格式(Format)和内部格式(Internalformat)类型将变为GL_DEPTH_COMPONENT,来反映深度缓冲的储存格式。要附加模板缓冲的话,需要将第二个参数设置为GL_STENCIL_ATTACHMENT,并将纹理的格式设定为GL_STENCIL_INDEX。也可以将深度缓冲和模板缓冲附加为一个单独的纹理。纹理的每32位数值将包含24位的深度信息和8位的模板信息。要将深度和模板缓冲附加为一个纹理的话,我们使用GL_DEPTH_STENCIL_ATTACHMENT类型,并配置纹理的格式,让它包含合并的深度和模板值。将一个深度和模板缓冲附加为一个纹理到帧缓冲的例子如下所示:
    */glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, 800, 600, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL
    );glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, texture, 0);
    

1.2.3 渲染缓冲对象Attachment

渲染缓冲对象(Renderbuffer Object)是在纹理之后引入OpenGL的,它也是一个真正的缓冲,它会将数据存储为OpenGL原生的渲染格式,它是为了离屏渲染到帧缓冲优化过的。

  • 创建
    unsigned int rbo;
    glGenRenderbuffers(1, &rbo);
    
  • 绑定
    glBindRenderbuffer(GL_RENDERBUFFER, rbo);
    
  • 创建深度和模板缓冲对象
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 800, 600);
    
  • 附加到渲染缓冲对象
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo);
    

注:

  • 因为它的数据已经是原生的格式了,当写入或者复制它的数据到其它缓冲中时是非常快的。所以,交换缓冲这样的操作在使用渲染缓冲对象时会非常快。我们在每个渲染迭代最后使用的glfwSwapBuffers,也可以通过渲染缓冲对象实现:只需要写入一个渲染缓冲图像,并在最后交换到另外一个渲染缓冲就可以了。渲染缓冲对象对这种操作非常完美。

1.2.4 两者的区别

  • 纹理是可读可写的,而渲染缓冲对象则是只写的,但可以使用glReadPixels来读取它(从当前绑定的帧缓冲而不是Attachment本身中返回特定区域的像素)

1.2.5 关于两者的使用场景

  • 如果不需要从一个缓冲中采样,此时使用渲染缓冲对象更好些
  • 如果需要从一个缓冲中进行采样颜色或深度值等数据,此时使用纹理Attachment更合理
  • 两者在性能方面不会差别非常大

2. Demo

将场景渲染到一个小窗口中,源码链接
在这里插入图片描述

3. 后期处理

Demo效果展示如下:

  • 反相(Inversion)
    在这里插入图片描述

  • 灰度(Grayscale)
    在这里插入图片描述

  • 加权(Weighted)
    在这里插入图片描述

  • 核(kernel)

    在一个纹理图像上做后期处理的另外一个好处是,我们可以从纹理的其它地方采样颜色值。比如说我们可以在当前纹理坐标的周围取一小块区域,对当前纹理值周围的多个纹理值进行采样。
    核(Kernel)(或卷积矩阵(Convolution Matrix))是一个类矩阵的数值数组,它的中心为当前的像素,它会用它的核值乘以周围的像素值,并将结果相加变成一个值。

    锐化(Sharpen)
    在这里插入图片描述
    模糊(Blur)
    在这里插入图片描述

    边缘检测(Edge-detection)
    在这里插入图片描述

4. 参考

  • OpenGL Learn

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

  • http://www.songho.ca/opengl/gl_fbo.html的翻译版

  • FBO使用示例

  • 单独使用 渲染缓冲对象示例

相关文章:

QT之OpenGL帧缓冲

QT之OpenGL帧缓冲1. 概述1.1 帧缓冲的创建与删除1.2 帧缓冲的数据来源1.2.1 数据源与帧缓冲的关系1.2.2 纹理Attachment1.2.3 渲染缓冲对象Attachment1.2.4 两者的区别1.2.5 关于两者的使用场景2. Demo3. 后期处理4. 参考1. 概述 OpenGL管线的最终渲染目的地被称作帧缓冲(fram…...

$ 6 :选择、循环

if-else语句 #include <stdio.h> //判断输入值是否大于0 int main() {int i;while (scanf("%d",&i)){if (i > 0)//不要在括号后加分号{printf("i is bigger than O\n");}else {printf("i is not bigger than O\n");}}return O; } …...

【项目设计】高并发内存池 (四)[pagecache实现]

&#x1f387;C学习历程&#xff1a;入门 博客主页&#xff1a;一起去看日落吗持续分享博主的C学习历程博主的能力有限&#xff0c;出现错误希望大家不吝赐教分享给大家一句我很喜欢的话&#xff1a; 也许你现在做的事情&#xff0c;暂时看不到成果&#xff0c;但不要忘记&…...

玩转qsort——“C”

各位CSDN的uu们你们好呀&#xff0c;今天小雅兰的内容还是我们的深度剖析指针呀&#xff0c;上篇博客我们学习了回调函数这个知识点&#xff0c;但是没有写完&#xff0c;因为&#xff1a;小雅兰觉得qsort值得单独写出来&#xff01;&#xff01;&#xff01;好啦&#xff0c;就…...

【干货】又是一年跳槽季!Nginx 10道核心面试题及解析

Nginx是一款轻量级的高性能Web服务器和反向代理服务器&#xff0c;由俄罗斯的Igor Sysoev开发。它具有占用资源少、高并发、稳定性高等优点&#xff0c;被广泛应用于互联网领域。在Nginx的面试过程中&#xff0c;面试官通常会提出一些核心问题&#xff0c;本文将介绍一些常见的…...

【线程安全的HashMap有哪些,CurrentHashMap底层是怎么实现线程安全的】

在 Java 中&#xff0c;线程安全的 HashMap 通常有以下几种实现&#xff1a; Collections.synchronizedMap 方法&#xff1a;该方法可以将 HashMap 转换为线程安全的 Map。 Hashtable 类&#xff1a;Hashtable 是一种线程安全的集合类&#xff0c;它与 HashMap 类似&#xff0…...

C语言-结构体【详解】

一、 结构体的基础知识 结构是一些值的集合&#xff0c;这些值称为成员变量结构的每个成员可以是不同类型的变量 &#xff08;1&#xff09;结构体的声明 写法一&#xff1a; 注&#xff1a; 括号后边的分号不能忘结构体末尾可以不创建变量&#xff0c;在主函数中再创建 struc…...

浏览器输入url到页面渲染完成经历了哪些步骤

一、URL解析 这一步比较容易理解&#xff0c;在浏览器地址栏输入url后&#xff0c;浏览器会判断这个url的合法性 &#xff0c;以及是否有可用缓存&#xff0c;如果判断是 url 则进行域名解析&#xff0c;如果不是 url &#xff0c;则直接使用搜索引擎搜索 二、域名解析 输入…...

大数据技术之Hadoop(Yarn)

第1章Yarn资源调度器思考&#xff1a;1&#xff09;如何管理集群资源&#xff1f;2&#xff09;如何给任务合理分配资源&#xff1f;Yarn是一个资源调度平台&#xff0c;负责为运算程序提供服务器运算资源&#xff0c;相当于一个分布式的操作系统平台&#xff0c;而MapReduce等…...

5.建造者模式

目录 简介 四个角色 应用场景 实现步骤 和工厂模式的区别 简介 建造者模式也叫生成器模式&#xff0c;是一种对象构建模式&#xff1b;它可以把复杂对象的建造过程抽象出来(抽象类别)&#xff0c;使这个抽象过程的不同实现方法可以构造出不同表现(属性)的对象&#xff1b;…...

数据库基础-数据库基本概念(1-1)

你好&#xff0c;欢迎来到数据库基础系列专栏&#xff0c;欢迎留言互动哦~ 目录一、数据库基础1. 数据库基本概念1.1 数据库1.2 什么是数据库管理软件1.3 表1.4 行1.5 列和数据类型1.6 主键1.7 什么是 SQL一、数据库基础 1. 数据库基本概念 1.1 数据库 数据库是一个以某种有…...

学习笔记-架构的演进之服务容错策略-服务发现-3月day01

文章目录前言服务容错容错策略附前言 “容错性设计”&#xff08;Design for Failure&#xff09;是微服务的一个核心原则。 使用微服务架构&#xff0c;拆分出的服务越来越多&#xff0c;也逐渐导致以下问题&#xff1a; 某一个服务的崩溃&#xff0c;会导致所有用到这个服务…...

采编式AIGC视频生产流程编排实践

作者 | 百度人工智能创作团队 导读 本文从业务出发&#xff0c;系统介绍了采编式 TTV的实现逻辑和实现路径。结合业务拆解&#xff0c;实现了一个轻量级服务编排引擎&#xff0c;有效实现业务诉求、高效支持业务扩展。 全文6451字&#xff0c;预计阅读时间17分钟。 01 背景 近…...

Leetcode23. 合并k个升序链表

一、题目描述&#xff1a; 给你一个链表数组&#xff0c;每个链表都已经按升序排列。 请你将所有链表合并到一个升序链表中&#xff0c;返回合并后的链表。 示例 1&#xff1a; 输入&#xff1a;lists [[1,4,5],[1,3,4],[2,6]]输出&#xff1a;[1,1,2,3,4,4,5,6]解释&#…...

从用户出发,互联网产品策划方法论

【一】从用户到需求 产品经理需要具备两个非常重要的技能,一个叫策划,一个叫感知用户。 我们在分析问题的时候往往会说“这么做,我认为用户会怎么怎么样”、“用户会认为这样很不爽”,当我们这样说时,很有可能是把自己当成了用户,用某些特定的情感或记忆代表了用户。 当我…...

STM32 E18-D80NK红外检测

本文代码使用 HAL 库。 文章目录前言一、E18-D80NK 红外传感器&#xff1a;1. E18-D80NK 的介绍2. 电器特性二、红外检测小实验代码讲解三、实验现象总结前言 这篇文章介绍 如何使用 STM32 控制 E18-D80NK 进行红外检测。 一、E18-D80NK 红外传感器&#xff1a; 1. E18-D80N…...

Linux常用命令--进程和计划任务管理

一、程序和进程的关系 1、程序 ①保存在硬盘、光盘等介质中的可执行代码和数据 ②静态保存的代码 2、进程 ①在cpu及内存中运行及进程代码 ②动态执行的代码 ③父&#xff08;fork&#xff09;、子进程&#xff0c;每个程序可以创建一个或多个进程 父进程和子进程的区别&am…...

Unity TextMeshPro

Unity TextMeshPro 简介 TextMeshPro(也简称为TMP)号称是Unity的终极文本解决方案,它是Unity 的 UI 文本和旧版文本网格体的完美替代品。 功能强大且易于使用,使用高级文本渲染技术以及一组自定义着色器;提供实质性的视觉质量改进,同时在文本样式和纹理方面为用户提供令人…...

虹科分享| 浅谈HK-Edgility边缘计算平台

上周&#xff0c;我们推出了虹科新品HK-Edgility边缘计算平台以及uCPE解决方案。本篇文章我们再来谈一谈到底什么是边缘计算&#xff1f;为什么需要边缘计算&#xff1f;边缘计算和云计算有什么关系&#xff1f;HK-Edgility边缘计算平台将为您带来什么&#xff1f;一、边缘计算…...

React Router v6详解

旧版本React Router使用方式 BrowserRouter&#xff1a;通过 history 库&#xff0c;传递 history 对象&#xff0c;location 对象Switch&#xff1a;匹配唯一的路由 Route&#xff0c;展示正确的路由组件Route&#xff1a;视图承载容器&#xff0c;控制渲染 UI 组件 新版本R…...

帮助100w人成功入职的软件测试面试常见问题以及答案

测试面试题怎么来设计测试方案根据测试需求&#xff08;包括功能需求和非功能性需求&#xff09;&#xff0c;识别测试要点&#xff0c;识别测试环境要求&#xff0c;安排测试轮次&#xff0c;根据项目计划和开发计划做整体的测试安排。被测试的特性&#xff1a;通过对需求规格…...

tensorflow2.4--2.回归问题分析

文章目录前言流程案例操作前言 流程 回归问题预测连续值,在某个区间内变动. 常见的线性回归问题模型是yaxb,然而现实世界由于大量的数据偏差以及复杂度,同时还有大量的噪声,往往达不到如此的精确解,实际解决问题时需要考虑噪声的存在 对于噪声,往往我们已经假设了它符合高斯…...

【2023】DevOps、SRE、运维开发面试宝典之Kafka相关面试题

文章目录 1、消息队列的流派2、kafka的优势3、Kafka与Zookeeper的关系4、Kafka消息队列各组件概念5、Kafka消息队列应用场景6、Kafka消息收发的过程7、Kafka消息数据存储概念8、kafka消息的偏移量概念原理9、Kafka消息数据的顺序消费概念原理10、Kafka单播消费消息的原理11、Ka…...

CentOS系统编译安装PHP-5.6.27版本

一、手动安装编译工具&#xff1a; yum install -y gcc gcc-c 二、添加用户和用户组&#xff1a; groupadd web useradd -M -s /sbin/nologin -g web php 三、yum安装依赖&#xff1a; yum -y install libmcrypt libmcrypt-devel mcrypt mhash libxml2-devel libpng-devel l…...

和风SDK查询城市ID(保姆级教程)

android studio版本&#xff1a;2021.2.1例程名&#xff1a;hfserachcityid这几天没什么事做&#xff0c;而且我原来那个“项目”因为免费api不能用了&#xff0c;只能改为和风的免费api,但需要申请&#xff0c;而且还要城市ID&#xff0c;玩天气的基本都知道城市ID这个东西&am…...

暴力递归到动态规划

暴力递归到动态规划 假设有排成一行的n个位置&#xff0c; 记为1~n&#xff0c;n-定大于或等于2。开始时机器人在其中的m位置上(m 一定是1~n中的一个)。如果机器人来到1位置&#xff0c;那么下一步只能往右来到2位置&#xff1b;如果机器人来到n位置&#xff0c; 那么下一步只能…...

Java:Java仍然处于领先地位?

没有多少编程语言能够自吹自擂并持续流行20多年&#xff0c;但Java就是其中之一。Java应用程序不仅局限于web和移动开发&#xff0c;而且给大数据和人工智能留下了深刻的印象。不用多说&#xff0c;让我们讨论一下Java流行的几个原因!!1.实用性根据JamesGosling的说法&#xff…...

虚拟地址空间

本节目录1.如何理解区域划分2.为什么一个变量可以存储两个不同的值&#xff1f;3.深入理解虚拟地址空间为什么要有地址空间&#xff1f;4.理解什么是挂起&#xff1f;1.虚拟地址空间究竟是什么&#xff1f;2.映射关系的维护是谁做的&#xff1f;1.如何理解区域划分 所谓的区域…...

Python基础篇(十五)-- Pygame游戏编程

1 初识Pygame Pygame是一个开源的Python模块&#xff0c;专门用于多媒体应用&#xff08;如电子游戏&#xff09;的开发&#xff0c;其中包含对图像、声音、视频、事件、碰撞等的支持。Pygame建立在SDL的基础上&#xff0c;SDL是一套跨平台的多媒体开发库&#xff0c;用C语言实…...

LeetCode 热题 HOT 100 Java 题解 -- Part 2

练习地址 Part 1 : https://blog.csdn.net/qq_41080854/article/details/128829494 LeetCode 热题 HOT 100 Java 题解 -- Part 236. 二叉树的中序遍历 9437. 不同的二叉搜索树 9638. 验证二叉搜索树 9839. 对称二叉树 10140. 二叉树的层序遍历 10241. 二叉树的最大深度 10442.…...

女教师网课入侵录屏 /seo教程之关键词是什么

第三章 日子过得就像那些不眠的晚上&#xff0c;她嚼着口香糖对墙满谈着理想。——————赵雷《成都》 NOIP过后我认识到了自己有多么菜&#xff0c;我换了座&#xff0c;到了靠窗户那排。 大王开始给我们介绍一些高端算法&#xff0c;那些日子都是在luogu试炼场刷动态规划&a…...

赚钱网站大全/公司网站优化

1.初始化"打字创建"属性代码类似于这样:var typing {_el: document.getElementById("demo"),_maxSpeed: 150,//最大输入速度_minSpeed: 20,//最小输入速度_textList: ["js实现简单的循环打字效果(思路分享)","关爱单身狗成长协会 ",&…...

家居网站开发项目计划书/网络推广怎么做效果好

IBM SPSS Statistics为用户提供了三种相关性分析的方法&#xff0c;分别是双变量分析、偏相关分析和距离分析&#xff0c;三种相关分析方法各针对不同的数据情况&#xff0c;接下来我们将为大家介绍如何使用SPSS相关性分析中的距离分析。 一、数据简述 距离分析和其他两类相关…...

做教学的视频网站有哪些/seo查询 工具

为什么80%的码农都做不了架构师&#xff1f;>>> 一、什么是sandbox 每个iOS应用都被限制在“沙盒”中&#xff0c;“沙盒”相当于一个加了仅主人可见权限的文件夹&#xff0c;苹果对沙盒主要有以下限制。 1、应用程序可以在自己的沙盒里运作&#xff0c;但是不能访…...

做网站分销违法吗/沈阳优化推广哪家好

显卡驱动程序就是用来驱动显卡的程序&#xff0c;它是硬件所对应的软件。驱动程序即添加到操作系统中的一小块代码&#xff0c;其中包含有关硬件设备的信息。有了此信息&#xff0c;计算机就可以与设备进行通信。驱动程序是硬件厂商根据操作系统编写的配置文件&#xff0c;可以…...

字体设计转换器/seo上海优化

本次结对编程是为了完成四则运算生成器&#xff0c;&#xff0c;针对这次结对编程的题目 我们决定支持最多 10 个运算符的应用程序&#xff0c;支持括号的运算&#xff0c;可以判断题目的对错。 这次代码的难点在于不仅仅要保证题目不重复&#xff0c;还要完成多功能。 需求分…...