Android OpenGL ES从入门到进阶(五)—— 很好用的OpenGL ES特效渲染框架

框架源码:https://github.com/smzhldr/AGLFramework

一、前言

安卓中,OpenGL ES的开发有基本着固定的代码形式,为实现不同的功能,只需将shader编写好,按步就班的在代码中调用就可以了,但是OpenGL ES提供的API比较抽象,写起来不容易记忆,而且重复代码有可能较多。为了使用的更方便,我们简单的封装成一个库的形式,这在第一篇《五分钟开发一款美颜相机》 中已经简单使用过该框架,确实简单易用,以后所提到的功能实现,我们基本上都基于该框架实现。

二、框架目录一览


	AGLView-----------------继承自GLSurfaceView,显示OpenGL ES代码输出结果。
	AGLRenderer-------------继承自GLSurfaceView.Renderer,渲染逻辑控制器。
	ISource-----------------AGLRenderer输入源,包括视屏,图片等数据流。
	IFilter-----------------数据处理器,可有不同的实现,比如美颜功能,y由不同的处理Filter完	成,只需在AGLRenderer中调用不同的Filter就可完成不同的图像处理效果。
	OpenGlUtils-------------OPenGl ES代码编译使用工具类

有了上面这几个类,基本上这个框架就可以使用的,实现不同的功能只需要调用用不同的Filter就行,其他部分完全相同不用重写,这在开发效率上和代码层次上有很大帮助。

三、框架原理浅析

该框架继承GLSurfaceView,逻辑部分都在AGLRenderer中,而实现部分都在Filter层,逻辑如下:

 	@Override
    public void onDrawFrame(GL10 gl) {
        GLES20.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);

        runAll(runOnDraw);

        if (rendererSource != null) {
        	//生成每一帧的数据源
            IFilter.Frame frame = source.createFrame();

			//为元数据添加美颜,贴纸等特效
            if (filter != null && !disable) {
                frame = filter.draw(frame);
            }
            //将美化后的数据输出到屏幕
            if (outputFilter != null) {
                outputFilter.draw(frame);
            }
        }

        runAll(runOnDrawEnd);
    }

可以看出框架的原理很简单也很清晰,我们使用框架的重点就是编写好自己的filter就可以实现我们想要的特效了。

三、Filter的使用

花时间造这个框架(其实也不算啥框架)的目的是为了更方便,更直接的编写OpenGL的代码,而不是把时间花在OpenGL的使用环境搭建上,就像是画画的核心是画内容而不是调颜料,虽然调颜料也很重要。。。
filter的使用我们只需实现Ifilter接口就行,请看栗子:


public class MyFilter implements IFilter {

	/*
	* draw方法是每一帧都会调用的方法
	* 在draw中运行我们的OpenGL代码以达到特效处理功能
	*/
	public Frame draw(Frame frame) {
		...
		return frame;
	}

	
	//释放OpenGL相关资源
	public void destroy() {
		...
	}
}

从上面的栗子可以看出,filter的内容几乎都在draw方法中,


draw方法中需要做的工作有:

1.使用OpenglUtils编译链接shader
2.初始化shader变量
3.填充数据并绘制



	//有了filter之后,一个set就可以使用
	AGLView.setFilter(IFilter filter)
	

对于每一个filter,其中大部分代码都是相同的,尤其是初始化和绘制的顶点坐标和纹理坐标,所以我们封装一个输出绘制原图的AGLFilter,一般的功能继承这个filter就可以:


public class MyFilter extends AGLFilter {

	@Override
    public void onInit() {
    	//编译shader,初始化shader变量
        programId = OpenGlUtils.loadProgram(vertexShaderCode, fragmentShaderCode);
        ...
    }
    
	@Override
    protected void onDrawArraysPre(Frame frame) {
        //父类中完成了渲染texture的工作
        //如果在渲染中需要额外的工作,需要重写此方法,否则不需要
    }
}

可以看出封装后我们只需要认真的编写好shader,并完成初始化,赋值就可以看到我们想要的特效了。

对于功能复杂的filter,可以直接去实现IFilter接口,虽然代码会多一些,但扩展起来更灵活。


四、后记

以后关于OpenGL ES的代码我们都将使用AGLFrameWork框架处理,也就是只需要编写不同的Filter就可以了。 还不理解可以参考文章开头框架源码或者留言交流。

猜你喜欢

转载自blog.csdn.net/liuderong0/article/details/90348762