/* * Copyright (C) 2012 CyberAgent * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jp.co.cyberagent.android.gpuimage; import android.opengl.GLES20; public class GPUImage3x3TextureSamplingFilter extends GPUImageFilter { public static final String THREE_X_THREE_TEXTURE_SAMPLING_VERTEX_SHADER = "" + "attribute vec4 position;\n" + "attribute vec4 inputTextureCoordinate;\n" + "\n" + "uniform highp float texelWidth; \n" + "uniform highp float texelHeight; \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" + "void main()\n" + "{\n" + " gl_Position = position;\n" + "\n" + " vec2 widthStep = vec2(texelWidth, 0.0);\n" + " vec2 heightStep = vec2(0.0, texelHeight);\n" + " vec2 widthHeightStep = vec2(texelWidth, texelHeight);\n" + " vec2 widthNegativeHeightStep = vec2(texelWidth, -texelHeight);\n" + "\n" + " textureCoordinate = inputTextureCoordinate.xy;\n" + " leftTextureCoordinate = inputTextureCoordinate.xy - widthStep;\n" + " rightTextureCoordinate = inputTextureCoordinate.xy + widthStep;\n" + "\n" + " topTextureCoordinate = inputTextureCoordinate.xy - heightStep;\n" + " topLeftTextureCoordinate = inputTextureCoordinate.xy - widthHeightStep;\n" + " topRightTextureCoordinate = inputTextureCoordinate.xy + widthNegativeHeightStep;\n" + "\n" + " bottomTextureCoordinate = inputTextureCoordinate.xy + heightStep;\n" + " bottomLeftTextureCoordinate = inputTextureCoordinate.xy - widthNegativeHeightStep;\n" + " bottomRightTextureCoordinate = inputTextureCoordinate.xy + widthHeightStep;\n" + "}"; private int mUniformTexelWidthLocation; private int mUniformTexelHeightLocation; private boolean mHasOverriddenImageSizeFactor = false; private float mTexelWidth; private float mTexelHeight; private float mLineSize = 1.0f; public GPUImage3x3TextureSamplingFilter() { this(NO_FILTER_VERTEX_SHADER); } public GPUImage3x3TextureSamplingFilter(final String fragmentShader) { super(THREE_X_THREE_TEXTURE_SAMPLING_VERTEX_SHADER, fragmentShader); } @Override public void onInit() { super.onInit(); mUniformTexelWidthLocation = GLES20.glGetUniformLocation(getProgram(), "texelWidth"); mUniformTexelHeightLocation = GLES20.glGetUniformLocation(getProgram(), "texelHeight"); if (mTexelWidth != 0) { updateTexelValues(); } } @Override public void onOutputSizeChanged(final int width, final int height) { super.onOutputSizeChanged(width, height); if (!mHasOverriddenImageSizeFactor) { setLineSize(mLineSize); } } public void setTexelWidth(final float texelWidth) { mHasOverriddenImageSizeFactor = true; mTexelWidth = texelWidth; setFloat(mUniformTexelWidthLocation, texelWidth); } public void setTexelHeight(final float texelHeight) { mHasOverriddenImageSizeFactor = true; mTexelHeight = texelHeight; setFloat(mUniformTexelHeightLocation, texelHeight); } public void setLineSize(final float size) { mLineSize = size; mTexelWidth = size / getOutputWidth(); mTexelHeight = size / getOutputHeight(); updateTexelValues(); } private void updateTexelValues() { setFloat(mUniformTexelWidthLocation, mTexelWidth); setFloat(mUniformTexelHeightLocation, mTexelHeight); } }