//
// Project:
//
//   D3D RightMark
//
// Description:
//   Effect file for "Geometry Processing Speed" test.
//
// Effect Version: 
//
//   DirectX 9.0 (Summer 2003 SDK Update)
//
// Shader Profile:
//
//   Fixed-Function Pixel Shader
//
//   Vertex Shaders 2.a ( HLSL )
//

float4 vLight0Diffuse = { 1.0f, 0.0f, 0.0f, 1.0f };
float4 vLight1Diffuse = { 0.0f, 1.0f, 0.0f, 1.0f };
float4 vLight2Diffuse = { 0.0f, 0.0f, 1.0f, 1.0f };

float4 vLight0Ambient = { 0.0f, 0.0f, 0.0f, 0.0f };
float4 vLight1Ambient = { 0.0f, 0.0f, 0.0f, 0.0f };
float4 vLight2Ambient = { 0.0f, 0.0f, 0.0f, 0.0f };

float4 vLight0Specular = { 1.0f, 1.0f, 1.0f, 1.0f };
float4 vLight1Specular = { 1.0f, 1.0f, 1.0f, 1.0f };
float4 vLight2Specular = { 1.0f, 1.0f, 1.0f, 1.0f };

float4 vLight0Attenuation = { 1.0f, 1.0f, 1.0f, 1.0f };
float4 vLight1Attenuation = { 1.0f, 1.0f, 1.0f, 1.0f };
float4 vLight2Attenuation = { 1.0f, 1.0f, 1.0f, 1.0f };

float4 vLight0Range = { 1.0f, 1.0f, 1.0f, 1.0f };
float4 vLight1Range = { 1.0f, 1.0f, 1.0f, 1.0f };
float4 vLight2Range = { 1.0f, 1.0f, 1.0f, 1.0f };

float4 vMaterialPower = { 1.0f, 1.0f, 1.0f, 1.0f };

float  fLight0Attenuation0 = 0.0f;
float  fLight1Attenuation0 = 0.0f;
float  fLight2Attenuation0 = 0.0f;

float  fLight0Attenuation1 = 0.1f;
float  fLight1Attenuation1 = 0.1f;
float  fLight2Attenuation1 = 0.1f;

float  fLight0Attenuation2 = 0.0f;
float  fLight1Attenuation2 = 0.0f;
float  fLight2Attenuation2 = 0.0f;

float  fLight0Range = 500.0f;
float  fLight1Range = 500.0f;
float  fLight2Range = 500.0f;

float3 vLight0Pos;
float3 vLight1Pos;
float3 vLight2Pos;

float4 vMaterialDiffuse  = { 40.0f, 40.0f, 40.0f, 255.0f };
float4 vMaterialSpecular = { 40.0f, 40.0f, 40.0f, 255.0f };
float4 vMaterialAmbient  = {  0.0f,  0.0f,  0.0f, 255.0f };
float4 vMaterialEmissive = {  0.0f,  0.0f,  0.0f, 255.0f };

float  fMaterialPower = 16;

struct rm_light
{
	float3 vPosition;

	float4 vDiffuse;
	float4 vSpecular;

	float3 vAttenuation;

	float  fLightRange;
};

rm_light Lights[3];     // Lights

float4 vAmbient;        // Ambient Color;

float4 vCameraPos;	// Camera Position

matrix mW;		// World Matrix
matrix mV;		// View  Matrix
matrix mP;		// Projection Matrix

matrix mWVP;		// World * View * Projection Matrix

vector vZero = { 0.0f, 0.0f, 0.0f, 0.0f };
vector vOne  = { 1.0f, 1.0f, 1.0f, 1.0f };

//
// Shaders
//

struct VS_INPUT
{
    float4 vPosition : POSITION;
    float4 vNormal   : NORMAL;
};

struct VS_OUTPUT
{
    float4 vPosition : POSITION;
    float4 vColor    : COLOR0;
};


VS_OUTPUT VSDiffuse( VS_INPUT In, uniform int nNumLights )
{
	VS_OUTPUT o;

	// Position

	o.vPosition = mul( In.vPosition, mWVP );

	// Vertex Position -> World Space

	float4 vPositionWorld = mul( In.vPosition, mW );
	float3 vNormalWorld   = mul( In.vNormal, (float3x3)mW );

	// Lighting

        float4 vColor  = vAmbient;

        for( int i = 0; i < nNumLights; i++ ) 
        { 
		float3 vLight = Lights[i].vPosition - vPositionWorld;

		float fLengthSquared = dot( vLight, vLight );
		float fLength = sqrt( fLengthSquared );

		if( fLength < Lights[i].fLightRange )
		{
			float LdotN = dot( vLight / fLength, vNormalWorld );

			vColor += vMaterialDiffuse * Lights[i].vDiffuse * LdotN / ( Lights[i].vAttenuation.x + Lights[i].vAttenuation.y * fLength + Lights[i].vAttenuation.z * fLengthSquared );
		}
        } 
	
	// Finalize

	o.vColor = vColor;

	return o;
}

VS_OUTPUT VSDiffuseSpecular( VS_INPUT In, uniform int nNumLights )
{
	VS_OUTPUT o;

	// Position

	o.vPosition = mul( In.vPosition, mWVP );

	// Vertex Position -> World Space

	float4 vPositionWorld = mul( In.vPosition, mW );
	float3 vNormalWorld   = mul( In.vNormal, (float3x3)mW );

	float3 vEye = normalize( vCameraPos.xyz - vPositionWorld.xyz );

	// Lighting

        float4 vColor  = vAmbient;

        for( int i = 0; i < nNumLights; i++ ) 
        { 
		float3 vLight = Lights[i].vPosition - vPositionWorld;

		float fLengthSquared = dot( vLight, vLight );
		float fLength = sqrt( fLengthSquared );

		if( fLength < Lights[i].fLightRange )
		{
			vLight /= fLength;
			float3 vHalfAngle = normalize( vEye + vLight );

			float LdotN = dot( vLight, vNormalWorld );
			float HdotN = dot( vHalfAngle, vNormalWorld );
	
			float4 I = lit( LdotN, HdotN, fMaterialPower );

			vColor += (vMaterialDiffuse * Lights[i].vDiffuse * I.y + vMaterialSpecular * Lights[i].vSpecular * I.z ) / ( Lights[i].vAttenuation.x + Lights[i].vAttenuation.y * fLength + Lights[i].vAttenuation.z * fLengthSquared );
		}
        } 
	
	// Finalize

	o.vColor = vColor;

	return o;
}

//
// Ambient Lighting
//

technique TAmbient
{   
	pass p0
	{
		//
		// Common States
		//

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

		ColorOp[ 0 ]             = SelectArg1;
	        ColorArg1[ 0 ] 		 = Diffuse;

		AlphaOp[ 0 ]             = SelectArg1;
	        AlphaArg1[ 0 ] 		 = Diffuse;
        
	        ColorOp[ 1 ]   		 = Disable;
        	AlphaOp[ 1 ]   		 = Disable;

		//
		// Shader Constants
		//
		VertexShaderConstant[0]  = <vZero>;	  // 0, 0, 0, 0
		VertexShaderConstant[1]  = <vOne>;	  // 1, 1, 1, 1

		VertexShaderConstant[16] = <mWVP>;	  // World * View * Projections Matrix

		//
		// Shaders
		//


		VertexShader = 

		   decl {
				stream 0;
				FLOAT    v0[3];
				FLOAT    v3[3];
			}
		   asm {	
				vs_2_0

				dcl_position v0
				dcl_normal   v3

				//
				// Position Setup
				//
				m4x4 oPos, v0, c16

				//
				// Lighting Setup
				//

				mov  oD0, c1			
			};
	}
}

//
// 1 Diffuse Per-Vertex Point Light 
//

technique T1Diffuse
{   
	pass p0
	{
		//
		// Common States
		//

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

		ColorOp[ 0 ]             = SelectArg1;
	        ColorArg1[ 0 ] 		 = Diffuse;

		AlphaOp[ 0 ]             = SelectArg1;
	        AlphaArg1[ 0 ] 		 = Diffuse;
        
	        ColorOp[ 1 ]   		 = Disable;
        	AlphaOp[ 1 ]   		 = Disable;

		//
		// Shaders
		//

		VertexShader = compile vs_2_a VSDiffuse( 1 );
	}
}

//
// 2 Diffuse Per-Vertex Point Light 
//

technique T2Diffuse
{   
	pass p0
	{
		//
		// Common States
		//

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

		ColorOp[ 0 ]             = SelectArg1;
	        ColorArg1[ 0 ] 		 = Diffuse;

		AlphaOp[ 0 ]             = SelectArg1;
	        AlphaArg1[ 0 ] 		 = Diffuse;
        
	        ColorOp[ 1 ]   		 = Disable;
        	AlphaOp[ 1 ]   		 = Disable;

		//
		// Shader Constants
		//


		//
		// Shaders
		//

		VertexShader = compile vs_2_a VSDiffuse( 2 );
	}
}

//
// 3 Diffuse Per-Vertex Point Light 
//

technique T3Diffuse
{   
	pass p0
	{
		//
		// Common States
		//

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

		ColorOp[ 0 ]             = SelectArg1;
	        ColorArg1[ 0 ] 		 = Diffuse;

		AlphaOp[ 0 ]             = SelectArg1;
	        AlphaArg1[ 0 ] 		 = Diffuse;
        
	        ColorOp[ 1 ]   		 = Disable;
        	AlphaOp[ 1 ]   		 = Disable;

		//
		// Shaders
		//

		VertexShader = compile vs_2_a VSDiffuse( 3 );
	}
}

technique T1DiffuseSpecular
{   
	pass p0
	{
		//
		// Common States
		//

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

		ColorOp[ 0 ]             = SelectArg1;
	        ColorArg1[ 0 ] 		 = Diffuse;

		AlphaOp[ 0 ]             = SelectArg1;
	        AlphaArg1[ 0 ] 		 = Diffuse;
        
	        ColorOp[ 1 ]   		 = Disable;
        	AlphaOp[ 1 ]   		 = Disable;

		//
		// Shaders
		//

		VertexShader = compile vs_2_a VSDiffuseSpecular( 1 );
	}
}

technique T2DiffuseSpecular
{   
	pass p0
	{
		//
		// Common States
		//

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

		ColorOp[ 0 ]             = SelectArg1;
	        ColorArg1[ 0 ] 		 = Diffuse;

		AlphaOp[ 0 ]             = SelectArg1;
	        AlphaArg1[ 0 ] 		 = Diffuse;
        
	        ColorOp[ 1 ]   		 = Disable;
        	AlphaOp[ 1 ]   		 = Disable;


		//
		// Shaders
		//

		VertexShader = compile vs_2_a VSDiffuseSpecular( 2 );
	}
}

technique T3DiffuseSpecular
{   
	pass p0
	{
		//
		// Common States
		//

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

		ColorOp[ 0 ]             = SelectArg1;
	        ColorArg1[ 0 ] 		 = Diffuse;

		AlphaOp[ 0 ]             = SelectArg1;
	        AlphaArg1[ 0 ] 		 = Diffuse;
        
	        ColorOp[ 1 ]   		 = Disable;
        	AlphaOp[ 1 ]   		 = Disable;

		//
		// Shaders
		//

		VertexShader = compile vs_2_a VSDiffuseSpecular( 3 );
	}
}