https://blog.csdn.net/gdliweibing/article/details/93832812
**
* Resembles a filter that consists of multiple filters applied after each
* other.
*/
public class GPUImageFilterGroup extends GPUImageFilter {
private List<GPUImageFilter> filters; /**滤镜组**/
private List<GPUImageFilter> mergedFilters;/**组合滤镜**/
private int[] frameBuffers; /**帧缓存*/
private int[] frameBufferTextures; /***纹理缓冲**/
private final FloatBuffer glCubeBuffer;
private final FloatBuffer glTextureBuffer;
private final FloatBuffer glTextureFlipBuffer;
/**
* Instantiates a new GPUImageFilterGroup with no filters.
*/
public GPUImageFilterGroup() {
this(null);
}
/**
* Instantiates a new GPUImageFilterGroup with the given filters.
*
* @param filters the filters which represent this filter
*/
public GPUImageFilterGroup(List<GPUImageFilter> filters) {
this.filters = filters;
if (this.filters == null) {
this.filters = new ArrayList<>();
} else {
updateMergedFilters();
}
/**顶点Buffer**/
glCubeBuffer = ByteBuffer.allocateDirect(CUBE.length * 4)
.order(ByteOrder.nativeOrder())
.asFloatBuffer();
glCubeBuffer.put(CUBE).position(0);
/**纹理Buffer**/
glTextureBuffer = ByteBuffer.allocateDirect(TEXTURE_NO_ROTATION.length * 4)
.order(ByteOrder.nativeOrder())
.asFloatBuffer();
glTextureBuffer.put(TEXTURE_NO_ROTATION).position(0);
/**纹理翻转Buffer**/
float[] flipTexture = TextureRotationUtil.getRotation(Rotation.NORMAL, false, true);
glTextureFlipBuffer = ByteBuffer.allocateDirect(flipTexture.length * 4)
.order(ByteOrder.nativeOrder())
.asFloatBuffer();
glTextureFlipBuffer.put(flipTexture).position(0);
}
/**添加单个滤镜到滤镜组**/
public void addFilter(GPUImageFilter aFilter) {
if (aFilter == null) {
return;
}
filters.add(aFilter);
updateMergedFilters();
}
/*初始化每个滤镜
* (non-Javadoc)
* @see jp.co.cyberagent.android.gpuimage.filter.GPUImageFilter#onInit()
*/
@Override
public void onInit() {
super.onInit();
for (GPUImageFilter filter : filters) {
filter.ifNeedInit();
}
}
/* 销毁每一个滤镜
* (non-Javadoc)
* @see jp.co.cyberagent.android.gpuimage.filter.GPUImageFilter#onDestroy()
*/
@Override
public void onDestroy() {
destroyFramebuffers();
for (GPUImageFilter filter : filters) {
filter.destroy();
}
super.onDestroy();
}
/**销毁纹理缓冲区 & 帧缓冲区**/
private void destroyFramebuffers() {
if (frameBufferTextures != null) {
GLES20.glDeleteTextures(frameBufferTextures.length, frameBufferTextures, 0);
frameBufferTextures = null;
}
if (frameBuffers != null) {
GLES20.glDeleteFramebuffers(frameBuffers.length, frameBuffers, 0);
frameBuffers = null;
}
}
/* 窗口改变大小时
* (non-Javadoc)
* @see
* jp.co.cyberagent.android.gpuimage.filter.GPUImageFilter#onOutputSizeChanged(int,
* int)
*/
@Override
public void onOutputSizeChanged(final int width, final int height) {
super.onOutputSizeChanged(width, height);
if (frameBuffers != null) {
destroyFramebuffers();
}
/***窗口改变大小时,每个滤镜都要改变大小***/
int size = filters.size();
for (int i = 0; i < size; i++) {
filters.get(i).onOutputSizeChanged(width, height);
}
/**为滤镜组中的每一个滤镜添加帧缓冲区frameBuffers 和纹理缓冲区frameBufferTextures**/
if (mergedFilters != null && mergedFilters.size() > 0) {
size = mergedFilters.size();
frameBuffers = new int[size - 1];
frameBufferTextures = new int[size - 1];
for (int i = 0; i < size - 1; i++) {
GLES20.glGenFramebuffers(1, frameBuffers, i);/**创建帧缓冲区**/
GLES20.glGenTextures(1, frameBufferTextures, i);/**创建纹理缓冲区**/
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, frameBufferTextures[i]);/**绑定纹理缓冲区**/
GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, width, height, 0,
GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, null);/**指定纹理缓冲区的带宽高和internalformat内部格式**/
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,
GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,
GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,
GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,
GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, frameBuffers[i]);/**绑定帧缓冲区**/
GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0,
GLES20.GL_TEXTURE_2D, frameBufferTextures[i], 0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
}
}
}
/*绘制
* (non-Javadoc)
* @see jp.co.cyberagent.android.gpuimage.filter.GPUImageFilter#onDraw(int,
* java.nio.FloatBuffer, java.nio.FloatBuffer)
*/
@SuppressLint("WrongCall")
@Override
public void onDraw(final int textureId, final FloatBuffer cubeBuffer,
final FloatBuffer textureBuffer) {
runPendingOnDrawTasks();/**首先执行被挂起的任务**/
if (!isInitialized() || frameBuffers == null || frameBufferTextures == null) {
return;
}
if (mergedFilters != null) {
int size = mergedFilters.size();/**合并后滤镜数组**/
int previousTexture = textureId;
for (int i = 0; i < size; i++) {
GPUImageFilter filter = mergedFilters.get(i);
boolean isNotLast = i < size - 1;/**非最后一个滤镜**/
if (isNotLast) {
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, frameBuffers[i]);/**绑定帧缓冲区**/
GLES20.glClearColor(0, 0, 0, 0);
}
if (i == 0) {/**第一个滤镜是不是帧缓冲区的**/
filter.onDraw(previousTexture, cubeBuffer, textureBuffer);
} else if (i == size - 1) {/**最后一个绘制方法**/
filter.onDraw(previousTexture, glCubeBuffer, (size % 2 == 0) ? glTextureFlipBuffer : glTextureBuffer);
} else {
filter.onDraw(previousTexture, glCubeBuffer, glTextureBuffer);
}
if (isNotLast) {
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
previousTexture = frameBufferTextures[i]; /**帧纹理缓冲区-->纹理**/
}
}
}
}
/**
* Gets the filters.
*
* @return the filters
*/
public List<GPUImageFilter> getFilters() {
return filters;
}
public List<GPUImageFilter> getMergedFilters() {
return mergedFilters;
}
/***更新合并的滤镜**/
public void updateMergedFilters() {
if (filters == null) {
return;
}
/***要清除所有的滤镜**/
if (mergedFilters == null) {
mergedFilters = new ArrayList<>();
} else {
mergedFilters.clear();
}
/**重新组合所有的滤镜**/
List<GPUImageFilter> filters;
for (GPUImageFilter filter : this.filters) {
if (filter instanceof GPUImageFilterGroup) {/***滤镜组**/
((GPUImageFilterGroup) filter).updateMergedFilters();/**更新合并滤镜组**/
filters = ((GPUImageFilterGroup) filter).getMergedFilters();
if (filters == null || filters.isEmpty())
continue;
mergedFilters.addAll(filters);/***将滤镜组的滤镜,全部合并到顶层GPUImageFilterGroup中**/
continue;
}
mergedFilters.add(filter);/**滤镜添加到滤镜合并数组中**/
}
}
}
public class GPUImageSketchFilter extends GPUImageFilterGroup {
public static final String SKETCH_FRAGMENT_SHADER = "" +
"precision mediump float;\n" +
"\n" +
"varying vec2 textureCoordinate;\n" +
"varying vec2 leftTextureCoordinate;\n" +
"varying vec2 rightTextureCoordinate;\n" +
"\n" +
"varying vec2 topTextureCoordinate;\n" +
"varying vec2 topLeftTextureCoordinate;\n" +
"varying vec2 topRightTextureCoordinate;\n" +
"\n" +
"varying vec2 bottomTextureCoordinate;\n" +
"varying vec2 bottomLeftTextureCoordinate;\n" +
"varying vec2 bottomRightTextureCoordinate;\n" +
"\n" +
"uniform sampler2D inputImageTexture;\n" +
"\n" +
"void main()\n" +
"{\n" +
"float bottomLeftIntensity = texture2D(inputImageTexture, bottomLeftTextureCoordinate).r;\n" +
"float topRightIntensity = texture2D(inputImageTexture, topRightTextureCoordinate).r;\n" +
"float topLeftIntensity = texture2D(inputImageTexture, topLeftTextureCoordinate).r;\n" +
"float bottomRightIntensity = texture2D(inputImageTexture, bottomRightTextureCoordinate).r;\n" +
"float leftIntensity = texture2D(inputImageTexture, leftTextureCoordinate).r;\n" +
"float rightIntensity = texture2D(inputImageTexture, rightTextureCoordinate).r;\n" +
"float bottomIntensity = texture2D(inputImageTexture, bottomTextureCoordinate).r;\n" +
"float topIntensity = texture2D(inputImageTexture, topTextureCoordinate).r;\n" +
"float h = -topLeftIntensity - 2.0 * topIntensity - topRightIntensity + bottomLeftIntensity + 2.0 * bottomIntensity + bottomRightIntensity;\n" +
"float v = -bottomLeftIntensity - 2.0 * leftIntensity - topLeftIntensity + bottomRightIntensity + 2.0 * rightIntensity + topRightIntensity;\n" +
"\n" +
"float mag = 1.0 - length(vec2(h, v));\n" +
"\n" +
"gl_FragColor = vec4(vec3(mag), 1.0);\n" +
"}\n";
public GPUImageSketchFilter() {
super();
addFilter(new GPUImageGrayscaleFilter());
addFilter(new GPUImage3x3TextureSamplingFilter(SKETCH_FRAGMENT_SHADER));
}
}
---------------------
作者:gdliweibing
来源:CSDN
原文:https://blog.csdn.net/gdliweibing/article/details/93832812
版权声明:本文为博主原创文章,转载请附上博文链接!