//
// Project:
//
//   D3D RightMark
//
// Description:
//   Effect file for "Point Sprites" test.
//
// Effect Version: 
//
//   DirectX 9.0 (Summer 2003 SDK Update)
//
// Shader Profile:
//
//   Fixed-Function Pipeline
//
//   Vertex Shaders 2.0 ( Hight-Level Shader Language )
//


float4 vLight0Pos;
float4 vLight1Pos;

float4 vLight0Color = { 20.0f,  0.0f,  0.0f, 255.0f };
float4 vLight1Color = {  0.0f, 20.0f,  0.0f, 255.0f };

float  fLightAttenuation = 0.10f;
float  fLightRange       = 1000.0f;

float4 vPointSize;

float4x4 mW;
float4x4 mWVP;

float  fTimer;

texture tSprite;

struct VS_INPUT
{
    float4 vPosition : POSITION0;
    float4 vNormal   : NORMAL0;
    float4 vDiffuse  : COLOR0;
};

struct VS_OUTPUT
{
    float4 vPosition  : POSITION;
    float4 vDiffuse   : COLOR0;
    float  fPointSize : PSIZE;
};

//
// Diffuse Light (Per-Vertex)
//

float4 ShaderDiffuseLight( const float4 vVertexPosition, 
			   const float4 vVertexNormal,
			   const float4 vLightPosition,
			   const float4 vLightDiffuse,
			   const float  fLightAttenuation, 
			   const float  fLightRange )
{
	float4 vLightDirection           = vLightPosition - vVertexPosition;
	float  fDistance                 = length( vLightDirection );
	float4 vLightDirectionNormalized = vLightDirection / fDistance;

	float  fNL = dot( vLightDirectionNormalized, vVertexNormal );	

	fNL /= fLightAttenuation;
	fNL /= fDistance;

	return vLightDiffuse * fNL;
}


//
// Vertex Shader with Ambient Lighting (Per-Vertex)
//

VS_OUTPUT ShaderAmbientLightingAnimation( const VS_INPUT v )
{
	VS_OUTPUT o;

	// Animation

	float4 vPosition = mul( v.vPosition, mWVP  );
	float fA = tan( fTimer + v.vDiffuse.x * 3.14 );

	vPosition.x -=  2.0f * fA;
	vPosition.y += 10.0f * fA;
	vPosition.z -=  2.0f * fA;

	// Finalize

	o.vPosition  = vPosition;
	o.vDiffuse   = max( 0, (1.0f - abs(fA/20.0f)));
	o.fPointSize = vPointSize.x;

	return o;
}

VS_OUTPUT ShaderAmbientLighting( const VS_INPUT v )
{
	VS_OUTPUT o;

	o.vPosition = mul( v.vPosition, mWVP  );
	o.vDiffuse   = float4( 1.0f, 1.0f, 1.0f, 1.0f );
	o.fPointSize = vPointSize.x;

	return o;
}

//
// Vertex Shader with 2 Diffuse Lights (PerVertex)
//

VS_OUTPUT Shader2DiffuseLightsAnimation( const VS_INPUT v )
{
	VS_OUTPUT o;

	// Lighting Setup

	float4 vPositionWorld = mul( v.vPosition, mW );

	float4 vNormal = float4( v.vNormal.x, v.vNormal.y, v.vNormal.z, 0.0f );
	float4 vNormalWorld = mul( vNormal, mW );
	float4 vNormalWorldNormalized = normalize( vNormalWorld );

	float4 vDiffuse = float4( 0.0f, 0.0f, 0.0f, 0.0f );

	float4 pLightPositions[2] = { vLight0Pos, vLight1Pos };
	float4 pLightColors[2] = { vLight0Color, vLight1Color };

	// Lighting

	for( int i = 0; i < 2; i++ )
	{
		vDiffuse += ShaderDiffuseLight( vPositionWorld,
						vNormalWorldNormalized, 
						pLightPositions[i],
						pLightColors[i],
						fLightAttenuation,
						fLightRange );
	}

	// Animation

	float4 vPosition = mul( v.vPosition, mWVP  );
	float fA = tan( fTimer + v.vDiffuse.x * 3.14 );

	vPosition.x -=  2.0f * fA;
	vPosition.y += 10.0f * fA;
	vPosition.z -=  2.0f * fA;

	// Finalize

	o.vPosition  = vPosition;
	o.vDiffuse   = vDiffuse * max( 0, (1.0f - abs(fA/20.0f)));
	o.fPointSize = vPointSize.x;

	return o;
}

VS_OUTPUT Shader2DiffuseLights( const VS_INPUT v )
{
	VS_OUTPUT o;

	// Lighting Setup

	float4 vPositionWorld = mul( v.vPosition, mW );

	float4 vNormal = float4( v.vNormal.x, v.vNormal.y, v.vNormal.z, 0.0f );
	float4 vNormalWorld = mul( vNormal, mW );
	float4 vNormalWorldNormalized = normalize( vNormalWorld );

	float4 vDiffuse = float4( 0.0f, 0.0f, 0.0f, 0.0f );

	float4 pLightPositions[2] = { vLight0Pos, vLight1Pos };
	float4 pLightColors[2] = { vLight0Color, vLight1Color };

	// Lighting

	for( int i = 0; i < 2; i++ )
	{
		vDiffuse += ShaderDiffuseLight( vPositionWorld,
						vNormalWorldNormalized, 
						pLightPositions[i],
						pLightColors[i],
						fLightAttenuation,
						fLightRange );
	}

	// Finalize

	o.vPosition  = mul( v.vPosition, mWVP  );
	o.vDiffuse   = vDiffuse;
	o.fPointSize = vPointSize.x;

	return o;
}

technique TNoLighting
{   
	pass p0
	{
		// Common States

		CullMode		 = None;
		AlphaBlendEnable	 = True;
		ZWriteEnable		 = False;
		Lighting		 = False;
		PointSpriteEnable	 = True;

		SrcBlend		 = One;
		DestBlend		 = One;

		// Texture Stages

		Texture[0]		 = <tSprite>;

		MinFilter[0]		 = Point;
		MagFilter[0]		 = Point;
		MipFilter[0]		 = None;

		ColorOp[ 0 ]             = Modulate;
		ColorArg1[ 0 ]           = Diffuse;
		ColorArg2[ 0 ]           = Texture;

		AlphaOp[ 0 ]             = Modulate;
	        AlphaArg1[ 0 ] 		 = Diffuse;
	        AlphaArg2[ 0 ] 		 = Texture;
        
	        ColorOp[ 1 ]   		 = Disable;
        	AlphaOp[ 1 ]   		 = Disable;

		VertexShader = compile vs_2_0 ShaderAmbientLighting();
	}
}

technique TNoLightingAnimation
{   
	pass p0
	{
		// Common States

		CullMode		 = None;
		AlphaBlendEnable	 = True;
		ZWriteEnable		 = False;
		Lighting		 = False;
		PointSpriteEnable	 = True;

		SrcBlend		 = One;
		DestBlend		 = One;

		// Texture Stages

		Texture[0]		 = <tSprite>;

		MinFilter[0]		 = Point;
		MagFilter[0]		 = Point;
		MipFilter[0]		 = None;

		ColorOp[ 0 ]             = Modulate;
		ColorArg1[ 0 ]           = Diffuse;
		ColorArg2[ 0 ]           = Texture;

		AlphaOp[ 0 ]             = Modulate;
	        AlphaArg1[ 0 ] 		 = Diffuse;
	        AlphaArg2[ 0 ] 		 = Texture;
        
	        ColorOp[ 1 ]   		 = Disable;
        	AlphaOp[ 1 ]   		 = Disable;

		VertexShader = compile vs_2_0 ShaderAmbientLightingAnimation();
	}
}

technique TLightingAnimation
{   
	pass p0
	{
		// Common States

		CullMode		 = CCW;
		AlphaBlendEnable	 = True;
		ZWriteEnable		 = False;
		PointSpriteEnable	 = True;

		SrcBlend		 = One;
		DestBlend		 = One;

		// Texture Stages

		Texture[0]		 = <tSprite>;

		MinFilter[0]		 = Point;
		MagFilter[0]		 = Point;
		MipFilter[0]		 = None;

		ColorOp[ 0 ]             = Modulate;
		ColorArg1[ 0 ]           = Diffuse;
		ColorArg2[ 0 ]           = Texture;

		AlphaOp[ 0 ]             = Modulate;
	        AlphaArg1[ 0 ] 		 = Diffuse;
	        AlphaArg2[ 0 ] 		 = Texture;
        
	        ColorOp[ 1 ]   		 = Disable;
        	AlphaOp[ 1 ]   		 = Disable;

		// Shaders

		VertexShader = compile vs_2_0 Shader2DiffuseLightsAnimation();
	}
}

technique TLighting
{   
	pass p0
	{
		// Common States

		CullMode		 = CCW;
		AlphaBlendEnable	 = True;
		ZWriteEnable		 = False;
		PointSpriteEnable	 = True;

		SrcBlend		 = One;
		DestBlend		 = One;

		// Texture Stages

		Texture[0]		 = <tSprite>;

		MinFilter[0]		 = Point;
		MagFilter[0]		 = Point;
		MipFilter[0]		 = None;

		ColorOp[ 0 ]             = Modulate;
		ColorArg1[ 0 ]           = Diffuse;
		ColorArg2[ 0 ]           = Texture;

		AlphaOp[ 0 ]             = Modulate;
	        AlphaArg1[ 0 ] 		 = Diffuse;
	        AlphaArg2[ 0 ] 		 = Texture;
        
	        ColorOp[ 1 ]   		 = Disable;
        	AlphaOp[ 1 ]   		 = Disable;

		// Shaders

		VertexShader = compile vs_2_0 Shader2DiffuseLights();
	}
}