|
| 1 | +package jp.co.cyberagent.android.gpuimage; |
| 2 | + |
| 3 | +import android.opengl.GLES20; |
| 4 | + |
| 5 | +public class GPUImageHalftoneFilter extends GPUImageFilter { |
| 6 | + public static final String HALFTONE_FRAGMENT_SHADER = "" + |
| 7 | + "varying highp vec2 textureCoordinate;\n" + |
| 8 | + |
| 9 | + "uniform sampler2D inputImageTexture;\n" + |
| 10 | + |
| 11 | + "uniform highp float fractionalWidthOfPixel;\n" + |
| 12 | + "uniform highp float aspectRatio;\n" + |
| 13 | + |
| 14 | + "const highp vec3 W = vec3(0.2125, 0.7154, 0.0721);\n" + |
| 15 | + |
| 16 | + "void main()\n" + |
| 17 | + "{\n" + |
| 18 | + " highp vec2 sampleDivisor = vec2(fractionalWidthOfPixel, fractionalWidthOfPixel / aspectRatio);\n" + |
| 19 | + " highp vec2 samplePos = textureCoordinate - mod(textureCoordinate, sampleDivisor) + 0.5 * sampleDivisor;\n" + |
| 20 | + " highp vec2 textureCoordinateToUse = vec2(textureCoordinate.x, (textureCoordinate.y * aspectRatio + 0.5 - 0.5 * aspectRatio));\n" + |
| 21 | + " highp vec2 adjustedSamplePos = vec2(samplePos.x, (samplePos.y * aspectRatio + 0.5 - 0.5 * aspectRatio));\n" + |
| 22 | + " highp float distanceFromSamplePoint = distance(adjustedSamplePos, textureCoordinateToUse);\n" + |
| 23 | + " lowp vec3 sampledColor = texture2D(inputImageTexture, samplePos).rgb;\n" + |
| 24 | + " highp float dotScaling = 1.0 - dot(sampledColor, W);\n" + |
| 25 | + " lowp float checkForPresenceWithinDot = 1.0 - step(distanceFromSamplePoint, (fractionalWidthOfPixel * 0.5) * dotScaling);\n" + |
| 26 | + " gl_FragColor = vec4(vec3(checkForPresenceWithinDot), 1.0);\n" + |
| 27 | + "}"; |
| 28 | + |
| 29 | + private int mFractionalWidthOfPixelLocation; |
| 30 | + private int mAspectRatioLocation; |
| 31 | + |
| 32 | + private float mFractionalWidthOfAPixel; |
| 33 | + private float mAspectRatio; |
| 34 | + |
| 35 | + public GPUImageHalftoneFilter() { |
| 36 | + this(0.01f); |
| 37 | + } |
| 38 | + |
| 39 | + public GPUImageHalftoneFilter(float fractionalWidthOfAPixel) { |
| 40 | + super(NO_FILTER_VERTEX_SHADER, HALFTONE_FRAGMENT_SHADER); |
| 41 | + mFractionalWidthOfAPixel = fractionalWidthOfAPixel; |
| 42 | + } |
| 43 | + |
| 44 | + @Override |
| 45 | + public void onInit() { |
| 46 | + super.onInit(); |
| 47 | + mFractionalWidthOfPixelLocation = GLES20.glGetUniformLocation(getProgram(), "fractionalWidthOfPixel"); |
| 48 | + mAspectRatioLocation = GLES20.glGetUniformLocation(getProgram(), "aspectRatio"); |
| 49 | + setFractionalWidthOfAPixel(mFractionalWidthOfAPixel); |
| 50 | + } |
| 51 | + |
| 52 | + @Override |
| 53 | + public void onOutputSizeChanged(final int width, final int height) { |
| 54 | + super.onOutputSizeChanged(width, height); |
| 55 | + setAspectRatio((float)height / (float) width); |
| 56 | + } |
| 57 | + |
| 58 | + public void setFractionalWidthOfAPixel(final float fractionalWidthOfAPixel) { |
| 59 | + mFractionalWidthOfAPixel = fractionalWidthOfAPixel; |
| 60 | + setFloat(mFractionalWidthOfPixelLocation, mFractionalWidthOfAPixel); |
| 61 | + } |
| 62 | + |
| 63 | + public void setAspectRatio(final float aspectRatio) { |
| 64 | + mAspectRatio = aspectRatio; |
| 65 | + setFloat(mAspectRatioLocation, mAspectRatio); |
| 66 | + } |
| 67 | +} |
0 commit comments