Android OpenGL ES 二 、 FBO 离屏渲染

Android OpenGL ES 二 、 FBO 离屏渲染1 什么是 FBO2 FBO 还需相关对象来辅佐 Shader 原纹理 texture 输出纹理 texture fbo 纹理 2 1 如何创建 FBOprivatein intwidth

大家好,欢迎来到IT知识分享网。

一、 FBO 相关

1.1    什么是 FBO

FBO(Frame Buffer Object)即帧缓冲区对象,用于离屏渲染缓冲, 实际上是一个可添加缓冲区的容器,

相对于其它同类技术,如数据拷贝或交换缓冲区等,使用FBO技术会更高效并且更容易实现。而且FBO不受窗口大小限制。FBO可以包含许多颜色缓冲区,可以同时从一个片元着色器写入

重要:

FBO是一个容器,自身不能用于渲染,需要与一些可渲染的缓冲区绑定在一起,像纹理或者渲染缓冲区

所以可以给他添加添加纹理(Texture )或渲染缓冲区对象(RBO)

它仅且提供了 3 个附着(Attachment):颜色附着、深度附着、模板附着。

渲染方式

 

1.2   为什么要使用 FBO

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

另一种方式是通过使用连接到纹理的 pbuffer 来实现渲染到纹理,但是与上下文和窗口系统提供的可绘制表面切换开销也很大。因此,引入了帧缓冲区对象 FBO 来解决这个问题。

OpenGL ES 开发中,经常使用 GLSurfaceView 将绘制结果显示到屏幕上(或者自己创建GL环境,绘制在 SurfaceView或者 TextureView上)。

1.提高渲染效率(后台绘制没有展示到窗口上)
2.避免闪屏
3.可以很方便的实现纹理共享等。

但是,也有许多场景不需要渲染到屏幕上,如利用 GPU 在后台完成一些图像转换、缩放等耗时操作,这个时候利用 FBO 可以方便实现类似需求。

 

1.3   使用FBO 的场景

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

Camera 美颜、滤镜、贴纸等功能。

 

二、API了解

Android OpenGL ES 二 、 FBO 离屏渲染

 2.1 生成纹理 ,第一个参数为需要的纹理数,第二个参数为存储获得的纹理ID的数组,第三个参数为数组的起始位置。 

//创建一个 2D 纹理用于连接 FBO 的颜色附着 GLES20.glGenTextures(int size,int[] textures,int start) 其C为void glGenTextures(GLsizei n,GLuint * textures);

 2.2 生成 FrameBuffer

GLES20.glGenFrameBuffers

 2.3 生成RenderBuffers

GLES20.glGenRenderBuffers

 2.4 设置FBO分配内存大小

 //2d图形,图层层级0,rgba,宽,高,0,rgba,无符号字节类型,null只分配大小 GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, 720, 1280, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, null); 

2.5  绑定、设置纹理参数 (2种纹理类型)

  (1)—– 设置纹理参数 扩展纹理 ——–

---------- 必须首先绑定纹理, 让GPU知道给谁设置 ------------ GLES20.glGenTextures(1, texture, 0); // GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, texture[0]); //设置 纹理参数 GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_LINEAR); GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR); GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE); GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE);

  (2)—- 设置纹理参数(2D 纹理的设置)  —-

---------- 必须首先绑定纹理, 让GPU知道给谁设置 ------------ GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texture[0]); //设置缩小过滤为使用纹理中坐标最接近的一个像素的颜色作为需要绘制的像素颜色 GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER,GLES20.GL_NEAREST); //设置放大过滤为使用纹理中坐标最接近的若干个颜色,通过加权平均算法得到需要绘制的像素颜色 GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER,GLES20.GL_LINEAR); //设置环绕方向S,截取纹理坐标到[1/2n,1-1/2n]。将导致永远不会与border融合 GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S,GLES20.GL_CLAMP_TO_EDGE); //设置环绕方向T,截取纹理坐标到[1/2n,1-1/2n]。将导致永远不会与border融合 GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T,GLES20.GL_CLAMP_TO_EDGE);

 2.6 使用纹理

 GLES20.glActiveTexture选择当前活跃的纹理单元。默认情况下当前活跃的纹理单元为GLES20.GL_TEXTURE0

选择当前活跃的纹理单元。默认情况下当前活跃的纹理单元为GLES20.GL_TEXTURE0 GLES20.glActiveTexture(GLES20.GL_TEXTURE0); //绑定2D纹理 GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mtextureID); //将纹理设置给Shader GLES20.glUniform1i(mHTexture,1);

 

三、 FBO的创建  并绑定 纹理

Render Buffer Object(RBO): 即为渲染缓冲对象,分为color buffer(颜色)、depth buffer(深度)、stencil buffer(模板)。 
在使用FBO做离屏渲染时,可以只绑定纹理,也可以只绑定Render Buffer,也可以都绑定或者绑定多个,视使用场景而定。如只是对一个图像做变色处理等,只绑定纹理即可。如果需要往一个图像上增加3D的模型和贴纸,则一定还要绑定depth Render Buffer。 
同Texture使用一样,FrameBuffer使用也需要调用GLES20.glGenFrameBuffers生成FrameBuffer,然后在需要使用的时候调用GLES20.glBindFrameBuffer

3.1 FrameBuffer的创建,Texture的创建及参数设置,代码如下:

 int[] fFrame= new int[1]; int[] textures= new int[1]; //---- 创建 FBO -------------------------------- GLES20.glGenFramebuffers(1, fFrame, 0

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/138487.html

(0)
上一篇 2024-11-23 18:15
下一篇 2024-11-23 18:26

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信