// Anaglyph to Side-by-Side
// by hunterk
// license: public domain
//
// This shader is designed to convert Mednafen-VB's anaglyph 3D output to
// side-by-side 3D for use with VR headsets, such as Oculus Rift and Google Cardboard.

#pragma parameter eye_sep "Eye Separation" 0.35 -1.0 5.0 0.01
#pragma parameter y_loc "Vertical Placement" 0.30 -1.0 1.0 0.025
#pragma parameter BOTH "Horizontal Placement" 0.64 -2.0 2.0 0.005
#pragma parameter ana_zoom "Zoom" 0.75 -2.0 2.0 0.05
#pragma parameter WIDTH "Side-by-Side Image Width" 3.05 1.0 7.0 0.05
#pragma parameter HEIGHT "Side-by-Side Image Height" 2.0 1.0 5.0 0.1
#pragma parameter palette "Red Palette Toggle" 0.0 0.0 1.0 1.0
#pragma parameter warpX "warpX" 0.3 0.0 0.5 0.05
#pragma parameter warpY "warpY" 0.3 0.0 0.5 0.05
#ifdef PARAMETER_UNIFORM
uniform float eye_sep;
uniform float y_loc;
uniform float ana_zoom;
uniform float WIDTH;
uniform float BOTH;
uniform float HEIGHT;
uniform float palette;
uniform float warpX;
uniform float warpY;
#else
#define eye_sep 0.35
#define y_loc 0.30
#define ana_zoom 0.75
#define WIDTH 3.05
#define BOTH 0.64
#define HEIGHT 2.0
#define palette 0.0
#define warpX 0.3
#define warpY 0.3
#endif

/* COMPATIBILITY 
   - HLSL compilers
   - Cg   compilers
   - FX11 compilers
*/

#include "../compat_includes.inc"
uniform COMPAT_Texture2D(decal) : TEXUNIT0;
uniform float4x4 modelViewProj;

struct out_vertex
{
	float4 position : COMPAT_POS;
	float2 texCoord : TEXCOORD0;
#ifndef HLSL_4
	float4 Color    : COLOR;
#endif
};

out_vertex main_vertex(COMPAT_IN_VERTEX)
{
	out_vertex OUT;
#ifdef HLSL_4
	float4 position = VIN.position;
	float2 texCoord = VIN.texCoord;
#else
	OUT.Color = color;
#endif
	float2 shift = 0.5 * COMPAT_video_size / COMPAT_texture_size;
	OUT.position = mul(modelViewProj, position);
	OUT.texCoord = ((texCoord - shift) * ana_zoom + shift) * float2(WIDTH, HEIGHT) - float2(BOTH, 0.0);
	
	return OUT;
}

//warp function from Lottes' scanline shader
float2 Warp(float2 pos)
{
	pos = pos*2.0 - 1.0;    
	pos *= float2(1.0 + (pos.y * pos.y) * warpX, 1.0 + (pos.x * pos.x) * warpY);
	return pos * 0.5 + 0.5;
}

float4 anaglyph_to_sbs(float2 texture_size, float2 video_size, float2 texCoord, COMPAT_Texture2D(decal))
{
	float2 warpCoord1 = Warp((texCoord.xy - float2(eye_sep, y_loc))*(texture_size.xy / video_size.xy))*(video_size.xy / texture_size.xy);
	float2 warpCoord2 = Warp((texCoord.xy + float2(eye_sep, -y_loc))*(texture_size.xy / video_size.xy))*(video_size.xy / texture_size.xy);

	float2 fragCoord1 = warpCoord1 * video_size / texture_size;
	float2 fragCoord2 = warpCoord2 * video_size / texture_size;

	//ghetto imitation of CLAMP_TO_BORDER
	float4 frame1 = float4(0,0,0,0);
	if ( fragCoord1.x < 1.0 && fragCoord1.x > 0.0 && fragCoord1.y < 1.0 && fragCoord1.y > 0.0 )
	frame1 = COMPAT_Sample(decal, warpCoord1);

	float4 frame2 = float4(0,0,0,0);
	if ( fragCoord2.x < 1.0 && fragCoord2.x > 0.0 && fragCoord2.y < 1.0 && fragCoord2.y > 0.0 )
	frame2 = COMPAT_Sample(decal, warpCoord2);

	frame1.gb = frame1.rr;
	frame2.r = frame2.g;

	float4 final = float4(0,0,0,0);
	if (palette > 0.5)
		final = frame1 + frame2;
	else
		final = float4(frame1.r + frame2.r, 0.0, 0.0, 1.0);
	
	return final;
}

float4 main_fragment(COMPAT_IN_FRAGMENT) : COMPAT_Output
{
	return anaglyph_to_sbs(COMPAT_texture_size, COMPAT_video_size, VOUT.texCoord, decal);
}
COMPAT_END