之前的博客opengl 离屏渲染,实现相机的实时滤镜讲到过离屏渲染,主要是android层的应用,这里在jni层来实现,并来讲解下原理,以及和android层的不同的地方。

#extension GL_OES_EGL_image_external : requireuniform samplerExternalOES vTexture;

 

opengl离屏渲染

平时我们设置shader,然后draw是将我们的纹理图像绘制到了系统默认的0号frambuffer中,这个buffer用户是读取不到的,只是用来显示渲染用。因此为了离屏渲染,我们需要自己创建frambuffer,当然我们自己创建的frambuffer是可以读取到里面的colorbuffer的,即texure。

创建frambuffer

glGenFramebuffers(1 , &fboObject);

这样创建了frambuffer我们还不能用来绑定,因为frambuffer得含有三部分:

colorBuffer:即所谓的texture的buffer

创建和纹理的创建一样:

void CreateTexture2D( GLuint* textures ,int number ,unsigned char *pixelData, int width, int height ,GLenum type){    glGenTextures(number ,textures);    for(int i=0 ;i< number ; i++) {        glBindTexture(GL_TEXTURE_2D, textures[i]);        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);// 表示图像放大时候,使用线性过滤        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);// 表示图像缩小时候,使用线性过滤        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);        glTexImage2D(GL_TEXTURE_2D, 0, type, width, height, 0, type, GL_UNSIGNED_BYTE,                     pixelData);//GL_RGBA        glBindTexture(GL_TEXTURE_2D, 0);    }}

depthBuffer:只让opengl读取,用户无法读取,但还是得创建

stencilBuffer:模板buffer,同样只有opengl读取,但也得创建。

其中后面的2个buffer,组成RenderBuffer,RenderBuffer第一个为depthbuffer,第二个为stencilBuffer

创建2个buffer,只需要创建RenderBuffer

    //生成renderbuffer    glGenRenderbuffers(1, &rbo);    glBindRenderbuffer(GL_RENDERBUFFER,rbo);    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, width, height);    glBindRenderbuffer(GL_RENDERBUFFER, 0);    // 挂载 depth buffer fbo上    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbo);    //挂载stencil buffer fbo上    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo);

node:这里的width和height都为纹理渲染的大小,若renderbuffer中的glRenderbufferStorage小了,可能导致图像纹理显示不全。

使用frambuffer

创建好了renderBuffer 和 colorbuffer后,调用下面函数就可以bind frambuffer,然后我们渲染的图像就会会知道我们定义的framebuffer中,屏幕将不会显示我们的图片,这时候如果调用filter,即其他的图像处理shader,处理我们定义的frambuffer中的colorbuffer,即texture, 就可以达到多次处理的效果了。

void fbo::bind(){    glBindFramebuffer(GL_FRAMEBUFFER , fboObject);    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,colorBuffer[(currentColorBufferIndex + 1)%2],0);    currentColorBufferIndex = (currentColorBufferIndex + 1)%2;    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbo);    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo);}

解除frambuffer

void fbo::unBind() {    glBindRenderbuffer(GL_RENDERBUFFER, 0);    glBindFramebuffer(GL_FRAMEBUFFER, 0);}

这里给出demo,给大家参考。

更多相关文章

  1. 【Android】上传代码至JCenter
  2. 设置Android(安卓)Studio工程布局文件的默认布局
  3. [Android]如何创建一个View的分割线
  4. Android(安卓)使用ExoPlayer视频播放 (一)
  5. Android中文件与文件夹的创建(file)
  6. android之微信分享图片
  7. android模拟器创建报错: PANIC: Could not open:.... 错误的解决
  8. 掌阅Android(安卓)App插件补丁实践(ZeusPlugin)
  9. Android(安卓)官方推荐 : DialogFragment 创建对话框

随机推荐

  1. sql分组后二次汇总(处理表重复记录查询和
  2. SQL去除重复记录(七种)
  3. java连接mysql数据库 java连接sql server
  4. Sql Server 2012完全卸载方法 只需8步轻
  5. SQL Server 聚焦存储过程性能优化、数据
  6. SQL查询中需要使用别名问题
  7. sql server2016里面的json功能浅析
  8. SQL Server 2012开窗函数
  9. SQL Server 2012 多表连接查询功能实例代
  10. CentOS 7.3上SQL Server vNext CTP 1.2安