//--------------------------------------------------------------------------------------
// File: ShaderPyramid.fx
//
//--------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------
// Global variables
//--------------------------------------------------------------------------------------
float4 g_AmbientColor;      // Material's ambient color
float4 g_DiffuseColor;      // Material's diffuse color

texture g_Texture;              // Color texture for mesh
texture g_Texture1;              // Color texture for mesh
texture g_Texture2;              // Color texture for mesh
texture g_Texture3;
texture g_Texture4;

matrix View;
matrix Projection;
matrix World;
        
//licht
float4 vLightDir;
static bool bAlphaBlend;

//--------------------------------------------------------------------------------------
// Texture samplers
//--------------------------------------------------------------------------------------
sampler MeshTextureSampler = sampler_state
{
    Texture = <g_Texture>;
    MipFilter = LINEAR;
    MinFilter = LINEAR;
    MagFilter = LINEAR;
    AddressU = wrap; //for car.x, veroorzaakt seam op skybox, gebruik clamp voor skybox
    AddressV = wrap;
};
sampler MeshTextureSampler1 = sampler_state
{
    Texture = <g_Texture1>;
    MipFilter = LINEAR;
    MinFilter = LINEAR;
    MagFilter = LINEAR;
};
sampler MeshTextureSampler2 = sampler_state
{
    Texture = <g_Texture2>;
    MipFilter = LINEAR;
    MinFilter = LINEAR;
    MagFilter = LINEAR;
};
sampler MeshTextureSampler3 = sampler_state
{
    Texture = <g_Texture3>;
    MipFilter = LINEAR;
    MinFilter = LINEAR;
    MagFilter = LINEAR;
};
sampler MeshTextureSampler4 = sampler_state
{
    Texture = <g_Texture4>;
    MipFilter = LINEAR;
    MinFilter = LINEAR;
    MagFilter = LINEAR;
};

sampler SkyboxSampler = sampler_state
{
    Texture = <g_Texture>;
    MipFilter = LINEAR;
    MinFilter = LINEAR;
    MagFilter = LINEAR;
    AddressU = clamp; //clamp voor skybox om horrible seam te voorkomen
    AddressV = clamp;
};

//--------------------------------------------------------------------------------------
//POSITION_NORMAL--POSITION_NORMAL--POSITION_NORMAL--POSITION_NORMAL--POSITION_NORMAL--POSITION_NORMAL--
//--------------------------------------------------------------------------------------

struct VS_INPUT_POSITION
{
    float4 Pos : POSITION;
    float4 Norm : NORMAL;

};
//--------------------------------------------------------------------------------------
// POSITION Vertex shader output structure = Pixel shader Input Structure
//--------------------------------------------------------------------------------------
struct PS_INPUT_POSITION
{
    float4 Pos : POSITION;
    float3 Norm : TEXCOORD0;//NORMAL not existing semantics for pixel shaders, so we use TEX...

};
//--------------------------------------------------------------------------------------
// POSITION Vertex Shader
//--------------------------------------------------------------------------------------
PS_INPUT_POSITION VS_POSITION( VS_INPUT_POSITION input )
{
    PS_INPUT_POSITION output = (PS_INPUT_POSITION)0;
    output.Pos = mul( input.Pos, World );
    output.Pos = mul( output.Pos, View );
    output.Pos = mul( output.Pos, Projection );
    output.Norm = -normalize(mul( input.Norm, (float3x3)World ));

    return output;
}
//--------------------------------------------------------------------------------------
// POSITION Pixel Shader
//--------------------------------------------------------------------------------------
//deze is de orginele, goedkopere pixel lighter

float4 PS_POSITION( PS_INPUT_POSITION input): COLOR0
{

    float4 finalColor = 0;
    finalColor = g_DiffuseColor +g_AmbientColor;
    finalColor.xyz = saturate( dot( vLightDir.xyz,input.Norm)) * finalColor.xyz ;
    finalColor.a = g_DiffuseColor.a;
    return finalColor;
}
technique RenderPosition
{

    pass P0
    {   
        AlphaBlendEnable=true;
		SrcBlend=srcalpha;
		DestBlend=invsrcalpha;
       
        VertexShader = compile vs_2_0 VS_POSITION();
        PixelShader  = compile ps_2_0 PS_POSITION(); 
    }
}





//--------------------------------------------------------------------------------------
//ambient_ambient_ambient_ambient_ambient_ambient_ambient_ambient_ambient_ambient_ambient_
//--------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------
// DIFFUSE Vertex shader input structure
//--------------------------------------------------------------------------------------
struct VS_INPUT_COLOR
{
    float4 Pos : POSITION;
    float4 Color : COLOR;
};
//--------------------------------------------------------------------------------------
// DIFFUSE Vertex shader output structure = Pixel shader Input Structure
//--------------------------------------------------------------------------------------
struct PS_INPUT_COLOR
{
    float4 Pos : POSITION;
    float4 Color: COLOR0;
};
//--------------------------------------------------------------------------------------
// DIFFUSE Vertex Shader
//--------------------------------------------------------------------------------------
PS_INPUT_COLOR VS_COLOR( VS_INPUT_COLOR input )
{
    PS_INPUT_COLOR output = (PS_INPUT_COLOR)0;
    output.Pos = mul( input.Pos, World );
    output.Pos = mul( output.Pos, View );
    output.Pos = mul( output.Pos, Projection );
    output.Color = input.Color;
    return output;
}
//--------------------------------------------------------------------------------------
// DIFFUSE Pixel Shader
//--------------------------------------------------------------------------------------
//deze is de orginele, goedkopere pixel lighter

float4 PS_COLOR( PS_INPUT_COLOR input): COLOR0
{

    float4 finalColor = 0;
    finalColor = input.Color;
    return finalColor;
}
technique RenderColor
{
    pass P0
    {          
        VertexShader = compile vs_2_0 VS_COLOR();
        PixelShader  = compile ps_2_0 PS_COLOR(); 
    }
}



//--------------------------------------------------------------------------------------
//NORMALCOLOR_NORMALCOLOR_NORMALCOLOR_NORMALCOLOR_NORMALCOLOR_NORMALCOLOR_NORMALCOLOR
//DIFFUSE_DIFFUSE_DIFFUSE_DIFFUSE_DIFFUSE_DIFFUSE_DIFFUSE_DIFFUSE_DIFFUSE_DIFFUSE_DIFFUSE
//--------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------
// NORMALCOLOR Vertex shader input structure
//--------------------------------------------------------------------------------------
struct VS_INPUT_NORMALCOLOR
{
    float4 Pos : POSITION;
    float4 Norm : NORMAL;
    float4 Color : COLOR;
};
//--------------------------------------------------------------------------------------
// NORMALCOLOR Pixel shader input structure
//--------------------------------------------------------------------------------------
struct PS_INPUT_NORMALCOLOR
{
    float4 Pos : POSITION;
    float3 Norm : TEXCOORD0;//NORMAL not existing semantics for pixel shaders, so we use TEX...
    float4 Color: COLOR0;
};
//--------------------------------------------------------------------------------------
// NORMALCOLOR Vertex Shader
//--------------------------------------------------------------------------------------
PS_INPUT_NORMALCOLOR VS_NORMALCOLOR( VS_INPUT_NORMALCOLOR input )
{
    PS_INPUT_NORMALCOLOR output = (PS_INPUT_NORMALCOLOR)0;
    output.Pos = mul( input.Pos, World );
    output.Pos = mul( output.Pos, View );
    output.Pos = mul( output.Pos, Projection );
    output.Norm = -normalize(mul( input.Norm, (float3x3)World ));
    
    output.Color = input.Color;
    return output;
}
//--------------------------------------------------------------------------------------
// NORMALCOLOR Pixel shader 
//--------------------------------------------------------------------------------------
float4 PS_NORMALCOLOR( PS_INPUT_NORMALCOLOR input) : COLOR0
{
    float4 finalColor = (float4)0;
    finalColor = input.Color;
    finalColor.xyz = saturate( dot( vLightDir.xyz,input.Norm)) * finalColor.xyz ;
    return finalColor;
}
technique RenderNormalColor
{
    pass P0
    {          
        VertexShader = compile vs_2_0 VS_NORMALCOLOR();
        PixelShader  = compile ps_2_0 PS_NORMALCOLOR(); // trivial pixel shader (could use FF instead if desired)
    }
}




//--------------------------------------------------------------------------------------
//TEXTURED_TEXTURED_TEXTURED_TEXTURED_TEXTURED_TEXTURED_TEXTURED_TEXTURED_TEXTURED_TEXTURED_
//--------------------------------------------------------------------------------------
struct VS_INPUT_TEXTURED
{
    float4 Pos : POSITION;
    float2 Tex : TEXCOORD;
};
struct PS_INPUT_TEXTURED
{
    float4 Pos : POSITION;
    float2 Tex  : TEXCOORD0;
};
//--------------------------------------------------------------------------------------
// TEXTURED Vertex Shader
//--------------------------------------------------------------------------------------
PS_INPUT_TEXTURED VS_TEXTURED( VS_INPUT_TEXTURED input )
{
    PS_INPUT_TEXTURED output = (PS_INPUT_TEXTURED)0;
    output.Pos = mul( input.Pos, World );
    output.Pos = mul( output.Pos, View );
    output.Pos = mul( output.Pos, Projection );
    output.Tex = input.Tex;
    return output;
}
//--------------------------------------------------------------------------------------
// TEXTURED Pixel shader 
//--------------------------------------------------------------------------------------
float4 PS_TEXTURED( PS_INPUT_TEXTURED input): COLOR0
{

    float4 finalColor = 0;
    finalColor = tex2D(MeshTextureSampler, input.Tex);
    return finalColor;
}
float4 PS_SKYBOX( PS_INPUT_TEXTURED input): COLOR0
{
    float4 finalColor = 0;
    finalColor = tex2D(SkyboxSampler, input.Tex);
    return finalColor;
}
float4 PS_TILEABLELANDSCAPE(PS_INPUT_TEXTURED input) : COLOR0
{
	float4 finalColor = 0;
	input.Tex *= 16;
	finalColor = tex2D(MeshTextureSampler, input.Tex);
	return finalColor;
}
technique RenderTexture
{
    pass P0
    {          
        VertexShader = compile vs_2_0 VS_TEXTURED();
        PixelShader  = compile ps_2_0 PS_TEXTURED(); 
    }
}
technique RenderTextureAlphaBlend
{
    pass P0
    {     
		AlphaBlendEnable=true;
		SrcBlend=srcalpha;
		DestBlend=invsrcalpha;
        
        VertexShader = compile vs_2_0 VS_TEXTURED();
        PixelShader  = compile ps_2_0 PS_TEXTURED(); 
		//AlphaBlendEnable=false;//mag niet
    }
}
technique RenderSkybox
{
    pass P0
    {          
        VertexShader = compile vs_2_0 VS_TEXTURED();
        PixelShader  = compile ps_2_0 PS_SKYBOX(); 
    }
}
technique RenderTileableLandscape
{
	pass P0
	{
		AlphaBlendEnable = true;
		SrcBlend = srcalpha;
		DestBlend = invsrcalpha;
		
		VertexShader = compile vs_2_0 VS_TEXTURED();
		PixelShader  = compile ps_2_0 PS_TILEABLELANDSCAPE(); 
	}
}





//--------------------------------------------------------------------------------------
//NORMALTEXTURED_NORMALTEXTURED_NORMALTEXTURED_NORMALTEXTURED_NORMALTEXTURED_NORMALTEXTURED_
//--------------------------------------------------------------------------------------
struct VS_INPUTNORMALTEXTURED
{
    float4 Pos : POSITION;
    float4 Norm : NORMAL;
    float2 Tex : TEXCOORD;
};
struct PS_INPUTNORMALTEXTURED
{
    float4 Pos : POSITION;
    float3 Norm : TEXCOORD0;
    float2 Tex : TEXCOORD1;//0 tot 16
};
//--------------------------------------------------------------------------------------
// Vertex Shader
//--------------------------------------------------------------------------------------
PS_INPUTNORMALTEXTURED VS_NORMALTEXTURED( VS_INPUTNORMALTEXTURED input )
{
    PS_INPUTNORMALTEXTURED output = (PS_INPUTNORMALTEXTURED)0;
	
    output.Pos = mul( input.Pos, World );
    output.Pos = mul( output.Pos, View );
    output.Pos = mul( output.Pos, Projection );
    output.Tex = input.Tex;
    output.Norm = -normalize(mul( input.Norm, (float3x3)World ));//correct using (float3x3) to remove translation ! http://en.wikipedia.org/wiki/Translation_matrix
    //output.Norm = -normalize(input.Norm);
    return output;
}
//--------------------------------------------------------------------------------------
// Pixel shader 
//--------------------------------------------------------------------------------------

float4 PS_NORMALTEXTURED( PS_INPUTNORMALTEXTURED input) : COLOR0
{
    float4 finalColor = 0;
    //add texture color
    finalColor = tex2D(MeshTextureSampler, input.Tex);
    //use normal lighting
    finalColor.xyz = saturate( dot( vLightDir.xyz,input.Norm) * finalColor.xyz) ;
    //done 
    return finalColor;
}
float4 PS_MULTITEXTURED( PS_INPUTNORMALTEXTURED input) : COLOR0
{
    float4 finalColor = 0;
    float4 Color1=0,Color2=0;
    Color1 = tex2D(MeshTextureSampler, input.Tex);//color of opaque texture
    Color2 = tex2D(MeshTextureSampler1, input.Tex);//color of alpha texture
    finalColor = lerp(Color1,Color2,Color2.a);
    finalColor.xyz = saturate( dot( vLightDir.xyz,input.Norm)) * finalColor.xyz ;
    //done
    return finalColor;
}
float4 PS_LANDSCAPE( PS_INPUTNORMALTEXTURED input): COLOR0
{
	float4 finalColor = 0;
	float4 controlColor = tex2D(MeshTextureSampler1,input.Tex);
	// r is amount of sand (sampler2) , g is amount of grass (sampler3) and b is amout of rock (sampler3)
	input.Tex *=256;
	finalColor += controlColor.x*tex2D(MeshTextureSampler2,input.Tex);
	finalColor += controlColor.y*tex2D(MeshTextureSampler3,input.Tex);
	finalColor += controlColor.z*tex2D(MeshTextureSampler4,input.Tex);
	finalColor.xyz = saturate(dot(vLightDir.xyz,input.Norm)) * finalColor.xyz;
	return finalColor;
}


technique RenderNormalTexture
{
    pass P0
    {      
        VertexShader = compile vs_2_0 VS_NORMALTEXTURED();
        PixelShader  = compile ps_2_0 PS_NORMALTEXTURED(); 
    }
}
technique RenderNormalTextureAlphaBlend
{
    pass P0
    {     
    	AlphaBlendEnable=true;
        SrcBlend=srcalpha;
        DestBlend=invsrcalpha;
        
        VertexShader = compile vs_2_0 VS_NORMALTEXTURED();
        PixelShader  = compile ps_2_0 PS_NORMALTEXTURED(); 
      	AlphaBlendEnable=false;

    }
}

technique RenderMultiTexture
{
	pass P0
	{
        VertexShader = compile vs_2_0 VS_NORMALTEXTURED();
        PixelShader  = compile ps_2_0 PS_MULTITEXTURED(); 
	}
}

technique RenderLandscape
{
	pass p0
	{
		VertexShader = compile vs_2_0 VS_NORMALTEXTURED();
		PixelShader = compile ps_2_0 PS_LANDSCAPE();
	}
}




//--------------------------------------------------------------------------------------
//HUD_HUD_HUD_HUD_HUD_HUD_HUD_HUD_HUD_HUD_HUD_HUD_HUD_HUD_HUD_HUD_HUD_HUD_HUD_HUD_HUD_HUD_
//--------------------------------------------------------------------------------------
struct VS_INPUT_HUD
{
    float2 Pos : TEXCOORD0;
    float2 Tex : TEXCOORD1;
};
struct PS_INPUT_HUD
{
    float4 Pos : POSITION;
    float2 Tex  : TEXCOORD0;
};
//--------------------------------------------------------------------------------------
// TEXTURED Vertex Shader
//--------------------------------------------------------------------------------------
PS_INPUT_HUD VS_HUD( VS_INPUT_HUD input )
{
    PS_INPUT_HUD output = (PS_INPUT_HUD)0;
    output.Pos.xy = input.Pos.xy;
    //output.Pos.z=0;
    //output.Pos.w=0;
    output.Tex = input.Tex;
    return output;
}
//--------------------------------------------------------------------------------------
// TEXTURED Pixel shader 
//--------------------------------------------------------------------------------------
float4 PS_HUD( PS_INPUT_HUD input): COLOR0
{
    float4 finalColor = 0;
    finalColor = tex2D(MeshTextureSampler, input.Tex);
    return finalColor;
}

technique RenderHUD
{
	pass P0
	{
	    //AlphaBlendEnable=true;
        //SrcBlend=srcalpha;
        //DestBlend=invsrcalpha;

        VertexShader = compile vs_2_0 VS_HUD();
        PixelShader  = compile ps_2_0 PS_HUD(); 
        
	    //AlphaBlendEnable=false;
	}
}