Skip to content

Commit

Permalink
Add new filters
Browse files Browse the repository at this point in the history
  • Loading branch information
nekocode committed Aug 8, 2016
1 parent fbc0acb commit 4a351e2
Show file tree
Hide file tree
Showing 26 changed files with 569 additions and 20 deletions.
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

Realtime camera filters. Process frames by OpenGL shaders.

**[Download the apk](https://github.com/WeLikeVis/CameraFilter/releases/download/1.1/app-debug.apk)** to have a try.
**[Download the apk](https://github.com/WeLikeVis/CameraFilter/releases/download/1.2/app-debug.apk)** to have a try.

## Filters

Expand All @@ -21,3 +21,8 @@ Realtime camera filters. Process frames by OpenGL shaders.
| Contrast | https://www.shadertoy.com/view/Xdf3RN | ![](art/10.png) |
| NoiseWarp | https://www.shadertoy.com/view/4sX3RN | ![](art/11.png) |
| Refraction | https://www.shadertoy.com/view/MsX3zN# | ![](art/12.png) |
| Mapping | https://www.shadertoy.com/view/XsX3R7# | ![](art/13.png) |
| Crosshatch | https://www.shadertoy.com/view/MdX3Dr | ![](art/14.png) |
| Lichtenstein-esque | https://www.shadertoy.com/view/Mdf3zS | ![](art/15.png) |
| Ascii Art | https://www.shadertoy.com/view/lssGDj# | ![](art/16.png) |
| Money Filter | https://www.shadertoy.com/view/XlsXDN | ![](art/17.png) |
28 changes: 25 additions & 3 deletions app/src/main/java/cn/nekocode/camerafilter/CameraRenderer.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import android.content.Context;
import android.graphics.SurfaceTexture;
import android.hardware.Camera;
import android.opengl.GLES11Ext;
import android.opengl.GLES20;
import android.util.Log;
import android.util.Pair;
Expand All @@ -18,7 +17,25 @@
import javax.microedition.khronos.egl.EGLDisplay;
import javax.microedition.khronos.egl.EGLSurface;

import cn.nekocode.camerafilter.filter.*;
import cn.nekocode.camerafilter.filter.AsciiArtFilter;
import cn.nekocode.camerafilter.filter.BasicDeformFilter;
import cn.nekocode.camerafilter.filter.BlueorangeFilter;
import cn.nekocode.camerafilter.filter.CameraFilter;
import cn.nekocode.camerafilter.filter.ChromaticAberrationFilter;
import cn.nekocode.camerafilter.filter.ContrastFilter;
import cn.nekocode.camerafilter.filter.CrosshatchFilter;
import cn.nekocode.camerafilter.filter.EMInterferenceFilter;
import cn.nekocode.camerafilter.filter.EdgeDetectionFilter;
import cn.nekocode.camerafilter.filter.LichtensteinEsqueFilter;
import cn.nekocode.camerafilter.filter.LegofiedFilter;
import cn.nekocode.camerafilter.filter.MappingFilter;
import cn.nekocode.camerafilter.filter.MoneyFilter;
import cn.nekocode.camerafilter.filter.NoiseWarpFilter;
import cn.nekocode.camerafilter.filter.OriginalFilter;
import cn.nekocode.camerafilter.filter.PixelizeFilter;
import cn.nekocode.camerafilter.filter.RefractionFilter;
import cn.nekocode.camerafilter.filter.TileMosaicFilter;
import cn.nekocode.camerafilter.filter.TrianglesMosaicFilter;

/**
* Created by nekocode on 16/8/5.
Expand Down Expand Up @@ -90,7 +107,7 @@ public void run() {
initGL(surfaceTexture);

// Create texture for camera preview
cameraTextureId = MyGLUtils.createTextureID(GLES11Ext.GL_TEXTURE_EXTERNAL_OES);
cameraTextureId = MyGLUtils.createCameraTextureID();
cameraSurfaceTexture = new SurfaceTexture(cameraTextureId);

cameraFilterMap.append(R.id.filter0, new OriginalFilter(context));
Expand All @@ -106,6 +123,11 @@ public void run() {
cameraFilterMap.append(R.id.filter10, new ContrastFilter(context));
cameraFilterMap.append(R.id.filter11, new NoiseWarpFilter(context));
cameraFilterMap.append(R.id.filter12, new RefractionFilter(context));
cameraFilterMap.append(R.id.filter13, new MappingFilter(context));
cameraFilterMap.append(R.id.filter14, new CrosshatchFilter(context));
cameraFilterMap.append(R.id.filter15, new LichtensteinEsqueFilter(context));
cameraFilterMap.append(R.id.filter16, new AsciiArtFilter(context));
cameraFilterMap.append(R.id.filter17, new MoneyFilter(context));
cameraFilter = cameraFilterMap.get(R.id.filter0);

try {
Expand Down
12 changes: 6 additions & 6 deletions app/src/main/java/cn/nekocode/camerafilter/MyGLUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,15 @@
public class MyGLUtils {
private static final String TAG = "MyGLUtils";

public static int createTextureID(int textureType) {
public static int createCameraTextureID() {
int[] texture = new int[1];

GLES20.glGenTextures(1, texture, 0);
GLES20.glBindTexture(textureType, texture[0]);
GLES20.glTexParameterf(textureType, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
GLES20.glTexParameterf(textureType, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
GLES20.glTexParameteri(textureType, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE);
GLES20.glTexParameteri(textureType, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE);
GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, texture[0]);
GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE);
GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE);

return texture[0];
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package cn.nekocode.camerafilter.filter;

import android.content.Context;

import cn.nekocode.camerafilter.MyGLUtils;
import cn.nekocode.camerafilter.R;

/**
* Created by nekocode on 16/8/6.
*/
public class AsciiArtFilter extends CameraFilter {
private int program;

public AsciiArtFilter(Context context) {
super(context);

// Build shaders
program = MyGLUtils.buildProgram(context, R.raw.vertext, R.raw.ascii_art);
}

@Override
public void draw(int textureId, int gwidth, int gheight) {
defaultDraw(program, textureId, gwidth, gheight);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package cn.nekocode.camerafilter.filter;

import android.content.Context;

import cn.nekocode.camerafilter.MyGLUtils;
import cn.nekocode.camerafilter.R;

/**
* Created by nekocode on 16/8/6.
*/
public class CrosshatchFilter extends CameraFilter {
private int program;

public CrosshatchFilter(Context context) {
super(context);

// Build shaders
program = MyGLUtils.buildProgram(context, R.raw.vertext, R.raw.crosshatch);
}

@Override
public void draw(int textureId, int gwidth, int gheight) {
defaultDraw(program, textureId, gwidth, gheight);
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package cn.nekocode.camerafilter.filter;

import android.content.Context;
import android.opengl.GLES11Ext;
import android.opengl.GLES20;

import cn.nekocode.camerafilter.MyGLUtils;
import cn.nekocode.camerafilter.R;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package cn.nekocode.camerafilter.filter;

import android.content.Context;
import android.opengl.GLES11Ext;
import android.opengl.GLES20;

import cn.nekocode.camerafilter.MyGLUtils;
import cn.nekocode.camerafilter.R;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package cn.nekocode.camerafilter.filter;

import android.content.Context;

import cn.nekocode.camerafilter.MyGLUtils;
import cn.nekocode.camerafilter.R;

/**
* Created by nekocode on 16/8/6.
*/
public class LichtensteinEsqueFilter extends CameraFilter {
private int program;

public LichtensteinEsqueFilter(Context context) {
super(context);

// Build shaders
program = MyGLUtils.buildProgram(context, R.raw.vertext, R.raw.lichtenstein_esque);
}

@Override
public void draw(int textureId, int gwidth, int gheight) {
defaultDraw(program, textureId, gwidth, gheight);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package cn.nekocode.camerafilter.filter;

import android.content.Context;
import android.opengl.GLES11Ext;
import android.opengl.GLES20;

import cn.nekocode.camerafilter.MyGLUtils;
import cn.nekocode.camerafilter.R;

/**
* Created by nekocode on 16/8/6.
*/
public class MappingFilter extends CameraFilter {
private int program;
private int texture2Id;

public MappingFilter(Context context) {
super(context);

// Build shaders
program = MyGLUtils.buildProgram(context, R.raw.vertext, R.raw.mapping);

// Load the texture will need for the shader
texture2Id = MyGLUtils.loadTexture(context, R.raw.tex00);
}

@Override
public void draw(int textureId, int gwidth, int gheight) {
// Use shaders
GLES20.glUseProgram(program);

int iResolution = GLES20.glGetUniformLocation(program, "iResolution");
// FIXME: Because we roate the texture, so we need to exchange the width and height
final float res[] = {(float) gheight, (float) gwidth, 1.0f};
GLES20.glUniform3fv(iResolution, 1, res, 0);

float time = ((float) (System.currentTimeMillis() - START_TIME)) / 1000.0f;
int iGlobalTime = GLES20.glGetUniformLocation(program, "iGlobalTime");
GLES20.glUniform1f(iGlobalTime, time);

int vPositionLocation = GLES20.glGetAttribLocation(program, "vPosition");
int vTexCoordLocation = GLES20.glGetAttribLocation(program, "vTexCoord");
int sTextureLocation = GLES20.glGetUniformLocation(program, "sTexture");
int sTexture2Location = GLES20.glGetUniformLocation(program, "sTexture2");

GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, textureId);
GLES20.glUniform1i(sTextureLocation, 0); // First layer texture

GLES20.glActiveTexture(GLES20.GL_TEXTURE1);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texture2Id);
GLES20.glUniform1i(sTexture2Location, 1); // Second layer texture

GLES20.glVertexAttribPointer(vPositionLocation, 2, GLES20.GL_FLOAT, false, 4 * 2, defaultVertexBuffer);
GLES20.glVertexAttribPointer(vTexCoordLocation, 2, GLES20.GL_FLOAT, false, 4 * 2, defaultTextureCoordBuffer);
GLES20.glEnableVertexAttribArray(vPositionLocation);
GLES20.glEnableVertexAttribArray(vTexCoordLocation);

// Draw the texture
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
}
}
25 changes: 25 additions & 0 deletions app/src/main/java/cn/nekocode/camerafilter/filter/MoneyFilter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package cn.nekocode.camerafilter.filter;

import android.content.Context;

import cn.nekocode.camerafilter.MyGLUtils;
import cn.nekocode.camerafilter.R;

/**
* Created by nekocode on 16/8/6.
*/
public class MoneyFilter extends CameraFilter {
private int program;

public MoneyFilter(Context context) {
super(context);

// Build shaders
program = MyGLUtils.buildProgram(context, R.raw.vertext, R.raw.money_filter);
}

@Override
public void draw(int textureId, int gwidth, int gheight) {
defaultDraw(program, textureId, gwidth, gheight);
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package cn.nekocode.camerafilter.filter;

import android.content.Context;
import android.opengl.GLES11Ext;
import android.opengl.GLES20;

import cn.nekocode.camerafilter.MyGLUtils;
import cn.nekocode.camerafilter.R;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package cn.nekocode.camerafilter.filter;

import android.content.Context;
import android.opengl.GLES11Ext;
import android.opengl.GLES20;

import cn.nekocode.camerafilter.MyGLUtils;
import cn.nekocode.camerafilter.R;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package cn.nekocode.camerafilter.filter;

import android.content.Context;
import android.opengl.GLES11Ext;
import android.opengl.GLES20;

import cn.nekocode.camerafilter.MyGLUtils;
import cn.nekocode.camerafilter.R;
Expand Down
30 changes: 30 additions & 0 deletions app/src/main/res/menu/filter.xml
Original file line number Diff line number Diff line change
Expand Up @@ -79,4 +79,34 @@
android:title="Refraction"
app:showAsAction="never"
/>

<item
android:id="@+id/filter13"
android:title="Mapping"
app:showAsAction="never"
/>

<item
android:id="@+id/filter14"
android:title="Crosshatch"
app:showAsAction="never"
/>

<item
android:id="@+id/filter15"
android:title="LichtensteinEsque"
app:showAsAction="never"
/>

<item
android:id="@+id/filter16"
android:title="AsciiArt"
app:showAsAction="never"
/>

<item
android:id="@+id/filter17"
android:title="MoneyFilter"
app:showAsAction="never"
/>
</menu>
46 changes: 46 additions & 0 deletions app/src/main/res/raw/ascii_art.fsh
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#extension GL_OES_EGL_image_external : require
precision highp float;

uniform vec3 iResolution;
uniform float iGlobalTime;
uniform samplerExternalOES sTexture;
varying vec2 texCoord;

// Bitmap to ASCII (not really) fragment shader by movAX13h, September 2013
// --- This shader is now used in Pixi JS ---

float character(float n, vec2 p) // some compilers have the word "char" reserved
{
p = floor(p*vec2(4.0, -4.0) + 2.5);
if (clamp(p.x, 0.0, 4.0) == p.x && clamp(p.y, 0.0, 4.0) == p.y)
{
if (int(mod(n/exp2(p.x + 5.0*p.y), 2.0)) == 1) return 1.0;
}
return 0.0;
}

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
vec2 uv = fragCoord.xy;
vec3 col = texture2D(sTexture, floor(uv/8.0)*8.0/iResolution.xy).rgb;

float gray = (col.r + col.g + col.b)/3.0;

float n = 65536.0; // .
if (gray > 0.2) n = 65600.0; // :
if (gray > 0.3) n = 332772.0; // *
if (gray > 0.4) n = 15255086.0; // o
if (gray > 0.5) n = 23385164.0; // &
if (gray > 0.6) n = 15252014.0; // 8
if (gray > 0.7) n = 13199452.0; // @
if (gray > 0.8) n = 11512810.0; // #

vec2 p = mod(uv/10.0, 2.0) - vec2(1.0);
col = gray*vec3(character(n, p));

fragColor = vec4(col, 1.0);
}

void main() {
mainImage(gl_FragColor, texCoord * iResolution.xy);
}
Loading

0 comments on commit 4a351e2

Please sign in to comment.