• Opengl ES之FBO


    FBO介绍

    FBO帧缓冲对象,它的主要作用一般就是用作离屏渲染,例如做Camera相机图像采集进行后期处理时就可能会用到FBO。假如相机出图的是OES纹理,为了方便后期处理,
    一般先将OES纹理通过FBO转换成普通的2D纹理,然后再通过FBO等增加美颜等其他各种特效滤镜,最后将FBO一路流送进编码器进行编码,另外一路渲染到屏幕上进行预览显示。

    FBO总结起来就是可以暂时将未处理完的帧不直接渲染到屏幕上,而是渲染到离屏Buffer中缓存起来,在恰当的时机再取出来渲染到屏幕。

    FBO(Frame Buffer Object)帧缓冲对象提供了与颜色缓冲区(color buffer)、深度缓冲区(depth buffer)和模版缓冲区(stencil buffer) ,但并不会直接为这些缓冲区分配空间,而只是为这些缓冲区提供一个或多个挂接点。我们需要分别为各个缓冲区创建对象,申请空间,然后挂接到相应的挂接点上。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lLg73qy1-1664416288414)(https://flyer-blog.oss-cn-shenzhen.aliyuncs.com/FBO%E6%8C%82%E8%BD%BD%E7%82%B9.png)]

    从上图可以看出FBO中包含了:

    1. 多个颜色附着点(GL_COLOR_ATTACHMENT0、GL_COLOR_ATTACHMENT1…)
    2. 一个深度附着点(GL_DEPTH_ATTACHMENT)
    3. 一个模板附着点(GL_STENCIL_ATTACHMENT)

    所谓的颜色附着(纹理附着)就是用于将颜色渲染到纹理中去的意思。后面我们主要介绍FBO的颜色附着。

    如何使用FBO

    1. 使用函数glGenFramebuffers生成一个FBO对象,保存对象ID。
    2. 使用函数glBindFramebuffer绑定FBO。
    3. 使用函数glFramebufferTexture2D关联纹理和FBO,并执行渲染步骤。后续如果需要使用FBO的效果时只需要操作与FBO绑定的纹理即可。
    4. 使用函数glBindFramebuffer解绑FBO,一般在Opengl中ID参数传递0就是解绑。
    5. 使用函数glDeleteFramebuffers删除FBO。

    当挂接完成之后,我们在执行FBO下面的操作之前,可以检查一下FBO的状态,使用函数GLenum glCheckFramebufferStatus(GLenum target)检查。

    本着学以致用的原则,我们将结合之前的文章,例如纹理贴图、VBO/VAO、EBO等相关知识点,使用这些知识点结合FBO绘制做一个实践的例子:首先将纹理渲染到FBO上去,然后再将FBO的纹理渲染到屏幕上。

    插个话。。。总有人盗用不贴原文链接,看看是谁。。。

    首先上代码,然后我们挑重要的稍微解读一下:
    FBOOpengl.h

    class FBOOpengl:public BaseOpengl{
    
    public:
        FBOOpengl();
        void onFboDraw();
        virtual ~FBOOpengl();
        // override要么就都写,要么就都不写,不要一个虚函数写override,而另外一个虚函数不写override,不然可能编译不过
        virtual void onDraw() override;
        virtual void setPixel(void *data, int width, int height, int length) override;
    private:
        void fboPrepare();
        GLint positionHandle{-1};
        GLint textureHandle{-1};
        GLuint vbo{0};
        GLuint vao{0};
        GLuint ebo{0};
        // 本身图像纹理id
        GLuint imageTextureId{0};
        // fbo纹理id
        GLuint fboTextureId{0};
        GLint textureSampler{-1};
        GLuint fboId{0};
        // 用于fbo的vbo和vao  也可以用数组的形式,这里为了方便理解先独立开来
        GLuint fboVbo{0};
        GLuint fboVao{0};
        int imageWidth{0};
        int imageHeight{0};
    };
    

    注意:override作为现代C++的一个关键字,使用的时候需要注意一点,要么就整个类的虚函数都用,要么整个类的虚函数都不用,不要一个虚函数用override修饰,另外一个虚函数又不用override关键字修饰,不然很有可能会编译不过的。

    在FBOOpengl中为了区分屏幕渲染和FBO离屏渲染,我们声明了两套VAO和VBO。

    FBOOpengl.cpp

    #include "FBOOpengl.h"
    #include "../utils/Log.h"
    
    // 顶点着色器
    static const char *ver = "#version 300
  • 相关阅读:
    Zip密码忘记了,如何破解密码?
    方案:AI赋能,森林防火可视化智能监管与风险预警系统解决方案
    详解Web应用安全系列(2)注入漏洞之XSS攻击
    多模态训练如何平衡不同模态
    基于Hadoop的学习行为数据云存储平台的设计与实现
    我的第一个Servlet程序,并理解浏览器和代码如何关联在一起
    Proteus中如何使用Arduino实现 ST7735显示屏十六宫格拼图游戏
    软考高级信息系统项目管理师系列之:信息系统项目管理师论文评分参考标准
    一篇学通Axios
    音频语言学习领域数据集现状、分类及评估
  • 原文地址:https://blog.csdn.net/u012944685/article/details/127101529