Android OpenGL ES滤镜开发设计

栏目: 编程工具 · 发布时间: 6年前

内容简介:按照正常的Android OpenGL开发,一般只需引入两个“主角”:这里定义一个滤镜需要实现的接口。

一、引入

按照正常的Android OpenGL开发,一般只需引入两个“主角”: GLSurfaceViewRenderer 。在拍摄这种各种挂件和特效纵横的场景下, Renderer 会变得臃肿和不堪重负,而且 不够灵活 地去替换各种挂机和特效。正如 Activity 引入 Fragment ,同理,这里我们的 Renderer 引入 Filter

二、定义

Filter 定义为一个小型的 Renderer ,一个 Renderer 可以有多个 Filter ,可以增删 FilterFilter 间可以互相叠加特效。

三、代码设计

1. IFilter

这里定义一个滤镜需要实现的接口。

public interface IFilter {
    void create(); // Renderer#onSurfaceCreated时调用
    void changeSize(int width, int height);// Renderer#onSurfaceChanged时调用
    void draw();// Renderer#onDrawFrame时调用
}

在这个接口的基础上,按照OpenGL常用的代码实现过程,抽出一个抽象类来。

public abstract class AbsFilter implements IFilter{
    @Override
    public final void create(){
        onCreateProgram();
        onCreate(mProgram);
    }
    @Override
    public final void changeSize(int width, int height){
        onSizeChange(width, height);
    }
    @Override
    public final void draw() {
        onClear();
        onUseProgram();
        onSetExpandData();
        onBindTexture();
        onDraw();
    }
    protected void onCreateProgram() {
		// loadShader && createProgram 减少代码阅读压力,此处简写
    }
    protected void onUseProgram() {
        GLES20.glUseProgram(mProgram);
    }
    protected abstract void onCreate(int program);
    protected abstract String getVertexShaderCode();  // 子类实现,返回vertex shader 代码段内容。
    protected abstract String getFragmentShaderCode();  // 子类实现,返回fragment shader 代码段内容。
    protected abstract void onSizeChange(int width, int height);
    protected abstract void onClear(); // 颜色清屏
    protected abstract void onSetExpandData(); // 传给shader一些其他的参数
    protected abstract void onBindTexture(); // 绑定texture
    protected abstract void onDraw(); // 绘制
}

2. IFilterGroup

除了 Filter ,还需要一个 FilterGroup 来管理这些个 Filter

public interface IFilterGroup {
    void addFilter(IFilter filter);
    void removeFilter(IFilter filter);
    boolean containsFilter(IFilter filter);
    void clear();
}

这时,其实有人会这么说,干嘛要用 FilterGroup ,直接用 List 来不就可以了吗?

我们先看下这个 IFilterGroup 的实现,以此来解答这个疑问。

public class FilterGroup implements IFilterGroup, IFilter{
    private int mWidth;
    private int mHeight;

    private Queue<IFilter> mFilterQueue = new ConcurrentLinkedQueue<IFilter>(); // glThread和MainThread都会操作这个,所以用ConcurrentLinkedQueue
    private List<IFilter> mFilters = new CopyOnWriteArrayList<IFilter>(); // 有遍历和多线程操作,防止抛异常

    @Override
    public void create() {
        for (IFilter filter : mFilters) {
            filter.create();
        }
    }

    @Override
    public void changeSize(int width, int height) {
        this.mWidth = width;
        this.mHeight = height;
        updateFilter();
        for (IFilter filter : mFilters) {
            filter.changeSize(width, height);
        }
    }

    @Override
    public void draw() {
        updateFilter();
        for (IFilter filter : mFilters) {
            filter.draw();
        }
    }

    @Override
    public void addFilter(IFilter filter) {   this.mFilterQueue.add(filter); }

    @Override
    public void removeFilter(IFilter filter) {	// 减少阅读压力,简单代码,此处省略
	}
    @Override
    public boolean containsFilter(IFilter filter) {	// 减少阅读压力,简单代码,此处省略
	}
    @Override
    public void clear() {	// 减少阅读压力,简单代码,此处省略
	}

    private void updateFilter() {
        IFilter f;
        while ((f=mFilterQueue.poll())!=null){
            f.create();
            f.changeSize(mWidth,mHeight);
            mFilters.add(f);
        }
    }
}

因为, Filter 有着与 Renderer 相似的方法,由于 Filter 可支持动态添加的缘故,可能会出现 RendereronSurfaceCreatedonSurfaceChanged 都执行过了, Filter 无法执行 createchangeSize ,之后执行 draw

故需要有一个如同 FilterGroup ,有一个 updateFilter 方法,将添加的 Filter 先存放在一个队列中,等要执行 RendereronDrawFrame 方法时,将所有从队列取出执行前面未执行到的 createchangeSize 方法,后才加入到正常的 FilterList 中,一起去执行 draw 方法。

而执行 updateFilter 方法的时机是 RendereronSurfaceChangedonDrawFrame 时。

3. FilterRenderer

讲完 IFilterIFilterGroup ,接下来就要讲下上面两个在 Renderer 里的使用了。

public class FilterRenderer implements GLSurfaceView.Renderer, IFilterGroup{
    private FilterGroup mDefaultFilterGroup = new FilterGroup();
    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        mDefaultFilterGroup.create();
    }
    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        mDefaultFilterGroup.changeSize(width, height);
    }
    @Override
    public void onDrawFrame(GL10 gl) {
        mDefaultFilterGroup.draw();
    }
    @Override
    public void addFilter(IFilter filter) {
        mDefaultFilterGroup.addFilter(filter);
    }
    @Override
    public void removeFilter(IFilter filter) {
        mDefaultFilterGroup.removeFilter(filter);
    }
    @Override
    public boolean containsFilter(IFilter filter) {
        return mDefaultFilterGroup.containsFilter(filter);
    }
    @Override
    public List<IFilter> getFilterList() {
        return mDefaultFilterGroup.getFilterList();
    }
    @Override
    public void clear() {
        mDefaultFilterGroup.clear();
    }
}

四、使用

1,. 继承 AbsFilter 或实现 IFilter 制作滤镜;

  1. 实现 FilterRenderer ,用 FilterRenderer#addFilter 添加自己写的滤镜(步骤3后面add也可以);
  2. GLSurfaceView#setRenderer

以上所述就是小编给大家介绍的《Android OpenGL ES滤镜开发设计》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

区块链:定义未来金融与经济新格局

区块链:定义未来金融与经济新格局

张健 / 机械工业出版社 / 2016-6-18 / 49.00

从构建价值互联网的角度看,区块链的出现意味着从0到1。正因如此,本书章节结构与常见的体例不同,从第0章开始。第0章从文字与货币的起源出发,通过论述人类信息传递和价值传输手段的进步,说明区块链技术诞生的必然性。第1章用深入浅出的语言讲解区块链的本质、运行原理、颠覆性潜力以及区块链技术的现状与未来;第2章宏观讲述了区块链技术带来的新产品和新机遇,包括数字货币、互联网金融、物联网,以及新一代的基础设施;......一起来看看 《区块链:定义未来金融与经济新格局》 这本书的介绍吧!

随机密码生成器
随机密码生成器

多种字符组合密码

URL 编码/解码
URL 编码/解码

URL 编码/解码

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具