#include "Mix/Private/Scene/Standard/Common/EffectPackage.h"

#include "Mix/IO/IReader.h"
#include "Mix/Graphics/IManager.h"
#include "Mix/Graphics/IDevice.h"
#include "Mix/Graphics/IVertexLayout.h"
#include "Mix/Graphics/IVertexShader.h"
#include "Mix/Graphics/IPixelShader.h"

namespace Mix{ namespace Scene{ namespace Standard{ namespace Common{

////////////////////////////////////////////////////////////////////////////////////////////////////
// EffectPackage : 定数
////////////////////////////////////////////////////////////////////////////////////////////////////

const wchar_t* EffectPackage::MEP_RENDERER_TYPE_TABLE[EffectPackage::MEP_RT_MAX] =
{
	L"Standard",
};

////////////////////////////////////////////////////////////////////////////////////////////////////
// EffectPackage : バーテックスレイアウト
////////////////////////////////////////////////////////////////////////////////////////////////////

//バーテックレイアウト : サンプリング
static const Mix::Graphics::VERTEX_ELEMENT MEP_VL_SAMPLING[] =
{
	{ Mix::Graphics::VLS_POSITION, 0, Mix::Graphics::VLF_FLOAT32_4,  0, },
	{ Mix::Graphics::VLS_TEXTURE,  0, Mix::Graphics::VLF_FLOAT32_2, 16, },
};
static const UInt32 MEP_VL_SAMPLING_COUNT = sizeof( MEP_VL_SAMPLING ) / sizeof( Mix::Graphics::VERTEX_ELEMENT );
static const wchar_t* MEP_VL_SAMPLING_NAME = L"Sampling";

//バーテックレイアウト : ガウシアンブラー
static const Mix::Graphics::VERTEX_ELEMENT MEP_VL_GAUSSIAN_BLUR[] =
{
	{ Mix::Graphics::VLS_POSITION, 0, Mix::Graphics::VLF_FLOAT32_4,  0, },
	{ Mix::Graphics::VLS_TEXTURE,  0, Mix::Graphics::VLF_FLOAT32_2, 16, },
};
static const UInt32 MEP_VL_GAUSSIAN_BLUR_COUNT = sizeof( MEP_VL_GAUSSIAN_BLUR ) / sizeof( Mix::Graphics::VERTEX_ELEMENT );
static const wchar_t* MEP_VL_GAUSSIAN_BLUR_NAME = L"GaussianBlur";

//バーテックレイアウト : スカイドーム
static const Mix::Graphics::VERTEX_ELEMENT MEP_VL_SKYDOME[] =
{
	{ Mix::Graphics::VLS_POSITION, 0, Mix::Graphics::VLF_FLOAT32_4,  0, },
	{ Mix::Graphics::VLS_TEXTURE,  0, Mix::Graphics::VLF_FLOAT32_2, 16, },
};
static const UInt32 MEP_VL_SKYDOME_COUNT = sizeof( MEP_VL_SKYDOME ) / sizeof( Mix::Graphics::VERTEX_ELEMENT );
static const wchar_t* MEP_VL_SKYDOME_NAME = L"SkyDome";

//バーテックレイアウト : レンズフレア( ゴースト )
static const Mix::Graphics::VERTEX_ELEMENT MEP_VL_LF_GHOST[] =
{
	{ Mix::Graphics::VLS_POSITION, 0, Mix::Graphics::VLF_FLOAT32_4,  0, },
	{ Mix::Graphics::VLS_COLOR,    0, Mix::Graphics::VLF_FLOAT32_4, 16, },
	{ Mix::Graphics::VLS_TEXTURE,  0, Mix::Graphics::VLF_FLOAT32_2, 32, },
};
static const UInt32 MEP_VL_LF_GHOST_COUNT = sizeof( MEP_VL_LF_GHOST ) / sizeof( Mix::Graphics::VERTEX_ELEMENT );
static const wchar_t* MEP_VL_LF_GHOST_NAME = L"LensFlare(Ghost)";

////////////////////////////////////////////////////////////////////////////////////////////////////
// EffectPackage
////////////////////////////////////////////////////////////////////////////////////////////////////

EffectPackage::EffectPackage( const wchar_t* pDirPath, const wchar_t* pName, const wchar_t* pFilePath ) :
Mix::Scene::Common::EffectPackage( pDirPath, pName, pFilePath ),
m_pGraphicsDev( NULL )
{
	Mix::Graphics::IManager* pGraphicsMgr;

	pGraphicsMgr = Mix::Graphics::GetManagerPtr();
	MIX_ASSERT( pGraphicsMgr != NULL );

	pGraphicsMgr->GetDevice( &m_pGraphicsDev );
	MIX_ASSERT( m_pGraphicsDev != NULL );
}

EffectPackage::~EffectPackage( void )
{
	for( EffectPackage::VertexEffectMap::iterator it = m_ResidentVEMap.begin(); it != m_ResidentVEMap.end(); ++it )
	{
		it->second.Dispose();
	}

	for( EffectPackage::PixelEffectMap::iterator it = m_ResidentPEMap.begin(); it != m_ResidentPEMap.end(); ++it )
	{
		it->second.Dispose();
	}

	for( EffectPackage::VertexEffectMap::iterator it = m_MaterialVEMap.begin(); it != m_MaterialVEMap.end(); ++it )
	{
		it->second.Dispose();
	}

	for( EffectPackage::PixelEffectMap::iterator it = m_MaterialPEMap.begin(); it != m_MaterialPEMap.end(); ++it )
	{
		it->second.Dispose();
	}

	MIX_RELEASE( m_pGraphicsDev );
}

Boolean EffectPackage::Initialize( Mix::IO::IReader* pReader )
{
	MIX_ASSERT( pReader != NULL );

	EffectPackage::MEP_DATA_HEADER dataHeader;
	Mix::STL::Vector<Mix::Memory::SECTION_SCENE, UInt8> buff;
	Mix::StringW tempStr;
	Mix::STL::Vector<Mix::Memory::SECTION_SCENE, Mix::Graphics::VERTEX_ELEMENT> elements;

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// データヘッダ
	////////////////////////////////////////////////////////////////////////////////////////////////////

	if( pReader->Read( &dataHeader, sizeof( dataHeader ) ) != sizeof( dataHeader ) )
	{
		MIX_LOG_ERROR( L"%s : %s(2) : FilePath[%s]",
			EffectPackage::FAILED_CREATE,
			EffectPackage::FAILED_CREATE_MEP_IO_ERROR,
			m_FilePath.GetConstPtr() );

		return False;
	}

	m_ProcFlags = dataHeader.processFlags;

	MIX_LOG_INFO( L"RendererType[%s]", EffectPackage::MEP_RENDERER_TYPE_TABLE[dataHeader.rendererType] );
	MIX_LOG_INFO( L"ProcessFlags[0x%08x]", dataHeader.processFlags );
	MIX_LOG_INFO( L"VertexShaderNum[%d]", dataHeader.vertexShaderNum );
	MIX_LOG_INFO( L"PixelShaderNum[%d]", dataHeader.pixelShaderNum );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// エフェクト
	////////////////////////////////////////////////////////////////////////////////////////////////////

	/*
		バーテックスシェーダー
	*/

	for( UInt32 i = 0; i < dataHeader.vertexShaderNum; i++ )
	{
		EffectPackage::MEP_VS_HEADER vsHeader;
		EffectPackage::VERTEX_EFFECT vsEffect;

		//ヘッダ
		if( pReader->Read( &vsHeader, sizeof( vsHeader ) ) == sizeof( vsHeader ) )
		{
			MIX_ASSERT( vsHeader.buffSize[EffectPackage::VES_MATERIAL_COLOR] > 0 );
			MIX_ASSERT( vsHeader.elementNum > 0 );
		}
		else
		{
			MIX_LOG_ERROR( L"%s : %s(1) : FilePath[%s]",
				EffectPackage::FAILED_CREATE,
				EffectPackage::FAILED_CREATE_MEP_IO_ERROR,
				m_FilePath.GetConstPtr() );

			return False;
		}

		//シェーダー
		for( UInt32 j = 0; j < EffectPackage::VES_MATERIAL_MAX; j++ )
		{
			UInt32 buffSize = vsHeader.buffSize[j];

			if( buffSize == 0 )
			{
				continue;
			}

			buff.clear();
			buff.resize( buffSize );

			if( pReader->Read( &( buff[0] ), MIX_UIT_TO_UI32( buff.size() ) ) == buffSize )
			{
				tempStr.Sprintf( L"MEP/VS_%08x_%d", vsHeader.id, j );

				if( m_pGraphicsDev->CreateVertexShaderFromMemory( &( buff[0] ), MIX_UIT_TO_UI32( buff.size() ), &( vsEffect.pShader[j] ), tempStr.GetConstPtr() ) == False )
				{
					return False;
				}
			}
			else
			{
				MIX_LOG_ERROR( L"%s : %s(2) : FilePath[%s]",
					EffectPackage::FAILED_CREATE,
					EffectPackage::FAILED_CREATE_MEP_IO_ERROR,
					m_FilePath.GetConstPtr() );

				return False;
			}
		}

		//レイアウト
		elements.clear();
		elements.resize( vsHeader.elementNum );

		if( pReader->Read( &( elements[0] ), MIX_UIT_TO_UI32( sizeof( Mix::Graphics::VERTEX_ELEMENT ) * elements.size() ) ) == MIX_UIT_TO_UI32( sizeof( Mix::Graphics::VERTEX_ELEMENT ) * vsHeader.elementNum ) )
		{
			tempStr.Sprintf( L"MEP/VL_%08x", vsHeader.id );

			if( m_pGraphicsDev->CreateVertexLayout( &( elements[0] ), MIX_UIT_TO_UI32( elements.size() ), vsEffect.pShader[EffectPackage::VES_DEFAULT], &( vsEffect.pLayout ), tempStr.GetConstPtr() ) == False )
			{
				return False;
			}
		}
		else
		{
			MIX_LOG_ERROR( L"%s : %s(3) : FilePath[%s]",
				EffectPackage::FAILED_CREATE,
				EffectPackage::FAILED_CREATE_MEP_IO_ERROR,
				m_FilePath.GetConstPtr() );

			return False;
		}

		m_MaterialVEMap.insert( EffectPackage::VertexEffectMap::value_type( vsHeader.id, vsEffect ) );
	}

	/*
		ピクセルシェーダー
	*/

	for( UInt32 i = 0; i < dataHeader.pixelShaderNum; i++ )
	{
		EffectPackage::MEP_PS_HEADER psHeader;
		EffectPackage::PIXEL_EFFECT psEffect;

		//ヘッダ
		if( pReader->Read( &psHeader, sizeof( psHeader ) ) == sizeof( psHeader ) )
		{
			MIX_ASSERT( psHeader.buffSize[EffectPackage::PES_MATERIAL_COLOR] > 0 );
		}
		else
		{
			MIX_LOG_ERROR( L"%s : %s(4) : FilePath[%s]",
				EffectPackage::FAILED_CREATE,
				EffectPackage::FAILED_CREATE_MEP_IO_ERROR,
				m_FilePath.GetConstPtr() );

			return False;
		}

		//シェーダー
		for( UInt32 j = 0; j < EffectPackage::PES_MATERIAL_MAX; j++ )
		{
			UInt32 buffSize = psHeader.buffSize[j];
			if( buffSize == 0 )
			{
				continue;
			}

			buff.clear();
			buff.resize( buffSize );

			if( pReader->Read( &( buff[0] ), MIX_UIT_TO_UI32( buff.size() ) ) == buffSize )
			{
				tempStr.Sprintf( L"MEP/PS_%08x_%d", psHeader.id, j );

				if( m_pGraphicsDev->CreatePixelShaderFromMemory( &( buff[0] ), MIX_UIT_TO_UI32( buff.size() ), &( psEffect.pShader[j] ), tempStr.GetConstPtr() ) == False )
				{
					return False;
				}
			}
			else
			{
				MIX_LOG_ERROR( L"%s : %s(5) : FilePath[%s]",
					EffectPackage::FAILED_CREATE,
					EffectPackage::FAILED_CREATE_MEP_IO_ERROR,
					m_FilePath.GetConstPtr() );

				return False;
			}
		}

		m_MaterialPEMap.insert( EffectPackage::PixelEffectMap::value_type( psHeader.id, psEffect ) );
	}

	return True;
}

UInt32 EffectPackage::GetProcessFlags( void ) const
{
	return m_ProcFlags;
}

EffectPackage::VERTEX_EFFECT* EffectPackage::GetVertexEffectPtr( UInt32 type, UInt32 opt )
{
	EffectPackage::VERTEX_EFFECT* pEffect = NULL;

	if( type == EffectPackage::E_RESIDENT )
	{
		EffectPackage::VertexEffectMap::iterator it = m_ResidentVEMap.find( opt );

		if( it != m_ResidentVEMap.end() )
		{
			pEffect = &( it->second );
		}
		else
		{
			EffectPackage::SHADER_BINARY binarys[EffectPackage::VES_MAX] = { NULL };
			UInt32 binaryCount = 0;

			const Mix::Graphics::VERTEX_ELEMENT* elements = NULL;
			UInt32 elementCount = 0;
			const wchar_t* pLayoutName = NULL;

			switch( opt )
			{
			case EffectPackage::ER_SAMPLING:
				GetShaderBinary( EffectPackage::SHADER_SAMPLING_VS, binarys[EffectPackage::VES_DEFAULT] );
				binaryCount = 1;
				elements = &( MEP_VL_SAMPLING[0] );
				elementCount = MEP_VL_SAMPLING_COUNT;
				pLayoutName = MEP_VL_SAMPLING_NAME;
				break;
			case EffectPackage::ER_GAUSSIAN_BLUR:
				GetShaderBinary( EffectPackage::SHADER_GAUSSIAN_BLUR_X_VS, binarys[EffectPackage::VES_GAUSSIAN_BLUR_X] );
				GetShaderBinary( EffectPackage::SHADER_GAUSSIAN_BLUR_Y_VS, binarys[EffectPackage::VES_GAUSSIAN_BLUR_Y] );
				binaryCount = 2;
				elements = &( MEP_VL_GAUSSIAN_BLUR[0] );
				elementCount = MEP_VL_GAUSSIAN_BLUR_COUNT;
				pLayoutName = MEP_VL_GAUSSIAN_BLUR_NAME;
				break;

			case EffectPackage::ER_SKYDOME_DEFAULT:
				GetShaderBinary( EffectPackage::SHADER_SKYDOME_DEFAULT_VS, binarys[EffectPackage::VES_DEFAULT] );
				binaryCount = 1;
				elements = &( MEP_VL_SKYDOME[0] );
				elementCount = MEP_VL_SKYDOME_COUNT;
				pLayoutName = MEP_VL_SKYDOME_NAME;
				break;
			case EffectPackage::ER_SKYDOME_ATMOSPHERE:
				GetShaderBinary( EffectPackage::SHADER_SKYDOME_ATMOSPHERE_VS, binarys[EffectPackage::VES_DEFAULT] );
				binaryCount = 1;
				elements = &( MEP_VL_SKYDOME[0] );
				elementCount = MEP_VL_SKYDOME_COUNT;
				pLayoutName = MEP_VL_SKYDOME_NAME;
				break;

			case EffectPackage::ER_SKYDOME_PANORAMA_D:
				GetShaderBinary( EffectPackage::SHADER_SKYDOME_PANORAMA_VS, binarys[EffectPackage::VES_SKYDOME_PANORAMA] );
				GetShaderBinary( EffectPackage::SHADER_SKYDOME_PANORAMA_VS, binarys[EffectPackage::VES_SKYDOME_PANORAMA_F] );
				binaryCount = 2;
				elements = &( MEP_VL_SKYDOME[0] );
				elementCount = MEP_VL_SKYDOME_COUNT;
				pLayoutName = MEP_VL_SKYDOME_NAME;
				break;
			case EffectPackage::ER_SKYDOME_PANORAMA_A:
				GetShaderBinary( EffectPackage::SHADER_SKYDOME_PANORAMA_VS,    binarys[EffectPackage::VES_SKYDOME_PANORAMA] );
				GetShaderBinary( EffectPackage::SHADER_SKYDOME_PANORAMA_FA_VS, binarys[EffectPackage::VES_SKYDOME_PANORAMA_F] );
				binaryCount = 2;
				elements = &( MEP_VL_SKYDOME[0] );
				elementCount = MEP_VL_SKYDOME_COUNT;
				pLayoutName = MEP_VL_SKYDOME_NAME;
				break;
			}

			MIX_ASSERT( binaryCount <= EffectPackage::VES_MAX );

			if( ( binaryCount > 0 ) &&
				( elementCount > 0 ) )
			{
				Boolean bSuccess = True;
				EffectPackage::VERTEX_EFFECT ve;

				for( UInt32 i = 0; ( i < binaryCount ) && ( bSuccess == True ); i++ )
				{
					const EffectPackage::SHADER_BINARY* psb = &( binarys[i] );

					if( m_pGraphicsDev->CreateVertexShaderFromMemory( psb->pData, psb->dataSize, &( ve.pShader[i] ), psb->name ) == False )
					{
						bSuccess = False;
					}
				}

				if( bSuccess == True )
				{
					MIX_ASSERT( ve.pShader[EffectPackage::VES_DEFAULT] != NULL );

					if( m_pGraphicsDev->CreateVertexLayout( elements, elementCount, ve.pShader[EffectPackage::VES_DEFAULT], &( ve.pLayout ), pLayoutName ) == False )
					{
						bSuccess = False;
					}
				}

				if( bSuccess == True )
				{
					m_ResidentVEMap.insert( EffectPackage::VertexEffectMap::value_type( opt, ve ) );

					it = m_ResidentVEMap.find( opt );
					if( it != m_ResidentVEMap.end() )
					{
						pEffect = &( it->second );
					}
					else
					{
						ve.Dispose();
					}
				}
				else
				{
					ve.Dispose();
				}
			}
		}
	}
	else if( type == EffectPackage::E_MATERIAL )
	{
		EffectPackage::VertexEffectMap::iterator it = m_MaterialVEMap.find( opt );
		if( it != m_MaterialVEMap.end() )
		{
			pEffect = &( it->second );
		}
	}

	return pEffect;
}

EffectPackage::PIXEL_EFFECT* EffectPackage::GetPixelEffectPtr( UInt32 type, UInt32 opt )
{
	EffectPackage::PIXEL_EFFECT* pEffect = NULL;

	if( type == EffectPackage::E_RESIDENT )
	{
		EffectPackage::PixelEffectMap::iterator it = m_ResidentPEMap.find( opt );
		if( it != m_ResidentPEMap.end() )
		{
			pEffect = &( it->second );
		}
		else
		{
			EffectPackage::SHADER_BINARY binarys[EffectPackage::PES_MAX] = { NULL };
			UInt32 binaryCount = 0;
			Boolean bSuccess = True;

			EffectPackage::PIXEL_EFFECT pe;

			switch( opt )
			{
			case EffectPackage::ER_SAMPLING:
				GetShaderBinary( EffectPackage::SHADER_SAMPLING_COPY_PS, binarys[EffectPackage::PES_SAMPLING_COPY] );
				GetShaderBinary( EffectPackage::SHADER_SAMPLING_DOWN2X_PS, binarys[EffectPackage::PES_SAMPLING_DOWN2X] );
				GetShaderBinary( EffectPackage::SHADER_SAMPLING_DOWN4X_PS, binarys[EffectPackage::PES_SAMPLING_DOWN4X] );
				binaryCount = 3;
				break;

			case EffectPackage::ER_BLUR3X:
				GetShaderBinary( EffectPackage::SHADER_BLUR3X_X_PS, binarys[EffectPackage::PES_COMMON_BLUR_X] );
				GetShaderBinary( EffectPackage::SHADER_BLUR3X_Y_PS, binarys[EffectPackage::PES_COMMON_BLUR_Y] );
				binaryCount = 2;
				break;
			case EffectPackage::ER_BLUR5X:
				GetShaderBinary( EffectPackage::SHADER_BLUR5X_X_PS, binarys[EffectPackage::PES_COMMON_BLUR_X] );
				GetShaderBinary( EffectPackage::SHADER_BLUR5X_Y_PS, binarys[EffectPackage::PES_COMMON_BLUR_Y] );
				binaryCount = 2;
				break;

			case EffectPackage::ER_GAUSSIAN_BLUR:
				GetShaderBinary( EffectPackage::SHADER_GAUSSIAN_BLUR_X_PS, binarys[EffectPackage::PES_COMMON_BLUR_X] );
				GetShaderBinary( EffectPackage::SHADER_GAUSSIAN_BLUR_Y_PS, binarys[EffectPackage::PES_COMMON_BLUR_Y] );
				binaryCount = 2;
				break;

			case EffectPackage::ER_GAUSSIAN_BLUR_EX:
				GetShaderBinary( EffectPackage::SHADER_GAUSSIAN_BLUR_EX_PS, binarys[EffectPackage::PES_DEFAULT] );
				binaryCount = 1;
				break;

			case EffectPackage::ER_BRIGHTPASS:
				GetShaderBinary( EffectPackage::SHADER_BP____PS, binarys[EffectPackage::PES_BP___] );
				GetShaderBinary( EffectPackage::SHADER_BP_L__PS, binarys[EffectPackage::PES_BP_L_] );
				GetShaderBinary( EffectPackage::SHADER_BP_LA_PS, binarys[EffectPackage::PES_BP_LA] );
				binaryCount = 3;
				break;

			case EffectPackage::ER_SKYDOME_DEFAULT:
				GetShaderBinary( EffectPackage::SHADER_SKYDOME_DEFAULT______PS, binarys[EffectPackage::PES_SD_DEF_____] );
				GetShaderBinary( EffectPackage::SHADER_SKYDOME_DEFAULT__C___PS, binarys[EffectPackage::PES_SD_DEF__C__] );
				GetShaderBinary( EffectPackage::SHADER_SKYDOME_DEFAULT__C2__PS, binarys[EffectPackage::PES_SD_DEF__C2_] );
				GetShaderBinary( EffectPackage::SHADER_SKYDOME_DEFAULT_B____PS, binarys[EffectPackage::PES_SD_DEF_B___] );
				GetShaderBinary( EffectPackage::SHADER_SKYDOME_DEFAULT_BC___PS, binarys[EffectPackage::PES_SD_DEF_BC__] );
				GetShaderBinary( EffectPackage::SHADER_SKYDOME_DEFAULT_BC2__PS, binarys[EffectPackage::PES_SD_DEF_BC2_] );
				binaryCount = 6;
				break;
			case EffectPackage::ER_SKYDOME_ATMOSPHERE:
				GetShaderBinary( EffectPackage::SHADER_SKYDOME_ATMOSPHERE______PS, binarys[EffectPackage::PES_SD_ASS_____] );
				GetShaderBinary( EffectPackage::SHADER_SKYDOME_ATMOSPHERE__C___PS, binarys[EffectPackage::PES_SD_ASS__C__] );
				GetShaderBinary( EffectPackage::SHADER_SKYDOME_ATMOSPHERE__C_L_PS, binarys[EffectPackage::PES_SD_ASS__C_L] );
				GetShaderBinary( EffectPackage::SHADER_SKYDOME_ATMOSPHERE__C2__PS, binarys[EffectPackage::PES_SD_ASS__C2_] );
				GetShaderBinary( EffectPackage::SHADER_SKYDOME_ATMOSPHERE__C2L_PS, binarys[EffectPackage::PES_SD_ASS__C2L] );
				GetShaderBinary( EffectPackage::SHADER_SKYDOME_ATMOSPHERE_B____PS, binarys[EffectPackage::PES_SD_ASS_B___] );
				GetShaderBinary( EffectPackage::SHADER_SKYDOME_ATMOSPHERE_BC___PS, binarys[EffectPackage::PES_SD_ASS_BC__] );
				GetShaderBinary( EffectPackage::SHADER_SKYDOME_ATMOSPHERE_BC_L_PS, binarys[EffectPackage::PES_SD_ASS_BC_L] );
				GetShaderBinary( EffectPackage::SHADER_SKYDOME_ATMOSPHERE_BC2__PS, binarys[EffectPackage::PES_SD_ASS_BC2_] );
				GetShaderBinary( EffectPackage::SHADER_SKYDOME_ATMOSPHERE_BC2L_PS, binarys[EffectPackage::PES_SD_ASS_BC2L] );
				binaryCount = 10;
				break;

			case EffectPackage::ER_SKYDOME_PANORAMA_D:
				GetShaderBinary( EffectPackage::SHADER_SKYDOME_PANORAMA_PS, binarys[EffectPackage::PES_SD_PANORAMA] );
				GetShaderBinary( EffectPackage::SHADER_SKYDOME_PANORAMA_FD_PS, binarys[EffectPackage::PES_SD_PANORAMA_F] );
				binaryCount = 2;
				break;
			case EffectPackage::ER_SKYDOME_PANORAMA_A:
				GetShaderBinary( EffectPackage::SHADER_SKYDOME_PANORAMA_PS, binarys[EffectPackage::PES_SD_PANORAMA] );
				GetShaderBinary( EffectPackage::SHADER_SKYDOME_PANORAMA_FA_PS, binarys[EffectPackage::PES_SD_PANORAMA_F] );
				binaryCount = 2;
				break;

			case EffectPackage::ER_SSAO:
				GetShaderBinary( EffectPackage::SHADER_SSAO_PS, binarys[EffectPackage::PES_SSAO] );
				GetShaderBinary( EffectPackage::SHADER_SSAO_TEX_PS, binarys[EffectPackage::PES_SSAO_TEX] );
				binaryCount = 2;
				break;

			case EffectPackage::ER_SM:
				GetShaderBinary( EffectPackage::SHADER_SM_FINISH____PS, binarys[EffectPackage::PES_SM_FINISH___] );
				GetShaderBinary( EffectPackage::SHADER_SM_FINISH__B_PS, binarys[EffectPackage::PES_SM_FINISH__B] );
				GetShaderBinary( EffectPackage::SHADER_SM_FINISH_R__PS, binarys[EffectPackage::PES_SM_FINISH_R_] );
				GetShaderBinary( EffectPackage::SHADER_SM_FINISH_RB_PS, binarys[EffectPackage::PES_SM_FINISH_RB] );
				binaryCount = 4;
				break;

			case EffectPackage::ER_UNDER_WATER:
				GetShaderBinary( EffectPackage::SHADER_UNDER_WATER_PS, binarys[EffectPackage::PES_DEFAULT] );
				binaryCount = 1;
				break;

			case EffectPackage::ER_LUMINANCE:
				GetShaderBinary( EffectPackage::SHADER_LUM_TRANSFORM_INITAL_PS,  binarys[EffectPackage::PES_LUM_TR_INITAL] );
				GetShaderBinary( EffectPackage::SHADER_LUM_TRANSFORM_ITERATE_PS, binarys[EffectPackage::PES_LUM_TR_ITERATE] );
				GetShaderBinary( EffectPackage::SHADER_LUM_TRANSFORM_FINAL_PS,   binarys[EffectPackage::PES_LUM_TR_FINAL] );
				GetShaderBinary( EffectPackage::SHADER_LUM_ADAPTED_PS,           binarys[EffectPackage::PES_LUM_ADAPTED] );
				GetShaderBinary( EffectPackage::SHADER_LUM_OPERATOR___B_PS,      binarys[EffectPackage::PES_LUM_OP___B] );
				GetShaderBinary( EffectPackage::SHADER_LUM_OPERATOR_T___PS,      binarys[EffectPackage::PES_LUM_OP_T__] );
				GetShaderBinary( EffectPackage::SHADER_LUM_OPERATOR_T_B_PS,      binarys[EffectPackage::PES_LUM_OP_T_B] );
				GetShaderBinary( EffectPackage::SHADER_LUM_OPERATOR_TA__PS,      binarys[EffectPackage::PES_LUM_OP_TA_] );
				GetShaderBinary( EffectPackage::SHADER_LUM_OPERATOR_TAB_PS,      binarys[EffectPackage::PES_LUM_OP_TAB] );
				binaryCount = 9;
				break;

			case EffectPackage::ER_LIGHT_SHAFTS:
				GetShaderBinary( EffectPackage::SHADER_LS_INIT___PS, binarys[EffectPackage::PES_LS_INIT__] );
				GetShaderBinary( EffectPackage::SHADER_LS_INIT_A_PS, binarys[EffectPackage::PES_LS_INIT_A] );
				GetShaderBinary( EffectPackage::SHADER_LS_BLUR_L_PS, binarys[EffectPackage::PES_LS_BLUR_L] );
				GetShaderBinary( EffectPackage::SHADER_LS_BLUR_M_PS, binarys[EffectPackage::PES_LS_BLUR_M] );
				GetShaderBinary( EffectPackage::SHADER_LS_BLUR_H_PS, binarys[EffectPackage::PES_LS_BLUR_H] );
				binaryCount = 5;
				break;

			case EffectPackage::ER_LENS_FLARE:
				GetShaderBinary( EffectPackage::SHADER_LF_IMAGE____PS, binarys[EffectPackage::PES_LF_IMAGE___] );
				GetShaderBinary( EffectPackage::SHADER_LF_IMAGE__H_PS, binarys[EffectPackage::PES_LF_IMAGE__H] );
				GetShaderBinary( EffectPackage::SHADER_LF_IMAGE_G__PS, binarys[EffectPackage::PES_LF_IMAGE_G_] );
				GetShaderBinary( EffectPackage::SHADER_LF_IMAGE_GH_PS, binarys[EffectPackage::PES_LF_IMAGE_GH] );
				GetShaderBinary( EffectPackage::SHADER_LF_MODIFY____PS, binarys[EffectPackage::PES_LF_MODIFY___] );
				GetShaderBinary( EffectPackage::SHADER_LF_MODIFY_D__PS, binarys[EffectPackage::PES_LF_MODIFY_D_] );
				GetShaderBinary( EffectPackage::SHADER_LF_MODIFY__B_PS, binarys[EffectPackage::PES_LF_MODIFY__B] );
				GetShaderBinary( EffectPackage::SHADER_LF_MODIFY_DB_PS, binarys[EffectPackage::PES_LF_MODIFY_DB] );
				binaryCount = 8;
				break;

			case EffectPackage::ER_FILMIC:
				GetShaderBinary( EffectPackage::SHADER_FI_HEJL_PS, binarys[EffectPackage::PES_FI_HEJL] );
				GetShaderBinary( EffectPackage::SHADER_FI_HABLE_PS, binarys[EffectPackage::PES_FI_HABLE] );
				binaryCount = 2;
				break;

			case EffectPackage::ER_GAMMA:
				GetShaderBinary( EffectPackage::SHADER_GAMMA_PS, binarys[EffectPackage::PES_DEFAULT] );
				binaryCount = 1;
				break;

			case EffectPackage::ER_CAM_MOTION_BLUR:
				GetShaderBinary( EffectPackage::SHADER_CAM_MOTION_BLUR_L_PS, binarys[EffectPackage::PES_CMB_L] );
				GetShaderBinary( EffectPackage::SHADER_CAM_MOTION_BLUR_M_PS, binarys[EffectPackage::PES_CMB_M] );
				GetShaderBinary( EffectPackage::SHADER_CAM_MOTION_BLUR_H_PS, binarys[EffectPackage::PES_CMB_H] );
				binaryCount = 3;
				break;

			case EffectPackage::ER_CHROMATISM:
				GetShaderBinary( EffectPackage::SHADER_CA_IMAGE___PS, binarys[EffectPackage::PES_CA_IMAGE__] );
				GetShaderBinary( EffectPackage::SHADER_CA_IMAGE_K_PS, binarys[EffectPackage::PES_CA_IMAGE_K] );
				GetShaderBinary( EffectPackage::SHADER_CA_FINISH___PS, binarys[EffectPackage::PES_CA_FINISH__] );
				GetShaderBinary( EffectPackage::SHADER_CA_FINISH_D_PS, binarys[EffectPackage::PES_CA_FINISH_D] );
				binaryCount = 4;
				break;

			case EffectPackage::ER_DOF:
				GetShaderBinary( EffectPackage::SHADER_DOF_PS, binarys[EffectPackage::PES_DEFAULT] );
				binaryCount = 1;
				break;

			case EffectPackage::ER_LENS_DIST:
				GetShaderBinary( EffectPackage::SHADER_LENS_DIST___PS, binarys[EffectPackage::PES_LD__] );
				GetShaderBinary( EffectPackage::SHADER_LENS_DIST_K_PS, binarys[EffectPackage::PES_LD_K] );
				binaryCount = 2;
				break;

			case EffectPackage::ER_VIGNETTE:
				GetShaderBinary( EffectPackage::SHADER_VIGNETTE_PS, binarys[EffectPackage::PES_DEFAULT] );
				binaryCount = 1;
				break;

			case EffectPackage::ER_FXAA:
				GetShaderBinary( EffectPackage::SHADER_AA_FXAA_PS, binarys[EffectPackage::PES_DEFAULT] );
				binaryCount = 1;
				break;
			}

			MIX_ASSERT( binaryCount <= EffectPackage::PES_MAX );

			for( UInt32 i = 0; ( i < binaryCount ) && ( bSuccess == True ); i++ )
			{
				MIX_ASSERT( binarys[i].pData != NULL );
				MIX_ASSERT( binarys[i].dataSize > 0 );

				const EffectPackage::SHADER_BINARY* psb = &( binarys[i] );

				if( m_pGraphicsDev->CreatePixelShaderFromMemory( psb->pData, psb->dataSize, &( pe.pShader[i] ), psb->name ) == False )
				{
					bSuccess = False;
				}
			}

			if( bSuccess == True )
			{
				m_ResidentPEMap.insert( EffectPackage::PixelEffectMap::value_type( opt, pe ) );

				it = m_ResidentPEMap.find( opt );
				if( it != m_ResidentPEMap.end() )
				{
					pEffect = &( it->second );
				}
				else
				{
					pe.Dispose();
				}
			}
			else
			{
				pe.Dispose();
			}
		}
	}
	else if( type == EffectPackage::E_MATERIAL )
	{
		EffectPackage::PixelEffectMap::iterator it = m_MaterialPEMap.find( opt );
		if( it != m_MaterialPEMap.end() )
		{
			pEffect = &( it->second );
		}
	}

	return pEffect;
}

UInt32 EffectPackage::ModifyRendererCaps( UInt32 caps ) const
{
	UInt32 procFlags = GetProcessFlags();
	UInt32 ret = 0;

	if( ( Mix::Dynamics::GetManagerPtr() != NULL ) &&
		( MIX_TESTBIT( caps, Mix::Scene::RCAP_DYNAMICS ) == Mix::Scene::RCAP_DYNAMICS ) )
	{
		ret |= Mix::Scene::RCAP_DYNAMICS;
	}

	if( ( MIX_TESTBIT( caps, Mix::Scene::RCAP_WIDGET ) == Mix::Scene::RCAP_WIDGET ) )
	{
		ret |= Mix::Scene::RCAP_WIDGET;
	}

	if( ( MIX_TESTBIT( caps, Mix::Scene::RCAP_ATMOSPHERE ) == Mix::Scene::RCAP_ATMOSPHERE ) &&
		( MIX_TESTBIT( procFlags, EffectPackage::EP_ATMOSPHERE ) == EffectPackage::EP_ATMOSPHERE ) )
	{
		ret |= Mix::Scene::RCAP_ATMOSPHERE;
	}

	if( ( MIX_TESTBIT( caps, Mix::Scene::RCAP_AMBIENT_OCCLUSION ) == Mix::Scene::RCAP_AMBIENT_OCCLUSION ) &&
		( MIX_TESTBIT( procFlags, EffectPackage::EP_SSAO ) == EffectPackage::EP_SSAO ) )
	{
		ret |= Mix::Scene::RCAP_AMBIENT_OCCLUSION;
	}

	if( ( MIX_TESTBIT( caps, Mix::Scene::RCAP_SHADOW_MAPPING ) == Mix::Scene::RCAP_SHADOW_MAPPING ) &&
		( MIX_TESTBIT( procFlags, EffectPackage::EP_SHADOW ) == EffectPackage::EP_SHADOW ) )
	{
		ret |= Mix::Scene::RCAP_SHADOW_MAPPING;
	}

	if( MIX_TESTBIT( caps, Mix::Scene::RCAP_LUMINOSITY ) == Mix::Scene::RCAP_LUMINOSITY )
	{
		ret |= Mix::Scene::RCAP_LUMINOSITY;
	}

	if( MIX_TESTBIT( caps, Mix::Scene::RCAP_BLOOM ) == Mix::Scene::RCAP_BLOOM )
	{
		ret |= Mix::Scene::RCAP_BLOOM;
	}

	if( ( MIX_TESTBIT( caps, Mix::Scene::RCAP_LIGHT_SHAFTS ) == Mix::Scene::RCAP_LIGHT_SHAFTS ) )
	{
		ret |= Mix::Scene::RCAP_LIGHT_SHAFTS;
	}

	if( ( MIX_TESTBIT( caps, Mix::Scene::RCAP_LENS_FLARE ) == Mix::Scene::RCAP_LENS_FLARE ) )
	{
		ret |= Mix::Scene::RCAP_LENS_FLARE;
	}

	if( ( MIX_TESTBIT( caps, Mix::Scene::RCAP_CHROMATISM ) == Mix::Scene::RCAP_CHROMATISM ) )
	{
		ret |= Mix::Scene::RCAP_CHROMATISM;
	}

	if( MIX_TESTBIT( caps, Mix::Scene::RCAP_DEPTH_OF_FIELD ) == Mix::Scene::RCAP_DEPTH_OF_FIELD )
	{
		ret |= Mix::Scene::RCAP_DEPTH_OF_FIELD;
	}

	return ret;
}

Mix::Scene::IRenderer::TYPE EffectPackage::GetRendererType( void ) const
{
	return Mix::Scene::IRenderer::FORWARD;
}

Mix::Scene::IMaterial::TYPE EffectPackage::GetMaterialType( void ) const
{
	return Mix::Scene::IMaterial::DEFAULT;
}

}}}}
