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


#define BONEMODE_4x3 1

#include "generic.fx"
#include "mrt.fx"
#include "GameLights.fx"



texture diffuseTexture : DiffuseTexture;

sampler DiffuseTextureSampler = sampler_state 
{
    texture = <diffuseTexture>;
    AddressU  = WRAP;        
    AddressV  = WRAP;
    AddressW  = WRAP;
    MIPFILTER = LINEAR;
    MINFILTER = LINEAR;
    MAGFILTER = LINEAR;
};

float3 campos : CAMERAPOS;

struct vertexInputBoned {
    float4 position				: POSITION;
    float3 normal				: NORMAL;
    float2 texCoordDiffuse		: TEXCOORD0;
    float4 boneids              : BLENDINDICES;
    float4 boneweights          : BLENDWEIGHT;
};

struct vertexInputUnboned {
    float4 position				: POSITION;
    float3 normal				: NORMAL;
    float2 texCoordDiffuse		: TEXCOORD0;
};

struct vertexOutput {
    float4 hPosition		: POSITION;
    float2 texCoordDiffuse	: TEXCOORD0;
#if PerVertexPreference
	half4 diffColor		: COLOR0;
	half4 specColor        : COLOR1;
    float dist		: TEXCOORD1;
#else
    float3 posWorld         : TEXCOORD1;
    float3 normWorld        : TEXCOORD2;
    float  dist		: TEXCOORD3;
#endif
};

struct vertexInputBatched {
    float4 position				: POSITION;
    float3 normal				: NORMAL;
    float2 texCoordDiffuse		: TEXCOORD0;
    float4 tangent              : TANGENT;
    float batchid               : BLENDINDICES;
};



vertexOutput VS_Shared(float4 pos, float3 norm, float2 uv)
{
    vertexOutput OUT;
	float2 velocity;
	
#if PerVertexPreference
    float3 colorSum = 0;
    float3 specularSum = 0;
    float3 eyeVecW = campos - pos.xyz;
	AddLights(norm, pos, colorSum, matSettings.Specular_Power.w, eyeVecW, specularSum);
    colorSum += matSettings.Ambient + ambientLevel;
    OUT.diffColor = float4(colorSum,1);
//    specularSum *= matSettings.Specular_Power.xyz;
    specularSum += matSettings.Emissive;
    OUT.specColor = float4(specularSum,1);
#else
    OUT.normWorld = norm;
    OUT.posWorld = pos;
#endif
    OUT.texCoordDiffuse = uv;
    OUT.hPosition = mul( pos , viewProj);
    
    OUT.dist = length( pos/100000- campos/100000 );
    return OUT;
}

vertexOutput VS_TransformBoned(vertexInputBoned IN) 
{
  	vertexOutput OUT;
    float4 pos;
    float3 norm;
    
    float weight4;
    weight4 = 1 - dot(IN.boneweights.xyz, float3(1,1,1));
    float4 weights = float4(IN.boneweights.xyz, weight4);
    
    float4 boneids = VS_ScaleBoneIDsFromD3DCOLOR(IN.boneids);
    VS_TransformBonesPN_4(IN.position, pos, IN.normal, norm, boneids, weights, world);
    
    OUT = VS_Shared(pos, norm, IN.texCoordDiffuse);
    
    return OUT;
}


vertexOutput VS_TransformUnboned(vertexInputUnboned IN) 
{
	vertexOutput OUT;
  
    float4 pos;
    float4 posLast;
    float3 norm;
    
    pos = mul(IN.position, world);
    
    norm = mul(IN.normal, world);
    
    OUT = VS_Shared(pos, norm, IN.texCoordDiffuse);
    return OUT;   
}



vertexOutput VS_TransformBatchedSM1(vertexInputBatched IN) 
{
    float4 pos;
    float4 posLast;
    float3 norm;
    float3 tang;
    
    pos = mul(IN.position, world);
    norm = mul(IN.normal, world);
    tang = float4( 1, 1, 1, 1 );
    
    VS_TransformBonesPNT_1_NoWorld(IN.position, pos, IN.normal, norm, IN.tangent, tang, VS_ScaleBatchID(IN.batchid));
  
  	return VS_Shared(pos, norm, IN.texCoordDiffuse);  
}


PS_OUTPUT PS_Textured( vertexOutput IN)
{
    half4 diffuseTexture = tex2D( DiffuseTextureSampler, IN.texCoordDiffuse );

    half3 colorSum = 0;
    half3 specularSum = 0;
    half4 outColor;
#if PerVertexPreference
	colorSum = IN.diffColor.xyz;
    outColor = matSettings.Diffuse_Opacity * diffuseTexture;
    outColor.xyz *= colorSum;
    outColor.xyz += IN.specColor.xyz;
#else   
    half3 normalWorld = normalize(IN.normWorld);
    half3 eyeVecW = campos - IN.posWorld.xyz;
	AddLights(normalWorld, IN.posWorld, colorSum, matSettings.Specular_Power.w, eyeVecW, specularSum);

    colorSum += matSettings.Ambient + ambientLevel;
    outColor = matSettings.Diffuse_Opacity * diffuseTexture;
    outColor.xyz *= colorSum;
    outColor.xyz += specularSum * matSettings.Specular_Power.xyz;
    outColor.xyz += matSettings.Emissive;
#endif
    
    PS_OUTPUT Out;
       
    // Output distance in .z
    //SetPSOutput( Out, outColor, float4( campos - IN.posWorld.xyz, 1) );
    SetPSOutput( Out, outColor, float4( 0, 0, IN.dist, 1) );
    return Out;
}


//-----------------------------------
technique boned
{
    pass p0 
    {		
		VertexShader = compile vs_2_0 VS_TransformBoned();
		PixelShader  = compile ps_2_0 PS_Textured();
    }
}

technique unboned
{
    pass p0 
    {		
		VertexShader = compile vs_2_0 VS_TransformUnboned();
		PixelShader  = compile ps_2_0 PS_Textured();
    }
}

technique batchedUnboned
{
    pass p0 
    {		
		VertexShader = compile vs_2_0 VS_TransformBatchedSM1();
		PixelShader  = compile ps_2_0 PS_Textured();
    }
}