////////////////////////////////////////////////////////////////////////////////////////////////////
// font.fx
////////////////////////////////////////////////////////////////////////////////////////////////////



// Transforms
////////////////////////////////////////////////////////////////////////////////////////////////////
float4x4 g_wvp_mtx;
float4x4 g_world_mtx;
float4x4 g_shadow_mtx;




// Lighting
////////////////////////////////////////////////////////////////////////////////////////////////////
float4 g_sun_dir;




// Textures & samplers
////////////////////////////////////////////////////////////////////////////////////////////////////
texture2D g_shadowmap_tex;

sampler2D g_shadowmap_samp = sampler_state 
{
		texture = <g_shadowmap_tex>;
		MinFilter = POINT;
		MagFilter = POINT;
		MipFilter = NONE;
		AddressU  = CLAMP;        
		AddressV  = CLAMP;
		AddressW  = CLAMP;
};




// Vertex shaders
////////////////////////////////////////////////////////////////////////////////////////////////////
void vs_shadowed(
    in float3 iPos			: POSITION0,
    in float3 iNrm			: NORMAL0,
    in float4 iCol			: COLOR0,

    out float4 oPos			: POSITION,
    out float3 oNrm			: TEXCOORD0,
    out float4 oSurfacePos	: TEXCOORD1,
    out float4 oCol			: COLOR0)
{
    // Transform position to clip space
    oPos = mul( float4( iPos.xyz, 1.0 ), g_wvp_mtx );

    // Copy color
    oCol = iCol;

    // Transform normal to world space
    oNrm = mul( iNrm, (float3x3)g_world_mtx );

	// Transform vertex position to shadow map space
	oSurfacePos = mul( float4( iPos.xyz, 1.0 ), g_shadow_mtx );	
}

void vs_main(
    in float3 iPos			: POSITION0,
    in float3 iNrm			: NORMAL0,
    in float4 iCol			: COLOR0,

    out float4 oPos			: POSITION,
    out float3 oNrm			: TEXCOORD0,
    out float4 oCol			: COLOR0)
{
    // Transform position to clip space
    oPos = mul( float4( iPos.xyz, 1.0 ), g_wvp_mtx );

    // Copy color
    oCol = iCol;

    // Transform normal to world space
    oNrm = mul( iNrm, (float3x3)g_world_mtx );
}



// Pixel shaders
////////////////////////////////////////////////////////////////////////////////////////////////////
void ps_shadowed(
    in float3 iNrm			: TEXCOORD0,
    in float4 iSurfacePos	: TEXCOORD1,
    in float4 iCol			: COLOR0,

    out float4 oCol			: COLOR0 )
{
		float3 n = normalize( iNrm );
		float light = saturate( dot( n, -g_sun_dir ));

		// Get shadow
		iSurfacePos.xyz /= iSurfacePos.w;
		float shadowmap_depth = tex2D( g_shadowmap_samp, iSurfacePos.xy ).r;
		float shadow = (shadowmap_depth + 0.00075f > iSurfacePos.z) ? 1.0f : 0.25f;

		oCol = iCol * light * shadow * 2.0f;
}

void ps_main(
    in float3 iNrm			: TEXCOORD0,
    in float4 iCol			: COLOR0,

    out float4 oCol			: COLOR0 )
{
		float3 n = normalize( iNrm );
		float light = 0.5f + ( 0.5f * dot( n, -g_sun_dir ));

		oCol = iCol * light * 2.0f;
}



// Techniques
////////////////////////////////////////////////////////////////////////////////////////////////////
technique main
{
   pass p0
   {
		ZEnable = true;
		AlphaBlendEnable = false;
		VertexShader = compile vs_3_0 vs_main();
		PixelShader  = compile ps_3_0 ps_main();
   }
}

technique shadowed
{
   pass p0
   {
		ZEnable = true;
		AlphaBlendEnable = false;
		VertexShader = compile vs_3_0 vs_shadowed();
		PixelShader  = compile ps_3_0 ps_shadowed();
   }
}
