• Android OpenGL ES 3.0 FBO 离屏渲染


    1.什么是FBO

    FBO:Frame Buffer Object,即帧缓冲区对象,实际上是一个可添加缓冲区的容器,可以为其添加纹理和缓冲区对象。

    FBO本身不能用于渲染,只有添加了纹理或者渲染缓冲区之后才能作为渲染目标,仅提供三种附着,颜色附着、深度附着、模板附着。

    2.为什么使用FBO

    默认情况下,OpenGL ES 通过绘制到窗口系统提供的帧缓冲区,然后将帧缓冲区的对应区域复制到纹理来实现渲染到纹理,但是此方法只有纹理尺寸小于或者等于帧缓冲区尺寸才有效果。

    另外一种方式是通过连接到pBuffer来显示渲染到纹理,但是与上下文和窗口系统系统的表面切换开销也很大。

    在这个情况下引入了FBO帧缓冲区对象,Android OpenGL ES 开发中,一般使用 GLSurfaceView 将绘制结果显示到屏幕上**,然而在实际应用中,也有许多场景不需要渲染到屏幕上,如利用 GPU 在后台完成一些图像转换、缩放等耗时操作,这个时候利用 FBO 可以方便实现类似需求**。

    使用 FBO 可以让渲染操作不用再渲染到屏幕上而是渲染到离屏 Buffer 中,然后可以使用 glReadPixels 或者 HardwareBuffer 将渲染后的图像数据读出来,从而实现在后台利用 GPU 完成对图像的处理。

    3.FBO的使用

    使用FBO作为渲染目标,首先需要为FBO的附着添加连接对象,如颜色附着需要连接纹理或者渲染缓冲区的颜色缓冲区。

    3.1创建FBO
    void MSFrameBufferObject::CreateWithSize(int width, int height)
    {
    	//创建一个纹理,并设置纹理的环绕方式
        glGenTextures(1,&m_textureId);
        glBindTexture(GL_TEXTURE_2D, m_textureId);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    
        glBindTexture(GL_TEXTURE_2D, 0);
    	
        //创建并Bind FBO,
        glGenFramebuffers(1, &m_fboId);
        glBindFramebuffer(GL_FRAMEBUFFER, m_fboId);
        
         //将纹理图像附加到帧缓冲对象
        glBindTexture(GL_TEXTURE_2D, m_textureId);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,GL_TEXTURE_2D,m_textureId,0);
        //为纹理设置宽 高等
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,width,height,0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); 
    
    	//创建渲染缓冲区 深度缓冲
        glGenRenderbuffers(1, &m_depthBufferId);//创建深度或深度/模板renderbuffer
        glBindRenderbuffer(GL_RENDERBUFFER, m_depthBufferId);
        glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width,height); 		//将其附加到framebuffer的深度附件点。
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_depthBufferId);
    
        GLenum status = glCheckFramebufferStatus( GL_FRAMEBUFFER);
        if(status == GL_FRAMEBUFFER_COMPLETE) {
            LOGD("Framebuffer creation successful\n");
        } else {
            LOGD("Error creating framebuffer [status: %d]\n", status);
        }
    
        glBindRenderbuffer(GL_RENDERBUFFER,0);
        glBindFramebuffer(GL_FRAMEBUFFER, 0);
        glBindTexture(GL_TEXTURE_2D, 0);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 可以为创建的FBO指定宽、高
    • 创建2d纹理,将纹理图像附加到帧缓冲对象
    • 创建渲染缓冲区 深度缓冲,将其附加到framebuffer的深度附件点。
    3.2使用FBO
    void MSGLScene::PaintGL() {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
        m_pFBO->Bind();
    
        m_pMSYUVVideo->Render(m_pCamera);
        m_pModelLoader->Render(m_pCamera);
        m_pModelLoader->UpdateTracking(m_pCamera,m_trkPos,m_trkScale,m_nVideoW,m_nVideoH);
        m_pFBO->Release();
    
        m_pTextureRender->Render(m_pCamera,m_pFBO->GetTextureID());
    }
    //这个是Bind方法的内容
    void MSFrameBufferObject::Bind()
    {
        glBindFramebuffer(GL_FRAMEBUFFER,m_fboId);
    }
    //这个是FBO Release方法内容
    void MSFrameBufferObject::Release()
    {
        glBindFramebuffer(GL_FRAMEBUFFER,0);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    创建好FBO之后使用就非常简单了,只需要渲染之前进行Bind操作,渲染结束之后进行Release操作就行。

    中间渲染的内容是:相机的YUV数据以及添加的3D模型道具特效。

    进行OpenGL的封装也是学好的一个关键步骤,因为OpenGL繁杂的API,如果不进行封装很容产生混乱。

  • 相关阅读:
    C# 如何优雅的写代码[进阶篇]
    基于ROS和turtlebot2的多机器人导航定位配置记录
    Python基本语法
    在3台不联网的 CentOS 7.8 服务器上部署 Elasticsearch 6.8 集群
    Jenkins
    这个c++程序到底错在哪里了?
    用于机器学习的 Pandas(ML)
    用DIV+CSS技术设计的明星个人网站制作(基于HTML+CSS+JavaScript制作明星彭于晏网页)
    【JUC】1.CompletableFuture异步编程
    制造业企业防范勒索病毒攻击的一些建议措施
  • 原文地址:https://blog.csdn.net/u014078003/article/details/128016272