#define BONEMATRIXPALETTE_SIZE ((MAXVERTEXSHADERCONST - 15) / 3)

#include "_shared.fx"
#include "_skinning.fx"

// parameters ------------------------------------------
float4x3 c_amMatrixPalette[BONEMATRIXPALETTE_SIZE] : BONEMATRIXPALETTE;
int      c_iNumBonesPerVertex;

float4x4 g_mWorld         : WORLD;
float4x4 g_mView          : VIEW;
float4x4 g_mProjection    : PROJECTION;

float4x4 g_mViewInverse   : VIEWINVERSE;


texture2D 	g_tDiffuseMap;

int g_iTransparency;

	
// input structs ---------------------------------------
sampler2D g_sDiffuseSampler = 
sampler_state
{
	Texture = <g_tDiffuseMap>;
	MinFilter = anisotropic;
	MagFilter = linear;
	MipFilter = linear;
	AddressU = wrap;
	AddressV = wrap;
};


struct VS_INPUT
{
	float3 vPositionOS	: POSITION0;
	float3 vNormalOS	: NORMAL0;
	float2 vTexcoord0	: TEXCOORD0;
};

struct VS_SKINNING
{
	float4 vBlendWeights	: BLENDWEIGHT0;
	float4 vBlendIndices	: BLENDINDICES0;
};

struct VS_OUTPUT
{
	float4 vPositionPS	: POSITION0;
	float4 vPositionPS2	: TEXCOORD0;
	float2 vTexcoord0	: TEXCOORD1_centroid;
};

// shaders ---------------------------------------------
VS_OUTPUT
vsMain(VS_INPUT i)
{
	// preshader->
	float4x4 mWorldView = mul(g_mWorld, g_mView);
	float4x4 mWorldViewProjection = mul(mWorldView, g_mProjection);
	// <-preshader


    i.vPositionOS -= i.vNormalOS * 0.01;


	VS_OUTPUT o;
	o.vPositionPS = mul(float4(i.vPositionOS, 1), mWorldViewProjection);
	o.vPositionPS2 = o.vPositionPS;
	o.vTexcoord0 = i.vTexcoord0;
	return o;
}

VS_OUTPUT
vsMainSkinning(VS_INPUT i, VS_SKINNING j, uniform int iNumBones)
{
	CalcSkinning(  i.vPositionOS, i.vNormalOS, 
                   j.vBlendWeights, j.vBlendIndices, 
                   iNumBones, c_amMatrixPalette);
	
	return vsMain(i);
}


float4
psMainShadowMap(VS_OUTPUT i) : COLOR0
{
    float4 vResult; 
    vResult.rgb = i.vPositionPS2.z / i.vPositionPS2.w;
    vResult.a = tex2D(g_sDiffuseSampler, i.vTexcoord0).a; 
    return vResult;    
}


VertexShader vsSkinShaderArray[4] =
{
    compile vs_1_1 vsMainSkinning(1), 
    compile vs_1_1 vsMainSkinning(2), 
    compile vs_1_1 vsMainSkinning(3), 
    compile vs_1_1 vsMainSkinning(4) 
};



// techniques ------------------------------------------

technique shadowmap_staticmesh
{
    pass p0
    {
		VertexShader = compile vs_1_1 vsMain();
		PixelShader = compile ps_2_0 psMainShadowMap();

		AlphaTestEnable = (g_iTransparency);
		AlphaRef = 128;
		AlphaFunc = Greater;
    }
}

technique shadowmap_skinnedmesh
{
    pass p0
    {
		VertexShader = vsSkinShaderArray[c_iNumBonesPerVertex - 1];
		PixelShader = compile ps_2_0 psMainShadowMap();

		AlphaTestEnable = (g_iTransparency);
		AlphaRef = 128;
		AlphaFunc = Greater;
	}
}

// -----------------------------------------------------
