/*
 * vertex shader for heightmap rendering
 *
 * renders the given mesh and sets each y-coordinate
 * by using information from the given texture
 *
 * written by:
 * christian moellinger <ch.moellinger@gmail.com>
 * 01/2011
 */

#version 330 core

uniform mat4 Camera_ProjectionMatrix;
uniform mat4 Camera_TransformMatrix;
uniform mat4 Camera_TempTransformMatrix;
uniform mat4 Model_TransformMatrix;
uniform mat3 NormalMatrix;
uniform vec4 Light0Position;

uniform sampler2D heightmap;

//uniform int instance;

in vec3 in_Position;

out vec2 texcoords;
out vec3 my_ObjPosition;
out vec4 my_WorldPosition;
out vec3 my_EyeDir;
out vec3 my_LightDir;
out vec3 my_Normal;
out mat3 NormalMatrix2;
out vec2 my_ShadowMapCoords;
out vec4 finalPosition;

out float fog;

/*out mat4 NormalMatrix2;*/

void main(void)
{
  const float terrain_resolution = 256;

  mat4 ProjectionMatrix = Camera_ProjectionMatrix;
  mat4 ModelViewMatrix = Camera_TransformMatrix * Model_TransformMatrix;

  vec3 real_in_Position = in_Position;
  real_in_Position.x += gl_InstanceID / terrain_resolution;

  texcoords = vec2(real_in_Position.x, real_in_Position.z);

  my_ObjPosition = real_in_Position;

  my_ObjPosition.y = (texture2D(heightmap, texcoords).r - 0.5) * 0.1;

  my_WorldPosition = Model_TransformMatrix * vec4(my_ObjPosition, 1.0);

  fog = clamp(-my_ObjPosition.y * 35, 0.0, 1.0);

  finalPosition = ProjectionMatrix * ModelViewMatrix * vec4(my_ObjPosition, 1.0);
  gl_Position = finalPosition;

  vec3 vVertex = (ModelViewMatrix * vec4(my_ObjPosition, 1.0)).xyz;
  vec3 my_Lightpos = (ModelViewMatrix * Light0Position).xyz;

  NormalMatrix2 = NormalMatrix;
  my_LightDir = my_Lightpos - vVertex;
  my_EyeDir = -vVertex;

  //to calculate the normal , we compare the heights of the some points in the neighboorhood

  float x_left = (texture2D(heightmap, vec2(texcoords.x - 0.01, texcoords.y)).r - 0.5) * 0.1;
  float x_right = (texture2D(heightmap, vec2(texcoords.x + 0.01, texcoords.y)).r - 0.5) * 0.1;

  float z_left = (texture2D(heightmap, vec2(texcoords.x, texcoords.y - 0.01)).r - 0.5) * 0.1;
  float z_right = (texture2D(heightmap, vec2(texcoords.x, texcoords.y + 0.01)).r - 0.5) * 0.1;

  float x_diff = x_left - x_right;
  float z_diff = z_left - z_right;

  //vec3 my_Tangent = vec3(1.0, 0.0, -x_diff);
  my_Normal = normalize(vec3(x_diff, 0.05, z_diff));

  vec3 my_Tangent;
  my_Tangent.x = my_Normal.y * my_Normal.z - my_Normal.x * my_Normal.z;
  my_Tangent.y = -(my_Normal.x * my_Normal.z - (-my_Normal.y) * my_Normal.z);
  my_Tangent.z = my_Normal.x * my_Normal.x - (-my_Normal.y) * my_Normal.y;
  my_Tangent = normalize(-my_Tangent);



  vec3 tempVec = my_Lightpos - vVertex;

  my_EyeDir = vVertex;

  vec3 n = normalize(NormalMatrix * my_Normal);
  vec3 t = normalize(NormalMatrix * my_Tangent);
  vec3 b = cross(n, t);

  vec3 v;
  v.x = dot(tempVec, t);
  v.y = dot(tempVec, b);
  v.z = dot(tempVec, n);
  my_LightDir = normalize(v);

  tempVec = -vVertex;
  v.x = dot(tempVec, t);
  v.y = dot(tempVec, b);
  v.z = dot(tempVec, n);

  my_EyeDir = normalize(v);
}
