#ifndef _RUSHADER_D3D_SKY_H_
#define _RUSHADER_D3D_SKY_H_

// Rune system core
#include "../../Direct3D/Shader/RuShader_D3D_Base.h"

#pragma unmanaged

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

class CRuShader_SkyDome : public CRuShader_Base
{
public:
											CRuShader_SkyDome(CRuEngineD3D *engine);
	virtual									~CRuShader_SkyDome();

	// Shader capabilities query
	virtual const char*						GetShaderName() const;
	virtual INT32							GetShaderPriority() const;
	virtual DWORD							GetCaps() const;

	// Rendering setup
	virtual INT32							GetNumPasses() const;
	virtual void							BeginPass(INT32 passNumber);
	virtual void							EndPass(INT32 passNumber);

	// Shader texture placement query
	virtual INT32							GetNumSamplers(INT32 passNumber) const;
	virtual RuTextureChannel				GetTextureChannel(INT32 passNumber, INT32 samplerNumber) const;

	// Shader parameter setup
	virtual void							SetParameters(const CRuParameterCache *paramCache);

	// Instancing helper
	virtual void							Instance(INT32 streamIndex, IRuMesh *mesh, UINT32 morphTargetIndex, void *buffer) const;
};

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

class CRuShader_SkyFX : public CRuShader_Base
{
public:
											CRuShader_SkyFX(CRuEngineD3D *engine);
	virtual									~CRuShader_SkyFX();

	// Shader capabilities query
	virtual const char*						GetShaderName() const;
	virtual INT32							GetShaderPriority() const;
	virtual DWORD							GetCaps() const;

	// Rendering setup
	virtual INT32							GetNumPasses() const;
	virtual void							BeginPass(INT32 passNumber);
	virtual void							EndPass(INT32 passNumber);

	// Shader texture placement query
	virtual INT32							GetNumSamplers(INT32 passNumber) const;
	virtual RuTextureChannel				GetTextureChannel(INT32 passNumber, INT32 samplerNumber) const;

	// Shader parameter setup
	virtual void							SetParameters(const CRuParameterCache *paramCache);

	// Instancing helper
	virtual void							Instance(INT32 streamIndex, IRuMesh *mesh, UINT32 morphTargetIndex, void *buffer) const;
};

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

/*!
	VERTEX SHADER CONSTANTS
	-----------------------
	[ 27 -  27] (u increment, v increment, ?, ?)
	[ 28 -  28] (u index 0, v index 0, u index 1, v index 1)

	PIXEL SHADER CONSTANTS
	----------------------
	[  2 -   2] (?, ?, ?, blend factor)
*/
class CRuShader_CloudPlane : public CRuShader_Base
{
protected:
	UINT32									m_numInstances;

public:
											CRuShader_CloudPlane(CRuEngineD3D *engine);
	virtual									~CRuShader_CloudPlane();

	// Shader capabilities query
	virtual const char*						GetShaderName() const;
	virtual INT32							GetShaderPriority() const;
	virtual DWORD							GetCaps() const;

	// Rendering setup
	virtual INT32							GetNumPasses() const;
	virtual void							BeginPass(INT32 passNumber);
	virtual void							EndPass(INT32 passNumber);

	// Shader texture placement query
	virtual INT32							GetNumSamplers(INT32 passNumber) const;
	virtual RuTextureChannel				GetTextureChannel(INT32 passNumber, INT32 samplerNumber) const;

	// Shader parameter setup
	virtual void							SetParameters(const CRuParameterCache *paramCache);

	// Instancing helper
	virtual void							Instance(INT32 streamIndex, IRuMesh *mesh, UINT32 morphTargetIndex, void *buffer) const;
};

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

inline const char *CRuShader_SkyDome::GetShaderName() const
{
	return "ruSHADER_SKYDOME";
}

inline INT32 CRuShader_SkyDome::GetShaderPriority() const
{
	return 900;
}

inline DWORD CRuShader_SkyDome::GetCaps() const
{
	return 0x00000000;
}

inline INT32 CRuShader_SkyDome::GetNumPasses() const
{
	return 1;
}

inline INT32 CRuShader_SkyDome::GetNumSamplers(INT32 passNumber) const
{
	return 2;
}

inline RuTextureChannel CRuShader_SkyDome::GetTextureChannel(INT32 passNumber, INT32 samplerNumber) const
{
	switch(samplerNumber)
	{
		case 0:
			return ruTEXCHANNEL_SKYDOME_GRADIENT_0;
		case 1:
			return ruTEXCHANNEL_SKYDOME_GRADIENT_1;
	}

	return ruTEXCHANNEL_INVALID;
}

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

inline const char *CRuShader_SkyFX::GetShaderName() const
{
	return "ruSHADER_SKYFX";
}

inline INT32 CRuShader_SkyFX::GetShaderPriority() const
{
	return 900;
}

inline DWORD CRuShader_SkyFX::GetCaps() const
{
	return 0x00000000;
}

inline INT32 CRuShader_SkyFX::GetNumPasses() const
{
	return 1;
}

inline INT32 CRuShader_SkyFX::GetNumSamplers(INT32 passNumber) const
{
	return 1;
}

inline RuTextureChannel CRuShader_SkyFX::GetTextureChannel(INT32 passNumber, INT32 samplerNumber) const
{
	switch(samplerNumber)
	{
		case 0:
			return ruTEXCHANNEL_DIFFUSEMAP;
	}

	return ruTEXCHANNEL_INVALID;
}

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

inline const char *CRuShader_CloudPlane::GetShaderName() const
{
	return "ruSHADER_CLOUDPLANE";
}

inline INT32 CRuShader_CloudPlane::GetShaderPriority() const
{
	return 901;
}

inline DWORD CRuShader_CloudPlane::GetCaps() const
{
	return 0x00000000;
}

inline INT32 CRuShader_CloudPlane::GetNumPasses() const
{
	return 1;
}

inline INT32 CRuShader_CloudPlane::GetNumSamplers(INT32 passNumber) const
{
	return 2;
}

inline RuTextureChannel CRuShader_CloudPlane::GetTextureChannel(INT32 passNumber, INT32 samplerNumber) const
{
	switch(samplerNumber)
	{
		case 0:
			return ruTEXCHANNEL_SKYDOME_CLOUD_0;
		case 1:
			return ruTEXCHANNEL_SKYDOME_CLOUD_1;
	}

	return ruTEXCHANNEL_INVALID;
}

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

#pragma managed

#endif
