本文主要记录个人对OpenGL里FBO的理解,附上测试事例
测试源码: github
FBO : Frame Buffer Object, 是一个存储一帧数据的容器。

原理这里不介绍,(主要我也没怎么看懂),使用FBO的步骤:
- 使用FBO的步骤
- 创建 glGenFramebuffers()
- 绑定 glBindFramebuffer()
- (这里使用绑定texture2D), glFramebufferTexture2D()把一幅纹理图像关联到一个FBO
- 检查FBO状态 glCheckFramebufferStatus()
这里使用的FBO与Texture一起绑定使用,OpenGL的绘制是如果我们绑定了Framebuffer即glBindFramebuffer(),openGL的绘制内容会绘制到framebuffer里,绑定framebuffer和texture,是为了通过绑定的texture从frambuffer里拿数据
基本生成frambuffer和绑定texture代码:

int[] frameBuffer = new int[1];int[] frameBufferTexture = new int[1];// generate frame bufferGLES20.glGenFramebuffers(1, frameBuffer, 0);GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, frameBuffer[0]);// generate textureGLES20.glGenTextures(1, frameBufferTexture, 0);GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, frameBufferTexture[0]);// 绑定一个空的glTexImage2D,方便framebuffer 填充数据GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, width, height, 0,        GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, null);GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);// set texture as colour attachmentGLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0,        GLES20.GL_TEXTURE_2D, frameBufferTexture[0], 0);// unbindGLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);GLES20.glBindRenderbuffer(GLES20.GL_RENDERBUFFER, 0);GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);

使用framebuffer 绘制两个滤镜,如何通过滤镜绘制图片略过
绘制之前需要绑定framebuffer,让openGL绘制到framebuffer,绘制完成后解除绑定,伪代码

// bind framebufferGLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, mFrameBufferId);// draw....// unbind framebufferGLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);

测试代码对比了方案一和方案二的时间,结果如下,可以看懂性能提升很明显

方案二的基本代码

private void showImageFilter2(Bitmap bmp, GLESBackEnv backEnv) {    int w =bmp.getWidth();    int h =bmp.getHeight();    NoFilter noFilter = new NoFilter();    noFilter.setBitmap(bmp);    noFilter.onCreate();    noFilter.onSizeChange(w, h);    // bind framebuffer    FrameBuffer buffer = new FrameBuffer();    buffer.create(w, h);    buffer.beginDrawToFrameBuffer();    noFilter.onDrawFrame();    buffer.endDrawToFrameBuffer();    // image filter 2, use textureId form framebuffer    ColorFiler colorFiler = new ColorFiler(ColorFiler.Filter.GRAY);    colorFiler.setTextureId(buffer.getTextureId());    colorFiler.onCreate();    colorFiler.onSizeChange(w, h);    float[] coord=new float[]{            0.0f, 1.0f,            0.0f, 0.0f,            1.0f, 1.0f,            1.0f, 0.0f,    };    colorFiler.setTexBuffer(coord);    colorFiler.onDrawFrame();    bmp = backEnv.getBitmap();    imageFilter2.setImageBitmap(bmp);    buffer.release(true);}

这里有个需要主意的是,bitmap的数据是从第一行开始存储, 而处理framebuffer 数据需要上下颠倒一下。
效果图

总结起来,FBO就是用来缓存opengl绘制的结果,通过绑定framebuffer和 textureId, 可以之间通过绑定的textureId获取绘制后的结果,可以方便我们更好的使用。

更多相关文章

  1. Android(安卓)SurfaceView onDraw()绘图问题
  2. Android中view绘制常用知识
  3. 图像滤镜(GPUImage/GPU加速)、美化/图像处理技术 拼接及Skia- An
  4. Android中的Data Binding初探 (一)
  5. android之Android(安卓)Studio下自定义属性的定义和使用
  6. Android(安卓)ColorDrawable那些事
  7. Android中实现iPhone开关
  8. Android(安卓)生成长图并添加水印(一)
  9. Android(安卓)页面手势滑动

随机推荐

  1. android的位置服务和地图
  2. Android(安卓)5.0新特性之Material Desig
  3. Android(安卓)调用系统相机拍照并获取图
  4. SharedPreferences 简介
  5. Android(安卓)ramdisk.img system.img us
  6. 使用 Annotation 改善 Android(安卓)代码
  7. Android(安卓)UI Libs之CircleImageView
  8. android avd 键盘上的对应键
  9. android4.2 长按POWER键3秒关机
  10. Android进阶之大话设计模式