内容简介:按照正常的Android OpenGL开发,一般只需引入两个“主角”:这里定义一个滤镜需要实现的接口。
一、引入
按照正常的Android OpenGL开发,一般只需引入两个“主角”: GLSurfaceView
和 Renderer
。在拍摄这种各种挂件和特效纵横的场景下, Renderer
会变得臃肿和不堪重负,而且 不够灵活
地去替换各种挂机和特效。正如 Activity
引入 Fragment
,同理,这里我们的 Renderer
引入 Filter
。
二、定义
Filter
定义为一个小型的 Renderer
,一个 Renderer
可以有多个 Filter
,可以增删 Filter
, Filter
间可以互相叠加特效。
三、代码设计
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
可支持动态添加的缘故,可能会出现 Renderer
的 onSurfaceCreated
和 onSurfaceChanged
都执行过了, Filter
无法执行 create
和 changeSize
,之后执行 draw
。
故需要有一个如同 FilterGroup
,有一个 updateFilter
方法,将添加的 Filter
先存放在一个队列中,等要执行 Renderer
的 onDrawFrame
方法时,将所有从队列取出执行前面未执行到的 create
和 changeSize
方法,后才加入到正常的 Filter
的 List
中,一起去执行 draw
方法。
而执行 updateFilter
方法的时机是 Renderer
的 onSurfaceChanged
和 onDrawFrame
时。
3. FilterRenderer
讲完 IFilter
和 IFilterGroup
,接下来就要讲下上面两个在 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
制作滤镜;
-
实现
FilterRenderer
,用FilterRenderer#addFilter
添加自己写的滤镜(步骤3后面add也可以); -
GLSurfaceView#setRenderer
。
以上所述就是小编给大家介绍的《Android OpenGL ES滤镜开发设计》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 作为后端开发如何设计数据库系列文章(二)设计大数据量表结构(Java开发)
- 微页面设计开发指南
- Kubernetes 设计与开发原则
- MongoDB提升性能的18原则(开发设计阶段)
- 从Git设计原理到业务系统设计与开发
- 设计和架构:业务开发指导原则
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Programming in Haskell
Graham Hutton / Cambridge University Press / 2007-1-18 / GBP 34.99
Haskell is one of the leading languages for teaching functional programming, enabling students to write simpler and cleaner code, and to learn how to structure and reason about programs. This introduc......一起来看看 《Programming in Haskell》 这本书的介绍吧!