共享texture(surfacetexture) 实现 滤镜实时效果(TextureView)预览 + GLSurfaceView 预览
1. 创建 一个 纹理
2. 根据相机框架结构, 设置 Surface
3.
1. 以一个SurfaceTexture作为接收相机预览数据的载体,这个SurfaceTexture就是处理器的输入。
2.SurfaceView、TextureView或者是Surface,提供SurfaceTexture或者Surface给处理器作为输出,来接收处理结果。
重点就是处理器了。处理器利用GLSurfaceView提供的GL环境,以相机数据作为输入,进行处理,处理的结果渲染到视图提供的输出点上,
而不是GLSurfaceView内部的Surface上。当然,也可以不用GLSurfaceView,自己利用EGL来实现GL环境,问题也不大。具体实现就参照GLSurfaceView的源码来了。
//这句是必要的,避免GLSurfaceView自带的Surface影响渲染
getHolder().addCallback(null);
//指定外部传入的surface为渲染的window surface
setEGLWindowSurfaceFactory(new GLSurfaceView.EGLWindowSurfaceFactory() {
@Override
public EGLSurface createWindowSurface(EGL10 egl, EGLDisplay display, EGLConfig
config, Object window) {
//这里的surface由外部传入,可以为Surface、SurfaceTexture或者SurfaceHolder
return egl.eglCreateWindowSurface(display,config,surface,null);
}
@Override
public void destroySurface(EGL10 egl, EGLDisplay display, EGLSurface surface) {
egl.eglDestroySurface(display, surface);
}
});
另外,GLSurfaceView的GL环境是受View的状态影响的,比如View的可见与否,创建和销毁,等等。我们需要尽可能的让GL环境变得可控。因此,GLSurfaceView有两个方法一顶要暴露出来:
public void attachedToWindow(){
super.onAttachedToWindow();
}
public void detachedFromWindow(){
super.onDetachedFromWindow();
}
这里就又有问题了,因为GLSurfaceView的onAttachedToWindow和onDetachedFromWindow是需要保证它有parent的。所以,在这里必须给GLSurfaceView一个父布局。
//自定义的GLSurfaceView
mGLView=new GLView(mContext);
//避免GLView的attachToWindow和detachFromWindow崩溃
new ViewGroup(mContext) {
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
}
}.addView(mGLView);
另外,GLSurfaceView的其他设置:
setEGLContextClientVersion(2);
setRenderer(TextureController.this);
setRenderMode(RENDERMODE_WHEN_DIRTY);
setPreserveEGLContextOnPause(true);
这样就可以使用GLSurfaceView来提供GL环境,给指定的Surface或者SurfaceTexture渲染图像了。