/*
**	Project:	Nix
**	File:		shield.fx
**
**	Author:		Richard Yeager
**	Created:	11-12-2003
**
**	Purpose:	(file description)
*/


// light intensity
shared const float4 ambient = { 0.3f, 0.3f, 0.3f, 1.0f };         // ambient
shared const float4 lightdiffuse = { 1.0f, 1.0f, 1.0f, 1.0f };    // diffuse
shared const float4 lightspecular = { 1.0f, 1.0f, 1.0f, 1.0f };   // specular

// material reflectivity
const float4 k_a= { 1.0f, 1.0f, 1.0f, 1.0f };    // ambient
const float4 k_d= { 1.0f, 1.0f, 1.0f, 1.0f };    // diffuse
const float4 k_s= { .5f, .5f, .5f, .5f };        // specular
const int    n    = 32;

// light direction (view space)
shared const float3 lightdir = {0, -1, 0}; // MUST HAVE DEFAULT VALUES!!!!!
shared const float3 camerapos;

// texture
texture diffuse;

// transformations
shared const float4x4 World          : WORLD;
shared const float4x4 View           : VIEW;
shared const float4x4 Projection     : PROJECTION;
shared const float4x4 WorldView      : WORLDVIEW;
shared const float4x4 ViewProjection : VIEWPROJECTION;


sampler Sampler = sampler_state
{
    Texture   = (diffuse);
    MipFilter = LINEAR;
    MinFilter = LINEAR;
    MagFilter = LINEAR;
};


// NEW STUFF BELOW ------------------------------------------------------------

// glow parameters
float4 GlowColor     = float4(0.8f, 0.2f, 0.2f, 1.0f);
float4 GlowAmbient   = float4(0.1f, 0.1f, 0.0f, 0.0f);
float  GlowThickness = 0.2f;



struct VSGLOW_OUTPUT
{
	float4 Position : POSITION;
	float4 Diffuse  : COLOR;
};

// Draws a transparent hull of an unskinned object
VSGLOW_OUTPUT VSGlow
(
	float4 Position : POSITION, 
	float3 Normal   : NORMAL
)
{
	VSGLOW_OUTPUT Out = (VSGLOW_OUTPUT)0;

	float3 N = normalize(mul(Normal, (float3x3)WorldView));     // normal (view space)
	float3 P = mul(Position, WorldView) + GlowThickness * N;    // displaced position (view space)
	float3 A = float3(0, 0, 1);                                 // glow axis

	float Power;
	
	Power  = dot(N, A);
	Power *= Power;
	Power -= 1;
	Power *= Power;     // Power = (1 - (N.A)^2)^2 [ = ((N.A)^2 - 1)^2 ]

	Out.Position = mul(float4(P, 1), Projection);   // projected position
	Out.Diffuse  = GlowColor * Power + GlowAmbient; // modulated glow color + glow ambient

	return Out;    
}


technique Glow
{
	// Copied from default.fx
	pass P0
	{
		// material
		MaterialAmbient  = (k_a); 
		MaterialDiffuse  = (k_d); 
		MaterialSpecular = (k_s); 
		MaterialPower    = (n);

		// lighting
		LightType[0]      = DIRECTIONAL;
		LightAmbient[0]   = (ambient);
		LightDiffuse[0]   = (lightdiffuse);
		LightSpecular[0]  = (lightspecular); 
		LightDirection[0] = (lightdir);
		LightRange[0]     = 100000.0f;

		LightEnable[0] = TRUE;
		Lighting       = TRUE;
		SpecularEnable = TRUE;

		// samplers
		Sampler[0] = (Sampler);

		// texture stages
		ColorOp[0]   = MODULATE;
		ColorArg1[0] = TEXTURE;
		ColorArg2[0] = DIFFUSE;
		AlphaOp[0]   = MODULATE;
		AlphaArg1[0] = TEXTURE;
		AlphaArg2[0] = DIFFUSE;

		ColorOp[1]   = DISABLE;
		AlphaOp[1]   = DISABLE;

		// shaders
		VertexShader = NULL;
		PixelShader  = NULL;
	}
    
	pass PGlow
	{   
		// glow shader
		VertexShader = compile vs_1_1 VSGlow();
		PixelShader  = NULL;

		// no texture
		Texture[0] = NULL;

		// enable alpha blending
		AlphaBlendEnable = TRUE;
		SrcBlend         = ONE;
		DestBlend        = ONE;

		// Should be disabled, but you must render after all solid
		// geometry (which isn't done) :(
		//ZWriteEnable = FALSE;
		
		FogEnable = FALSE;
		
		// set up texture stage states to use the diffuse color
		ColorOp[0]   = SELECTARG2;
		ColorArg2[0] = DIFFUSE;
		AlphaOp[0]   = SELECTARG2;
		AlphaArg2[0] = DIFFUSE;

		ColorOp[1]   = DISABLE;
		AlphaOp[1]   = DISABLE;
	}
}

 
// Need to apply scaling matrix...
technique GlowNoShader
{
	// Copied from default.fx
	pass P0
	{
		// material
		MaterialAmbient  = (k_a); 
		MaterialDiffuse  = (k_d); 
		MaterialSpecular = (k_s); 
		MaterialPower    = (n);

		// lighting
		LightType[0]      = DIRECTIONAL;
		LightAmbient[0]   = (ambient);
		LightDiffuse[0]   = (lightdiffuse);
		LightSpecular[0]  = (lightspecular); 
		LightDirection[0] = (lightdir);
		LightRange[0]     = 100000.0f;

		LightEnable[0] = TRUE;
		Lighting       = TRUE;
		SpecularEnable = TRUE;

		// samplers
		Sampler[0] = (Sampler);

		// texture stages
		ColorOp[0]   = MODULATE;
		ColorArg1[0] = TEXTURE;
		ColorArg2[0] = DIFFUSE;
		AlphaOp[0]   = MODULATE;
		AlphaArg1[0] = TEXTURE;
		AlphaArg2[0] = DIFFUSE;

		ColorOp[1]   = DISABLE;
		AlphaOp[1]   = DISABLE;

		// shaders
		VertexShader = NULL;
		PixelShader  = NULL;
	}
	
	pass PGlow
	{
		// glow shader
		VertexShader = NULL;
		PixelShader  = NULL;

		// no texture
		Texture[0] = NULL;

		// enable alpha blending
		AlphaBlendEnable = TRUE;
		SrcBlend         = ONE;
		DestBlend        = ONE;

		FogEnable = FALSE;
		
		TextureFactor = 0xFFCC4C33;
		
		// set up texture stage states to use the diffuse color
		ColorOp[0]   = SELECTARG2;
		ColorArg2[0] = TFACTOR;
		AlphaOp[0]   = SELECTARG2;
		AlphaArg2[0] = DIFFUSE;

		ColorOp[1]   = DISABLE;
		AlphaOp[1]   = DISABLE;	
	}
}
