opengl fbo 离屏渲染
之前的博客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,给大家参考。
更多相关文章
- 【Android】上传代码至JCenter
- 设置Android(安卓)Studio工程布局文件的默认布局
- [Android]如何创建一个View的分割线
- Android(安卓)使用ExoPlayer视频播放 (一)
- Android中文件与文件夹的创建(file)
- android之微信分享图片
- android模拟器创建报错: PANIC: Could not open:.... 错误的解决
- 掌阅Android(安卓)App插件补丁实践(ZeusPlugin)
- Android(安卓)官方推荐 : DialogFragment 创建对话框