前言
本文主要介绍 如何在 opengles 中使用FBO 实现渲染到纹理的功能
软硬件环境:
硬件:PC
软件:ubuntu22.04 opengles3.0 egl1.4
一、FBO介绍
1. FBO 简介
FBO(Framebuffer Object)是OpenGL的一个扩展,它允许我们将渲染结果直接绘制到一个纹理或者渲染缓冲对象中,而不是默认的帧缓冲。
使用FBO可以实现一些高级的渲染技术,如离屏渲染、后期处理、抗锯齿等。它提供了一个独立于窗口的帧缓冲对象,可以将渲染的结果存储到纹理或者渲染缓冲对象中,并且可以在后续的渲染中作为输入来进行处理。
2. FBO的关键组成部分
- Color Attachment:用于存储颜色信息的附件,可以是纹理或者渲染缓冲对象;
- Depth Attachment:用于存储深度信息的附件,也可以是纹理或者渲染缓冲对象;
- Stencil Attachment:用于存储模板信息的附件,同样可以是纹理或者渲染缓冲对象;
3. FBO的基本工作流程
- 创建一个FBO并绑定到OpenGLES上下文;
- 创建并绑定颜色附件、深度附件和模板附件;
- 进行渲染操作,绘制到FBO中的附件;
- 在需要时,将FBO的附件纹理或者渲染缓冲对象用作输入进行后续处理;
- 最后,将FBO解绑并恢复默认的帧缓冲;
4. FBO 实现渲染到纹理
如果纹理被附着到 FBO 的颜色缓冲区就可以实现渲染到纹理,FBO实现离屏渲染的步骤如下:
- 创建一个FBO对象,将其绑定到OpenGLES上下文中;
GLuint fbo;
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
- 创建一个纹理对象,并将其绑定为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等常量来分别表示不同的颜色附件
- 为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);
- 检查FBO帧缓冲的完整性
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE) {
// 帧缓冲不完整,处理错误
}
- 进行渲染到纹理操作,即在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);
- 将渲染结果从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);
- 在完成所有的操作后,需要释放FBO和相关的附件资源
glDeleteFramebuffers(1, &fbo);
glDeleteTextures(1, &texture);
5. FBO 实现离屏渲染
如果渲染缓冲区对象RBO被附着到 FBO 的颜色缓冲区, 就可以实现离屏渲染,离屏渲染的步骤同渲染到纹理的步骤类似:
- 创建一个FBO对象,将其绑定到OpenGLES上下文中;
GLuint fbo;
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
- 创建一个渲染缓冲对象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);
- 为FBO创建一个深度附件或者模板附件,如果需要的话(在这里这一步可以不需要,只用到了颜色附件);
- 检查帧缓冲FBO的完整性;
- 进行渲染操作,将渲染结果存储到渲染缓冲对象中;
- 渲染完成后,解绑帧缓冲对象;
二、FBO 实现渲染到纹理的代码实例
以下代码实例实现了渲染到纹理到效果,将纯蓝色的图像渲染到一个640x480 大小的纹理中,然后将该纹理进行纹理贴图操作上屏显示;文章来源:https://www.toymoban.com/news/detail-829736.html
1. egl_wayland_texture3_2.c
代码如下(示例):文章来源地址https://www.toymoban.com/news/detail-829736.html
#include <wayland-client.h>
#include <wayland-server.h>
#include <wayland-egl.h>
#include <EGL/egl.h>
#include <GLES3/gl
到了这里,关于wayland(xdg_wm_base) + egl + opengles 使用FBO渲染到纹理实例(六)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!