@Override
  protected void setupShader(DrawContext dc) {
    if (shaderProgram == -1) {
      initShader(dc);
    }

    GL gl = dc.getGL().getGL2();
    gl.glUseProgram(shaderProgram);

    // double minElevation = ((ElevationTesselator)
    // dc.getGlobe().getTessellator()).getMinElevation();
    // double maxElevation = ((ElevationTesselator)
    // dc.getGlobe().getTessellator()).getMaxElevation();
    double minElevation = clamp(shaderMinElevation, minElevationClamp, maxElevationClamp);
    double maxElevation = clamp(shaderMaxElevation, minElevationClamp, maxElevationClamp);
    gl.glUniform1f(minElevationUniform, (float) minElevation);
    gl.glUniform1f(maxElevationUniform, (float) maxElevation);
    gl.glUniform1f(exaggerationUniform, (float) exaggeration);
    gl.glUniform1f(bakedExaggerationUniform, (float) bakedExaggeration);
    gl.glUniform1f(opacityUniform, (float) getOpacity());

    Matrix modelViewInv = dc.getView().getModelviewMatrix().getInverse();
    float[] modelViewInvArray =
        new float[] {
          (float) modelViewInv.m11,
          (float) modelViewInv.m21,
          (float) modelViewInv.m31,
          (float) modelViewInv.m41,
          (float) modelViewInv.m12,
          (float) modelViewInv.m22,
          (float) modelViewInv.m32,
          (float) modelViewInv.m42,
          (float) modelViewInv.m13,
          (float) modelViewInv.m23,
          (float) modelViewInv.m33,
          (float) modelViewInv.m43,
          (float) modelViewInv.m14,
          (float) modelViewInv.m24,
          (float) modelViewInv.m34,
          (float) modelViewInv.m44
        };
    gl.glUniformMatrix4fv(oldModelViewInverseUniform, 1, false, modelViewInvArray, 0);

    Vec4 eye = dc.getView().getEyePoint();
    gl.glUniform3f(eyePositionUniform, (float) eye.x, (float) eye.y, (float) eye.z);
    gl.glUniform3f(
        sunPositionUniform,
        (float) sunPositionNormalized.x,
        (float) sunPositionNormalized.y,
        (float) sunPositionNormalized.z);
  }
  protected void initShader(DrawContext dc) {
    GL gl = dc.getGL().getGL2();
    int v = gl.glCreateShader(GL.GL_VERTEX_SHADER);
    int f = gl.glCreateShader(GL.GL_FRAGMENT_SHADER);
    String vsrc = "", fsrc = "", line;

    try {
      BufferedReader brv =
          new BufferedReader(
              new InputStreamReader(this.getClass().getResourceAsStream("vertexshader.glsl")));
      while ((line = brv.readLine()) != null) {
        vsrc += line + "\n";
      }

      BufferedReader brf =
          new BufferedReader(
              new InputStreamReader(this.getClass().getResourceAsStream("fragmentshader.glsl")));
      while ((line = brf.readLine()) != null) {
        fsrc += line + "\n";
      }
    } catch (Exception e) {
      e.printStackTrace();
    }

    gl.glShaderSource(v, 1, new String[] {vsrc}, new int[] {vsrc.length()}, 0);
    gl.glCompileShader(v);
    gl.glShaderSource(f, 1, new String[] {fsrc}, new int[] {fsrc.length()}, 0);
    gl.glCompileShader(f);

    shaderProgram = gl.glCreateProgram();
    gl.glAttachShader(shaderProgram, v);
    gl.glAttachShader(shaderProgram, f);
    gl.glLinkProgram(shaderProgram);
    gl.glValidateProgram(shaderProgram);

    gl.glUseProgram(shaderProgram);
    gl.glUniform1i(gl.glGetUniformLocation(shaderProgram, "tex0"), 0);
    gl.glUniform1i(gl.glGetUniformLocation(shaderProgram, "tex1"), 1);
    minElevationUniform = gl.glGetUniformLocation(shaderProgram, "minElevation");
    maxElevationUniform = gl.glGetUniformLocation(shaderProgram, "maxElevation");
    minTexElevationUniform = gl.glGetUniformLocation(shaderProgram, "minTexElevation");
    maxTexElevationUniform = gl.glGetUniformLocation(shaderProgram, "maxTexElevation");
    exaggerationUniform = gl.glGetUniformLocation(shaderProgram, "exaggeration");
    bakedExaggerationUniform = gl.glGetUniformLocation(shaderProgram, "bakedExaggeration");
    opacityUniform = gl.glGetUniformLocation(shaderProgram, "opacity");
    eyePositionUniform = gl.glGetUniformLocation(shaderProgram, "eyePosition");
    sunPositionUniform = gl.glGetUniformLocation(shaderProgram, "sunPosition");
    oldModelViewInverseUniform = gl.glGetUniformLocation(shaderProgram, "oldModelViewInverse");
  }
 public void unbind(GL gl) {
   gl.glUseProgram(0);
 }
 public void bind(GL gl) {
   gl.glUseProgram(program);
 }