/*===============================================================================*\
|########################   [GLSL PSX FX SHADER V1.0]    #########################|
|########################	   [BY ASMODEAN@PCSX2]	     #########################|
||																				 ||
||			  		   ,---.  .---..-.   .-.  ,---..-.   .-.					 ||
||					   | .-.\( .-._)) \_/ /   | .-' ) \_/ / 					 ||
||					   | |-' )) \  (_)   /    | `-.(_)   /  					 ||
||					   | |--'_ \ \   / _ \    | .-'  / _ \  					 ||
||					   | | ( `-'  ) / / ) \   | |   / / ) \ 					 ||
||					   /(   `----' `-' (_)-'  )\|  `-' (_)-'					 ||
||					  (__)                   (__)           					 ||
||																				 ||
||		  This program is free software; you can redistribute it and/or			 ||
||		  modify it under the terms of the GNU General Public License			 ||
||		  as published by the Free Software Foundation; either version 2		 ||
||		  of the License, or (at your option) any later version.				 ||
||																				 ||
||		  This program is distributed in the hope that it will be useful,		 ||
||		  but WITHOUT ANY WARRANTY; without even the implied warranty of		 ||
||		  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the			 ||
||		  GNU General Public License for more details.							 ||
||																				 ||
|#################################################################################|
\*===============================================================================*/
#version 430 compatibility

/*------------------------------------------------------------------------------
								[EXTENSIONS]
------------------------------------------------------------------------------*/

#extension GL_NV_gpu_shader5 : enable
#extension GL_ARB_gpu_shader5 : enable  
#extension GL_ARB_shader_precision : enable
#extension GL_ARB_conservative_depth : enable
#extension GL_ARB_uniform_buffer_object : enable
#extension GL_ARB_vertex_buffer_object : enable
#extension GL_ARB_vertex_attrib_64bit : enable
#extension GL_NV_explicit_multisample : enable
#extension GL_ARB_shader_texture_lod : enable
#extension GL_ARB_texture_multisample : enable
#extension GL_ARB_texture_rectangle : enable
#extension GL_ARB_sample_shading : enable

precision highp int;
precision highp float;

/*------------------------------------------------------------------------------
                     [DEFINITIONS & LOCAL VARIABLES]
------------------------------------------------------------------------------*/

#define SPRITE_INTERPOLATION 0 /*Make 1 to enable 2DAA. Make 0 to enable FXAA (Default)*/

#define FXAA_PIXEL_SIZE vec2(1.0/2560.0, 1.0/1440.0)
#define MAX_LIGHTS 32
#define NUM_LIGHTS 32

uniform sampler2D Vectors;

precise uniform float FXAA_SUBPIX_SHIFT = (1.0/16.0);
precise uniform float rt_w = (2560.0);
precise uniform float rt_h = (1440.0);
precise uniform float Depth;

uniform vec4 color;

uniform vec2 TextureSize = FXAA_PIXEL_SIZE;
precise float dx = (1.0 / TextureSize.x);
precise float dy = (1.0 / TextureSize.y);
precise float att;

precise in int gl_VertexID;
precise in vec4 position;
precise in vec4 vertex;
precise in vec3 Normal;
precise in vec2 texCoord0;
precise in vec2 texCoord1;
precise in vec3 tangent;
precise in vec4 inputColor;
precise vec3 lightVec[MAX_LIGHTS]; 
precise vec3 lightPosition;
precise vec4 shadowCoord;
precise vec3 eyeVec;

smooth out vec3 vNormal;
smooth out vec3 vLightPos;
smooth out vec2 vTexCoords;
smooth out vec4 gl_Position;
smooth out vec4 posPos;
smooth out vec4 gl_Color;
smooth out vec4 vertOutFragColor;

precise mat3 normalMatrix;
precise uniform mat4 MVP;
precise uniform mat4 ModelView;

out VertexData
{
   precise vec3 normal;
} vertexData;

/*------------------------------------------------------------------------------
                        [MAIN() & VERTEX CODE SECTION]
------------------------------------------------------------------------------*/

void main()
{
	vTexCoords = texCoord0.st;
	gl_Position = position;
	gl_Position.z = Depth;
	vNormal = Normal;
	gl_Color = inputColor;
	vertexData.normal = Normal;
	
	float VertexAccuracy = texture(Vectors, vTexCoords).a;
    vec4 displaced = vec4(position.x, position.y, VertexAccuracy, 1.0);
    gl_Position = displaced;
	
	vertexData.normal = normalize(gl_NormalMatrix * gl_Normal);
	
	normalMatrix[0] = normalize (ModelView[0].xyz);
    normalMatrix[1] = normalize (ModelView[1].xyz);
    normalMatrix[2] = normalize (ModelView[2].xyz);
	
	vec3 v = vec3(gl_ModelViewMatrix * gl_Vertex);
	vec3 n = normalize (normalMatrix * Normal);
    vec3 t = normalize (normalMatrix * tangent);
    vec3 b = cross (n, t);

    vNormal = gl_NormalMatrix * gl_Normal;

	precise vec4 vertexPos = ModelView * vertex;
    precise vec3 vertexEyePos = vertexPos.xyz / vertexPos.w;
	
	vec3 vVertex = vec3(gl_ModelViewMatrix * gl_Vertex);
	vec3 lightDir = vec3(gl_LightSource[0].position.xyz - vVertex);
	eyeVec = -vVertex;
	
	float d = length(lightDir);
	
	att = 1.0 / ( gl_LightSource[0].constantAttenuation + 
				(gl_LightSource[0].linearAttenuation*d) + 
				(gl_LightSource[0].quadraticAttenuation*d*d) );
	
	shadowCoord = gl_TextureMatrix[7] * gl_Vertex;
	
	for (int i=0; i<NUM_LIGHTS; i++)
	{
		lightPosition = normalize(gl_LightSource[i].position.xyz - (gl_ModelViewMatrix * gl_Vertex).xyz); 
		
		vec3 v;
		v.x = dot (lightPosition, t);
		v.y = dot (lightPosition, b);
		v.z = dot (lightPosition, n);
		lightVec[i] = normalize (v);
	}
	
    gl_Position = gl_ModelViewProjectionMatrix * position;
	gl_Position = ftransform();
	gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
	
	gl_FogFragCoord = gl_Position.z;

	gl_TexCoord[0] = gl_MultiTexCoord0;
	
	#if (SPRITE_INTERPOLATION == 1)
		float x = (0.75/4096.0);
		float y = (0.75/2048.0);
		vec2 dg1 = vec2(x, y);  	vec2 dg2 = vec2(-x, y);
		vec2 sd1 = dg1*(0.5/0.75);	vec2 sd2 = dg2*(0.5/0.75);
		vec2 ddx = vec2(x, 0.0); 	vec2 ddy = vec2(0.0, y);
	
		gl_TexCoord[1].xy = gl_TexCoord[0].xy - sd1;
		gl_TexCoord[2].xy = gl_TexCoord[0].xy - sd2;
		gl_TexCoord[3].xy = gl_TexCoord[0].xy + sd1;
		gl_TexCoord[4].xy = gl_TexCoord[0].xy + sd2;
		gl_TexCoord[5].xy = gl_TexCoord[0].xy - dg1;
		gl_TexCoord[6].xy = gl_TexCoord[0].xy + dg1;
		gl_TexCoord[5].zw = gl_TexCoord[0].xy - dg2;
		gl_TexCoord[6].zw = gl_TexCoord[0].xy + dg2;
		gl_TexCoord[1].zw = gl_TexCoord[0].xy - ddy;
		gl_TexCoord[2].zw = gl_TexCoord[0].xy + ddx;
		gl_TexCoord[3].zw = gl_TexCoord[0].xy + ddy;
		gl_TexCoord[4].zw = gl_TexCoord[0].xy - ddx;
	#else
		gl_TexCoord[1] = gl_MultiTexCoord0.xxxy + vec4(    -dx,   0,  dx, -2.0*dy);  //  A1 B1 C1
		gl_TexCoord[2] = gl_MultiTexCoord0.xxxy + vec4(    -dx,   0,  dx,     -dy);  //   A  B  C
		gl_TexCoord[3] = gl_MultiTexCoord0.xxxy + vec4(    -dx,   0,  dx,       0);  //   D  E  F
		gl_TexCoord[4] = gl_MultiTexCoord0.xxxy + vec4(    -dx,   0,  dx,      dy);  //   G  H  I
		gl_TexCoord[5] = gl_MultiTexCoord0.xxxy + vec4(    -dx,   0,  dx,  2.0*dy);  //  G5 H5 I5
		gl_TexCoord[6] = gl_MultiTexCoord0.xyyy + vec4(-2.0*dx, -dy,   0,      dy);  //  A0 D0 G0
		gl_TexCoord[7] = gl_MultiTexCoord0.xyyy + vec4( 2.0*dx, -dy,   0,      dy);  //  C4 F4 I4 
	#endif

	
	precise vec2 rcpFrame = vec2(1.0/rt_w, 1.0/rt_h);
	posPos.xy = gl_MultiTexCoord0.xy;
	posPos.zw = gl_MultiTexCoord0.xy - (rcpFrame * (FXAA_SUBPIX_SHIFT));

}
