当前位置: 首页 > 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…...

Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器

第一章 引言&#xff1a;语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域&#xff0c;文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量&#xff0c;支撑着搜索引擎、推荐系统、…...

P3 QT项目----记事本(3.8)

3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...

听写流程自动化实践,轻量级教育辅助

随着智能教育工具的发展&#xff0c;越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式&#xff0c;也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建&#xff0c;…...

管理学院权限管理系统开发总结

文章目录 &#x1f393; 管理学院权限管理系统开发总结 - 现代化Web应用实践之路&#x1f4dd; 项目概述&#x1f3d7;️ 技术架构设计后端技术栈前端技术栈 &#x1f4a1; 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 &#x1f5c4;️ 数据库设…...

安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖

在Vuzix M400 AR智能眼镜的助力下&#xff0c;卢森堡罗伯特舒曼医院&#xff08;the Robert Schuman Hospitals, HRS&#xff09;凭借在无菌制剂生产流程中引入增强现实技术&#xff08;AR&#xff09;创新项目&#xff0c;荣获了2024年6月7日由卢森堡医院药剂师协会&#xff0…...

GruntJS-前端自动化任务运行器从入门到实战

Grunt 完全指南&#xff1a;从入门到实战 一、Grunt 是什么&#xff1f; Grunt是一个基于 Node.js 的前端自动化任务运行器&#xff0c;主要用于自动化执行项目开发中重复性高的任务&#xff0c;例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...

uniapp 开发ios, xcode 提交app store connect 和 testflight内测

uniapp 中配置 配置manifest 文档&#xff1a;manifest.json 应用配置 | uni-app官网 hbuilderx中本地打包 下载IOS最新SDK 开发环境 | uni小程序SDK hbulderx 版本号&#xff1a;4.66 对应的sdk版本 4.66 两者必须一致 本地打包的资源导入到SDK 导入资源 | uni小程序SDK …...

NPOI操作EXCEL文件 ——CAD C# 二次开发

缺点:dll.版本容易加载错误。CAD加载插件时&#xff0c;没有加载所有类库。插件运行过程中用到某个类库&#xff0c;会从CAD的安装目录找&#xff0c;找不到就报错了。 【方案2】让CAD在加载过程中把类库加载到内存 【方案3】是发现缺少了哪个库&#xff0c;就用插件程序加载进…...

Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement

Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement 1. LAB环境2. L2公告策略2.1 部署Death Star2.2 访问服务2.3 部署L2公告策略2.4 服务宣告 3. 可视化 ARP 流量3.1 部署新服务3.2 准备可视化3.3 再次请求 4. 自动IPAM4.1 IPAM Pool4.2 …...

协议转换利器,profinet转ethercat网关的两大派系,各有千秋

随着工业以太网的发展&#xff0c;其高效、便捷、协议开放、易于冗余等诸多优点&#xff0c;被越来越多的工业现场所采用。西门子SIMATIC S7-1200/1500系列PLC集成有Profinet接口&#xff0c;具有实时性、开放性&#xff0c;使用TCP/IP和IT标准&#xff0c;符合基于工业以太网的…...