/// LSU EE 4702-1 (Fall 2023), GPU Programming
//
 /// Fragment Shader / Phong Shading Demonstration

 /// See demo-09-shader.cc for details.


// Specify version of OpenGL Shading Language.
//
#version 460

#extension GL_GOOGLE_include_directive : enable
#include <light.h>
#include "shader-common-generic-lighting.h"


///
 /// Shader Uniforms
///

// Note: this uniform is also defined in transform.h.
layout ( binding = BIND_TRANSFORM ) uniform Uni_Transform
{
  //   Course Name           OpenGL Name
  mat4 eye_from_object;   // gl_ModelViewMatrix
  mat4 clip_from_eye;     // gl_ProjectionMatrix
  mat4 clip_from_object;  // gl_ModelViewProjectionMatrix
  mat4 object_from_eye;   // gl_ModelViewMatrixInverse
  mat4 eye_from_clip;     // gl_ProjectionMatrixInverse
  mat4 object_from_clip;  // gl_ModelViewProjectionMatrixInverse
};

layout (binding = BIND_MAT_COLOR ) uniform Uni_Material
{
  vec4 color_front, color_back;
};


#ifdef _VERTEX_SHADER_

 /// Vertex Shader Inputs
///
layout ( location = LOC_IN_POS ) in vec4 in_vertex;
layout ( location = LOC_IN_NORMAL ) in vec3 in_normal;
layout ( location = LOC_IN_TCOOR ) in vec2 in_tcoor;

// Declare some outputs as a group. These are grouped together
// because they are used by the generic lighting routine.
//
layout (location = 0) out VF
{
  vec4 vertex_e;
  vec3 normal_e;
  vec2 texcoord;
} Out;

void
vs_main_phong()
{
  // Transform vertex to clip space.
  gl_Position = clip_from_object * in_vertex;

  // Compute eye-space vertex coordinate and normal.
  // These are outputs of the vertex shader and inputs to the frag shader.
  //
  Out.vertex_e = eye_from_object * in_vertex;
  Out.normal_e = normalize( mat3(eye_from_object) * in_normal );

  // Copy texture coordinate to output (no need to modify it).
  Out.texcoord = in_tcoor;
}
#endif


#ifdef _FRAGMENT_SHADER_

 /// Fragment Shader Uniform
//
layout ( binding = BIND_TEXUNIT ) uniform sampler2D tex_unit_0;

 /// Fragment Shader Inputs
//
layout ( location = 0 ) in VF
{
  vec4 vertex_e;
  vec3 normal_e;
  vec2 texcoord;
} In;

 /// Fragment Shader Output
//
layout ( location = 0 ) out vec4 out_frag_color;

void
fs_main_phong()
{
  // Get filtered texel.
  //
  vec4 texel = texture( tex_unit_0, In.texcoord );

  vec4 our_color = gl_FrontFacing ? color_front : color_back;
  vec4 lighted_color = generic_lighting( In.vertex_e, our_color, In.normal_e );

  // Multiply filtered texel color with lighted color of fragment.
  //
  out_frag_color = texel * lighted_color;
}
#endif