#include "../../Direct3D/Shader/RuShader_D3D_Static_FX.h"

#pragma unmanaged

// ************************************************************************************************************************************************************

CRuShader_Static_Highlight::CRuShader_Static_Highlight(CRuEngineD3D *engine)
:	CRuShader_Static_Base(engine)
{
	char *vsSource = "\
																													\n\
	vs_1_1															; Vertex shader version 1.1						\n\
																													\n\
	dcl_position0		v0											; Declare position								\n\
	dcl_normal			v1											; Declare normal								\n\
	dcl_texcoord0		v5											; Declare input texcoord 0						\n\
																													\n\
	; Transform position into homogeneous space																		\n\
	mov					r0,			c20.yyyy						; Move 1 into r0								\n\
	mov					r1,			c20.yyyy						; Move 1 into r1								\n\
	m4x3				r0.xyz,		v0,			c0					; Transform vertex to world space				\n\
	m4x3				r1.xyz,		r0,			c3					; Transform vertex to view space				\n\
	m4x4				oPos,		r1,			c6					; Transform vertex to homogeneous space			\n\
																													\n\
	; Fog factor																									\n\
	sub					r2.x,		c25.z,		c25.y				; Fog End - Fog Start into r2.x					\n\
	rcp					r2.x,		r2.x							; Reciprocal of fog range into r0.x				\n\
	sub					r3.x,		r1.z,		c25.y				; Offset vertex z by fog start into r3.x		\n\
	mul					r2.x,		r3.x,		r2.x				; Divide z by fog range into r0					\n\
	sub					r2.x,		c20.y,		r2.x				; Invert fog factor								\n\
	max					r2.x,		r2.x,		c20.w				; Clamp to [0, 1]								\n\
	min					r2.x,		r2.x,		c20.y																\n\
	mov					oFog,		r2.x							; Output fog factor								\n"
	"																												\n\
	; Diffuse color																									\n\
	mov					oD0,		c27								; Output global diffuse							\n"
	"																												\n\
	; Texture coordinates																							\n\
	mov					oT0,		v5								; Copy diffuse texture coordinates to output	\n\
	";

	char *psSource = "\
																													\n\
	ps_1_1																											\n\
																													\n\
	; Texture sampling																								\n\
	tex					t0											; Sample diffuse texture						\n\
																													\n\
	; Arithmetic ops																								\n\
	mov					r0,			v0								; Copy diffuse color to output					\n\
	mov					r0.w,		t0.w							; Copy texture alpha to output					\n\
	";

	// Assemble vertex shader
	m_vertexShader = RuD3DAssembleVertexShader(vsSource);

	// Assemble pixel shader
	m_pixelShader = RuD3DAssemblePixelShader(psSource);

	// Enable alpha blending override
	m_override_AlphaBlend = TRUE;
}

CRuShader_Static_Highlight::~CRuShader_Static_Highlight()
{
}

void CRuShader_Static_Highlight::BeginPass(INT32 passNumber)
{
	// Call base BeginPass to perform any additional setup
	CRuShader_Static_Base::BeginPass(passNumber);

	if(passNumber == 0)
	{
		m_vertexDecl->Select();
		m_engine->SetVertexShader(m_vertexShader);
		m_engine->SetPixelShader(m_pixelShader);
		m_engine->GetD3DDevice()->SetVertexShaderConstantF(0, m_shaderConstants, m_numBaseConstants + 2);
		m_engine->GetD3DDevice()->SetPixelShaderConstantF(0, m_pixelShaderConstants, m_numBasePixelShaderConstants);

		m_engine->SetRenderState(D3DRS_ZWRITEENABLE, TRUE);
		m_engine->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL);

		m_engine->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
		m_engine->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
		m_engine->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);

		m_engine->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
		m_engine->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);

		m_engine->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
		m_engine->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
		m_engine->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
	}
}

void CRuShader_Static_Highlight::EndPass(INT32 passNumber)
{
}

void CRuShader_Static_Highlight::SetParameters(const CRuParameterCache *paramCache)
{
	// Chain set parameters call to parent
	CRuShader_Static_Base::SetParameters(paramCache);

	DWORD param;
	if(paramCache->GetParameter(ruPARAMTYPE_DWORD_0, param))
	{
		INT32 highlightColorOffset = 108;
		RUCOLOR highlightColor = static_cast<RUCOLOR>(param);

		m_shaderConstants[highlightColorOffset++] = ((highlightColor >> 16) & 0xFF) / 255.0f;
		m_shaderConstants[highlightColorOffset++] = ((highlightColor >>  8) & 0xFF) / 255.0f;
		m_shaderConstants[highlightColorOffset++] = ((highlightColor >>  0) & 0xFF) / 255.0f;
	}
}

// ************************************************************************************************************************************************************

#pragma managed
