Android Open Source - geoar-app Feature Shader






From Project

Back to project page geoar-app.

License

The source code is released under:

Apache License

If you think the Android project geoar-app listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/**
 * Copyright 2012 52North Initiative for Geospatial Open Source Software GmbH
 *//from   www.  j ava 2 s  . c  o  m
 * 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 org.n52.geoar.view.geoar.gl.mode;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.opengl.GLES20;
import android.opengl.GLU;
import android.opengl.GLUtils;

/**
 * 
 * @author Arne de Wall
 * 
 */
public class FeatureShader {

  private boolean hasLight;
  private boolean hasColor;
  private boolean hasTexture;

  // TODO unused!
  static final int SIZE_OF_VERTEX_ELEMENT = 3;
  static final int SIZE_OF_NORMAL_ELEMENT = 3;
  static final int SIZE_OF_COLOR_ELEMENT = 4;
  static final int SIZE_OF_TEXTURECOORD_ELEMENT = 2;

  static final int SIZE_OF_FLOAT = 4;
  static final int SIZE_OF_SHORT = 2;

  /** OpenGL handles and uniforms to our program */
  protected static final String ATTRIBUTE_POSITION = "attr_Position";
  protected static final String ATTRIBUTE_NORMAL = "attr_Normal";
  protected static final String ATTRIBUTE_COLOR = "attr_Color";
  protected static final String ATTRIBUTE_TEXTURE = "attr_TexCoordinate";

  protected static final String UNIFORM_MATRIX_MVP = "unif_MVPMatrix";
  protected static final String UNIFORM_MATRIX_MV = "unif_MVMatrix";
  protected static final String UNIFORM_MATRIX_V = "unif_VMatrix";

  protected static final String UNIFORM_VEC3_LIGHTPOS = "unif_LightPos";
  protected static final String UNIFORM_SAMPLER_TEXTURE = "unif_Texture";

  private static final Logger LOG = LoggerFactory
      .getLogger(FeatureShader.class);

  private static final Set<WeakReference<FeatureShader>> INSTANCES = new HashSet<WeakReference<FeatureShader>>();

  public static void resetShaders() {
    Iterator<WeakReference<FeatureShader>> iterator = INSTANCES.iterator();
    while (iterator.hasNext()) {
      FeatureShader next = iterator.next().get();
      if (next == null) {
        iterator.remove();
      } else {
        next.reset();
      }
    }
  }

  private static void compileShader(final int shaderHandle,
      final String shaderProgram) {
    if (shaderHandle <= 0) {
      throw new IllegalArgumentException("Invalid handle");
    }

    GLES20.glShaderSource(shaderHandle, shaderProgram);
    GLES20.glCompileShader(shaderHandle);
    final int[] status = new int[1];
    GLES20.glGetShaderiv(shaderHandle, GLES20.GL_COMPILE_STATUS, status, 0);

    if (status[0] == 0) {
      LOG.error(
          "FeatureShader " + GLES20.glGetShaderInfoLog(shaderHandle),
          "Error compiling shader: "
              + GLES20.glGetShaderInfoLog(shaderHandle));
      GLES20.glDeleteShader(shaderHandle);
    }
  }

  private static float calculateIntegralImageKey(Bitmap bitmap) {
    final int width = bitmap.getWidth();
    final int height = bitmap.getHeight();

    float sum = 0;

    // for (int i = 0, j = 0; i < height && j < width; i++, j++) {
    // float[] hueSatBright = new float[3];
    // int what = bitmap.getPixel(j, i);
    // Color.RGBToHSV((what >> 16) & 0xff, (what >> 8) & 0xff,
    // what & 0xff, hueSatBright);
    // /** we calculate the integral over the brightness */
    // sum += hueSatBright[2] * 255;
    // }

    return 12;

    // final float[][] integral = new float[height][width];

    // for(int i = 0; i < height; i++){
    // float sumOfTheRow = 0;
    // for(int j = 0; j < width; j++){
    // float[] hueSatBright = new float[3];
    // int what = bitmap.getPixel(j, i);
    // Color.RGBToHSV((what >> 16) & 0xff, (what >> 8) & 0xff, what & 0xff,
    // hueSatBright);
    // /** we calculate the integral over the brightness */
    // sumOfTheRow += hueSatBright[2]*255;
    // if(i > 0){
    // integral[i][j] = integral[i-1][j] + sumOfTheRow;
    // } else {
    // integral[i][j] = integral[i][j] + sumOfTheRow;
    // }
    // }
    // }

  }

  private int programHandle = -1;

  private int positionHandle = -1;
  private int colorHandle = -1;
  private int normalHandle = -1;
  private int lightPosHandle = -1;

  private int vertexShaderHandle = -1;
  private int fragmentShaderHandle = -1;

  private int textureCoordinateHandle = -1;
  // private int textureDataHandle = -1;

  private int textureUniformHandle = -1;

  private int mvpMatrixUniform = -1;
  private int mvMatrixUniform = -1;
  private int vMatrixUniform = -1;

  private final float[] lightPosInModelSpace = new float[] { 0.0f, 0.0f,
      0.0f, 1.0f };
  private final float[] lightPosInWorldSpace = new float[4];
  private final float[] lightPosInEyeSpace = new float[4];

  private final String vertexShader, fragmentShader;

  final boolean supportsNormals;
  final boolean supportsColors;
  final boolean supportsTextures;
  final boolean supportsLight;

  public FeatureShader(String vertexShader, String fragmentShader) {
    this.vertexShader = vertexShader;
    this.fragmentShader = fragmentShader;

    /** searches with the aid of regex for the normal attribute */
    Pattern pattern = Pattern.compile(".*" + ATTRIBUTE_NORMAL + ".*");
    Matcher matcher = pattern.matcher(vertexShader);
    supportsNormals = matcher.find();

    /** Searches with the aid of regex for color attribute */
    pattern = Pattern.compile(".*" + ATTRIBUTE_COLOR + ".*");
    matcher = pattern.matcher(vertexShader);
    supportsColors = matcher.find();

    /** searches with the aid of regex for texture attribute */
    pattern = Pattern.compile(".*" + ATTRIBUTE_TEXTURE + ".*");
    matcher = pattern.matcher(vertexShader);
    supportsTextures = matcher.find();

    pattern = Pattern.compile(".*" + UNIFORM_VEC3_LIGHTPOS + ".*");
    matcher = pattern.matcher(vertexShader);
    supportsLight = matcher.find();

    INSTANCES.add(new WeakReference<FeatureShader>(this));
  }

  public int getColorHandle() {
    if (programHandle == -1) {
      initProgram();
    }

    return colorHandle;
  }

  public int getNormalHandle() {
    if (programHandle == -1) {
      initProgram();
    }
    return normalHandle;
  }

  public int getPositionHandle() {
    if (programHandle == -1) {
      initProgram();
    }
    return positionHandle;
  }

  public int getLightPosHandle() {
    if (programHandle == -1) {
      initProgram();
    }
    return lightPosHandle;
  }

  public int getTextureCoordinateHandle() {
    if (programHandle == -1) {
      initProgram();
    }
    return textureCoordinateHandle;
  }

  public int getTextureUniform() {
    if (programHandle == -1) {
      initProgram();
    }

    return textureUniformHandle;
  }

  /******************************************************************
   * Methods for setting required object Data
   ******************************************************************/
  public void setVertices(final int vertexBufferHandle) {
    if (programHandle == -1) {
      initProgram();
    }

    if (vertexBufferHandle >= 0) {
      GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vertexBufferHandle);
      GLES20.glVertexAttribPointer(positionHandle, 3, GLES20.GL_FLOAT,
          false, 0, 0);
      GLES20.glEnableVertexAttribArray(positionHandle);
    } else {
      LOG.debug("vertexbufferhandle is not a valid handle");
    }
  }

  public void setTextureCoordinates(final int textureBufferHandle) {
    if (programHandle == -1) {
      initProgram();
    }

    if (textureCoordinateHandle >= 0) {
      GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, textureBufferHandle);
      GLES20.glEnableVertexAttribArray(textureCoordinateHandle);
      GLES20.glVertexAttribPointer(textureCoordinateHandle, 2,
          GLES20.GL_FLOAT, false, 0, 0);
    }
  }

  public void setColors(final int colorBufferHandle) {
    if (colorBufferHandle < 0) {
      LOG.debug("colorbufferhandle is not a valid handle");
      return;
    }
    if (programHandle == -1) {
      initProgram();
    }

    if (colorHandle >= 0) {
      GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, colorBufferHandle);
      GLES20.glVertexAttribPointer(colorHandle, 4, GLES20.GL_FLOAT,
          false, 0, 0);
      GLES20.glEnableVertexAttribArray(colorHandle);
    }
  }

  public void setNormals(final int normalBufferHandle) {
    if (normalBufferHandle < 0) {
      LOG.debug("normalbufferhandle is not a valid handle");
      return;
    }
    if (programHandle == -1) {
      initProgram();
    }

    if (normalHandle >= 0) {
      GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, normalBufferHandle);
      GLES20.glVertexAttribPointer(normalHandle, 3, GLES20.GL_FLOAT,
          false, 0, 0);
      GLES20.glEnableVertexAttribArray(normalHandle);
    }
  }

  public void setModelViewProjectionMatrix(float[] mvpMatrix) {
    if (programHandle == -1) {
      initProgram();
    }
    // combined Matrix
    mvpMatrixUniform = GLES20.glGetUniformLocation(programHandle,
        UNIFORM_MATRIX_MVP);
    if (mvpMatrixUniform >= 0)
      GLES20.glUniformMatrix4fv(mvpMatrixUniform, 1, false, mvpMatrix, 0);
  }

  public void setModelViewMatrix(float[] mvMatrix) {
    if (programHandle == -1) {
      initProgram();
    }

    mvMatrixUniform = GLES20.glGetUniformLocation(programHandle,
        UNIFORM_MATRIX_MV);
    if (mvMatrixUniform >= 0) {
      GLES20.glUniformMatrix4fv(mvMatrixUniform, 1, false, mvMatrix, 0);
    }
  }

  public void setLightPositionVec(float[] lightPosition) {
    if (programHandle == -1) {
      initProgram();
    }

    lightPosHandle = GLES20.glGetUniformLocation(programHandle,
        UNIFORM_VEC3_LIGHTPOS);
    if (lightPosHandle >= 0) {
      GLES20.glUniform3f(lightPosHandle, lightPosition[0],
          lightPosition[1], lightPosition[2]);
    }
  }

  // FIXME view gibts nicht... genauso wie modematrix
  public void setRenderMatrices(float[] mvpMatrix, float[] modelMatrix,
      float[] viewMatrix) {
    if (programHandle == -1) {
      initProgram();
    }
    // combined Matrix
    mvpMatrixUniform = GLES20.glGetUniformLocation(programHandle,
        UNIFORM_MATRIX_MVP);
    if (mvpMatrixUniform >= 0)
      GLES20.glUniformMatrix4fv(mvpMatrixUniform, 1, false, mvpMatrix, 0);
    // Model view matrix
    // mvMatrixUniform = GLES20.glGetUniformLocation(programHandle,
    // "u_MVMatrix");
    // if(mvMatrixUniform >= 0)
    // GLES20.glUniformMatrix4fv(mvMatrixUniform, 1, false, modelMatrix, 0);
    // // View Matrix
    // vMatrixUniform = GLES20.glGetUniformLocation(programHandle,
    // "u_VMatrix");
    // if(vMatrixUniform >= 0)
    // GLES20.glUniformMatrix4fv(vMatrixUniform, 1, false, viewMatrix, 0);
  }

  public boolean supportsColors() {
    return supportsColors;
  }

  public boolean supportsNormals() {
    return supportsNormals;
  }

  public boolean supportsTextures() {
    return supportsTextures;
  }

  public void useProgram() {
    if (programHandle == -1) {
      initProgram();
    }
    /** installs the program object as part of the current rendering */
    GLES20.glUseProgram(programHandle);
  }

  private void initProgram() {
    if (vertexShader == null || fragmentShader == null)
      throw new IllegalStateException("Shaders not set");

    if (vertexShaderHandle == -1) {
      vertexShaderHandle = GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER);
    }
    compileShader(vertexShaderHandle, vertexShader);

    if (fragmentShaderHandle == -1) {
      fragmentShaderHandle = GLES20
          .glCreateShader(GLES20.GL_FRAGMENT_SHADER);
    }
    compileShader(fragmentShaderHandle, fragmentShader);

    if (programHandle == -1) {
      programHandle = GLES20.glCreateProgram();
    }
    linkProgram(new String[] { "aPosition", "aNormal", "aColor" });

    mvpMatrixUniform = GLES20.glGetUniformLocation(programHandle,
        UNIFORM_MATRIX_MVP);
    positionHandle = GLES20.glGetAttribLocation(programHandle,
        ATTRIBUTE_POSITION);
    if (supportsNormals)
      normalHandle = GLES20.glGetAttribLocation(programHandle,
          ATTRIBUTE_NORMAL);
    if (supportsColors)
      colorHandle = GLES20.glGetAttribLocation(programHandle,
          ATTRIBUTE_COLOR);
    if (supportsLight)
      lightPosHandle = GLES20.glGetUniformLocation(programHandle,
          UNIFORM_VEC3_LIGHTPOS);
    if (supportsTextures) {
      textureCoordinateHandle = GLES20.glGetAttribLocation(programHandle,
          ATTRIBUTE_TEXTURE);
      textureUniformHandle = GLES20.glGetUniformLocation(programHandle,
          UNIFORM_SAMPLER_TEXTURE);
    }
  }

  private void linkProgram(final String[] attributes) {
    if (programHandle <= 0) {
      throw new IllegalStateException("Invalid program handle");
    }
    if (vertexShaderHandle <= 0) {
      throw new IllegalStateException("Invalid vertex shader handle");
    }
    if (fragmentShaderHandle <= 0) {
      throw new IllegalStateException("Invalid fragment shader handle");
    }
    if (programHandle != 0) {
      GLES20.glAttachShader(programHandle, vertexShaderHandle);
      GLES20.glAttachShader(programHandle, fragmentShaderHandle);

      GLES20.glBindAttribLocation(programHandle, 0, ATTRIBUTE_POSITION);
      // GLES20.glBindAttribLocation(programHandle, 1, ATTRIBUTE_COLOR);
      GLES20.glBindAttribLocation(programHandle, 1, ATTRIBUTE_NORMAL);
      // GLES20.glBindAttribLocation(programHandle, 3, ATTRIBUTE_TEXTURE);
      // if (attributes != null) {
      // for (int i = 0, size = attributes.length; i < size; i++)
      // GLES20.glBindAttribLocation(programHandle, i+1, attributes[i]);
      // }

      GLES20.glLinkProgram(programHandle);

      final int[] status = new int[1];
      GLES20.glGetProgramiv(programHandle, GLES20.GL_LINK_STATUS, status,
          0);

      if (status[0] == 0) {
        LOG.error("Error compiling program: "
            + GLES20.glGetProgramInfoLog(programHandle));
        // GLES20.glDeleteProgram(programHandle);
        // programHandle = 0;
      }
    } else {
      throw new RuntimeException("Error creating Program.");
    }
  }

  private void reset() {
    programHandle = positionHandle = colorHandle = normalHandle = mvpMatrixUniform = vertexShaderHandle = fragmentShaderHandle = -1;
  }

}




Java Source Code List

.DataSourcesOverlay.java
.VisualizationOverlayItem.java
org.n52.geoar.AboutDialog.java
org.n52.geoar.DataSourceListAdapter.java
org.n52.geoar.GeoARActivity.java
org.n52.geoar.GeoARApplication.java
org.n52.geoar.ar.view.ARFragment.java
org.n52.geoar.ar.view.ARObject.java
org.n52.geoar.ar.view.ARView.java
org.n52.geoar.ar.view.DataSourceVisualizationHandler.java
org.n52.geoar.ar.view.IntroController.java
org.n52.geoar.ar.view.IntroViewer.java
org.n52.geoar.ar.view.gl.ARSurfaceViewRenderer.java
org.n52.geoar.ar.view.gl.ARSurfaceView.java
org.n52.geoar.ar.view.gl.GLESCamera.java
org.n52.geoar.ar.view.gl.MultisampleConfigs.java
org.n52.geoar.ar.view.gl.SurfaceTopology.java
org.n52.geoar.ar.view.overlay.ARCanvasSurfaceView.java
org.n52.geoar.ar.view.overlay.GUIDrawable.java
org.n52.geoar.ar.view.overlay.Radar.java
org.n52.geoar.exception.UnsupportedGeometryType.java
org.n52.geoar.map.view.DataSourceOverlayHandler.java
org.n52.geoar.map.view.GeoARMapView.java
org.n52.geoar.map.view.MapActivityContext.java
org.n52.geoar.map.view.MapFragment.java
org.n52.geoar.map.view.overlay.DataSourceOverlay.java
org.n52.geoar.map.view.overlay.DataSourcePointOverlay.java
org.n52.geoar.map.view.overlay.DataSourcePolygonOverlay.java
org.n52.geoar.map.view.overlay.DataSourcePolylineOverlay.java
org.n52.geoar.map.view.overlay.DataSourcesOverlay.java
org.n52.geoar.map.view.overlay.OverlayType.java
org.n52.geoar.map.view.overlay.PointOverlayType.java
org.n52.geoar.map.view.overlay.PolygonOverlayType.java
org.n52.geoar.map.view.overlay.PolylineOverlayType.java
org.n52.geoar.newdata.CheckList.java
org.n52.geoar.newdata.DataCache.java
org.n52.geoar.newdata.DataSourceHolder.java
org.n52.geoar.newdata.DataSourceInstanceHolder.java
org.n52.geoar.newdata.DataSourceInstanceSettingsDialogActivity.java
org.n52.geoar.newdata.InstalledPluginHolder.java
org.n52.geoar.newdata.PluginActivityContext.java
org.n52.geoar.newdata.PluginContext.java
org.n52.geoar.newdata.PluginDialogFragment.java
org.n52.geoar.newdata.PluginDownloadHolder.java
org.n52.geoar.newdata.PluginDownloader.java
org.n52.geoar.newdata.PluginFragment.java
org.n52.geoar.newdata.PluginGridAdapter.java
org.n52.geoar.newdata.PluginHolder.java
org.n52.geoar.newdata.PluginLoader.java
org.n52.geoar.newdata.PluginLogger.java
org.n52.geoar.newdata.PluginStateInputStream.java
org.n52.geoar.newdata.Tile.java
org.n52.geoar.settings.DateTimeSettingsViewField.java
org.n52.geoar.settings.DateUtils.java
org.n52.geoar.settings.NumberSettingsViewField.java
org.n52.geoar.settings.SettingsException.java
org.n52.geoar.settings.SettingsHelper.java
org.n52.geoar.settings.SettingsViewField.java
org.n52.geoar.settings.SettingsView.java
org.n52.geoar.settings.SpinnerSettingsViewField.java
org.n52.geoar.settings.StringSettingsViewField.java
org.n52.geoar.tracking.camera.CameraView.java
org.n52.geoar.tracking.camera.RealityCamera.java
org.n52.geoar.tracking.location.AdaptiveLowPassSensorBuffer.java
org.n52.geoar.tracking.location.LocationHandler.java
org.n52.geoar.tracking.location.LowPassSensorBuffer.java
org.n52.geoar.tracking.location.MeanSensorBuffer.java
org.n52.geoar.tracking.location.SensorBuffer.java
org.n52.geoar.view.InfoView.java
org.n52.geoar.view.geoar.CalibrationControlView.java
org.n52.geoar.view.geoar.Settings.java
org.n52.geoar.view.geoar.gl.mode.BilligerColorShader.java
org.n52.geoar.view.geoar.gl.mode.BilligerLightShader.java
org.n52.geoar.view.geoar.gl.mode.BilligerTextureShader.java
org.n52.geoar.view.geoar.gl.mode.BoundingBox.java
org.n52.geoar.view.geoar.gl.mode.FeatureShader.java
org.n52.geoar.view.geoar.gl.mode.PhongFeatureShader.java
org.n52.geoar.view.geoar.gl.mode.RenderFeature2.java
org.n52.geoar.view.geoar.gl.mode.Spatial.java
org.n52.geoar.view.geoar.gl.mode.TextureFeatureShader.java
org.n52.geoar.view.geoar.gl.mode.Texture.java
org.n52.geoar.view.geoar.gl.mode.features.CubeFeature2.java
org.n52.geoar.view.geoar.gl.mode.features.FlatCircleFeature.java
org.n52.geoar.view.geoar.gl.mode.features.HeightMapFeature.java
org.n52.geoar.view.geoar.gl.mode.features.NewGridFeature.java
org.n52.geoar.view.geoar.gl.mode.features.ReferencedGridFeature.java
org.n52.geoar.view.geoar.gl.mode.features.SphereFeature.java
org.n52.geoar.view.geoar.gl.mode.features.TriangleFeature.java