//*******************************************************************
//
// File: Asura_Direct3D_Carpet_Game_Render_Shaders.cpp
//
// Created: 3 Feb 2006
//
// Description: 
//
//*******************************************************************

// system libraries
#include "Core/Asura.h"

#if defined( ASURA_USE_CARPET)

// main header
#include "Asura_Direct3D_Carpet_Game_Render.h"

// other libraries
#include "Light/Asura_Photon.h"

#include "Rendering/Asura_Render.h"
#include "Rendering/Asura_Direct3d.h"
#include "Rendering/Asura_Direct3D_Shaders.h"
#include "Rendering/Asura_Direct3D_Caps.h"
#include "Rendering/Asura_Fog.h"

#include "Carpet/Asura_Carpet_MeshManager.h"

// internal dependencies

//*******************************************************************
// Constants
//*******************************************************************

#define ASURA_DIRECT3D_CARPET_GAME_RENDER_VS_CONST_MOVEMENTSCALE_INDEX 35
#define ASURA_DIRECT3D_CARPET_GAME_RENDER_VS_CONST_STYLE_START         36

//*******************************************************************
// Local Classes
//*******************************************************************

class Asura_Direct3D_CGR_VSConstants_Wave
{
public:
	float m_afWave[4];
};

class Asura_Direct3D_CGR_VSConstants_Base
{
public:
	float m_afTransform[4][4];
	float m_afBillboardRight[4];
	float m_afBillboardUp[4];
//	float m_afConstants1[4];
	float m_afCameraPlane[4];
	float m_afConstants2[4];
	float m_afCorners[4][4];
	
	Asura_Direct3D_CGR_VSConstants_Wave m_axWaves[16];
	
#if !defined( ASURA_DIRECT3D_BGR_SUPPORT_SM30)
	union
	{
		struct 
		{
			float m_afFogLinearPlane[4];
			float m_afFogLinearColour[4];
		};
		struct 
		{
			float m_afFogGraphPlane[4];
			float m_afFogGraphScale[2][4];
			float m_afFogGraphCoeffs[2][4];
		};
	};
	
	float m_afDynamicLightX[4];
	float m_afDynamicLightY[4];
	float m_afDynamicLightZ[4];
#endif
};

class Asura_Direct3D_CGR_VSConstants_Style
{
public:
	float m_afWidth, m_afHeight, m_afFadeStart, m_afFadeScale;
	float m_afUV[4];
};



//*******************************************************************
// Static Data
//*******************************************************************

static Direct3D_VertexElement g_xaVSD_Carpet_Simple[] =
{
	// Vertex position and colour...
	{0,	0,		D3DDECLTYPE_FLOAT3,		D3DDECLMETHOD_DEFAULT,	D3DDECLUSAGE_POSITION,	0},

#if defined( ASURA_DIRECT3D_BGR_SUPPORT_SM30)
	{0,	12,		D3DDECLTYPE_FLOAT4,		D3DDECLMETHOD_DEFAULT,	D3DDECLUSAGE_COLOR,		0},
	{0,	28,		D3DDECLTYPE_D3DCOLOR,	D3DDECLMETHOD_DEFAULT,	D3DDECLUSAGE_COLOR,		1},
#else
	{0,	12,		D3DDECLTYPE_D3DCOLOR,	D3DDECLMETHOD_DEFAULT,	D3DDECLUSAGE_COLOR,		0},
	{0,	16,		D3DDECLTYPE_D3DCOLOR,	D3DDECLMETHOD_DEFAULT,	D3DDECLUSAGE_COLOR,		1},
#endif

	D3DDECL_END()
};
Direct3D_VertexElement* Asura_Direct3D_Carpet_Game_Render::s_paxVSD_Carpet_Simple = g_xaVSD_Carpet_Simple;


#if !defined( ASURA_DIRECT3D_BGR_SUPPORT_SM30)
static const char* const g_szVS_Carpet_Base_Code =

// Environment shader
// Emulates the fixed function pipeline
// Expected constants:
//  c00-c03: ViewProj matrix
//	c04: Billboard Right X, Y, Z, 0.5
//	c05: Billboard Up X, Y, Z, 1.0
//  c06: Camera Position
//  c07: 255, 512, ASURA_DIRECT3D_CARPET_GAME_RENDER_VS_CONST_STYLE_START, 0
//	c08 09 10 11:
//		Array[4] Corner Offsets X, Y, U, V
//  
//  c12:
//		Array[16] Wave Table XYZ
//Linear Fog
//	c28: Fog Plane
//  c29: Fog Values
//Graph Fog
//	c28: Fog Plane (Scaled for Spline Enteries)
//	c29: Fog *, *, Dist Clamp Min, Dist Clamp Max
//	c29: 
//		Array[2] 
//			Dist Scale, Dist Offset, *, *
//	c31: 
//		Array[2] 
//			Spline Coeffs XYZW
//Dynamic Lights
//	c33: Dynamic LightX transform
//	c34: Dynamic LightY transform
//	c35: Dynamic LightZ transform
//
//Billboard Styles
//  c36: 
//		Array[Dynamic] Billboard Styles
//			Size Width, Height
//			UV	TL, TR, BL, BR

//	r6: Position
//	r7: Fade
//	r8: Wind
//	r9: Style
//	r10: Style
//	r11: Corner

"#line 1 \" "__FILE__"\" \n"
"vs.1.1 \n"
"dcl_position0	v0 \n"
"dcl_color0 v1 \n"
"dcl_color1 v3 \n"

// Do the position
//"m4x4 oPos, v0, c0 \n"

// Get the Corner Info
"mul r0.x, c7.x, v3.z \n"
"mov a0.x, r0.x \n"
"mov r11, c[ a0.x + 8] \n"

// Get the Style
"mad r0.x, c7.y, v3.x, c7.z \n"
"mov a0.x, r0.x \n"
"mov r9, c[ a0.x + 0] \n"
"mov r10, c[ a0.x + 1] \n"

// Get the Wind
"mul r0.x, c7.x, v3.y \n"
"mov a0.x, r0.x \n"
"mov r8, c[ a0.x + 12] \n"

// Setup the Fade
"dp4 r0.x, v0, c6 \n"
"mad r7, r0.x, r9.w, r9.z \n"
"min r7, r7, c5.w \n"

// Setup the Instance Scales
"mul r11.xy, r11.xy, v3.ww \n"
// Setup the Style Scales
"mul r11.xy, r11.xy, r9.xy \n"
// Setup the fade scales
"sge r0, r7, c7.w \n"
"mul r11.xy, r11.xy, r0.xx \n"

// Setup the Position

"mov r6.w, v0.w \n"
// Width
"mad r0.xyz, c4.xyz, r11.x, v0 \n"
// Height
"mad r0.xyz, c5.xyz, r11.y, r0 \n"
// Wind
"mad r6.xyz, r11.y, r8, r0 \n"

"m4x4 oPos, r6, c0 \n"
" \n"
" \n"

// Setup Up the Textures
"mad oT0.xy, r10.zw, r11.zw, r10.xy \n"

// Setup Colour
"mov oD0.xyz, v1 \n"
//"mov oD0.w, r7.x \n"
"mul oD0.w, c4.w, r7.w\n"
;

static const char* const g_szVS_Carpet_FogL_Code =
// Setup the Fog
"mov oD1.xyz, c7.w \n"
"dp4 r0.x, c28, r6 \n "
"min r0.x, r0.x, c5.w \n"
"mad oFog, c29.x, r0.x, c29.y \n"
//"mov oFog, r7.x \n"
" \n"
;

static const char* const g_szVS_Carpet_FogG_Code =
// Setup the Fog
"mov oD1.xyz, c7.w \n"

// Fog: Get range fog near and far planes (Scaled by the number of splines)
"dp4 r1.z, c28, r6 \n"
// Fog: Clamp to 0 - (Max of Spline Index)
"max r1.z, r1.z, c29.z \n"
"min r1.z, r1.z, c29.w \n"
// Fog: Setup Fog Table offset
"sge r0.x, r1.z, c30.z \n"
"mov a0.x, r0.x \n"
// Fog: Scale Index into Coeff useful values
"mad r1.z, r1.z, c[a0.x + 29].x, c[a0.x + 29].y \n"
// Fog: Build (r1.z^3, r1.z^2, r1.z, 1) for easy calc
"mov r1.w, c5.w \n"
"mul r1.y, r1.z, r1.z \n"
"mul r1.x, r1.y, r1.z \n"
// Fog: Calc fog via lookup coeffs
"dp4 oFog, r1, c[a0.x + 31] \n"
//"mov oFog, r1.z \n"
" \n"
;

static const char* const g_szVS_Carpet_LightingS_Code =
"\n"
;

static const char* const g_szVS_Carpet_LightingD_Code =
"dp4 oT1.x, r6, c33 \n"
"dp4 oT1.y, r6, c34 \n"
"dp4 oT2.x, r6, c35 \n"
"mov oT2.y, c4.w \n"
"\n"
;


static char* GetShaderCode( const bool bGraphFog, const bool bDynamicLights)
{
	// DLH - 28 June 2006 10:40:21 - [bGraphFog] [bDynamicLights]
	static Asura_String xStringCodeTable[2][2];
	const u_int uIndexFog = (true == bGraphFog) ? 1 : 0;
	const u_int uIndexLighting = (true == bDynamicLights) ? 1 : 0;
	Asura_String& xStringCode = xStringCodeTable[ uIndexFog][ uIndexLighting];
	
	if( 0 == xStringCode.GetLength())
	{
		static const char* pszStringFog[ 2] = 
		{
			g_szVS_Carpet_FogL_Code,
			g_szVS_Carpet_FogG_Code,
		};
		static const char* pszStringLighting[ 2] = 
		{
			g_szVS_Carpet_LightingS_Code,
			g_szVS_Carpet_LightingD_Code,
		};
		xStringCode = g_szVS_Carpet_Base_Code;
		xStringCode += pszStringFog[ uIndexFog];
		xStringCode += pszStringLighting[ uIndexLighting];
	}
	
	return( xStringCode.GetString());
}

// Register the shader with Asura
const Asura_Direct3D_VertexShader xVS_Carpet_FogL_LightingS_Shader(ASURA_D3D_VS_CARPET_FOGL_LIGHTS, GetShaderCode( false, false), &g_xaVSD_Carpet_Simple[0]);
const Asura_Direct3D_VertexShader xVS_Carpet_FogG_LightingS_Shader(ASURA_D3D_VS_CARPET_FOGG_LIGHTS, GetShaderCode( true, false), &g_xaVSD_Carpet_Simple[0]);
const Asura_Direct3D_VertexShader xVS_Carpet_FogL_LightingD_Shader(ASURA_D3D_VS_CARPET_FOGL_LIGHTD, GetShaderCode( false, true), &g_xaVSD_Carpet_Simple[0]);
const Asura_Direct3D_VertexShader xVS_Carpet_FogG_LightingD_Shader(ASURA_D3D_VS_CARPET_FOGG_LIGHTD, GetShaderCode( true, true), &g_xaVSD_Carpet_Simple[0]);
#endif //!defined( ASURA_DIRECT3D_BGR_SUPPORT_SM30)

static const char* const g_szPS_Carpet_LightS_Code =
	"ps.1.1				\n"
	"tex t0				\n"	// base texture

	"mul_x2_sat r0.rgb, t0, v0 \n"
	"sub_sat r0.a, t0.a, 1 - v0.a \n"
;

// Register the shader with Asura
const Asura_Direct3D_PixelShader xPS_Carpet_LightS_Shader(ASURA_D3D_PS_CARPET_LIGHTS, g_szPS_Carpet_LightS_Code);

static const char* const g_szPS_Carpet_LightD_Code =
	"ps.1.1				\n"
	"tex t0				\n"	// base texture
	"tex t1				\n"	// light texture 0
	"tex t2				\n"	// light texture 1

	"mul r0.rgb, t1, t2 \n"
	"mul r0.rgb, t0, r0 \n"
	"mul_x4 r0.rgb, c0, r0 \n"
	"mov_x2_sat r0.rgb, r0 \n"
	"sub_sat r0.a, t0.a, 1 - v0.a \n"
;

// Register the shader with Asura
const Asura_Direct3D_PixelShader xPS_Carpet_LightD_Shader(ASURA_D3D_PS_CARPET_LIGHTD, g_szPS_Carpet_LightD_Code);


//*******************************************************************
// Function Definitions
//*******************************************************************
bool Asura_Direct3D_Carpet_Game_Render::RenderSetShaderConstantsStyles( const uint32 uiStyleIndex, const Asura_Direct3D_CGR_Style& xStyle)
{
	HRESULT xResult;
	Asura_Direct3D_CGR_VSConstants_Style xVSConstantsStyle;
	
	xVSConstantsStyle.m_afWidth = xStyle.m_fWidth;
	xVSConstantsStyle.m_afHeight = xStyle.m_fHeight;
	xVSConstantsStyle.m_afFadeScale = -1.0f / xStyle.m_fLodFadeDelta;
	xVSConstantsStyle.m_afFadeStart = xStyle.m_fLodFadeFar / xStyle.m_fLodFadeDelta ;
	xVSConstantsStyle.m_afUV[0] = xStyle.m_afU[0];
	xVSConstantsStyle.m_afUV[1] = xStyle.m_afV[0];
	xVSConstantsStyle.m_afUV[2] = xStyle.m_afU[1] - xStyle.m_afU[0];
	xVSConstantsStyle.m_afUV[3] = xStyle.m_afV[1] - xStyle.m_afV[0];

#if defined( ASURA_DIRECT3D_BGR_SUPPORT_SM30)
	float afMovementScale[4] = {xStyle.m_fMovementScale,0,0,0};
	xResult = Asura_Direct3D::D3DDevice->SetVertexShaderConstantF( ASURA_DIRECT3D_CARPET_GAME_RENDER_VS_CONST_MOVEMENTSCALE_INDEX, afMovementScale, 1 );
	ASURA_D3D_OK( xResult);	
#endif
	
	const uint32 uiConstantCount = sizeof( xVSConstantsStyle) / sizeof( float[4]);
	const uint32 uiConstantIndex = ASURA_DIRECT3D_CARPET_GAME_RENDER_VS_CONST_STYLE_START + (2 * uiStyleIndex);
	Asura_Assert( (uiConstantIndex + 2) <= Asura_Direct3D_Caps::GetNumberOfVertexShaderConstants(), "This gfx card does not have enough constants");
	xResult = Asura_Direct3D::D3DDevice->SetVertexShaderConstantF( uiConstantIndex, (float*)&xVSConstantsStyle, uiConstantCount);
	ASURA_D3D_OK( xResult);	
	
	return( true);
}

bool Asura_Direct3D_Carpet_Game_Render::RenderSetShaderConstantsStatic( const Asura_Carpet_Mesh_Data_Frame& xDataFrame, const Asura_Photon* const pxPhoton)
{
	HRESULT xResult;
	Asura_Direct3D_CGR_VSConstants_Base xVSConstantsBase;

	{
		D3DXMATRIX& xMat = *((D3DXMATRIX*)( xVSConstantsBase.m_afTransform));
		D3DXMATRIX xMatView, xMatProj;

		Asura_Direct3D::D3DDevice->GetTransform( D3DTS_VIEW, &xMatView );
		Asura_Direct3D::D3DDevice->GetTransform( D3DTS_PROJECTION, &xMatProj );

		D3DXMatrixMultiply( &xMat, &xMatView, &xMatProj );
		D3DXMatrixTranspose( &xMat, &xMat );
	}

	xVSConstantsBase.m_afBillboardRight[0] = xDataFrame.m_xBillboardRight[0];
	xVSConstantsBase.m_afBillboardRight[1] = xDataFrame.m_xBillboardRight[1];
	xVSConstantsBase.m_afBillboardRight[2] = xDataFrame.m_xBillboardRight[2];
	xVSConstantsBase.m_afBillboardRight[3] = 0.5f;
	
	xVSConstantsBase.m_afBillboardUp[0] = xDataFrame.m_xBillboardUp[0];
	xVSConstantsBase.m_afBillboardUp[1] = xDataFrame.m_xBillboardUp[1];
	xVSConstantsBase.m_afBillboardUp[2] = xDataFrame.m_xBillboardUp[2];
	xVSConstantsBase.m_afBillboardUp[3] = 1.0f;
	
	
	xVSConstantsBase.m_afCameraPlane[0] = xDataFrame.m_xCameraForwards[0];
	xVSConstantsBase.m_afCameraPlane[1] = xDataFrame.m_xCameraForwards[1];
	xVSConstantsBase.m_afCameraPlane[2] = xDataFrame.m_xCameraForwards[2];
	xVSConstantsBase.m_afCameraPlane[3] = xDataFrame.m_fCameraPlaneDistance;
	
	xVSConstantsBase.m_afConstants2[0] = 0x100;
	xVSConstantsBase.m_afConstants2[1] = 2 * 0x100;
	xVSConstantsBase.m_afConstants2[2] = ASURA_DIRECT3D_CARPET_GAME_RENDER_VS_CONST_STYLE_START;
	xVSConstantsBase.m_afConstants2[3] = 0;
	
	xVSConstantsBase.m_afCorners[0][0] = -0.5;
	xVSConstantsBase.m_afCorners[0][1] = +1.0;
	xVSConstantsBase.m_afCorners[0][2] = +0.0;
	xVSConstantsBase.m_afCorners[0][3] = +0.0;
	
	xVSConstantsBase.m_afCorners[1][0] = +0.5;
	xVSConstantsBase.m_afCorners[1][1] = +1.0;
	xVSConstantsBase.m_afCorners[1][2] = +1.0;
	xVSConstantsBase.m_afCorners[1][3] = +0.0;
	
	xVSConstantsBase.m_afCorners[2][0] = +0.5;
	xVSConstantsBase.m_afCorners[2][1] = +0.0;
	xVSConstantsBase.m_afCorners[2][2] = +1.0;
	xVSConstantsBase.m_afCorners[2][3] = +1.0;
	
	xVSConstantsBase.m_afCorners[3][0] = -0.5;
	xVSConstantsBase.m_afCorners[3][1] = +0.0;
	xVSConstantsBase.m_afCorners[3][2] = +0.0;
	xVSConstantsBase.m_afCorners[3][3] = +1.0;
	
	{
		const uint32 uiWavesCount = sizeof( xVSConstantsBase.m_axWaves) / sizeof( xVSConstantsBase.m_axWaves[ 0]);
		for( uint32 uiWaveIndex = 0; uiWaveIndex < uiWavesCount; uiWaveIndex += 1)
		{
			Asura_Direct3D_CGR_VSConstants_Wave& xWave = xVSConstantsBase.m_axWaves[ uiWaveIndex];
			
			xWave.m_afWave[0] = xDataFrame.m_afWaveX[ uiWaveIndex];
			xWave.m_afWave[1] = xDataFrame.m_afWaveY[ uiWaveIndex];
			xWave.m_afWave[2] = xDataFrame.m_afWaveZ[ uiWaveIndex];
			xWave.m_afWave[3] = 0;
		}
	}
	
#if !defined( ASURA_DIRECT3D_BGR_SUPPORT_SM30)
	if(Asura_Fog::IsGraphFogEnabled())
	{
		const float fStart = Asura_Fog::GetFogNearPlane();
		const float fEnd = Asura_Fog::GetFogFarPlane();
		const float fScale = ( fStart != fEnd) ? (1.0f / (fEnd - fStart)) : 0;

		// DLH - 15 May 2006 15:27:09 - Calc scaled Plane to workout ABS distance from camera into 0-1 fog range value
		Asura_Vector_3 xFogPlane = xDataFrame.m_xCameraForwards;
		xFogPlane.Normalise();
		xFogPlane *= fScale;
		
		Asura_Vector_3 xFogPoint = (xDataFrame.m_xCameraForwards * fStart) + xDataFrame.m_xCameraPosition;
		const float fPlaneDistance = xFogPoint * xFogPlane;
		
		xVSConstantsBase.m_afFogGraphPlane[0] = xFogPlane.GetX();
		xVSConstantsBase.m_afFogGraphPlane[1] = xFogPlane.GetY();
		xVSConstantsBase.m_afFogGraphPlane[2] = xFogPlane.GetZ();
		xVSConstantsBase.m_afFogGraphPlane[3] = -fPlaneDistance;
		
		const Asura_Vector_2 &xCenterpoint = Asura_Fog::GetGraphFogPoint();

		// DLH - 15 May 2006 15:24:22 - Scale 0-2 to 0-CenterPoint
		xVSConstantsBase.m_afFogGraphScale[0][0] = 1.0f / xCenterpoint.x;
		xVSConstantsBase.m_afFogGraphScale[0][1] = 0.0f;
		// DLH - 15 May 2006 15:23:50 - Clamp a0.x Lookup values
		xVSConstantsBase.m_afFogGraphScale[0][2] = 0.0f;
		xVSConstantsBase.m_afFogGraphScale[0][3] = 1.0f;
		
		// DLH - 15 May 2006 15:24:22 - Scale 0-2 to CenterPoint-1
		xVSConstantsBase.m_afFogGraphScale[1][0] = 1.0f / (1.0f-xCenterpoint.x);
		xVSConstantsBase.m_afFogGraphScale[1][1] = -xCenterpoint.x / (1.0f - xCenterpoint.x);
		// DLH - 15 May 2006 15:59:53 - Center point for comprassison
		xVSConstantsBase.m_afFogGraphScale[1][2] = xCenterpoint.x;
		xVSConstantsBase.m_afFogGraphScale[1][3] = 0.0f;
		
		// DLH - 15 May 2006 15:25:12 - Coeffs Spline One
		{
			const float fValue0 = 1.f - (-xCenterpoint.y);
			const float fValue1 = 1.f - (0.f);
			const float fValue2 = 1.f - (xCenterpoint.y);
			const float fValue3 = 1.f - (Asura_Fog::GetFogValueAtFarPlane());

			xVSConstantsBase.m_afFogGraphCoeffs[0][0] =  0.5f * ( fValue0 * -1.0f + fValue1 *  3.0f + fValue2 * -3.0f + fValue3 *  1.0f );
			xVSConstantsBase.m_afFogGraphCoeffs[0][1] =  0.5f * ( fValue0 *  2.0f + fValue1 * -5.0f + fValue2 *  4.0f + fValue3 * -1.0f );
			xVSConstantsBase.m_afFogGraphCoeffs[0][2] =  0.5f * ( fValue0 * -1.0f +                   fValue2 *  1.0f                   );
			xVSConstantsBase.m_afFogGraphCoeffs[0][3] =  fValue1;
		}
		// DLH - 15 May 2006 15:25:12 - Coeffs Spline Two
		{
			const float fValue0 = 1.f - (0.f);
			const float fValue1 = 1.f - (xCenterpoint.y);
			const float fValue2 = 1.f - (Asura_Fog::GetFogValueAtFarPlane());
			const float fValue3 = 1.f - (2.f * Asura_Fog::GetFogValueAtFarPlane() - xCenterpoint.y);

			xVSConstantsBase.m_afFogGraphCoeffs[1][0] =  0.5f * ( fValue0 * -1.0f + fValue1 *  3.0f + fValue2 * -3.0f + fValue3 *  1.0f );
			xVSConstantsBase.m_afFogGraphCoeffs[1][1] =  0.5f * ( fValue0 *  2.0f + fValue1 * -5.0f + fValue2 *  4.0f + fValue3 * -1.0f );
			xVSConstantsBase.m_afFogGraphCoeffs[1][2] =  0.5f * ( fValue0 * -1.0f +                   fValue2 *  1.0f                   );
			xVSConstantsBase.m_afFogGraphCoeffs[1][3] =  fValue1;
		}
	}
	else
	{
		const float fStrenght = Asura_Fog::GetFogValueAtFarPlane();
		const float fStart = Asura_Fog::GetFogNearPlane();
		const float fEnd = Asura_Fog::GetFogFarPlane();
		const float fScale = ( fStart != fEnd) ? (1.0f / (fEnd - fStart)) : 0;

		Asura_Vector_3 xFogPlane = xDataFrame.m_xCameraForwards;
		xFogPlane.Normalise();
		xFogPlane *= fScale;
		
		Asura_Vector_3 xFogPoint = (xDataFrame.m_xCameraForwards * fStart) + xDataFrame.m_xCameraPosition;
		const float fPlaneDistance = xFogPoint * xFogPlane;
		
		xVSConstantsBase.m_afFogLinearPlane[0] = xFogPlane.GetX();
		xVSConstantsBase.m_afFogLinearPlane[1] = xFogPlane.GetY();
		xVSConstantsBase.m_afFogLinearPlane[2] = xFogPlane.GetZ();
		xVSConstantsBase.m_afFogLinearPlane[3] = -fPlaneDistance;
		
		xVSConstantsBase.m_afFogLinearColour[0] = -(fStrenght);
		xVSConstantsBase.m_afFogLinearColour[1] = 1.0f;
		xVSConstantsBase.m_afFogLinearColour[2] = 0.75f;
		xVSConstantsBase.m_afFogLinearColour[3] = 0.5f;
	}
#endif
	
#if !defined( ASURA_DIRECT3D_BGR_SUPPORT_SM30)
	if( NULL == pxPhoton)
	{
		xVSConstantsBase.m_afDynamicLightX[0] = 0;
		xVSConstantsBase.m_afDynamicLightX[1] = 0;
		xVSConstantsBase.m_afDynamicLightX[2] = 0;
		xVSConstantsBase.m_afDynamicLightX[3] = 0;
		
		xVSConstantsBase.m_afDynamicLightY[0] = 0;
		xVSConstantsBase.m_afDynamicLightY[1] = 0;
		xVSConstantsBase.m_afDynamicLightY[2] = 0;
		xVSConstantsBase.m_afDynamicLightY[3] = 0;
		
		xVSConstantsBase.m_afDynamicLightZ[0] = 0;
		xVSConstantsBase.m_afDynamicLightZ[1] = 0;
		xVSConstantsBase.m_afDynamicLightZ[2] = 0;
		xVSConstantsBase.m_afDynamicLightZ[3] = 0;
	}
	else
	{
		const Asura_Photon& xPhoton = *pxPhoton;
		
		Asura_Vector_3 xPosition = xPhoton.GetPosition();
		const float fRange = xPhoton.GetRange();
		const float fScale = 1.0f / fRange;
		const float fScale2 = 0.5f * fScale;
		
		xVSConstantsBase.m_afDynamicLightX[0] = fScale2;
		xVSConstantsBase.m_afDynamicLightX[1] = 0;
		xVSConstantsBase.m_afDynamicLightX[2] = 0;
		xVSConstantsBase.m_afDynamicLightX[3] = 0.5f - (fScale2 * xPosition.GetX());
		
		xVSConstantsBase.m_afDynamicLightZ[0] = 0;
		xVSConstantsBase.m_afDynamicLightZ[1] = fScale2;
		xVSConstantsBase.m_afDynamicLightZ[2] = 0;
		xVSConstantsBase.m_afDynamicLightZ[3] = 0.5f - (fScale2 * xPosition.GetY());
		
		xVSConstantsBase.m_afDynamicLightY[0] = 0;
		xVSConstantsBase.m_afDynamicLightY[1] = 0;
		xVSConstantsBase.m_afDynamicLightY[2] = fScale2;
		xVSConstantsBase.m_afDynamicLightY[3] = 0.5f - (fScale2 * xPosition.GetZ());
		
	
		{
			const float fBrightnessScale = 1.0f / 4.0f;
			float afColour[4];
			
			afColour[0] = fBrightnessScale * xPhoton.GetRedComponent();
			afColour[1] = fBrightnessScale * xPhoton.GetGreenComponent();
			afColour[2] = fBrightnessScale * xPhoton.GetBlueComponent();
			afColour[3] = 1.0f;
			
			xResult = Asura_Direct3D::D3DDevice->SetPixelShaderConstantF( 0, afColour, 1);
		}
	}
#endif
	
	const uint32 uiConstantCount = sizeof( xVSConstantsBase) / sizeof( float[4]);
	xResult = Asura_Direct3D::D3DDevice->SetVertexShaderConstantF( 0, (float*)&xVSConstantsBase, uiConstantCount);
	ASURA_D3D_OK( xResult);	
	
	return( true);
}

#endif //defined( ASURA_USE_CARPET)

//*******************************************************************
//
// (c) 2006 Rebellion (Derby)
//
// Warning: This computer program is protected by copyright law and 
// international treaties. Unauthorized reproduction or distribution
// of this program, or any portion of it, may result in severe civil and
// criminal penalties, and will be prosecuted to the maximum extent 
// possible under the law.
//
//*******************************************************************

