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

wayland(xdg_wm_base) + egl + opengles 使用FBO渲染到纹理实例(六)

文章目录

  • 前言
  • 一、FBO介绍
    • 1. FBO 简介
    • 2. FBO的关键组成部分
    • 3. FBO的基本工作流程
    • 4. FBO 实现渲染到纹理
    • 5. FBO 实现离屏渲染
  • 二、FBO 实现渲染到纹理的代码实例
    • 1. egl_wayland_texture3_2.c
    • 2. xdg-shell-client-protocol.h 和 xdg-shell-protocol.c
    • 3. 编译
    • 4. 运行
  • 总结
  • 参考资料


前言

本文主要介绍 如何在 opengles 中使用FBO 实现渲染到纹理的功能
软硬件环境:
硬件:PC
软件:ubuntu22.04 opengles3.0 egl1.4


一、FBO介绍

1. FBO 简介

FBO(Framebuffer Object)是OpenGL的一个扩展,它允许我们将渲染结果直接绘制到一个纹理或者渲染缓冲对象中,而不是默认的帧缓冲。

使用FBO可以实现一些高级的渲染技术,如离屏渲染、后期处理、抗锯齿等。它提供了一个独立于窗口的帧缓冲对象,可以将渲染的结果存储到纹理或者渲染缓冲对象中,并且可以在后续的渲染中作为输入来进行处理。

2. FBO的关键组成部分

  1. Color Attachment:用于存储颜色信息的附件,可以是纹理或者渲染缓冲对象;
  2. Depth Attachment:用于存储深度信息的附件,也可以是纹理或者渲染缓冲对象;
  3. Stencil Attachment:用于存储模板信息的附件,同样可以是纹理或者渲染缓冲对象;

3. FBO的基本工作流程

  1. 创建一个FBO并绑定到OpenGLES上下文;
  2. 创建并绑定颜色附件、深度附件和模板附件;
  3. 进行渲染操作,绘制到FBO中的附件;
  4. 在需要时,将FBO的附件纹理或者渲染缓冲对象用作输入进行后续处理;
  5. 最后,将FBO解绑并恢复默认的帧缓冲;

4. FBO 实现渲染到纹理

如果纹理被附着到 FBO 的颜色缓冲区就可以实现渲染到纹理,FBO实现离屏渲染的步骤如下:

  1. 创建一个FBO对象,将其绑定到OpenGLES上下文中;
GLuint fbo;
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
  1. 创建一个纹理对象,并将其绑定为FBO的颜色附件;
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);      //这里最后一个参数是NULL ,很重要
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);         //GL_COLOR_ATTACHMENT0是FBO的颜色附件,它是一个内置枚举常量,指定了FBO中可用的颜色附件的编号。在OpenGLES中,可以将多个颜色附件绑定到同一个FBO上,使用GL_COLOR_ATTACHMENT0、GL_COLOR_ATTACHMENT1、GL_COLOR_ATTACHMENT2等常量来分别表示不同的颜色附件
  1. 为FBO创建一个深度附件或者模板附件,如果需要的话(在这里这一步可以不需要,只用到了颜色附件)
GLuint depthBuffer;
glGenRenderbuffers(1, &depthBuffer);
glBindRenderbuffer(GL_RENDERBUFFER, depthBuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthBuffer);
  1. 检查FBO帧缓冲的完整性
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE) {// 帧缓冲不完整,处理错误
}
  1. 进行渲染到纹理操作,即在FBO上进行渲染绘制
// 渲染之前需要将FBO绑定
glBindFramebuffer(GL_FRAMEBUFFER, fbo);// 渲染操作
glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// 进行绘制操作// 渲染结束后需要将FBO解绑
glBindFramebuffer(GL_FRAMEBUFFER, 0);
  1. 将渲染结果从FBO中读取到CPU内存或进行纹理贴图上屏显示
// 读取FBO中的颜色附件数据到CPU内存
glReadBuffer(GL_COLOR_ATTACHMENT0);
GLubyte* data = new GLubyte[width * height * 4];
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data);// 渲染到屏幕
glBindFramebuffer(GL_FRAMEBUFFER, 0);                //FBO解绑
glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// 设置顶点和纹理坐标数组
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, vVertices);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, vtexcoords);
glEnableVertexAttribArray(1);textureLocation = glGetUniformLocation(shaderProgram, "uTexture");
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
glUniform1i(textureLocation, 0);glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
  1. 在完成所有的操作后,需要释放FBO和相关的附件资源
glDeleteFramebuffers(1, &fbo);
glDeleteTextures(1, &texture);

5. FBO 实现离屏渲染

如果渲染缓冲区对象RBO被附着到 FBO 的颜色缓冲区, 就可以实现离屏渲染,离屏渲染的步骤同渲染到纹理的步骤类似:

  1. 创建一个FBO对象,将其绑定到OpenGLES上下文中;
GLuint fbo;
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
  1. 创建一个渲染缓冲对象RBO,并将其绑定为FBO的颜色附件;
GLuint rbo;
glGenRenderbuffers(1, &rbo);
glBindRenderbuffer(GL_RENDERBUFFER, rbo);
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA, width, height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
  1. 为FBO创建一个深度附件或者模板附件,如果需要的话(在这里这一步可以不需要,只用到了颜色附件);
  2. 检查帧缓冲FBO的完整性;
  3. 进行渲染操作,将渲染结果存储到渲染缓冲对象中;
  4. 渲染完成后,解绑帧缓冲对象;

二、FBO 实现渲染到纹理的代码实例

以下代码实例实现了渲染到纹理到效果,将纯蓝色的图像渲染到一个640x480 大小的纹理中,然后将该纹理进行纹理贴图操作上屏显示;

1. egl_wayland_texture3_2.c

代码如下(示例):

#include <wayland-client.h>
#include <wayland-server.h>
#include <wayland-egl.h>
#include <EGL/egl.h>
#include <GLES3/gl
http://www.lryc.cn/news/302859.html

相关文章:

  • 基于 RisingWave、Instaclustr 和 Apache Superset 对维基百科实时监控
  • 建站用帝国CMS好还是WordPress好
  • 深度学习基础之《TensorFlow框架(2)—图》
  • Web3区块链游戏:创造虚拟世界的全新体验
  • 单机启动/开机启动SpringBoot服务的正确方式
  • [C#]winform基于opencvsharp结合CSRNet算法实现低光图像增强黑暗图片变亮变清晰
  • 抓包分析 TCP 协议
  • 代码随想录算法训练营day27 | 93.复原IP地址、78.子集、90.子集II
  • RuntimeError: CUDA out of memory.【多种场景下的解决方案】
  • LeetCode刷题| Leetcode 45. 跳跃游戏,1190. 反转每对括号间的子串,781. 森林中的兔子,739. 每日温度
  • Redis(03)——发布订阅
  • ⭐北邮复试刷题LCR 034. 验证外星语词典__哈希思想 (力扣119经典题变种挑战)
  • ECMAScript 6+ 新特性 ( 二 )
  • JS游戏项目合集【附源码】
  • React中hooks使用限制及保存函数组件状态
  • 用git命令来上传项目到GitHub我自己的仓库
  • .NET有哪些微服务框架
  • uniapp中打开蓝牙需要哪些权限
  • virtualbox虚拟机运行中断,启动报错“获取 VirtualBox COM 对象失败”
  • 【JVM篇】什么是运行时数据区
  • Jetpack 之Glance+Compose实现一个小组件
  • 实时矢量搜索如何彻底改变各行各业?
  • 【Linux】指令 【scp】
  • 文件IO,目录IO的学习
  • leetcode(动态规划)53.最大子数组和(C++详细解释)DAY12
  • BUGKU-WEB bp
  • 代码的复用——Mixin使用例子
  • easyx 枪声模拟器
  • python 与 neo4j 交互(py2neo 使用)
  • Python基础笔记11