/*********************************************************************NVMH3****

Terrain rendering.
This is a port of the old DX8 ASM shaders --
but with a normal map per layer, and support for 3 directional lights and 3 points.

******************************************************************************/
#include "..\mrt.fx"

float4x4 worldViewProj : WorldViewProjection;
float4x4 viewProj : ViewProjection;
float4x4 world   : World;

int	DrawWireFrame : DRAW_WIRE;

struct DirectionalLight
{
    float3 Direction    : DIRECTION;
    float3 Diffuse      : DIFFUSE;
    float3 Specular     : SPECULAR;
};

struct PointLight
{
    float4 Position_Att0     : POSITION_ATT0;
    float4 Diffuse_Att1      : DIFFUSE_ATT1;
    float4 Specular_Att2     : SPECULAR_ATT2;
};

struct Material
{
    float4 Diffuse_Opacity  : DIFFUSE_OPACITY;
    float4 Specular_Power : SPECULAR_POWER;
    float3 Ambient  : AMBIENT;
    float3 Emissive : EMISSIVE;
};

DirectionalLight    dirLights[3]    : DIRLIGHT;
PointLight          pointLights[3]  : POINTLIGHT;
Material            matSettings   : MATERIAL;

float4 DiffuseOpacity0 : DIFFUSE_OPACITY0;
float4 DiffuseOpacity1 : DIFFUSE_OPACITY1;
float4 DiffuseOpacity2 : DIFFUSE_OPACITY2;
float4 DiffuseOpacity3 : DIFFUSE_OPACITY3;

float4 Specular_Power0 : SPECULAR_POWER0;
float4 Specular_Power1 : SPECULAR_POWER1;
float4 Specular_Power2 : SPECULAR_POWER2;
float4 Specular_Power3 : SPECULAR_POWER3;

float3 Surface_Ambient0 : SURFACE_AMBIENT0;
float3 Surface_Ambient1 : SURFACE_AMBIENT1;
float3 Surface_Ambient2 : SURFACE_AMBIENT2;
float3 Surface_Ambient3 : SURFACE_AMBIENT3;

float3 ambientLevel : AMBIENT = {0.3, 0.3, 0.3};
float3 campos : CAMERAPOS;

float4x4 UVTransform0 : UVTransform4x4;
float4x4 UVTransform1 : UVTransform4x4;
float4x4 UVTransform2 : UVTransform4x4;
float4x4 UVTransform3 : UVTransform4x4;


// Parallax mapping constants
float HeightScale0 : HEIGHTSCALE0 = 0.0;
float HeightScale1 : HEIGHTSCALE1 = 0.0;
float HeightScale2 : HEIGHTSCALE2 = 0.0;
float HeightScale3 : HEIGHTSCALE3 = 0.0;

float HeightBias0 : HEIGHTBIAS0 = 0.0;
float HeightBias1 : HEIGHTBIAS1 = 0.0;
float HeightBias2 : HEIGHTBIAS2 = 0.0;
float HeightBias3 : HEIGHTBIAS3 = 0.0;


// UV rotate bad! 
float4x4 UVRotate : UVRotate4x4;

float  timeScale : TimeScale = 0.0f;

texture revealTexture0 : DiffuseTexture;
sampler RevealTextureSampler0 = sampler_state 
{
    texture = <revealTexture0>;
    AddressU  = WRAP;        
    AddressV  = WRAP;
    AddressW  = WRAP;
    MIPFILTER = LINEAR;
    MINFILTER = LINEAR;
    MAGFILTER = LINEAR;
};

texture revealTexture1 : Custom0;
sampler RevealTextureSampler1 = sampler_state 
{
    texture = <revealTexture1>;
    AddressU  = WRAP;        
    AddressV  = WRAP;
    AddressW  = WRAP;
    MIPFILTER = LINEAR;
    MINFILTER = LINEAR;
    MAGFILTER = LINEAR;
};

texture revealTexture2 : Custom1;
sampler RevealTextureSampler2 = sampler_state 
{
    texture = <revealTexture2>;
    AddressU  = WRAP;        
    AddressV  = WRAP;
    AddressW  = WRAP;
    MIPFILTER = LINEAR;
    MINFILTER = LINEAR;
    MAGFILTER = LINEAR;
};

texture revealTexture3 : Custom2;
sampler RevealTextureSampler3 = sampler_state 
{
    texture = <revealTexture3>;
    AddressU  = WRAP;        
    AddressV  = WRAP;
    AddressW  = WRAP;
    MIPFILTER = LINEAR;
    MINFILTER = LINEAR;
    MAGFILTER = LINEAR;
};


texture revealBumpTexture0 : BumpTexture;
sampler RevealBumpTextureSampler0 = sampler_state 
{
    texture = <revealBumpTexture0>;
    AddressU  = WRAP;        
    AddressV  = WRAP;
    AddressW  = WRAP;
    MIPFILTER = LINEAR;
    MINFILTER = LINEAR;
    MAGFILTER = LINEAR;
};

texture revealBumpTexture1 : Custom3;
sampler RevealBumpTextureSampler1 = sampler_state 
{
    texture = <revealBumpTexture1>;
    AddressU  = WRAP;        
    AddressV  = WRAP;
    AddressW  = WRAP;
    MIPFILTER = LINEAR;
    MINFILTER = LINEAR;
    MAGFILTER = LINEAR;
};

texture revealBumpTexture2 : Custom4;
sampler RevealBumpTextureSampler2 = sampler_state 
{
    texture = <revealBumpTexture2>;
    AddressU  = WRAP;        
    AddressV  = WRAP;
    AddressW  = WRAP;
    MIPFILTER = LINEAR;
    MINFILTER = LINEAR;
    MAGFILTER = LINEAR;
};

texture revealBumpTexture3 : Custom5;
sampler RevealBumpTextureSampler3 = sampler_state 
{
    texture = <revealBumpTexture3>;
    AddressU  = WRAP;        
    AddressV  = WRAP;
    AddressW  = WRAP;
    MIPFILTER = LINEAR;
    MINFILTER = LINEAR;
    MAGFILTER = LINEAR;
};


//---------------------------
// Specular masks
texture specMaskTexture0 : Custom6;
sampler SpecMaskTextureSampler0 = sampler_state 
{
    texture = <specMaskTexture0>;
    AddressU  = WRAP;        
    AddressV  = WRAP;
    AddressW  = WRAP;
    MIPFILTER = LINEAR;
    MINFILTER = LINEAR;
    MAGFILTER = LINEAR;
};

texture specMaskTexture1 : Custom7;
sampler SpecMaskTextureSampler1 = sampler_state 
{
    texture = <specMaskTexture1>;
    AddressU  = WRAP;        
    AddressV  = WRAP;
    AddressW  = WRAP;
    MIPFILTER = LINEAR;
    MINFILTER = LINEAR;
    MAGFILTER = LINEAR;
};

texture specMaskTexture2 : Custom8;
sampler SpecMaskTextureSampler2 = sampler_state 
{
    texture = <specMaskTexture2>;
    AddressU  = WRAP;        
    AddressV  = WRAP;
    AddressW  = WRAP;
    MIPFILTER = LINEAR;
    MINFILTER = LINEAR;
    MAGFILTER = LINEAR;
};

texture specMaskTexture3 : Custom9;
sampler SpecMaskTextureSampler3 = sampler_state 
{
    texture = <specMaskTexture3>;
    AddressU  = WRAP;        
    AddressV  = WRAP;
    AddressW  = WRAP;
    MIPFILTER = LINEAR;
    MINFILTER = LINEAR;
    MAGFILTER = LINEAR;
};


//---------------------------
// Heightmaps for parallax mapping
texture heightTexture0 : Custom10;
sampler HeightTextureSampler0 = sampler_state 
{
    texture = <heightTexture0>;
    AddressU  = WRAP;        
    AddressV  = WRAP;
    AddressW  = WRAP;
    MIPFILTER = LINEAR;
    MINFILTER = LINEAR;
    MAGFILTER = LINEAR;
};

texture heightTexture1 : Custom11;
sampler HeightTextureSampler1 = sampler_state 
{
    texture = <heightTexture1>;
    AddressU  = WRAP;        
    AddressV  = WRAP;
    AddressW  = WRAP;
    MIPFILTER = LINEAR;
    MINFILTER = LINEAR;
    MAGFILTER = LINEAR;
};

texture heightTexture2 : Custom12;
sampler HeightTextureSampler2 = sampler_state 
{
    texture = <heightTexture2>;
    AddressU  = WRAP;        
    AddressV  = WRAP;
    AddressW  = WRAP;
    MIPFILTER = LINEAR;
    MINFILTER = LINEAR;
    MAGFILTER = LINEAR;
};

texture heightTexture3 : Custom13;
sampler HeightTextureSampler3 = sampler_state 
{
    texture = <heightTexture3>;
    AddressU  = WRAP;        
    AddressV  = WRAP;
    AddressW  = WRAP;
    MIPFILTER = LINEAR;
    MINFILTER = LINEAR;
    MAGFILTER = LINEAR;
};



//------------------------------------
struct vertexInput {
    float4 position				: POSITION;
    float4 blendgoo				: COLOR0;
    float3 normal               : NORMAL;
    float4 tangentVec			: TANGENT;
    float2 noisefactor			: COLOR1;
};    

struct vertexOutput
{
	float4 hPosition : POSITION;
    float4 posWorld         : TEXCOORD0;
    float2 texCoordDiffuse0	: TEXCOORD1;
};

float WorkingSaturate(float x)
{
    if (x<0)
        x = 0;
    else if (x>1)
        x = 1;
    return x;
}



//------------------------------------
vertexOutput VS_TransformAndTexture(vertexInput IN) 
{
    vertexOutput OUT;
    
    OUT.hPosition = mul( IN.position, worldViewProj);
    
    float4 posWorld = mul(IN.position, world);   
    OUT.posWorld = posWorld;
    
    float4 baseUVs = float4(posWorld.x,0,-posWorld.z,1); 	
   	float4 uvs = mul( baseUVs, UVTransform0 );     
      
	OUT.texCoordDiffuse0.x = uvs.x;
    OUT.texCoordDiffuse0.y = -uvs.z;
    return OUT;
}


//-----------------------------------
PS_OUTPUT PS_Textured( vertexOutput IN)
{ 		 
	PS_OUTPUT Out;
	   
 	float4 outColor = tex2D( RevealTextureSampler0, IN.texCoordDiffuse0 );
    
    if( DrawWireFrame )
		outColor = float4(1,1,1,1); 
	else
		outColor = tex2D( RevealTextureSampler0, IN.texCoordDiffuse0 );	
    
    SetPSOutput( Out, float4(outColor.xyz, 1.0f), float4( campos - IN.posWorld.xyz, 1) );
    return Out;
}


//-----------------------------------
technique textured
{
    pass p0 
    {		
        //ZWriteEnable = false;
        //AlphaBlendEnable = true;
        //AlphaTestEnable = false;
        //SrcBlend = ZERO;
        //DestBlend = SRCCOLOR;
        
		VertexShader = compile vs_2_0 VS_TransformAndTexture();
		PixelShader  = compile ps_2_0 PS_Textured();
    }
}