/// LSU EE 4702-1 (Fall 2023), GPU Programming
//
 /// Simple Rendering Pipeline

 /// 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_Mat
{
  vec4 color_front, color_back;
};


// Declare variables for communication between vertex shader
// and fragment shader.
//
#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;
layout ( location = LOC_IN_COLOR ) in vec4 in_color;

// 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 color;
  vec2 texcoord;
} Out;

#endif

 // Entry Point for Vertex Shader Code
//
#ifdef _VERTEX_SHADER_
void
vs_main_classic()
{
  // Transform vertex coordinate to clip space.
  gl_Position = clip_from_object * in_vertex;
  //
  // Note: gl_Position is one of the few pre-defined outputs.

  // Compute eye-space coordinates for vertex and normal.
  //
  vec4 vertex_e = eye_from_object * in_vertex;
  vec3 normal_e = normalize( mat3(eye_from_object) * in_normal );

  // Call our lighting routine to compute the lighted color of this
  // vertex.
  //
  Out.color = generic_lighting( vertex_e, in_color, normal_e );

  // 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 color;
  vec2 texcoord;
} In;

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

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

  // Multiply filtered texel color with lighted color of fragment or
  // unlighted back.
  //
  out_frag_color = texel * ( gl_FrontFacing ? In.color : color_back );
}

#endif