package com.marshalchen.common.uimodule.imageprocessing.filter.processing; import com.marshalchen.common.uimodule.imageprocessing.filter.MultiPixelRenderer; import android.opengl.GLES20; /** * Currently only used as part of the CannyEdgeDetectionFilter. * @author Chris Batt */ public class DirectionalNonMaximumSuppressionFilter extends MultiPixelRenderer { private static final String UNIFORM_UPPER_THRESHOLD = "u_UpperThreshold"; private static final String UNIFORM_LOWER_THRESHOLD = "u_LowerThreshold"; private float upperThreshold; private float lowerThreshold; private int upperThresholdHandle; private int lowerThresholdHandle; /** * Creates a ImageGammaFilter with the given gamma adjustment value. * @param gamma * The gamma adjustment value. */ public DirectionalNonMaximumSuppressionFilter(float upperThreshold, float lowerThreshold) { this.upperThreshold = upperThreshold; this.lowerThreshold = lowerThreshold; } @Override protected String getFragmentShader() { return "precision mediump float;\n" +"uniform sampler2D "+UNIFORM_TEXTURE0+";\n" +"varying vec2 "+VARYING_TEXCOORD+";\n" +"uniform float "+UNIFORM_TEXELWIDTH+";\n" +"uniform float "+UNIFORM_TEXELHEIGHT+";\n" +"uniform float "+UNIFORM_UPPER_THRESHOLD+";\n" +"uniform float "+UNIFORM_LOWER_THRESHOLD+";\n" +"void main(){\n" +" vec3 currentGradientAndDirection = texture2D("+UNIFORM_TEXTURE0+","+VARYING_TEXCOORD+").rgb;\n" +" vec2 gradientDirection = ((currentGradientAndDirection.gb * 2.0) - 1.0) * vec2("+UNIFORM_TEXELWIDTH+", "+UNIFORM_TEXELHEIGHT+");\n" +" float firstSampledGradientMagnitude = texture2D("+UNIFORM_TEXTURE0+","+VARYING_TEXCOORD+" + gradientDirection).r;\n" +" float secondSampledGradientMagnitude = texture2D("+UNIFORM_TEXTURE0+","+VARYING_TEXCOORD+" - gradientDirection).r;\n" +" float multiplier = step(firstSampledGradientMagnitude, currentGradientAndDirection.r);\n" +" multiplier = multiplier * step(secondSampledGradientMagnitude, currentGradientAndDirection.r);\n" +" float thresholdCompliance = smoothstep("+UNIFORM_LOWER_THRESHOLD+", "+UNIFORM_UPPER_THRESHOLD+", currentGradientAndDirection.r);\n" +" multiplier = multiplier * thresholdCompliance;\n" +" gl_FragColor = vec4(vec3(multiplier), 1.0);\n" +"}\n"; } @Override protected void initShaderHandles() { super.initShaderHandles(); upperThresholdHandle = GLES20.glGetUniformLocation(programHandle, UNIFORM_UPPER_THRESHOLD); lowerThresholdHandle = GLES20.glGetUniformLocation(programHandle, UNIFORM_LOWER_THRESHOLD); } @Override protected void passShaderValues() { super.passShaderValues(); GLES20.glUniform1f(upperThresholdHandle, upperThreshold); GLES20.glUniform1f(lowerThresholdHandle, lowerThreshold); } }