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);
}
  • 可以为创建的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);
}

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

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

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

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: OpenGLES 3.0是一个用于移动设备的图形渲染API,可以用来渲染3D图形和动画。要实现视频数据离屏渲染,可以按照以下步骤: 1.创建一个FBO(Frame Buffer Object)。FBO是一个特殊的OpenGL对象,它可以将渲染结果存储到一个纹理或者渲染缓冲区中。 2.创建一个纹理对象,用来存储渲染结果。将纹理对象作为FBO的颜色附件绑定到FBO上。 3.将FBO绑定到OpenGL上下文中。 4.创建一个渲染程序(Program),用于将视频数据渲染FBO中。该渲染程序应该包含一个顶点着色器(Vertex Shader)和一个片元着色器(Fragment Shader)。 5.将视频数据上传到纹理对象中。 6.设置顶点和纹理坐标,将视频数据渲染FBO中。 7.将FBOOpenGL上下文中解绑。 8.从纹理对象中获取渲染结果数据。 9.销毁FBO、纹理对象和渲染程序。 以上步骤需要使用OpenGL ES 3.0的相关函数和常量进行操作,具体实现可以参考OpenGL ES 3.0的相关文档和示例代码。 ### 回答2: OpenGLESOpenGL for Embedded Systems)是一种针对嵌入式系统的2D和3D图形API。OpenGLES 3.0OpenGLES的一个版本,它引入了更多的功能和更高的性能,以满足现代移动设备和嵌入式系统对图形渲染的需求。 要实现为视频数据进行离屏渲染,首先需要获取视频数据。可以通过各种方式获取视频数据,例如从文件中读取、网络传输等等。获取到视频数据后,就可以进行渲染操作了。 接下来,需要创建一个离屏渲染的环境。在OpenGLES中,可以通过创建一个离屏帧缓冲对象(FBO)来实现离屏渲染离屏帧缓冲对象可以将渲染结果存储在纹理或渲染缓冲中。 创建离屏帧缓冲对象后,需要将其绑定为当前的渲染目标。这样,所有的渲染操作将会在离屏帧缓冲对象中进行,而不是直接渲染到屏幕上。可以使用glBindFramebuffer函数来绑定离屏帧缓冲对象。 一旦离屏帧缓冲对象被绑定,就可以通过OpenGL ES渲染管线来进行渲染操作了。可以使用顶点缓冲对象、着色器程序和纹理等来设置渲染的属性和效果。可以使用glDrawArrays或glDrawElements函数来执行渲染操作。 渲染完成后,可以将离屏帧缓冲对象中的渲染结果存储在纹理中,或者将其拷贝到其他地方,例如内存或文件中。可以使用glFramebufferTexture2D或glReadPixels函数来实现这些操作。 最后,需要清除和释放离屏渲染使用的资源,例如离屏帧缓冲对象、纹理和顶点缓冲对象等。可以使用glDeleteFramebuffers、glDeleteTextures和glDeleteBuffers函数来释放相应的资源。 通过以上步骤,就可以使用OpenGLES 3.0实现为视频数据进行离屏渲染。这样可以将渲染结果用于后续的处理、保存或显示等用途。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值