上一篇文章Camera 采集数据通过 textureview 预览,手动对焦、自动对焦 (一)中使用了textureView进行预览,但是如果想做更多的功能,比如说增加水印、滤镜、离屏渲染等等,这使用GLSurfaceView预览更加合适,所以这篇文章是在上一篇的代码的基础上进行修改替换,并且这里不介绍GLSurfaceView和Android GLES的相关知识。(附带源码)
自定义继承自GLSurfaceView的CameraGLSurfaceView
GLSurfaceView 继承自SurfaceView,都有自己独立的绘制线程,不一样的是Surfaceview是独立的线程在画布上绘制,而GLSurfaceView是GLThread绘制在独立的Surface,并且自己默认创建EGL上下文环境,利用了GPU的能力。
1. 初始化
private void init(Context context) {
setEGLContextClientVersion(2);// 设置EGL的版本,一定要设置
mRender = new CameraGLSufaceRender(context, this); // 自定义的渲染器
setRenderer(mRender);
setRenderMode(RENDERMODE_WHEN_DIRTY);// 绘制模式
}
绘制模式有两种:RENDERMODE_WHEN_DIRTY(按需渲染:调用requestRender才会渲染)、RENDERMODE_CONTINUOUSLY(持续渲染)
自定义Render
CameraGLSufaceRender继承自GLAbstractRender,GLAbstractRender也是自己定义的继承自GLSurfaceView.Renderer的抽象类,用来封装一些GLES常用的方法,例如加载链接着色器等等。
1. 生命周期
GLSurfaceView.Renderer有三个生命周期:
void onSurfaceCreated(GL10 gl10, EGLConfig eglConfig);// surface创建完成
void onSurfaceChanged(GL10 gl10, int width, int height);// surface尺寸发生变化
void onDrawFrame(GL10 gl10);// surface的绘制工作(我们关注的主要部分)
2. 结合Render的生命周期做工作流程
(1)加载顶点着色器、片元着色器
@Override
protected String getVertexSource() {
final String source = "attribute vec4 av_Position; " +
"attribute vec2 af_Position; " +
"varying vec2 v_texPo; " +
"void main() { " +
" v_texPo = af_Position; " +
" gl_Position = av_Position; " +
"}";
return source;
}
@Override
protected String getFragmentSource() {
final String source = "#extension GL_OES_EGL_image_external : require \n" +
"precision mediump float; " +
"varying vec2 v_texPo; " +
"uniform samplerExternalOES s_Texture; " +
"void main() { " +
" gl_FragColor = texture2D(s_Texture, v_texPo); " +
"} ";
return source;
}
- 我们使用的外部的camera的外部纹理,所以这里用的不是sampler2D 而是samplerExternalOES
- 记得
#extension GL_OES_EGL_image_external : require
(2)创建program,链接顶点、片元着色器
protected void createProgram() {
mVertexShader = loadShader(GLES20.GL_VERTEX_SHADER, getVertexSource());
mFragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, getFragmentSource());
mProgram = GLES20.glCreateProgram();
GLES20.glAttachShader(mProgram, mVertexShader);
GLES20.glAttachShader