/*
 * vertex shader for (reflected) 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 Model_TransformMatrix;
uniform mat3 NormalMatrix;
uniform vec4 Light0Position;

uniform sampler2D heightmap;

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 float fog;

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;

  fog = 0.0;

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

  gl_ClipDistance[0] = dot((Model_TransformMatrix * vec4(my_ObjPosition, 1.0)).xyz, vec3(0, -1, 0));

  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.02, texcoords.y)).r - 0.5) * 0.1;
  float x_right = (texture2D(heightmap, vec2(texcoords.x + 0.02, 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;
  my_Normal = vec3(x_diff*25, 1.0, z_diff*25);
}
