1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > android opengl滤镜 Android OpenGL ES滤镜开发设计

android opengl滤镜 Android OpenGL ES滤镜开发设计

时间:2020-04-17 13:50:03

相关推荐

android opengl滤镜 Android OpenGL ES滤镜开发设计

一、引入

按照正常的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 mFilterQueue = new ConcurrentLinkedQueue(); // glThread和MainThread都会操作这个,所以用ConcurrentLinkedQueue

private List mFilters = new CopyOnWriteArrayList(); // 有遍历和多线程操作,防止抛异常

@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 getFilterList() {

return mDefaultFilterGroup.getFilterList();

}

@Override

public void clear() {

mDefaultFilterGroup.clear();

}

}

四、使用

1,. 继承 AbsFilter

或实现 IFilter

制作滤镜;

实现 FilterRenderer

,用 FilterRenderer#addFilter

添加自己写的滤镜(步骤3后面add也可以);

GLSurfaceView#setRenderer

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。