#include "Mix/Tool/Win32/Core/Graphics/Manager.h"

#include <algorithm>
#include <sstream>

#include "Mix/Tool/Win32/Core/Path.h"
#include "Mix/Tool/Win32/Core/Directory.h"
#include "Mix/Tool/Win32/Core/File/OutputStream.h"

#include "Mix/Tool/Win32/Core/Graphics/DeviceObject.h"
#include "Mix/Tool/Win32/Core/Graphics/VertexLayout.h"
#include "Mix/Tool/Win32/Core/Graphics/VertexShader.h"
#include "Mix/Tool/Win32/Core/Graphics/PixelShader.h"
#include "Mix/Tool/Win32/Core/Graphics/VertexBuffer.h"
#include "Mix/Tool/Win32/Core/Graphics/IndexBuffer.h"
#include "Mix/Tool/Win32/Core/Graphics/FileTexture.h"
#include "Mix/Tool/Win32/Core/Graphics/TargetTextureD.h"
#include "Mix/Tool/Win32/Core/Graphics/TargetTextureL.h"
#include "Mix/Tool/Win32/Core/Graphics/CubeTexture.h"
#include "Mix/Tool/Win32/Core/Graphics/SwapChain.h"

#include "Mix/Tool/Win32/Core/Graphics/Scene.h"
#include "Mix/Tool/Win32/Core/Graphics/Camera.h"
#include "Mix/Tool/Win32/Core/Graphics/MaterialShader.h"
#include "Mix/Tool/Win32/Core/Graphics/ObjectModel.h"
#include "Mix/Tool/Win32/Core/Graphics/MapModel.h"

#include "Mix/Tool/Win32/Core/Graphics/MAMTypes.h"
#include "Mix/Tool/Win32/Core/Graphics/MTMTypes.h"

namespace Mix{ namespace Tool{ namespace Win32{ namespace Graphics{

////////////////////////////////////////////////////////////////////////////////////////////////////
// テーブル
////////////////////////////////////////////////////////////////////////////////////////////////////

//エフェクトパッケージの拡張子
const wchar_t* Manager::MEP_EXT = L".mep";

//エフェクトパッケージのセーブ情報テーブル
const Manager::MEP_SAVE_INFO Manager::MEP_SAVE_INFO_TABLE[3] =
{
	{ SHADER_MODEL_3, 3, Manager::SHADER_PROFILE_VS_3, Manager::SHADER_PROFILE_PS_3, },
	{ SHADER_MODEL_4, 4, Manager::SHADER_PROFILE_VS_4, Manager::SHADER_PROFILE_PS_4, },
	{ SHADER_MODEL_5, 5, Manager::SHADER_PROFILE_VS_5, Manager::SHADER_PROFILE_PS_5, },
};

const unsigned int Manager::MEP_SAVE_INFO_COUNT = sizeof( Manager::MEP_SAVE_INFO_TABLE ) / sizeof( Manager::MEP_SAVE_INFO );

//D3Dバーテックスエレメントのセマンティックテーブル
const unsigned int Manager::D3D_VE_SEMANTIC_TABLE[MAXD3DDECLUSAGE] =
{
	VES_POSITION,
	VES_BLENDWEIGHT,
	VES_BLENDINDICES,
	VES_NORMAL,
	VES_PSIZE,
	VES_TEXTURE,
	VES_TANGENT,
	VES_BINORMAL,
	0xFFFFFFFF,
	0xFFFFFFFF,
	VES_COLOR,
	0xFFFFFFFF,
	0xFFFFFFFF,
};

//D3Dバーテックスエレメントのフォーマットテーブル
const unsigned int Manager::D3D_VE_FORMAT_TABLE[MAXD3DDECLTYPE] =
{
	VEF_FLOAT32_1,
	VEF_FLOAT32_2,
	VEF_FLOAT32_3,
	VEF_FLOAT32_4,
	0xFFFFFFFF,
	VEF_UINT8_4,
	VEF_INT16_2,
	VEF_INT16_4,
	VEF_UINT8_4N,
	VEF_INT16_2N,
	VEF_INT16_4N,
	VEF_UINT16_2N,
	VEF_UINT16_4N,
	0xFFFFFFFF,
	0xFFFFFFFF,
	VEF_FLOAT16_2,
	VEF_FLOAT16_4,
};

//D3Dバーテックスエレメントのサイズテーブル
const unsigned int Manager::D3D_VE_FORMAT_SIZE_TABLE[MAXD3DDECLTYPE] =
{
	4,				//D3DDECLTYPE_FLOAT1
	8,				//D3DDECLTYPE_FLOAT2
	12,				//D3DDECLTYPE_FLOAT3
	16,				//D3DDECLTYPE_FLOAT4
	4,				//D3DDECLTYPE_D3DCOLOR
	4,				//D3DDECLTYPE_UBYTE4
	4,				//D3DDECLTYPE_SHORT2
	8,				//D3DDECLTYPE_SHORT4
	4,				//D3DDECLTYPE_UBYTE4N
	4,				//D3DDECLTYPE_SHORT2N
	8,				//D3DDECLTYPE_SHORT4N
	4,				//D3DDECLTYPE_USHORT2N
	8,				//D3DDECLTYPE_USHORT4N
	0xFFFFFFFF,		//D3DDECLTYPE_UDEC3( 使用しない )
	0xFFFFFFFF,		//D3DDECLTYPE_DEC3N( 使用しない )
	4,				//D3DDECLTYPE_FLOAT16_2
	8,				//D3DDECLTYPE_FLOAT16_4
};

//バーテックスエレメントのセマンティックタイプテーブル
const unsigned char Manager::VES_TABLE[Mix::Tool::Win32::Graphics::VERTEX_ELEMENT_SEMANTIC_MAX] =
{
	D3DDECLUSAGE_POSITION,
	D3DDECLUSAGE_BLENDWEIGHT,
	D3DDECLUSAGE_BLENDINDICES,
	D3DDECLUSAGE_NORMAL,
	D3DDECLUSAGE_PSIZE,
	D3DDECLUSAGE_TEXCOORD,
	D3DDECLUSAGE_TANGENT,
	D3DDECLUSAGE_BINORMAL,
	D3DDECLUSAGE_COLOR,
};

//バーテックスレイアトのフォーマットテーブル
const unsigned char Manager::VE_FORMAT_TABLE[Mix::Tool::Win32::Graphics::VERTEX_ELEMENT_FORMAT_MAX] =
{
	D3DDECLTYPE_FLOAT1,
	D3DDECLTYPE_FLOAT2,
	D3DDECLTYPE_FLOAT3,
	D3DDECLTYPE_FLOAT4,
	D3DDECLTYPE_UBYTE4,
	D3DDECLTYPE_SHORT2,
	D3DDECLTYPE_SHORT4,
	D3DDECLTYPE_UBYTE4N,
	D3DDECLTYPE_SHORT2N,
	D3DDECLTYPE_SHORT4N,
	D3DDECLTYPE_USHORT2N,
	D3DDECLTYPE_USHORT4N,
	D3DDECLTYPE_FLOAT16_2,
	D3DDECLTYPE_FLOAT16_4,
};

//バーテックスエレメントのサイズテーブル
const unsigned char Manager::VE_FORMAT_SIZE_TABLE[Mix::Tool::Win32::Graphics::VERTEX_ELEMENT_FORMAT_MAX] =
{
	4,	//VL_FLOAT32_1
	8,	//VL_FLOAT32_2
	12,	//VL_FLOAT32_3
	16,	//VL_FLOAT32_4
	4,	//VL_UINT8_4
	4,	//VL_INT16_2
	8,	//VL_INT16_4
	4,	//VL_UINT8_4N
	4,	//VL_INT16_2N
	8,	//VL_INT16_4N
	4,	//VL_UINT16_2N
	8,	//VL_UINT16_4N
	4,	//VL_FLOAT16_2
	8,	//VL_FLOAT16_4
};

//インデックスフォーマットテーブル
const D3DFORMAT Manager::INDEX_FORMAT_TABLE[Mix::Tool::Win32::Graphics::INDEX_TYPE_MAX] =
{
	D3DFMT_INDEX16,
	D3DFMT_INDEX32,
};

//インデックスサイズテーブル
const unsigned int Manager::INDEX_STRIDE_TABLE[Mix::Tool::Win32::Graphics::INDEX_TYPE_MAX] =
{
	2,
	4,
};

//シェーダープロファイルテーブル
const char* Manager::SHADER_PROFILE_TABLE[Manager::SHADER_PROFILE_MAX] =
{
	"vs_3_0",
	"ps_3_0",
	"vs_4_0",
	"ps_4_0",
	"vs_5_0",
	"ps_5_0",
};

//シェーダープロファイルテーブル
const wchar_t* Manager::SHADER_PROFILE_TABLE_W[Manager::SHADER_PROFILE_MAX] =
{
	L"vs_3_0",
	L"ps_3_0",
	L"vs_4_0",
	L"ps_4_0",
	L"vs_5_0",
	L"ps_5_0",
};

//シェーダープロファイル番号テーブル
const unsigned int Manager::SHADER_PROFILE_NUMBER_TABLE[Manager::SHADER_PROFILE_MAX] =
{
	3,
	3,
	4,
	4,
	5,
	5,
};

//シェーダーモデル定義テーブル
LPCSTR Manager::SHADER_DEFMODEL_TABLE[Manager::SHADER_PROFILE_MAX] =
{
	"MIX_SM_3",
	"MIX_SM_3",
	"MIX_SM_4",
	"MIX_SM_4",
	"MIX_SM_5",
	"MIX_SM_5",
};

//シェーダーONE定義テーブル
LPCSTR Manager::SHADER_DEFONE = "1";

//テクスチャ拡張子テーブル
const wchar_t* Manager::TEXTURE_EXT_TABLE[6] =
{
	L".dds",
	L".png",
	L".tga",
	L".jpg",
	L".bmp",
	L".dib",
};

const unsigned int Manager::TEXTURE_EXT_COUNT = 6;

////////////////////////////////////////////////////////////////////////////////////////////////////
// ライブラリ : シェーダー 3 4 5
////////////////////////////////////////////////////////////////////////////////////////////////////

// スタンダード : デフォルトマテリアル ( VS )
static const unsigned char MANAGER_MATERIAL_STANDARD_VS[] = 
{
	#include "Mix/Tool/Win32/Core/Graphics/Shader/Standard/Material/default.vs.inc"
};

// スタンダード : デフォルトマテリアル ( PS )
static const unsigned char MANAGER_MATERIAL_STANDARD_PS[] =
{
	#include "Mix/Tool/Win32/Core/Graphics/Shader/Standard/Material/default.ps.inc"
};

////////////////////////////////////////////////////////////////////////////////////////////////////
// ツール : シェーダー 3
////////////////////////////////////////////////////////////////////////////////////////////////////

// ライン : VL
static const D3DVERTEXELEMENT9 MANAGER_LINE_VE[] =
{
	{ 0,  0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0, },
	{ 0, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,    0, },
	D3DDECL_END()
};

// クワッド : VE
static const D3DVERTEXELEMENT9 MANAGER_QUAD_VE[] =
{
	{ 0,  0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0, },
	{ 0, 16, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0, },
	D3DDECL_END()
};

// ライン : VS_3
static const unsigned char MANAGER_LINE_VS_3[] =
{
	#include "Mix/Tool/Win32/Core/Graphics/Shader/Misc/line.vs.inc"
};

// ライン : PS_3
static const unsigned char MANAGER_LINE_PS_3[] =
{
	#include "Mix/Tool/Win32/Core/Graphics/Shader/Misc/line.ps.inc"
};

// クワッド : VS_3
static const unsigned char MANAGER_QUAD_VS_3[] =
{
	#include "Mix/Tool/Win32/Core/Graphics/Shader/Misc/quad.vs.inc"
};

// クワッド : PS_3
static const unsigned char MANAGER_QUAD_PS_3[] =
{
	#include "Mix/Tool/Win32/Core/Graphics/Shader/Misc/quad.ps.inc"
};

////////////////////////////////////////////////////////////////////////////////////////////////////
// Manager
////////////////////////////////////////////////////////////////////////////////////////////////////

Manager* Manager::g_pInstance = NULL;

Manager::Manager( void ) :
m_RootDirectoryPath( L"" ),
m_pD3D( NULL ),
m_pD3DDevice( NULL ),
m_pD3DBackBuffer( NULL ),
m_SupportShaderModels( 0 ),
m_MSPShaderModels( 0 ),
m_MSPProcFlags( 0 ),
m_ActionType( Manager::ACTION_RENDER_SCENE ),
m_hShaderCompileModule( NULL ),
m_pShaderCompile( NULL ),
m_pD3DFont( NULL ),
m_pLineVL( NULL ),
m_pLineVS( NULL ),
m_pLinePS( NULL ),
m_pQuadVL( NULL ),
m_pQuadVS( NULL ),
m_pQuadPS( NULL )
{
	g_pInstance = this;

	::D3DXMatrixIdentity( &m_ProjectionMatrix );

	m_MouseOption.scalingSensitivity = 0.2f;
	m_MouseOption.rotationSensitivity = 0.5f;
	m_MouseOption.translationSensitivity = 0.01f;

	m_TextureOption.specular = L"$(DIR)$(FILENAME)_s";
	m_TextureOption.emissive = L"$(DIR)$(FILENAME)_e";
	m_TextureOption.bump = L"$(DIR)$(FILENAME)_n";

	m_PerspectiveOption.fovY = 60.0f;
	m_PerspectiveOption.nearZ = 0.1f;
	m_PerspectiveOption.farZ = 500.0f;

	ResetTargetState();
	ResetDrawState();
}

Manager::~Manager( void )
{
	MIX_RELEASE( m_pLineVL );
	MIX_RELEASE( m_pLineVS );
	MIX_RELEASE( m_pLinePS );

	MIX_RELEASE( m_pQuadVL );
	MIX_RELEASE( m_pQuadVS );
	MIX_RELEASE( m_pQuadPS );

	MEP_Release();

	ReleaseDevice();

	MIX_RELEASE( m_pD3D );

	if( m_hShaderCompileModule != NULL )
	{
		::FreeLibrary( m_hShaderCompileModule );
		m_hShaderCompileModule = NULL;
	}

	g_pInstance = NULL;
}

Manager* Manager::GetInstance( void )
{
	return g_pInstance;
}

bool Manager::Initialize( void )
{
	/*
		Direct3D9 を作成
	*/

	m_pD3D = ::Direct3DCreate9( D3D_SDK_VERSION );
	if( m_pD3D == NULL )
	{
		MessageBox( ::GetActiveWindow(), L"グラフィックス", L"Direct3DCreate9 がエラーを返しました", MB_OK | MB_ICONERROR );
		return false;
	}

	/*
		シェーダーコンパイラを取得( DirectX10 or 11用 )
	*/

	{
		std::wostringstream moduleName;
		void* pFunction = NULL;

		m_SupportShaderModels = SHADER_MODEL_3;

		moduleName << L"d3dx11_" << D3DX11_SDK_VERSION << L".dll";
		m_hShaderCompileModule = LoadLibrary( moduleName.str().c_str() );

		if( m_hShaderCompileModule != NULL )
		{
			pFunction = ::GetProcAddress( m_hShaderCompileModule, "D3DX11CompileFromMemory" );
			if( pFunction != NULL )
			{
				m_SupportShaderModels |= ( SHADER_MODEL_4 | SHADER_MODEL_5 );
			}
			else
			{
				LogPrint( LT_WARNING, L"シェーダモデル４でのコンパイルはできません" );

				::FreeLibrary( m_hShaderCompileModule );
				m_hShaderCompileModule = NULL;
			}
		}

		if( m_hShaderCompileModule == NULL )
		{
			moduleName << L"d3dx10_" << D3DX10_SDK_VERSION << L".dll";
			m_hShaderCompileModule = LoadLibrary( moduleName.str().c_str() );

			if( m_hShaderCompileModule != NULL )
			{
				pFunction = ::GetProcAddress( m_hShaderCompileModule, "D3DX10CompileFromMemory" );
				if( pFunction != NULL )
				{
					m_SupportShaderModels |= SHADER_MODEL_4;
				}
				else
				{
					LogPrint( LT_WARNING, L"シェーダモデル５でのコンパイルはできません" );
					::FreeLibrary( m_hShaderCompileModule );
					m_hShaderCompileModule = NULL;
				}
			}
		}

		if( pFunction != NULL )
		{
			m_pShaderCompile = static_cast<Manager::D3DXCompileFromMemoryFunc>( pFunction );
		}
	}

	/*
		マテリアルシェーダーモデルの初期値を決定
	*/

	m_MSPShaderModels = m_SupportShaderModels;

	/*
		ラインシェーダーを作成
	*/

	m_pLineVL = CreateVertexLayout( MANAGER_LINE_VE );
	if( m_pLineVL == NULL )
	{
		MessageBox( ::GetActiveWindow(), L"グラフィックス", L"CreateVertexLayout(Line) がエラーを返しました", MB_OK | MB_ICONERROR );
		return false;
	}

	m_pLineVS = CreateVertexShader( MANAGER_LINE_VS_3, sizeof( MANAGER_LINE_VS_3 ) );
	if( m_pLineVS == NULL )
	{
		MessageBox( ::GetActiveWindow(), L"グラフィックス", L"CreateVertexShader(Line) がエラーを返しました", MB_OK | MB_ICONERROR );
		return false;
	}

	m_pLinePS = CreatePixelShader( MANAGER_LINE_PS_3, sizeof( MANAGER_LINE_PS_3 ) );
	if( m_pLinePS == NULL )
	{
		MessageBox( ::GetActiveWindow(), L"グラフィックス", L"CreatePixelShader(Line) がエラーを返しました", MB_OK | MB_ICONERROR );
		return false;
	}

	/*
		クワッドシェーダーを作成
	*/

	m_pQuadVL = CreateVertexLayout( MANAGER_QUAD_VE );
	if( m_pQuadVL == NULL )
	{
		MessageBox( ::GetActiveWindow(), L"グラフィックス", L"CreateVertexLayout(Quad) がエラーを返しました", MB_OK | MB_ICONERROR );
		return false;
	}

	m_pQuadVS = CreateVertexShader( MANAGER_QUAD_VS_3, sizeof( MANAGER_QUAD_VS_3 ) );
	if( m_pQuadVS == NULL )
	{
		MessageBox( ::GetActiveWindow(), L"グラフィックス", L"CreateVertexShader(Quad) がエラーを返しました", MB_OK | MB_ICONERROR );
		return false;
	}

	m_pQuadPS = CreatePixelShader( MANAGER_QUAD_PS_3, sizeof( MANAGER_QUAD_PS_3 ) );
	if( m_pQuadPS == NULL )
	{
		MessageBox( ::GetActiveWindow(), L"グラフィックス", L"CreatePixelShader(Quad) がエラーを返しました", MB_OK | MB_ICONERROR );
		return false;
	}

	return true;
}

unsigned int Manager::GetSupportShaderModels( void ) const
{
	return m_SupportShaderModels;
}

const wchar_t* Manager::GetRootDirectoryPath( void ) const
{
	return m_RootDirectoryPath.c_str();
}

void Manager::SetRootDirectoryPath( const wchar_t* pDirectoryName )
{
	if( ( pDirectoryName == NULL ) ||
		( ::wcslen( pDirectoryName ) < 4 ) )
	{
		return;
	}

	Mix::Tool::Win32::Directory::Modify( pDirectoryName, m_RootDirectoryPath );
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Public : マテリアルエフェクトパッケージ
////////////////////////////////////////////////////////////////////////////////////////////////////

bool Manager::MEP_Load(	unsigned int models, unsigned int procFlags, const wchar_t* pDirectoryName, const wchar_t* pName )
{
	if( ( pDirectoryName == NULL ) ||
		( ::wcslen( pDirectoryName ) == 0 ) ||
		( pName == NULL ) ||
		( ::wcslen( pName ) == 0 ) )
	{
		return false;
	}

	std::vector<Manager::MEP_FILE_INFO> fileInfoList;
	const Manager::MEP_FILE_INFO* pFileInfo;
	int ret;
	bool bSuccess = false;

	/*
		ログ : 開始
	*/

	LogPrint( LT_INFO, L"----------------------------------------------------------------------------------------------------" );
	LogPrint( LT_INFO, L"  マテリアルエフェクトパッケージの読み込み : Directory[%s] Name[%s]", pDirectoryName, pName );
	LogPrint( LT_INFO, L"" );

	/*
		パラメータの設定
	*/

	m_MSPShaderModels = MIX_TEST_BIT( models, m_SupportShaderModels );
	m_MSPProcFlags = procFlags;
	m_MSPDirectoryName = pDirectoryName;
	m_MSPName = pName;

	/*
		解放
	*/

	MEP_Release();

	/*
		ロード
	*/

	if( MEP_CreateFileInfoList( fileInfoList ) == true )
	{
		pFileInfo = &( fileInfoList[0] );
	}
	else
	{
		return false;
	}

	ret = MEP_Load( pFileInfo->path.c_str() );
	if( ret == 0 )
	{
		//ファイルが見つからなかった
		LogPrint( LT_INFO, L"  ファイルが見つかりませんでした。" );
	}
	else if( ret == 1 )
	{
		//ファイルが見つかり、読み込みが成功した
		bSuccess = true;
	}
	else
	{
		//読み込み中にエラーが発生
		;
	}

	return bSuccess;
}

bool Manager::MEP_Save( void )
{
	std::map<unsigned int, Manager::MEP_MTL_VS_WORK> vsMap;
	std::map<unsigned int, Manager::MEP_MTL_PS_WORK> psMap;

	/*
		ログ : 開始
	*/

	LogPrint( LT_INFO, L"----------------------------------------------------------------------------------------------------" );
	LogPrint( LT_INFO, L"  マテリアルエフェクトパッケージの保存 : Directory[%s] : Name[%s]", m_MSPDirectoryName.c_str(), m_MSPName.c_str() );
	LogPrint( LT_INFO, L"" );

	/*
		バーテックスシェーダーのワークマップを作成
	*/

	{
		Manager::MSVertexShaderMap::const_iterator it_begin = m_MSVertexShaderMap.begin();
		Manager::MSVertexShaderMap::const_iterator it_end = m_MSVertexShaderMap.end();
		Manager::MSVertexShaderMap::const_iterator it;

		std::vector<Manager::SHADER_MACRO> macroList;

		for( it = it_begin; it != it_end; ++it )
		{
			if( it->second.state != Manager::MS_STATE_NEW )
			{
				continue;
			}

			unsigned int id = it->first;
			unsigned int compileFlags = id;

			std::map<unsigned int, Manager::MEP_MTL_VS_WORK>::iterator it_work;

			//エラーチェック
			it_work = vsMap.find( id );
			if( it_work != vsMap.end() )
			{
				LogPrint( LT_INFO, L"    バーテックスシェーダーのIDが重複しています : ID[0x%08x]", id );
				return false;
			}

			//挿入
			vsMap.insert( std::pair<unsigned int, Manager::MEP_MTL_VS_WORK>( id, Manager::MEP_MTL_VS_WORK() ) );
			it_work = vsMap.find( id );
			MIX_ASSERT( it_work != vsMap.end() );

			const std::vector<D3DVERTEXELEMENT9>& srcVertexElements = it->second.pCommonVL->GetElementList();
			MIX_ASSERT( srcVertexElements.size() > 1 );

			//バーテックスエレメントを変換
			ConvertVertexElementList( srcVertexElements, it_work->second.elements );

			//バーテックスシェーダーのコンパイルマクロリストを作成
			CreateCompileMacroList( compileFlags, true, it_work->second.macros );
		}
	}

	/*
		ピクセルシェーダーのワークマップを作成
	*/

	{
		Manager::MSPixelShaderMap::const_iterator it_begin = m_MSPixelShaderMap.begin();
		Manager::MSPixelShaderMap::const_iterator it_end = m_MSPixelShaderMap.end();
		Manager::MSPixelShaderMap::const_iterator it;

		std::vector<Manager::SHADER_MACRO> macroList;

		for( it = it_begin; it != it_end; ++it )
		{
			if( it->second.state != Manager::MS_STATE_NEW )
			{
				continue;
			}

			unsigned int id = it->first;
			unsigned int compileFlags = id;
			std::map<unsigned int, Manager::MEP_MTL_PS_WORK>::iterator it_work;

			//エラーチェック
			it_work = psMap.find( id );
			if( it_work != psMap.end() )
			{
				LogPrint( LT_ERROR, L"    ピクセルシェーダーのIDが重複しています : ID[0x%08x]", id );
				return false;
			}

			//挿入
			psMap.insert( std::pair<unsigned int, Manager::MEP_MTL_PS_WORK>( id, Manager::MEP_MTL_PS_WORK() ) );
			it_work = psMap.find( id );
			MIX_ASSERT( it_work != psMap.end() );

			//コンパイルマクロリストを作成
			CreateCompileMacroList( compileFlags, true, it_work->second.macros );
		}
	}

	/*
		保存
	*/

	std::vector<Manager::MEP_FILE_INFO> fileInfoList;

	std::vector<Manager::MEP_FILE_INFO>::iterator it_begin;
	std::vector<Manager::MEP_FILE_INFO>::iterator it_end;
	std::vector<Manager::MEP_FILE_INFO>::iterator it;

	if( MEP_CreateFileInfoList( fileInfoList ) == false )
	{
		LogPrint( LT_INFO,  L"" );
		LogPrint( LT_ERROR, L"    シェーダープロファイル毎のファイルのリストアップに失敗しました" );
		return false;
	}

	it_begin = fileInfoList.begin();
	it_end = fileInfoList.end();

	for( it = it_begin; it != it_end; ++it )
	{
		const Manager::MEP_FILE_INFO* pFileInfo = &( *it );

		Mix::Tool::Win32::File::InputStream input;

		// 新規のものをコンパイル
		if( MEP_Compile( pFileInfo->vsProf, pFileInfo->psProf, vsMap, psMap ) == false )
		{
			LogPrint( LT_INFO,  L"" );
			LogPrint( LT_ERROR, L"    シェーダーのコンパイルに失敗しました : File[%s] VS[%s] PS[%s]",
				pFileInfo->path.c_str(),
				Manager::SHADER_PROFILE_TABLE_W[pFileInfo->vsProf],
				Manager::SHADER_PROFILE_TABLE_W[pFileInfo->psProf] );

			return false;
		}

		// 既存のものを読み込む
		if( input.Open( pFileInfo->path.c_str() ) == true )
		{
			Manager::MEP_FILE_HEADER fileHeader;
			Manager::MEP_DATA_HEADER dataHeader;

			// ファイルヘッダ
			if( input.Read( &fileHeader, sizeof( fileHeader ) ) == false )
			{
				input.Close();
				return false;
			}

			if( fileHeader.magicNumber != Manager::MEP_MAGIC_NUMBER )
			{
				input.Close();
				return false;
			}

			// データヘッダー
			if( fileHeader.version == MEP_VERSION )
			{
				//最新バージョン
				if( input.Read( &dataHeader, sizeof( dataHeader ) ) == false )
				{
					input.Close();
					return false;
				}
			}
			else if( fileHeader.version == MEP_VERSION_OLD )
			{
				//旧バージョン
				dataHeader.rendererType = Manager::MEP_RT_STANDARD;

				if( input.Read( &( dataHeader.processFlags ), sizeof( dataHeader.processFlags ) ) == false )
				{
					input.Close();
					return false;
				}

				if( input.Read( &( dataHeader.vertexShaderNum ), sizeof( dataHeader.vertexShaderNum ) ) == false )
				{
					input.Close();
					return false;
				}

				if( input.Read( &( dataHeader.pixelShaderNum ), sizeof( dataHeader.pixelShaderNum ) ) == false )
				{
					input.Close();
					return false;
				}
			}
			else
			{
				input.Close();
				return false;
			}

			// バーテックスシェーダー
			{
				const unsigned int VLE_STRUCT_SIZE = sizeof( Mix::Tool::Win32::Graphics::VERTEX_ELEMENT );

				for( unsigned int i = 0; i < dataHeader.vertexShaderNum; i++ )
				{
					Manager::MEP_VS_HEADER vsDesc;
					unsigned int elementsSize;

					if( input.Read( &vsDesc, sizeof( vsDesc ) ) == false )
					{
						input.Close();
						return false;
					}

					std::map<unsigned int, Manager::MEP_MTL_VS_WORK>::iterator it = vsMap.find( vsDesc.id );
					if( it == vsMap.end() )
					{
						vsMap.insert( std::pair<unsigned int, Manager::MEP_MTL_VS_WORK>( vsDesc.id, Manager::MEP_MTL_VS_WORK() ) );
						it = vsMap.find( vsDesc.id );
						if( it == vsMap.end() )
						{
							input.Close();
							return false;
						}
					}

					elementsSize = VLE_STRUCT_SIZE * vsDesc.elementNum;

					if( it->second.macros.size() == 0 )
					{
						for( unsigned int j = 0; j < Manager::MEP_MTL_TYPE_MAX; j++ )
						{
							unsigned int buffSize = vsDesc.buffSize[j];

							if( buffSize > 0 )
							{
								it->second.buff[j].resize( buffSize );

								if( input.Read( &( it->second.buff[j][0] ), buffSize ) == false )
								{
									input.Close();
									return false;
								}
							}
						}

						if( vsDesc.elementNum > 0 )
						{
							it->second.elements.resize( vsDesc.elementNum );

							if( input.Read( &( it->second.elements[0] ), elementsSize ) == false )
							{
								input.Close();
								return false;
							}
						}
					}
					else
					{
						unsigned int skipSize = vsDesc.buffSize[Manager::MEP_MTL_COLOR] +
												vsDesc.buffSize[Manager::MEP_MTL_MASK] +
												vsDesc.buffSize[Manager::MEP_MTL_SHADOW];

						input.Skip( skipSize + elementsSize );
					}
				}
			}

			//ピクセルシェーダー
			{
				for( unsigned int i = 0; i < dataHeader.pixelShaderNum; i++ )
				{
					Manager::MEP_PS_HEADER psDesc;

					if( input.Read( &psDesc, sizeof( psDesc ) ) == false )
					{
						input.Close();
						return false;
					}

					std::map<unsigned int, Manager::MEP_MTL_PS_WORK>::iterator it = psMap.find( psDesc.id );
					if( it == psMap.end() )
					{
						psMap.insert( std::pair<unsigned int, Manager::MEP_MTL_PS_WORK>( psDesc.id, Manager::MEP_MTL_PS_WORK() ) );

						it = psMap.find( psDesc.id );
						if( it == psMap.end() )
						{
							input.Close();
							return false;
						}
					}

					if( it->second.macros.size() == 0 )
					{
						for( unsigned int j = 0; j < Manager::MEP_MTL_TYPE_MAX; j++ )
						{
							unsigned int buffSize = psDesc.buffSize[j];

							if( buffSize > 0 )
							{
								it->second.buff[j].resize( buffSize );

								if( input.Read( &( it->second.buff[j][0] ), buffSize ) == false )
								{
									input.Close();
									return false;
								}
							}
						}
					}
					else
					{
						unsigned int skipSize = psDesc.buffSize[Manager::MEP_MTL_COLOR] +
												psDesc.buffSize[Manager::MEP_MTL_MASK] +
												psDesc.buffSize[Manager::MEP_MTL_SHADOW];

						input.Skip( skipSize );
					}
				}
			}

			input.Close();
		}

		//セーブ
		if( MEP_Save( pFileInfo->path.c_str(), vsMap, psMap ) == false )
		{
			LogPrint( LT_INFO,  L"" );
			LogPrint( LT_ERROR, L"    保存に失敗しました : File[\"%s\"], VS[%s] PS[%s]",
				pFileInfo->path.c_str(),
				Manager::SHADER_PROFILE_TABLE_W[pFileInfo->vsProf],
				Manager::SHADER_PROFILE_TABLE_W[pFileInfo->psProf] );

			return false;
		}
	}

	/*
		新規状態のものを既存状態にする
	*/

	unsigned int vsUpdateCount = 0;
	unsigned int psUpdateCount = 0;

	//バーテックスシェーダー
	for( Manager::MSVertexShaderMap::iterator it = m_MSVertexShaderMap.begin(); it != m_MSVertexShaderMap.end(); ++it )
	{
		if( it->second.state == Manager::MS_STATE_NEW )
		{
			vsUpdateCount++;
			it->second.state = Manager::MS_STATE_EXIST;
		}
	}

	//ピクセルシェーダー
	for( Manager::MSPixelShaderMap::iterator it = m_MSPixelShaderMap.begin(); it != m_MSPixelShaderMap.end(); ++it )
	{
		if( it->second.state == Manager::MS_STATE_NEW )
		{
			psUpdateCount++;
			it->second.state = Manager::MS_STATE_EXIST;
		}
	}

	/*
		ログ : 終了
	*/

	if( ( vsUpdateCount > 0 ) ||
		( psUpdateCount > 0 ) )
	{
		LogPrint( LT_INFO, L"" );
		LogPrint( LT_INFO, L"  保存が完了しました" );
	}
	else
	{
		LogPrint( LT_INFO, L"  更新はありません" );
	}

	return true;
}

bool Manager::MEP_Compile( void )
{
	std::vector<Manager::MEP_FILE_INFO> fileInfoList;
	std::map<unsigned int, Manager::MEP_MTL_VS_WORK> vsMap;
	std::map<unsigned int, Manager::MEP_MTL_PS_WORK> psMap;

	/*
		ログ : 開始
	*/

	LogPrint( LT_INFO, L"----------------------------------------------------------------------------------------------------" );
	LogPrint( LT_INFO, L"  マテリアルエフェクトパッケージのコンパイル : Directory[%s] Name[%s]", m_MSPDirectoryName.c_str(), m_MSPName.c_str() );
	LogPrint( LT_INFO, L"" );

	/*
		ファイル情報リストを作成
	*/

	if( MEP_CreateFileInfoList( fileInfoList ) == false )
	{
		return false;
	}

	/*
		ワークマップを作成
	*/

	if( MEP_CreateWorkFromFile( fileInfoList.begin()->path.c_str(), vsMap, psMap ) == false )
	{
		return false;
	}

	/*
		バーテックスシェーダーのコンパイル用マクロリストを作成
	*/

	{
		std::map<unsigned int, Manager::MEP_MTL_VS_WORK>::iterator it_begin = vsMap.begin();
		std::map<unsigned int, Manager::MEP_MTL_VS_WORK>::iterator it_end = vsMap.end();
		std::map<unsigned int, Manager::MEP_MTL_VS_WORK>::iterator it;

		std::vector<D3DVERTEXELEMENT9> srcElementList;

		for( it = it_begin; it != it_end; ++it )
		{
			//コンパイルマクロリストを作成
			CreateCompileMacroList( it->first, true, it->second.macros );

			//バーテックスエレメントリストを作成
			CreateVertexElementList( it->first, srcElementList );
			ConvertVertexElementList( srcElementList, it->second.elements );
		}
	}

	/*
		ピクセルシェーダーのコンパイル用マクロリストを作成
	*/

	{
		std::map<unsigned int, Manager::MEP_MTL_PS_WORK>::iterator it_begin = psMap.begin();
		std::map<unsigned int, Manager::MEP_MTL_PS_WORK>::iterator it_end = psMap.end();
		std::map<unsigned int, Manager::MEP_MTL_PS_WORK>::iterator it;

		for( it = it_begin; it != it_end; ++it )
		{
			//コンパイルマクロリストを作成
			CreateCompileMacroList( it->first, true, it->second.macros );
		}
	}

	/*
		コンパイルしてセーブ
	*/

	{
		std::vector<Manager::MEP_FILE_INFO>::iterator it_begin = fileInfoList.begin();
		std::vector<Manager::MEP_FILE_INFO>::iterator it_end = fileInfoList.end();
		std::vector<Manager::MEP_FILE_INFO>::iterator it;

		for( it = it_begin; it != it_end; ++it )
		{
			const Manager::MEP_FILE_INFO* pFileInfo = &( *it );

			if( MEP_Compile( pFileInfo->vsProf, pFileInfo->psProf, vsMap, psMap ) == false )
			{
				return false;
			}

			if( MEP_Save( pFileInfo->path.c_str(), vsMap, psMap ) == false )
			{
				return false;
			}
		}
	}

	/*
		ログ : 終了
	*/

	LogPrint( LT_INFO, L"  コンパイルが完了しました" );

	return true;
}

bool Manager::MEP_Compile( const std::vector<std::wstring>& subDirList )
{
	std::vector<Manager::MEP_FILE_INFO> fileInfoList;
	std::map<unsigned int, Manager::MEP_MTL_VS_WORK> vsMap;
	std::map<unsigned int, Manager::MEP_MTL_PS_WORK> psMap;

	/*
		ログ : 開始
	*/

	LogPrint( LT_INFO, L"----------------------------------------------------------------------------------------------------" );
	LogPrint( LT_INFO, L"  マテリアルエフェクトパッケージのコンパイル : Directory[%s] Name[%s]", m_MSPDirectoryName.c_str(), m_MSPName.c_str() );
	LogPrint( LT_INFO, L"" );

	/*
		ファイル情報リストを作成
	*/

	if( MEP_CreateFileInfoList( fileInfoList ) == false )
	{
		return false;
	}

	/*
		ワークマップを作成( マテリアル、オブジェクトモデル、マップモデルを検索 )
	*/

	LogPrint( LT_INFO, L"  ルートディレクトリを検索 : Path[%s]", m_RootDirectoryPath.c_str() );

	//ルートディレクトリ
	if( MEP_CreateWorkFromDirectory( m_RootDirectoryPath.c_str(), vsMap, psMap ) == false )
	{
		return false;
	}

	//サブディレクトリ
	if( subDirList.size() > 0 )
	{
		std::vector<std::wstring>::const_iterator it_begin = subDirList.begin();
		std::vector<std::wstring>::const_iterator it_end = subDirList.end();
		std::vector<std::wstring>::const_iterator it;

		for( it = it_begin; it != it_end; ++it )
		{
			const wchar_t* pDirPath = it->c_str();

			LogPrint( LT_INFO, L"  サブディレクトリを検索 : Path[%s]", pDirPath );

			if( MEP_CreateWorkFromDirectory( pDirPath, vsMap, psMap ) == false )
			{
				return false;
			}
		}
	}

	if( ( vsMap.size() > 0 ) ||
		( psMap.size() > 0 ) )
	{
		LogPrint( LT_INFO, L"" );
	}
	else
	{
		LogPrint( LT_INFO, L"  ファイルが見つかりませんでした" );
	}

	/*
		バーテックスシェーダーのコンパイル用マクロリストを作成
	*/

	{
		std::map<unsigned int, Manager::MEP_MTL_VS_WORK>::iterator it_begin = vsMap.begin();
		std::map<unsigned int, Manager::MEP_MTL_VS_WORK>::iterator it_end = vsMap.end();
		std::map<unsigned int, Manager::MEP_MTL_VS_WORK>::iterator it;

		std::vector<D3DVERTEXELEMENT9> srcElementList;

		for( it = it_begin; it != it_end; ++it )
		{
			//コンパイルマクロリストを作成
			CreateCompileMacroList( it->first, true, it->second.macros );

			//バーテックスエレメントリストを作成
			CreateVertexElementList( it->first, srcElementList );
			ConvertVertexElementList( srcElementList, it->second.elements );
		}
	}

	/*
		ピクセルシェーダーのコンパイル用マクロリストを作成
	*/

	{
		std::map<unsigned int, Manager::MEP_MTL_PS_WORK>::iterator it_begin = psMap.begin();
		std::map<unsigned int, Manager::MEP_MTL_PS_WORK>::iterator it_end = psMap.end();
		std::map<unsigned int, Manager::MEP_MTL_PS_WORK>::iterator it;

		for( it = it_begin; it != it_end; ++it )
		{
			//コンパイルマクロリストを作成
			CreateCompileMacroList( it->first, true, it->second.macros );
		}
	}

	/*
		コンパイルしてセーブ
	*/

	{
		std::vector<Manager::MEP_FILE_INFO>::iterator it_begin = fileInfoList.begin();
		std::vector<Manager::MEP_FILE_INFO>::iterator it_end = fileInfoList.end();
		std::vector<Manager::MEP_FILE_INFO>::iterator it;

		for( it = it_begin; it != it_end; ++it )
		{
			const Manager::MEP_FILE_INFO* pFileInfo = &( *it );

			if( MEP_Compile( pFileInfo->vsProf, pFileInfo->psProf, vsMap, psMap ) == false )
			{
				return false;
			}

			if( MEP_Save( pFileInfo->path.c_str(), vsMap, psMap ) == false )
			{
				return false;
			}
		}
	}

	/*
		ログ : 終了
	*/

	LogPrint( LT_INFO, L"  コンパイルが完了しました" );

	return true;
}

unsigned int Manager::MEP_GetShaderModels( void ) const
{
	return m_MSPShaderModels;
}

unsigned int Manager::MEP_GetProcessFlags( void ) const
{
	return m_MSPProcFlags;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Public : マウスの操作
////////////////////////////////////////////////////////////////////////////////////////////////////

float Manager::GetMouseScalingSensitivity( void ) const
{
	return m_MouseOption.scalingSensitivity;
}

void Manager::SetMouseScalingSensitivity( float ratio )
{
	m_MouseOption.scalingSensitivity = ratio;
}

float Manager::GetMouseRotationSensitivity( void ) const
{
	return m_MouseOption.rotationSensitivity;
}

void Manager::SetMouseRotationSensitivity( float ratio )
{
	m_MouseOption.rotationSensitivity = ratio;
}

float Manager::GetMouseTranslationSensitivity( void ) const
{
	return m_MouseOption.translationSensitivity;
}

void Manager::SetMouseTranslationSensitivity( float ratio )
{
	m_MouseOption.translationSensitivity = ratio;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Public : テクスチャファイル名のフォーマット
////////////////////////////////////////////////////////////////////////////////////////////////////

void Manager::SetSpecularTextureFindFormat( const wchar_t* pFormat )
{
	m_TextureOption.specular = pFormat;
}

void Manager::SetEmissiveTextureFindFormat( const wchar_t* pFormat )
{
	m_TextureOption.emissive = pFormat;
}

void Manager::SetBumpTextureFindFormat( const wchar_t* pFormat )
{
	m_TextureOption.bump = pFormat;
}

const wchar_t* Manager::GetSpecularTextureFindFormat( void ) const
{
	return m_TextureOption.specular.c_str();
}

const wchar_t* Manager::GetEmissiveTextureFindFormat( void ) const
{
	return m_TextureOption.emissive.c_str();
}

const wchar_t* Manager::GetBumpTextureFindFormat( void ) const
{
	return m_TextureOption.bump.c_str();
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Public : カメラ共通の射影行列関係
////////////////////////////////////////////////////////////////////////////////////////////////////

float Manager::GetPerspectiveFovY( void ) const
{
	return m_PerspectiveOption.fovY;
}

void Manager::SetPerspectiveFovY( float fovY )
{
	m_PerspectiveOption.fovY = MIX_CLAMP( fovY, 0.0f, 180.0f );
}

float Manager::GetPerspectiveNearZ( void ) const
{
	return m_PerspectiveOption.nearZ;
}

void Manager::SetPerspectiveNearZ( float nearZ )
{
	m_PerspectiveOption.nearZ = max( 0.01f, nearZ );
}

float Manager::GetPerspectiveFarZ( void ) const
{
	return m_PerspectiveOption.farZ;
}

void Manager::SetPerspectiveFarZ( float farZ )
{
	m_PerspectiveOption.farZ = max( 0.01f, farZ );
}

void Manager::UpdateProjectionMatrix( void )
{
	float aspect = static_cast<float>( m_D3DDevicePresentParam.BackBufferWidth ) / static_cast<float>( m_D3DDevicePresentParam.BackBufferHeight );

	::D3DXMatrixIdentity( &m_ProjectionMatrix );
	::D3DXMatrixPerspectiveFovLH( &m_ProjectionMatrix, D3DXToRadian( m_PerspectiveOption.fovY ), aspect, m_PerspectiveOption.nearZ, m_PerspectiveOption.farZ );
}

const D3DXMATRIX& Manager::GetProjectionMatrix( void ) const
{
	return m_ProjectionMatrix;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Private : シーン関係
////////////////////////////////////////////////////////////////////////////////////////////////////

void Manager::Update( int baseFps, float fps, float mag )
{
	std::list<Mix::Tool::Win32::Graphics::Scene*>::iterator it_scene_begin = m_SceneList.begin();
	std::list<Mix::Tool::Win32::Graphics::Scene*>::iterator it_scene_end = m_SceneList.end();
	std::list<Mix::Tool::Win32::Graphics::Scene*>::iterator it_scene;

	std::list<Mix::Tool::Win32::Graphics::Material*>::iterator it_wave_begin = m_WaveMaterialList.begin();
	std::list<Mix::Tool::Win32::Graphics::Material*>::iterator it_wave_end = m_WaveMaterialList.end();
	std::list<Mix::Tool::Win32::Graphics::Material*>::iterator it_wave;

	IDirect3DSurface9* pOldBackBuffer = NULL;

	/*
		FPS の更新
	*/

	m_Fps = fps;

	/*
		デバイスロスト時の処理
	*/

	if( m_ActionType != Manager::ACTION_RENDER_SCENE )
	{
		if( m_ActionType == Manager::ACTION_INVALIDATE_DEVICEOBJECT )
		{
			InvalidateDeviceObject();

			m_ActionType = Manager::ACTION_VALIDATE_DEVICEOBJECT;

			LogPrint( LT_INFO, L"グラフィックデバイスがロストしました" );
		}
		else if( m_ActionType == Manager::ACTION_VALIDATE_DEVICEOBJECT )
		{
			if( m_pD3DDevice != NULL )
			{
				switch( m_pD3DDevice->TestCooperativeLevel() )
				{
				case D3DERR_DEVICENOTRESET:
					if( m_pD3DDevice->Reset( &m_D3DDevicePresentParam ) == D3D_OK )
					{
						ValidateDeviceObject();
						m_ActionType = Manager::ACTION_RENDER_SCENE;

						LogPrint( LT_INFO, L"グラフィックデバイスが復帰しました" );
					}
					else
					{
						::Sleep( 0 );
					}
					break;

				case D3DERR_DEVICELOST:
					::Sleep( 200 );
					break;
				}
			}
		}
		else if( m_ActionType == Manager::ACTION_CREATE_DEVICE )
		{
			Mix::Tool::Win32::Graphics::SwapChain* pSwapChain = GetFirstSwapChain();
			if( pSwapChain != NULL )
			{
				if( CreateDevice( pSwapChain->GetWindowHandle() ) == true )
				{
					m_ActionType = Manager::ACTION_RENDER_SCENE;
				}
			}
			else
			{
				m_ActionType = Manager::ACTION_RENDER_SCENE;
				return ;
			}
		}

		if( m_ActionType != Manager::ACTION_RENDER_SCENE )
		{
			return;
		}
	}

	if( m_pD3DDevice == NULL )
	{
		return;
	}

	/*
		ウェーブアニメーション指定のウォーターマテリアルを更新
	*/

	for( it_wave = it_wave_begin; it_wave != it_wave_end; ++it_wave )
	{
		Mix::Tool::Win32::Graphics::Material* pMaterial = ( *it_wave );
		pMaterial->OnUpdate( baseFps, mag );
	}

	/*
		シーンを更新
	*/

	for( it_scene = it_scene_begin; it_scene != it_scene_end; ++it_scene )
	{
		Mix::Tool::Win32::Graphics::Scene* pScene = ( *it_scene );
		pScene->OnUpdate();
	}
}

void Manager::Refresh( void )
{
	std::list<Mix::Tool::Win32::Graphics::Scene*>::iterator it_scene_begin = m_SceneList.begin();
	std::list<Mix::Tool::Win32::Graphics::Scene*>::iterator it_scene_end = m_SceneList.end();
	std::list<Mix::Tool::Win32::Graphics::Scene*>::iterator it_scene;

	for( it_scene = it_scene_begin; it_scene != it_scene_end; ++it_scene )
	{
		Mix::Tool::Win32::Graphics::Scene* pScene = ( *it_scene );
		pScene->OnRefresh();
	}
}

void Manager::Draw( void )
{
	if( m_ActionType != Manager::ACTION_RENDER_SCENE )
	{
		return;
	}

	/*
		シーンを描画
	*/

	std::list<Mix::Tool::Win32::Graphics::Scene*>::iterator it_scene_begin = m_SceneList.begin();
	std::list<Mix::Tool::Win32::Graphics::Scene*>::iterator it_scene_end = m_SceneList.end();
	std::list<Mix::Tool::Win32::Graphics::Scene*>::iterator it_scene;

	for( it_scene = it_scene_begin; it_scene != it_scene_end; ++it_scene )
	{
		Mix::Tool::Win32::Graphics::Scene* pScene = ( *it_scene );

		if( pScene->OnDraw() == false )
		{
			break;
		}
	}

	/*
		描画のリセット
	*/

	ResetTargetState();
	ResetDrawState();
}

float Manager::GetFramesPerSec( void ) const
{
	return m_Fps;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Public : デバイス
////////////////////////////////////////////////////////////////////////////////////////////////////

bool Manager::CreateDevice( HWND hWnd )
{
	/*
		テーブル
	*/

	static const D3DRENDERSTATETYPE D3DRenderStateTypeTable[Manager::RENDERSTATE_TYPE_MAX] =
	{
		D3DRS_FILLMODE,
		D3DRS_CULLMODE,
		D3DRS_SCISSORTESTENABLE,
		D3DRS_ZENABLE,
		D3DRS_ZWRITEENABLE,
		D3DRS_ALPHABLENDENABLE,
		D3DRS_SRCBLEND,
		D3DRS_DESTBLEND,
		D3DRS_BLENDOP,
		D3DRS_COLORWRITEENABLE,
	};

	static const unsigned int D3DRenderStateTypeCount = ( sizeof( D3DRenderStateTypeTable ) / sizeof( D3DRENDERSTATETYPE ) );

	static const D3DSAMPLERSTATETYPE D3DSamplerStateTypeTable[Manager::SAMPLERSTATE_TYPE_MAX] =
	{
		D3DSAMP_MAGFILTER,
		D3DSAMP_MINFILTER,
		D3DSAMP_MIPFILTER,
		D3DSAMP_ADDRESSU,
		D3DSAMP_ADDRESSV,
		D3DSAMP_ADDRESSW,
		D3DSAMP_MAXANISOTROPY,
	};

	static const unsigned int D3DSamplerStateTypeCount = ( sizeof( D3DSamplerStateTypeTable ) / sizeof( D3DSAMPLERSTATETYPE ) );

	static const DWORD D3DCreateFlagTable[] =
	{
		D3DCREATE_HARDWARE_VERTEXPROCESSING,
		D3DCREATE_MIXED_VERTEXPROCESSING,
		D3DCREATE_SOFTWARE_VERTEXPROCESSING,
	};

	static const unsigned int D3DCreateFlagCount = ( sizeof( D3DCreateFlagTable ) / sizeof( DWORD ) );

	static const D3DFORMAT D3DDepthFormatTable[] =
	{
		D3DFMT_D32,
		D3DFMT_D24X8,
		D3DFMT_D24S8,
		D3DFMT_D16,
	};

	static const unsigned int D3DDepthFormatCount = ( sizeof( D3DDepthFormatTable ) / sizeof( D3DFORMAT ) );

	/*
		変数宣言
	*/

	unsigned int i;
	unsigned int j;
	unsigned int d3dAdapModeCount;
	bool bD3DFindBestDispMode;
	D3DDISPLAYMODE d3dDispMode;
	D3DDISPLAYMODE d3dBestDispMode;
	D3DFORMAT depthFormat;

	/*
		デバイスを作成するためのパラメータを取得
	*/

	if( m_pD3D->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &d3dDispMode ) != D3D_OK )
	{
		LogPrint( LT_ERROR, L"グラフィックデバイス(DirectX9)の作成に失敗 : IDirect3D::GetAdapterDisplayMode がエラーを返しました" );
		return false;
	}

	d3dAdapModeCount = m_pD3D->GetAdapterModeCount( D3DADAPTER_DEFAULT, D3DFMT_X8R8G8B8 );

	bD3DFindBestDispMode = false;

	for( i = 0; i < d3dAdapModeCount; i++ )
	{
		D3DDISPLAYMODE d3dTempDispMode;

		if( m_pD3D->EnumAdapterModes( D3DADAPTER_DEFAULT, D3DFMT_X8R8G8B8, i, &d3dTempDispMode ) != D3D_OK )
		{
			continue;
		}

		if( ( d3dDispMode.Format != d3dTempDispMode.Format ) ||
			( d3dDispMode.RefreshRate != d3dTempDispMode.RefreshRate ) )
		{
			continue;
		}

		if( ( d3dDispMode.Width >= d3dTempDispMode.Width ) &&
			( d3dDispMode.Height >= d3dTempDispMode.Height ) )
		{
			d3dBestDispMode = d3dTempDispMode;
			bD3DFindBestDispMode = true;
		}
		else if(	( d3dDispMode.Width == d3dTempDispMode.Width ) &&
					( d3dDispMode.Height == d3dTempDispMode.Height ) )
		{
			d3dBestDispMode = d3dTempDispMode;
			bD3DFindBestDispMode = true;
			break;
		}
	}

	if( bD3DFindBestDispMode == false )
	{
		LogPrint( LT_ERROR, L"グラフィックデバイス(DirectX9)の作成に失敗 : 最適なディスプレイモードが見つかりませんでした" );
		return false;
	}

	/*
		デプスフォーマットを決定
	*/

	depthFormat = D3DFMT_UNKNOWN;

	for( i = 0; ( i < D3DDepthFormatCount ) && ( depthFormat == D3DFMT_UNKNOWN ); i++ )
	{
		if( m_pD3D->CheckDeviceFormat(	0,
										D3DDEVTYPE_HAL,
										d3dBestDispMode.Format,
										D3DUSAGE_DEPTHSTENCIL,
										D3DRTYPE_SURFACE,
										D3DDepthFormatTable[i] ) == D3D_OK )
		{
			depthFormat = D3DDepthFormatTable[i];
		}
	}

	if( depthFormat == D3DFMT_UNKNOWN )
	{
		LogPrint( LT_ERROR, L"グラフィックデバイス(DirectX9)の作成に失敗 : 最適なデプスフォーマットが見つかりませんでした" );
		return false;
	}

	/*
		プレゼントパラメータを作成
	*/

	::ZeroMemory( &m_D3DDevicePresentParam, sizeof( m_D3DDevicePresentParam ) );

	m_D3DDevicePresentParam.BackBufferWidth = d3dBestDispMode.Width;
	m_D3DDevicePresentParam.BackBufferHeight = d3dBestDispMode.Height;
	m_D3DDevicePresentParam.BackBufferFormat = d3dBestDispMode.Format;
	m_D3DDevicePresentParam.BackBufferCount = 1;
	m_D3DDevicePresentParam.MultiSampleType = D3DMULTISAMPLE_NONE;
	m_D3DDevicePresentParam.MultiSampleQuality = 0;
	m_D3DDevicePresentParam.SwapEffect = D3DSWAPEFFECT_DISCARD;
	m_D3DDevicePresentParam.hDeviceWindow = hWnd;
	m_D3DDevicePresentParam.Windowed = TRUE;
	m_D3DDevicePresentParam.EnableAutoDepthStencil = TRUE;
	m_D3DDevicePresentParam.AutoDepthStencilFormat = depthFormat;
	m_D3DDevicePresentParam.Flags = 0;
	m_D3DDevicePresentParam.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
	m_D3DDevicePresentParam.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;

	/*
		Direct3Dデバイスを作成
	*/

	for( i = 0; i < D3DCreateFlagCount; i++ )
	{
		if( m_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, NULL, D3DCreateFlagTable[i], &m_D3DDevicePresentParam, &m_pD3DDevice ) == D3D_OK )
		{
			break;
		}
	}

	if( m_pD3DDevice == NULL )
	{
		LogPrint( LT_ERROR, L"グラフィックデバイス(DirectX9)の作成に失敗 : IDirect3D::CreateDevice がエラーを返しました" );
		return false;
	}

	if( m_pD3DDevice->GetBackBuffer( 0, 0, D3DBACKBUFFER_TYPE_MONO, &m_pD3DBackBuffer ) != D3D_OK )
	{
		LogPrint( LT_ERROR, L"グラフィックデバイス(DirectX9)の作成に失敗 : IDirect3DDevice9::GetBackBuffer がエラーを返しました" );
		return false;
	}

	/*
		レンダーステートテーブルを作成
	*/

	for( i = 0; i < D3DRenderStateTypeCount; i++ )
	{
		Manager::RENDERSTATE* pRenderState = &( m_RenderStateTable[i] );
		D3DRENDERSTATETYPE type = D3DRenderStateTypeTable[i];
		DWORD value = 0;

		if( m_pD3DDevice->GetRenderState( type, &value ) != D3D_OK )
		{
			return false;
		}

		pRenderState->type = type;
		pRenderState->defValue = value;
		pRenderState->nowValue = value;
	}

	/*
		サンプラーステートテーブルを作成
	*/

	for( i = 0; i < Mix::Tool::Win32::Graphics::TEXTURE_STAGE_MAX; i++ )
	{
		for( j = 0; j < D3DSamplerStateTypeCount; j++ )
		{
			Manager::SAMPLERSTATE* pSamplerState = &( m_SamplerStateTable[i][j] );
			D3DSAMPLERSTATETYPE type = D3DSamplerStateTypeTable[j];
			DWORD value = 0;

			if( m_pD3DDevice->GetSamplerState( i, type, &value ) != D3D_OK )
			{
				return false;
			}

			pSamplerState->type = type;
			pSamplerState->defValue = value;
			pSamplerState->nowValue = value;
		}
	}

	/*
		フォントを作成
	*/

	if( ::D3DXCreateFont(	m_pD3DDevice,
							14,
							0,
							FW_NORMAL,
							1,
							false,
							DEFAULT_CHARSET,
							OUT_TT_ONLY_PRECIS,
							ANTIALIASED_QUALITY,
							FF_DONTCARE,
							L"ＭＳ ゴシック",
							&m_pD3DFont ) == D3D_OK )
	{
		if( m_pD3DFont->PreloadCharacters( 0x00, 0xFF ) != D3D_OK )
		{
			LogPrint( LT_ERROR, L"グラフィックデバイス(DirectX9)の作成に失敗 : ID3DXFont::PreloadCharacters がエラーを返しました" );
			return false;
		}
	}
	else
	{
		LogPrint( LT_ERROR, L"グラフィックデバイス(DirectX9)の作成に失敗 : D3DXCreateFont がエラーを返しました" );
		return false;
	}

	/*
		射影行列
	*/

	UpdateProjectionMatrix();

	/*
		デバイスオブジェクトを有効にする
	*/

	ValidateDeviceObject();

	return true;
}

void Manager::ReleaseDevice( void )
{
	bool bExistDevice = ( m_pD3DDevice != NULL );

	/*
		解放
	*/

	InvalidateDeviceObject();

	MIX_RELEASE( m_pD3DFont );

	MIX_RELEASE( m_pD3DBackBuffer );
	MIX_RELEASE( m_pD3DDevice );

	/*
		ログ
	*/

	if( bExistDevice == true )
	{
		LogPrint( LT_INFO, L"グラフィックデバイス(DirectX9)を解放" );
	}
}

void Manager::LostRenderState( void )
{
	unsigned int i;

	for( i = 0; i < Manager::RENDERSTATE_TYPE_MAX; i++ )
	{
		Manager::RENDERSTATE* pRenderState = &( m_RenderStateTable[i] );
		pRenderState->nowValue = pRenderState->defValue;
	}
}

void Manager::LostSamplerState( void )
{
	unsigned int i;
	unsigned int j;

	for( i = 0; i < Mix::Tool::Win32::Graphics::TEXTURE_STAGE_MAX; i++ )
	{
		for( j = 0; j < Manager::SAMPLERSTATE_TYPE_MAX; j++ )
		{
			Manager::SAMPLERSTATE* pSamplerState = &( m_SamplerStateTable[i][j] );
			pSamplerState->nowValue = pSamplerState->defValue;
		}
	}
}

void Manager::ResetTargetState( void )
{
	m_TargetState.pT0 = NULL;
	m_TargetState.pT1 = NULL;
	m_TargetState.pT2 = NULL;
	m_TargetState.pT3 = NULL;

	if( m_pD3DDevice != NULL )
	{
		m_pD3DDevice->SetRenderTarget( 0, m_pD3DBackBuffer );
		m_pD3DDevice->SetRenderTarget( 1, NULL );
		m_pD3DDevice->SetRenderTarget( 2, NULL );
		m_pD3DDevice->SetRenderTarget( 3, NULL );
	}
}

void Manager::ResetDrawState( void )
{
	unsigned int i;

	m_DrawState.current.pD3DVertexLayout = NULL;
	m_DrawState.current.pD3DVertexShader = NULL;
	m_DrawState.current.pD3DPixelShader = NULL;
	m_DrawState.current.pD3DVertexBuffer = NULL;
	m_DrawState.current.vertexStride = 0;
	m_DrawState.current.pD3DIndexBuffer = NULL;

	m_DrawState.next.pD3DVertexLayout = NULL;
	m_DrawState.next.pD3DVertexShader = NULL;
	m_DrawState.next.pD3DPixelShader = NULL;
	m_DrawState.next.pD3DVertexBuffer = NULL;
	m_DrawState.next.vertexStride = 0;
	m_DrawState.next.pD3DIndexBuffer = NULL;

	for( i = 0; i < Mix::Tool::Win32::Graphics::TEXTURE_STAGE_MAX; i++ )
	{
		m_DrawState.current.pD3DTexture[i] = NULL;
		m_DrawState.next.pD3DTexture[i] = NULL;
	}

	if( m_pD3DDevice != NULL )
	{
		for( i = 0; i < Mix::Tool::Win32::Graphics::TEXTURE_STAGE_MAX; i++ )
		{
			m_pD3DDevice->SetTexture( i, NULL );
		}
	}
}

void Manager::FlushDrawState( void )
{
	if( m_pD3DDevice == NULL )
	{
		return;
	}

	unsigned int i;

	if( m_DrawState.current.pD3DVertexLayout != m_DrawState.next.pD3DVertexLayout )
	{
		if( m_DrawState.next.pD3DVertexLayout != NULL )
		{
			m_pD3DDevice->SetVertexDeclaration( m_DrawState.next.pD3DVertexLayout );
		}

		m_DrawState.current.pD3DVertexLayout = m_DrawState.next.pD3DVertexLayout;
	}

	if( m_DrawState.current.pD3DVertexShader != m_DrawState.next.pD3DVertexShader )
	{
		m_pD3DDevice->SetVertexShader( m_DrawState.next.pD3DVertexShader );

		m_DrawState.current.pD3DVertexShader = m_DrawState.next.pD3DVertexShader;
	}

	if( m_DrawState.current.pD3DPixelShader != m_DrawState.next.pD3DPixelShader )
	{
		m_pD3DDevice->SetPixelShader( m_DrawState.next.pD3DPixelShader );

		m_DrawState.current.pD3DPixelShader = m_DrawState.next.pD3DPixelShader;
	}

	if( m_DrawState.current.pD3DVertexBuffer != m_DrawState.next.pD3DVertexBuffer )
	{
		if( m_DrawState.next.pD3DVertexBuffer != NULL )
		{
			m_pD3DDevice->SetStreamSource( 0, m_DrawState.next.pD3DVertexBuffer, 0, m_DrawState.next.vertexStride );
		}

		m_DrawState.current.pD3DVertexBuffer = m_DrawState.next.pD3DVertexBuffer;
		m_DrawState.current.vertexStride = m_DrawState.next.vertexStride;
	}

	if( m_DrawState.current.pD3DIndexBuffer != m_DrawState.next.pD3DIndexBuffer )
	{
		if( m_DrawState.next.pD3DIndexBuffer != NULL )
		{
			m_pD3DDevice->SetIndices( m_DrawState.next.pD3DIndexBuffer );
		}

		m_DrawState.current.pD3DIndexBuffer = m_DrawState.next.pD3DIndexBuffer;
	}

	for( i = 0; i < Mix::Tool::Win32::Graphics::TEXTURE_STAGE_MAX; i++ )
	{
		if( m_DrawState.current.pD3DTexture[i] != m_DrawState.next.pD3DTexture[i] )
		{
			m_pD3DDevice->SetTexture( i, m_DrawState.next.pD3DTexture[i] );

			m_DrawState.current.pD3DTexture[i] = m_DrawState.next.pD3DTexture[i];
		}
	}
}

void Manager::NotifyDeviceLost( void )
{
	m_ActionType = Manager::ACTION_INVALIDATE_DEVICEOBJECT;
}

void Manager::InvalidateDeviceObject( void )
{
	{
		std::list<Mix::Tool::Win32::Graphics::DeviceObject*>::iterator it_begin = m_DeviceObjectList.begin();
		std::list<Mix::Tool::Win32::Graphics::DeviceObject*>::iterator it_end = m_DeviceObjectList.end();
		std::list<Mix::Tool::Win32::Graphics::DeviceObject*>::iterator it;

		for( it = it_begin; it != it_end; ++it )
		{
			( *it )->OnInvalidate();
		}
	}

	if( m_pD3DFont != NULL )
	{
		m_pD3DFont->OnLostDevice();
	}

	LostRenderState();
	LostSamplerState();
}

void Manager::ValidateDeviceObject( void )
{
	std::list<Mix::Tool::Win32::Graphics::DeviceObject*>::iterator it_begin = m_DeviceObjectList.begin();
	std::list<Mix::Tool::Win32::Graphics::DeviceObject*>::iterator it_end = m_DeviceObjectList.end();
	std::list<Mix::Tool::Win32::Graphics::DeviceObject*>::iterator it;

	for( it = it_begin; it != it_end; ++it )
	{
		( *it )->OnValidate();
	}

	m_pD3DFont->OnResetDevice();
}

void Manager::AddDeviceObject( Mix::Tool::Win32::Graphics::DeviceObject* pDeviceObject )
{
	m_DeviceObjectList.push_back( pDeviceObject );
}

void Manager::RemoveDeviceObject( Mix::Tool::Win32::Graphics::DeviceObject* pDeviceObject )
{
	m_DeviceObjectList.remove( pDeviceObject );

	Mix::Tool::Win32::Object::TYPE objType = pDeviceObject->GetType();

	if( objType == Mix::Tool::Win32::Object::GRAPHICS__SWAPCHAIN )
	{
		Mix::Tool::Win32::Graphics::SwapChain* pSwapChain = static_cast<Mix::Tool::Win32::Graphics::SwapChain*>( pDeviceObject );

		if( pSwapChain->IsDevice() == true )
		{
			ReleaseDevice();
			m_ActionType = Manager::ACTION_CREATE_DEVICE;
		}
	}
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Private : デバイスコンテキスト
////////////////////////////////////////////////////////////////////////////////////////////////////

void Manager::SetRenderState( Manager::RENDERSTATE_TYPE type, DWORD value )
{
	if( m_pD3DDevice == NULL )
	{
		return;
	}

	Manager::RENDERSTATE* pRenderState = &( m_RenderStateTable[type] );

	if( pRenderState->nowValue != value )
	{
		if( m_pD3DDevice->SetRenderState( pRenderState->type, value ) == D3D_OK )
		{
			pRenderState->nowValue = value;
		}
	}
}

void Manager::SetSamplerState( unsigned int stage, Manager::SAMPLERSTATE_TYPE type, DWORD value )
{
	if( m_pD3DDevice == NULL )
	{
		return;
	}

	if( Mix::Tool::Win32::Graphics::TEXTURE_STAGE_MAX <= stage )
	{
		return;
	}

	Manager::SAMPLERSTATE* pSamplerState = &( m_SamplerStateTable[stage][type] );

	if( pSamplerState->nowValue != value )
	{
		if( m_pD3DDevice->SetSamplerState( stage, pSamplerState->type, value ) == D3D_OK )
		{
			pSamplerState->nowValue = value;
		}
	}
}

void Manager::SetRasterizerState( D3DFILLMODE fill, D3DCULL cull, bool bScissoring )
{
	SetRenderState( Manager::RENDERSTATE_FILLMODE, fill );
	SetRenderState( Manager::RENDERSTATE_CULLMODE, cull );
	SetRenderState( Manager::RENDERSTATE_SCISSORTESTENABLE, ( bScissoring == true )? TRUE : FALSE );
}

void Manager::SetDepthState( bool bTest, bool bWrite )
{
	SetRenderState( Manager::RENDERSTATE_ZENABLE, ( bTest == true )? TRUE : FALSE );
	SetRenderState( Manager::RENDERSTATE_ZWRITEENABLE, ( bWrite == true )? TRUE : FALSE );
}

void Manager::SetBlendState( Mix::Tool::Win32::Graphics::BLEND_MODE blend, unsigned int colorMask )
{
	SetRenderState( Manager::RENDERSTATE_ALPHABLENDENABLE, TRUE );

	switch( blend )
	{
	case Mix::Tool::Win32::Graphics::BLEND_COPY:
		SetRenderState( Manager::RENDERSTATE_SRCBLEND, D3DBLEND_ONE );
		SetRenderState( Manager::RENDERSTATE_DESTBLEND, D3DBLEND_ZERO );
		SetRenderState( Manager::RENDERSTATE_BLENDOP, D3DBLENDOP_ADD );
		break;

	case Mix::Tool::Win32::Graphics::BLEND_NORMAL:
		SetRenderState( Manager::RENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA );
		SetRenderState( Manager::RENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA );
		SetRenderState( Manager::RENDERSTATE_BLENDOP, D3DBLENDOP_ADD );
		break;

	case Mix::Tool::Win32::Graphics::BLEND_ADD:
		SetRenderState( Manager::RENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA );
		SetRenderState( Manager::RENDERSTATE_DESTBLEND, D3DBLEND_ONE );
		SetRenderState( Manager::RENDERSTATE_BLENDOP, D3DBLENDOP_ADD );
		break;

	case Mix::Tool::Win32::Graphics::BLEND_SUB:
		SetRenderState( Manager::RENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA );
		SetRenderState( Manager::RENDERSTATE_DESTBLEND, D3DBLEND_ONE );
		SetRenderState( Manager::RENDERSTATE_BLENDOP, D3DBLENDOP_REVSUBTRACT );
		break;

	case Mix::Tool::Win32::Graphics::BLEND_MUL:
		SetRenderState( Manager::RENDERSTATE_SRCBLEND, D3DBLEND_ZERO );
		SetRenderState( Manager::RENDERSTATE_DESTBLEND, D3DBLEND_SRCCOLOR );
		SetRenderState( Manager::RENDERSTATE_BLENDOP, D3DBLENDOP_ADD );
		break;

	case Mix::Tool::Win32::Graphics::BLEND_SCREEN:
		SetRenderState( Manager::RENDERSTATE_SRCBLEND, D3DBLEND_INVDESTCOLOR );
		SetRenderState( Manager::RENDERSTATE_DESTBLEND, D3DBLEND_ONE );
		SetRenderState( Manager::RENDERSTATE_BLENDOP, D3DBLENDOP_ADD );
		break;
	}

	SetRenderState( Manager::RENDERSTATE_COLORWRITE, colorMask );
}

void Manager::SetScissorRect( const RECT& rect )
{
	if( m_pD3DDevice == NULL )
	{
		return;
	}

	m_pD3DDevice->SetScissorRect( &rect );
}

void Manager::SetScissorRect( unsigned int width, unsigned int height )
{
	RECT rect;

	rect.left = 0;
	rect.top = 0;
	rect.right = rect.left + width;
	rect.bottom = rect.top + height;

	SetScissorRect( rect );
}

void Manager::SetScissorRect( unsigned int x, unsigned int y, unsigned int width, unsigned int height )
{
	RECT rect;

	rect.left = x;
	rect.top = y;
	rect.right = rect.left + width;
	rect.bottom = rect.top + height;

	SetScissorRect( rect );
}

void Manager::SetViewport( unsigned int width, unsigned int height )
{
	SetViewport( 0, 0, width, height );
}

void Manager::SetViewport( unsigned int x, unsigned int y, unsigned int width, unsigned int height )
{
	D3DVIEWPORT9 vp;

	vp.X = x;
	vp.Y = y;
	vp.Width = width;
	vp.Height = height;
	vp.MinZ = 0.0f;
	vp.MaxZ = 1.0f;

	SetViewport( vp );
}

void Manager::SetViewport( const D3DVIEWPORT9& vp )
{
	m_pD3DDevice->SetViewport( &vp );
}

void Manager::SetTarget(	Mix::Tool::Win32::Graphics::Texture* pT0,
							Mix::Tool::Win32::Graphics::Texture* pT1,
							Mix::Tool::Win32::Graphics::Texture* pT2,
							Mix::Tool::Win32::Graphics::Texture* pT3 )
{
	if( m_TargetState.pT0 != pT0 )
	{
		if( ( pT0 != NULL ) &&
			( ( pT0->GetType() == Mix::Tool::Win32::Object::GRAPHICS__BACK_BUFFER ) ||
			  ( pT0->GetType() == Mix::Tool::Win32::Object::GRAPHICS__TARGET_TEXTURE_D ) ||
			  ( pT0->GetType() == Mix::Tool::Win32::Object::GRAPHICS__TARGET_TEXTURE_L ) ) )
		{
			m_pD3DDevice->SetRenderTarget( 0, pT0->GetSurfacePtr() );
		}
		else
		{
			m_pD3DDevice->SetRenderTarget( 0, m_pD3DBackBuffer );
		}

		m_TargetState.pT0 = pT0;
	}

	if( m_TargetState.pT1 != pT1 )
	{
		if( pT1 != NULL )
		{
			if( pT1->GetType() == Mix::Tool::Win32::Object::GRAPHICS__TARGET_TEXTURE_D )
			{
				m_pD3DDevice->SetRenderTarget( 1, pT1->GetSurfacePtr() );
			}
		}
		else
		{
			m_pD3DDevice->SetRenderTarget( 1, NULL );
		}

		m_TargetState.pT1 = pT1;
	}

	if( m_TargetState.pT2 != pT2 )
	{
		if( pT2 != NULL )
		{
			if( pT2->GetType() == Mix::Tool::Win32::Object::GRAPHICS__TARGET_TEXTURE_D )
			{
				m_pD3DDevice->SetRenderTarget( 2, pT2->GetSurfacePtr() );
			}
		}
		else
		{
			m_pD3DDevice->SetRenderTarget( 2, NULL );
		}

		m_TargetState.pT2 = pT2;
	}

	if( m_TargetState.pT3 != pT3 )
	{
		if( pT3 != NULL )
		{
			if( pT3->GetType() == Mix::Tool::Win32::Object::GRAPHICS__TARGET_TEXTURE_D )
			{
				m_pD3DDevice->SetRenderTarget( 3, pT3->GetSurfacePtr() );
			}
		}
		else
		{
			m_pD3DDevice->SetRenderTarget( 3, NULL );
		}

		m_TargetState.pT3 = pT3;
	}
}

void Manager::Clear( bool clearTarget, bool clearDepth, const D3DXVECTOR4& clearColor )
{
	DWORD flags = 0;
	DWORD clearColorD = 0;

	if( clearTarget == true ) { flags |= D3DCLEAR_TARGET; }
	if( clearDepth == true ) { flags |= D3DCLEAR_ZBUFFER; }

	clearColorD |= MIX_CLAMP( static_cast<DWORD>( clearColor.w * 255.0f ), 0, 255 ) << 24;
	clearColorD |= MIX_CLAMP( static_cast<DWORD>( clearColor.x * 255.0f ), 0, 255 ) << 16;
	clearColorD |= MIX_CLAMP( static_cast<DWORD>( clearColor.y * 255.0f ), 0, 255 ) << 8;
	clearColorD |= MIX_CLAMP( static_cast<DWORD>( clearColor.z * 255.0f ), 0, 255 );

	m_pD3DDevice->Clear( 0, NULL, flags, clearColorD, 1.0f, 0L );
}

void Manager::SetVertexShaderConstant( unsigned int slot, const D3DXVECTOR3& v )
{
	SetVertexShaderConstant( slot, D3DXVECTOR4( v.x, v.y, v.z, 1.0f ) );
}

void Manager::SetVertexShaderConstant( unsigned int slot, const D3DXVECTOR4& v )
{
	if( m_pD3DDevice == NULL )
	{
		return;
	}

	m_pD3DDevice->SetVertexShaderConstantF( slot, static_cast<const float*>( v ), 1 );
}

void Manager::SetVertexShaderConstant( unsigned int slot, const D3DXMATRIX& m )
{
	if( m_pD3DDevice == NULL )
	{
		return;
	}

	D3DXMATRIX tm;

	::D3DXMatrixTranspose( &tm, &m );

	m_pD3DDevice->SetVertexShaderConstantF( slot, &( tm.m[0][0] ), 4 );
}

void Manager::SetVertexShaderConstant( unsigned int slot, const D3DXMATRIX* m, unsigned int count )
{
	if( ( m_pD3DDevice == NULL ) ||
		( m == NULL ) ||
		( count == 0 ) )
	{
		return;
	}

	const D3DXMATRIX* pSrc = &( m[0] );
	const D3DXMATRIX* pSrcEnd = pSrc + count;

	D3DXMATRIX tempMat;

	m_TempMatList.clear();
	m_TempMatList.reserve( count );

	while( pSrc != pSrcEnd )
	{
		::D3DXMatrixTranspose( &tempMat, pSrc );
		m_TempMatList.push_back( tempMat );
		pSrc++;
	}

	m_pD3DDevice->SetVertexShaderConstantF( slot, reinterpret_cast<const float*>( &( m_TempMatList[0] ) ), count * 4 );
}

void Manager::SetPixelShaderConstant( unsigned int slot, const D3DXVECTOR3& v )
{
	SetPixelShaderConstant( slot, D3DXVECTOR4( v.x, v.y, v.z, 1.0f ) );
}

void Manager::SetPixelShaderConstant( unsigned int slot, const D3DXVECTOR4& v )
{
	if( m_pD3DDevice == NULL )
	{
		return;
	}

	m_pD3DDevice->SetPixelShaderConstantF( slot, static_cast<const float*>( v ), 1 );
}

void Manager::SetPixelShaderConstant( unsigned int slot, const D3DXMATRIX& m )
{
	if( m_pD3DDevice == NULL )
	{
		return;
	}

	m_pD3DDevice->SetPixelShaderConstantF( slot, &( m.m[0][0] ), 4 );
}

void Manager::SetVertexLayout( Mix::Tool::Win32::Graphics::VertexLayout* pVertexLayout )
{
	m_DrawState.next.pD3DVertexLayout = pVertexLayout->GetInterfacePtr();
}

void Manager::SetVertexShader( Mix::Tool::Win32::Graphics::VertexShader* pVertexShader )
{
	m_DrawState.next.pD3DVertexShader = pVertexShader->GetInterfacePtr();
}

void Manager::SetPixelShader( Mix::Tool::Win32::Graphics::PixelShader* pPixelShader )
{
	m_DrawState.next.pD3DPixelShader = pPixelShader->GetInterfacePtr();
}

void Manager::SetVertexBuffer( Mix::Tool::Win32::Graphics::VertexBuffer* pVertexBuffer )
{
	if( pVertexBuffer != NULL )
	{
		m_DrawState.next.pD3DVertexBuffer = pVertexBuffer->GetInterfacePtr();
		m_DrawState.next.vertexStride = pVertexBuffer->GetStride();
	}
	else
	{
		m_DrawState.next.pD3DVertexBuffer = NULL;
		m_DrawState.next.vertexStride = 0;
	}
}

void Manager::SetIndexBuffer( Mix::Tool::Win32::Graphics::IndexBuffer* pIndexBuffer )
{
	if( pIndexBuffer != NULL )
	{
		m_DrawState.next.pD3DIndexBuffer = pIndexBuffer->GetInterfacePtr();
	}
	else
	{
		m_DrawState.next.pD3DIndexBuffer = NULL;
	}
}

void Manager::SetTexture(	unsigned int stage, 
							D3DTEXTUREFILTERTYPE filter,
							D3DTEXTUREADDRESS address,
							Mix::Tool::Win32::Graphics::Texture* pTexture )
{
	if( Mix::Tool::Win32::Graphics::TEXTURE_STAGE_MAX <= stage )
	{
		return;
	}

	DWORD minFilter;
	DWORD magFilter;
	DWORD mipFilter;
	DWORD anisotropy;

	switch( filter )
	{
	case D3DTEXF_POINT:
		minFilter = D3DTEXF_POINT;
		magFilter = D3DTEXF_POINT;
		mipFilter = D3DTEXF_NONE;
		anisotropy = 1;
		break;

	case D3DTEXF_LINEAR:
		minFilter = D3DTEXF_LINEAR;
		magFilter = D3DTEXF_LINEAR;
		mipFilter = D3DTEXF_LINEAR;
		anisotropy = 1;
		break;

	case D3DTEXF_ANISOTROPIC:
		minFilter = D3DTEXF_ANISOTROPIC;
		magFilter = D3DTEXF_LINEAR;
		mipFilter = D3DTEXF_LINEAR;
		anisotropy = 8;
		break;

	default:
		minFilter = D3DTEXF_POINT;
		magFilter = D3DTEXF_POINT;
		mipFilter = D3DTEXF_NONE;
		anisotropy = 1;
		break;
	}

	SetSamplerState( stage, Manager::SAMPLERSTATE_MINFILTER,  minFilter );
	SetSamplerState( stage, Manager::SAMPLERSTATE_MAGFILTER,  magFilter );
	SetSamplerState( stage, Manager::SAMPLERSTATE_MIPFILTER,  mipFilter );
	SetSamplerState( stage, Manager::SAMPLERSTATE_ANISOTROPY, anisotropy );

	SetSamplerState( stage, Manager::SAMPLERSTATE_ADDRESSU, address );
	SetSamplerState( stage, Manager::SAMPLERSTATE_ADDRESSV, address );
	SetSamplerState( stage, Manager::SAMPLERSTATE_ADDRESSW, D3DTADDRESS_CLAMP );

	m_DrawState.next.pD3DTexture[stage] = ( pTexture != NULL )? pTexture->GetTexturePtr() : NULL;
}

void Manager::DrawIndexedTL( unsigned int vertexStart, unsigned int vertexCount, unsigned int indexStart, unsigned int indexCount )
{
	if( m_pD3DDevice == NULL )
	{
		return;
	}

	if( ( m_DrawState.next.pD3DVertexLayout == NULL ) ||
		( m_DrawState.next.pD3DVertexShader == NULL ) ||
		( m_DrawState.next.pD3DPixelShader == NULL ) ||
		( m_DrawState.next.pD3DVertexBuffer == NULL ) ||
		( m_DrawState.next.pD3DIndexBuffer == NULL ) )
	{
		return;
	}

	FlushDrawState();

	m_pD3DDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, vertexStart, vertexCount, indexStart, ( indexCount / 3 ) );
}

void Manager::DrawLine( const D3DXMATRIX& mat, const std::vector<Mix::Tool::Win32::Graphics::LINE_VERTEX>& vertices )
{
	if( vertices.size() == 0 )
	{
		return;
	}

	SetVertexLayout( m_pLineVL );
	SetVertexBuffer( NULL );
	SetIndexBuffer( NULL );
	SetVertexShader( m_pLineVS );
	SetPixelShader( m_pLinePS );

	SetVertexShaderConstant( 0, mat );

	FlushDrawState();

	m_pD3DDevice->DrawPrimitiveUP(	D3DPT_LINELIST,
									( vertices.size() / 2 ),
									&( vertices[0] ),
									sizeof( Mix::Tool::Win32::Graphics::LINE_VERTEX ) );
}

void Manager::DrawQuad( Mix::Tool::Win32::Graphics::Texture* pTexture )
{
	if( pTexture == NULL )
	{
		return;
	}

	float width = static_cast<float>( m_D3DDevicePresentParam.BackBufferWidth );
	float height = static_cast<float>( m_D3DDevicePresentParam.BackBufferHeight );
	float invHalfWidth = MIX_FLOAT_DIV( 1.0f, ( width * 0.5f ) );
	float invHalfHeight = MIX_FLOAT_DIV( 1.0f, ( height * 0.5f ) );
	float x = ( -0.5f * invHalfWidth ) - 1.0f;
	float y = 1.0f - ( -0.5f * invHalfHeight );
	float xx = ( width - 0.5f ) * invHalfWidth - 1.0f;
	float yy = 1.0f - ( height - 0.5f ) * invHalfHeight;

	Mix::Tool::Win32::Graphics::QUAD_VERTEX vertices[4] =
	{
		QUAD_VERTEX(  x,  y, 0.0f, 0.0f ),
		QUAD_VERTEX( xx,  y, 1.0f, 0.0f ),
		QUAD_VERTEX(  x, yy, 0.0f, 1.0f ),
		QUAD_VERTEX( xx, yy, 1.0f, 1.0f ),
	};

	D3DXVECTOR4 param(	MIX_FLOAT_DIV( 1.0f, static_cast<float>( pTexture->GetWidth() ) ),
						MIX_FLOAT_DIV( 1.0f, static_cast<float>( pTexture->GetHeight() ) ),
						1.0f,
						0.0f );

	SetPixelShaderConstant( 0, param );

	SetTexture( 0, D3DTEXF_POINT, D3DTADDRESS_CLAMP, pTexture );

	SetVertexLayout( m_pQuadVL );
	SetVertexShader( m_pQuadVS );
	SetPixelShader( m_pQuadPS );
	SetVertexBuffer( NULL );
	SetIndexBuffer( NULL );

	FlushDrawState();

	m_pD3DDevice->DrawPrimitiveUP(	D3DPT_TRIANGLESTRIP,
									2,
									&( vertices[0] ),
									sizeof( Mix::Tool::Win32::Graphics::QUAD_VERTEX ) );
}

void Manager::DrawText( const D3DXVECTOR4& color, const POINT& pos, const wchar_t* pText )
{
	if( m_pD3DFont == NULL )
	{
		return;
	}

	RECT rect;

	rect.left = pos.x;
	rect.top = pos.y;
	rect.right = pos.x;
	rect.bottom = pos.y;

	ResetDrawState();

	m_pD3DFont->DrawText( NULL, pText, -1, &rect, DT_LEFT | DT_TOP | DT_NOCLIP | DT_WORDBREAK, Manager::ToColorUI( color ) );
}

void Manager::DrawText( const D3DXVECTOR4& color, const RECT& rect, const wchar_t* pText )
{
	if( m_pD3DFont == NULL )
	{
		return;
	}

	ResetDrawState();

	m_pD3DFont->DrawText( NULL, pText, -1, const_cast<LPRECT>( &rect ), DT_LEFT | DT_TOP | DT_WORDBREAK, Manager::ToColorUI( color ) );
}

int Manager::GetTextHeight( void ) const
{
	D3DXFONT_DESC desc;

	ZeroMemory( &desc, sizeof( desc ) );
	m_pD3DFont->GetDesc( &desc );

	return static_cast<int>( desc.Height );
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Public : Object
////////////////////////////////////////////////////////////////////////////////////////////////////

Mix::Tool::Win32::Object::TYPE Manager::GetType( void ) const
{
	return Mix::Tool::Win32::Object::GRAPHICS__MANAGER;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Private : IDirect3Dインターフェースの作成
////////////////////////////////////////////////////////////////////////////////////////////////////

IDirect3DSwapChain9* Manager::D3D_CreateSwapChain( HWND hWnd, D3DPRESENT_PARAMETERS& d3dPresentParam, bool& bDevice )
{
	if( m_pD3DDevice == NULL )
	{
		return NULL;
	}

	/*
		作成
	*/

	IDirect3DSwapChain9* pD3DSwapChain = NULL;

	if( m_D3DDevicePresentParam.hDeviceWindow == hWnd )
	{
		if( m_pD3DDevice->GetSwapChain( 0, &pD3DSwapChain ) != D3D_OK )
		{
			return NULL;
		}

		::CopyMemory( &d3dPresentParam, &m_D3DDevicePresentParam, sizeof( D3DPRESENT_PARAMETERS ) );

		bDevice = true;
	}
	else
	{
		D3DPRESENT_PARAMETERS tempPresentParam;

		::CopyMemory( &tempPresentParam, &m_D3DDevicePresentParam, sizeof( D3DPRESENT_PARAMETERS ) );

		tempPresentParam.hDeviceWindow = hWnd;
		tempPresentParam.EnableAutoDepthStencil = FALSE;
		tempPresentParam.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
		tempPresentParam.SwapEffect = D3DSWAPEFFECT_COPY;

		if( m_pD3DDevice->CreateAdditionalSwapChain( &tempPresentParam, &pD3DSwapChain ) != D3D_OK )
		{
			return NULL;
		}

		::CopyMemory( &d3dPresentParam, &tempPresentParam, sizeof( D3DPRESENT_PARAMETERS ) );

		bDevice = false;
	}

	return pD3DSwapChain;
}

IDirect3DVertexDeclaration9* Manager::D3D_CreateVertexLayout( const D3DVERTEXELEMENT9* pElements )
{
	if( m_pD3DDevice == NULL )
	{
		return NULL;
	}

	IDirect3DVertexDeclaration9* pD3DVertexLayout = NULL;

	if( m_pD3DDevice->CreateVertexDeclaration( pElements, &pD3DVertexLayout ) != D3D_OK )
	{
		return NULL;
	}

	return pD3DVertexLayout;
}

IDirect3DVertexShader9* Manager::D3D_CreateVertexShader( const void* pFunction )
{
	if( m_pD3DDevice == NULL )
	{
		return NULL;
	}

	IDirect3DVertexShader9* pD3DVertexShader = NULL;

	if( m_pD3DDevice->CreateVertexShader( static_cast<const DWORD*>( pFunction ), &pD3DVertexShader ) != D3D_OK )
	{
		return NULL;
	}

	return pD3DVertexShader;
}

IDirect3DPixelShader9* Manager::D3D_CreatePixelShader( const void* pFunction )
{
	if( m_pD3DDevice == NULL )
	{
		return NULL;
	}

	IDirect3DPixelShader9* pD3DPixelShader = NULL;

	if( m_pD3DDevice->CreatePixelShader( static_cast<const DWORD*>( pFunction ), &pD3DPixelShader ) != D3D_OK )
	{
		return NULL;
	}

	return pD3DPixelShader;
}

IDirect3DVertexBuffer9* Manager::D3D_CreateVertexBuffer( unsigned int size )
{
	if( m_pD3DDevice == NULL )
	{
		return NULL;
	}

	IDirect3DVertexBuffer9* pD3DBuffer = NULL;

	if( m_pD3DDevice->CreateVertexBuffer( size, D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &pD3DBuffer, NULL ) != D3D_OK )
	{
		return NULL;
	}

	return pD3DBuffer;
}

IDirect3DIndexBuffer9* Manager::D3D_CreateIndexBuffer( D3DFORMAT format, unsigned int size )
{
	if( m_pD3DDevice == NULL )
	{
		return NULL;
	}

	IDirect3DIndexBuffer9* pD3DBuffer = NULL;

	if( m_pD3DDevice->CreateIndexBuffer(	size,
										D3DUSAGE_WRITEONLY,
										format,
										D3DPOOL_DEFAULT,
										&pD3DBuffer,
										NULL ) != D3D_OK )
	{
		return NULL;
	}

	return pD3DBuffer;
}

IDirect3DTexture9* Manager::D3D_CreateTexture( const wchar_t* pFileName, const void* pBuffer, unsigned int bufferSize, D3DSURFACE_DESC& d3dSurfaceDesc )
{
	if( ( m_pD3DDevice == NULL ) ||
		( pBuffer == NULL ) ||
		( bufferSize == 0 ) )
	{
		return NULL;
	}

	D3DXIMAGE_INFO texInfo;
	IDirect3DTexture9* pD3DTexture;

	/*
		ディメンジョン数を確認
	*/

	if( ( 4 + sizeof( DDSURFACEDESC2 ) ) <= bufferSize )
	{
		const unsigned char* pAddr = static_cast<const unsigned char*>( pBuffer );
		unsigned int magicNumber = *reinterpret_cast<const unsigned int*>( &( pAddr[0] ) );

		if( magicNumber == 0x20534444/*DDS*/ )
		{
			const DDSURFACEDESC2* pDesc = reinterpret_cast<const DDSURFACEDESC2*>( &( pAddr[4] ) );

			if( pDesc->dwSize == 124 )
			{
				if( ( pDesc->dwFlags & DDSD_DEPTH ) == DDSD_DEPTH )
				{
					//3Dテクスチャはダメ
					return NULL;
				}
			}
		}
	}

	/*
		作成
	*/

	if( D3DXGetImageInfoFromFileInMemory( pBuffer, bufferSize, &texInfo ) != D3D_OK )
	{
		return NULL;
	}

	if( D3DXCreateTextureFromFileInMemoryEx(	m_pD3DDevice,
												pBuffer,
												bufferSize,
												texInfo.Width,
												texInfo.Height,
												texInfo.MipLevels,
												0,
												D3DFMT_UNKNOWN,
												D3DPOOL_DEFAULT,
												D3DX_FILTER_NONE,
												D3DX_FILTER_NONE,
												0,
												NULL,
												NULL,
												&pD3DTexture ) != D3D_OK )
	{
		return NULL;
	}

	if( pD3DTexture->GetLevelDesc( 0, &d3dSurfaceDesc ) != D3D_OK )
	{
		MIX_RELEASE( pD3DTexture );
		return NULL;
	}

	return pD3DTexture;
}

IDirect3DTexture9* Manager::D3D_CreateTargetTexture( D3DSURFACE_DESC& desc )
{
	if( m_pD3DDevice == NULL )
	{
		return NULL;
	}

	IDirect3DTexture9* pD3DTexture = NULL;

	/*
		作成
	*/

	if( m_pD3DDevice->CreateTexture( m_D3DDevicePresentParam.BackBufferWidth, m_D3DDevicePresentParam.BackBufferHeight, 0, D3DUSAGE_RENDERTARGET, desc.Format, D3DPOOL_DEFAULT, &pD3DTexture, NULL ) != D3D_OK )
	{
		return NULL;
	}

	if( pD3DTexture->GetLevelDesc( 0, &desc ) != D3D_OK )
	{
		MIX_RELEASE( pD3DTexture );
		return NULL;
	}

	return pD3DTexture;
}

IDirect3DSurface9* Manager::D3D_CreateTargetSurface( D3DSURFACE_DESC& desc )
{
	if( m_pD3DDevice == NULL )
	{
		return NULL;
	}

	D3DSURFACE_DESC bbDesc;
	IDirect3DSurface9* pD3DSurface = NULL;

	/*
		バックバッファの情報を取得
	*/

	if( m_pD3DBackBuffer->GetDesc( &bbDesc ) != D3D_OK )
	{
		return NULL;
	}

	/*
		作成
	*/

	if( m_pD3DDevice->CreateRenderTarget( bbDesc.Width, bbDesc.Height, bbDesc.Format, bbDesc.MultiSampleType, 0, TRUE, &pD3DSurface, NULL ) != D3D_OK )
	{
		return NULL;
	}

	if( pD3DSurface->GetDesc( &desc ) != D3D_OK )
	{
		MIX_RELEASE( pD3DSurface );
		return NULL;
	}

	return pD3DSurface;
}

IDirect3DCubeTexture9* Manager::D3D_CreateCubeTexture( const void* pBuffer, unsigned int bufferSize, D3DSURFACE_DESC& d3dSurfaceDesc )
{
	if( ( m_pD3DDevice == NULL ) ||
		( pBuffer == NULL ) ||
		( bufferSize == 0 ) )
	{
		return NULL;
	}

	D3DXIMAGE_INFO texInfo;
	IDirect3DCubeTexture9* pD3DTexture;

	/*
		作成
	*/

	if( D3DXGetImageInfoFromFileInMemory( pBuffer, bufferSize, &texInfo ) != D3D_OK )
	{
		return NULL;
	}

	if( texInfo.ResourceType != D3DRTYPE_CUBETEXTURE )
	{
		return NULL;
	}

	if( D3DXCreateCubeTextureFromFileInMemoryEx(	m_pD3DDevice,
													pBuffer,
													bufferSize,
													texInfo.Width,
													texInfo.MipLevels,
													0,
													D3DFMT_UNKNOWN,
													D3DPOOL_DEFAULT,
													D3DX_FILTER_NONE,
													D3DX_FILTER_NONE,
													0,
													NULL,
													NULL,
													&pD3DTexture ) != D3D_OK )
	{
		return NULL;
	}

	if( pD3DTexture->GetLevelDesc( 0, &d3dSurfaceDesc ) != D3D_OK )
	{
		MIX_RELEASE( pD3DTexture );
	}

	return pD3DTexture;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Private : リソースの作成
////////////////////////////////////////////////////////////////////////////////////////////////////

Mix::Tool::Win32::Graphics::SwapChain* Manager::GetFirstSwapChain( void )
{
	std::list<Mix::Tool::Win32::Graphics::DeviceObject*>::iterator it_begin = m_DeviceObjectList.begin();
	std::list<Mix::Tool::Win32::Graphics::DeviceObject*>::iterator it_end = m_DeviceObjectList.end();
	std::list<Mix::Tool::Win32::Graphics::DeviceObject*>::iterator it;

	for( it = it_begin; it != it_end; ++it )
	{
		if( ( *it )->GetType() == Mix::Tool::Win32::Object::GRAPHICS__SWAPCHAIN )
		{
			return static_cast<Mix::Tool::Win32::Graphics::SwapChain*>( ( *it ) );
		}
	}

	return NULL;
}

Mix::Tool::Win32::Graphics::SwapChain* Manager::CreateSwapChain( HWND hWnd )
{
	Mix::Tool::Win32::Graphics::SwapChain* pSwapChain = NULL;

	/*
		スワップチェーンを作成
	*/

	pSwapChain = Mix::Tool::Win32::Graphics::SwapChain::CreateInstance( hWnd );
	if( pSwapChain != NULL )
	{
		pSwapChain->OnValidate();
	}
	else
	{
		return NULL;
	}

	/*
		デバイスが作成されていなかったら、作成要求を出す
	*/

	if( m_pD3DDevice == NULL )
	{
		m_ActionType = Manager::ACTION_CREATE_DEVICE;
	}

	return pSwapChain;
}

Mix::Tool::Win32::Graphics::VertexLayout* Manager::CreateVertexLayout( const D3DVERTEXELEMENT9* pElements )
{
	if( pElements == NULL )
	{
		return NULL;
	}

	/*
		エレメント数を数える
	*/

	unsigned int stride = 0;
	unsigned int elementCount = 0;
	const D3DVERTEXELEMENT9* pTemp = &( pElements[0] );

	for( ;; )
	{
		if( ( pTemp->Stream == 0xFF ) &&
			( pTemp->Offset == 0 ) &&
			( pTemp->Type == D3DDECLTYPE_UNUSED ) &&
			( pTemp->Method == 0 ) &&
			( pTemp->Usage == 0 ) &&
			( pTemp->UsageIndex == 0 ) )
		{
			break;
		}

		unsigned int veSize = Manager::D3D_VE_FORMAT_SIZE_TABLE[pTemp->Type];
		if( veSize == 0xFFFFFFFF )
		{
			return false;
		}

		stride += veSize;
		elementCount++;

		pTemp++;
	}

	if( elementCount == 0 )
	{
		return NULL;
	}

	/*
		作成
	*/

	Mix::Tool::Win32::Graphics::VertexLayout* pVertexLayout = NULL;

	pVertexLayout = Mix::Tool::Win32::Graphics::VertexLayout::CreateInstance( pElements, stride );
	if( pVertexLayout != NULL )
	{
		pVertexLayout->OnValidate();
	}
	else
	{
		return NULL;
	}

	return pVertexLayout;
}

Mix::Tool::Win32::Graphics::VertexShader* Manager::CreateVertexShader( const void* pBuffer, unsigned int bufferSize )
{
	if( ( pBuffer == NULL ) ||
		( bufferSize == 0 ) )
	{
		return NULL;
	}

	Mix::Tool::Win32::Graphics::VertexShader* pVertexShader = NULL;

	pVertexShader = Mix::Tool::Win32::Graphics::VertexShader::CreateInstance( pBuffer, bufferSize );
	if( pVertexShader != NULL )
	{
		pVertexShader->OnValidate();
	}
	else
	{
		return NULL;
	}

	return pVertexShader;
}

Mix::Tool::Win32::Graphics::PixelShader* Manager::CreatePixelShader( const void* pBuffer, unsigned int bufferSize )
{
	if( ( pBuffer == NULL ) ||
		( bufferSize == 0 ) )
	{
		return NULL;
	}

	Mix::Tool::Win32::Graphics::PixelShader* pPixelShader = NULL;

	pPixelShader = Mix::Tool::Win32::Graphics::PixelShader::CreateInstance( pBuffer, bufferSize );
	if( pPixelShader != NULL )
	{
		pPixelShader->OnValidate();
	}
	else
	{
		return NULL;
	}

	return pPixelShader;
}

Mix::Tool::Win32::Graphics::VertexBuffer* Manager::CreateVertexBuffer( unsigned int stride, unsigned int count, const void* initialData )
{
	unsigned int size = stride * count;
	Mix::Tool::Win32::Graphics::VertexBuffer* pVertexBuffer = NULL;

	pVertexBuffer = Mix::Tool::Win32::Graphics::VertexBuffer::CreateInstance( stride, count, initialData );
	if( pVertexBuffer != NULL )
	{
		pVertexBuffer->OnValidate();
	}
	else
	{
		return NULL;
	}

	return pVertexBuffer;
}

Mix::Tool::Win32::Graphics::IndexBuffer* Manager::CreateIndexBuffer( Mix::Tool::Win32::Graphics::INDEX_TYPE type, unsigned int count, const void* initialData )
{
	D3DFORMAT format = Manager::INDEX_FORMAT_TABLE[type];
	unsigned int size = Manager::INDEX_STRIDE_TABLE[type] * count;
	Mix::Tool::Win32::Graphics::IndexBuffer* pIndexBuffer = NULL;

	pIndexBuffer = Mix::Tool::Win32::Graphics::IndexBuffer::CreateInstance( format, count, size, initialData );
	if( pIndexBuffer != NULL )
	{
		pIndexBuffer->OnValidate();
	}
	else
	{
		return NULL;
	}

	return pIndexBuffer;
}

Mix::Tool::Win32::Graphics::FileTexture* Manager::CreateTexture( const wchar_t* pFileName )
{
	if( ( pFileName == NULL ) ||
		( ::wcslen( pFileName ) == 0 ) )
	{
		return false;
	}

	/*
		テクスチャマップから探してみる
	*/

	Manager::TextureMap::iterator it = m_TextureMap.find( pFileName );
	if( it != m_TextureMap.end() )
	{
		MIX_ADD_REF( it->second );
		return it->second;
	}

	/*
		新規に作成
	*/

	Mix::Tool::Win32::Graphics::FileTexture* pTexture = NULL;
	Mix::Tool::Win32::File::InputStream input;
	unsigned char* pDst;

	/*
		インターフェースを作成
	*/

	pTexture = Mix::Tool::Win32::Graphics::FileTexture::CreateInstance( pFileName );
	if( pTexture == NULL )
	{
		return NULL;
	}

	/*
		バッファにファイルを読み込む
	*/

	if( input.Open( pFileName ) == false )
	{
		MIX_RELEASE( pTexture );
		return false;
	}

	pDst = static_cast<unsigned char*>( pTexture->AllocateBuffer( input.GetSize() ) );
	if( pDst == NULL )
	{
		MIX_RELEASE( pTexture );
		input.Close();
		return false;
	}

	if( input.Read( pDst, pTexture->GetBufferSize() ) == false )
	{
		MIX_RELEASE( pTexture );
		input.Close();
		return false;
	}

	input.Close();

	/*
		インターフェースを有効にする
	*/

	pTexture->OnValidate();

	/*
		テクスチャマップに追加
	*/

	m_TextureMap.insert( std::pair<std::wstring, Mix::Tool::Win32::Graphics::FileTexture*>( pFileName, pTexture ) );

	return pTexture;
}

Mix::Tool::Win32::Graphics::FileTexture* Manager::CreateTexture( const wchar_t* pFileName, const void* pBuffer, unsigned int bufferSize )
{
	if( ( pFileName == NULL ) ||
		( ::wcslen( pFileName ) == 0 ) ||
		( pBuffer == NULL ) ||
		( bufferSize == 0 ) )
	{
		return false;
	}

	/*
		テクスチャマップから探してみる
	*/

	Manager::TextureMap::iterator it = m_TextureMap.find( pFileName );
	if( it != m_TextureMap.end() )
	{
		MIX_ADD_REF( it->second );
		return it->second;
	}

	/*
		新規に作成
	*/

	Mix::Tool::Win32::Graphics::FileTexture* pTexture = NULL;
	unsigned char* pDst = NULL;

	/*
		インターフェースを作成
	*/

	pTexture = Mix::Tool::Win32::Graphics::FileTexture::CreateInstance( pFileName );
	if( pTexture == NULL )
	{
		return NULL;
	}

	/*
		バッファをコピー
	*/

	pDst = static_cast<unsigned char*>( pTexture->AllocateBuffer( bufferSize ) );
	if( pDst != NULL )
	{
		::CopyMemory( pDst, pBuffer, bufferSize );
	}
	else
	{
		MIX_RELEASE( pTexture );
		return NULL;
	}

	/*
		インターフェースを有効にする
	*/

	pTexture->OnValidate();

	/*
		テクスチャマップに追加
	*/

	m_TextureMap.insert( std::pair<std::wstring, Mix::Tool::Win32::Graphics::FileTexture*>( pFileName, pTexture ) );

	return pTexture;
}

void Manager::RemoveTexture( const wchar_t* pFileName )
{
	Manager::TextureMap::iterator it = m_TextureMap.find( pFileName );
	if( it != m_TextureMap.end() )
	{
		if( it->second->GetRefCount() == 0 )
		{
			m_TextureMap.erase( it );
		}
	}
}

bool Manager::CheckTargetTextureFormat( D3DFORMAT d3dFormat )
{
	D3DDISPLAYMODE d3dDispMode;

	if( m_pD3D->GetAdapterDisplayMode( 0, &d3dDispMode ) != D3D_OK )
	{
		return false;
	}

	return ( m_pD3D->CheckDeviceFormat( 0, D3DDEVTYPE_HAL, d3dDispMode.Format, D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, d3dFormat ) == D3D_OK );
}

Mix::Tool::Win32::Graphics::TargetTexture* Manager::CreateTargetTexture( D3DFORMAT d3dFormat )
{
	Mix::Tool::Win32::Graphics::TargetTexture* pTexture = NULL;

	/*
		インターフェースを作成
	*/

	pTexture = TargetTextureD::CreateInstance( d3dFormat );
	if( pTexture == NULL )
	{
		return NULL;
	}

	/*
		有効にする
	*/

	pTexture->OnValidate();

	return pTexture;
}

Mix::Tool::Win32::Graphics::TargetTexture* Manager::CreateLockableTargetTexture( void )
{
	Mix::Tool::Win32::Graphics::TargetTexture* pTexture = NULL;

	/*
		インターフェースを作成
	*/

	pTexture = TargetTextureL::CreateInstance();
	if( pTexture == NULL )
	{
		return NULL;
	}

	/*
		有効にする
	*/

	pTexture->OnValidate();

	return pTexture;
}

Mix::Tool::Win32::Graphics::CubeTexture* Manager::CreateCubeTexture( const wchar_t* pFileName )
{
	if( ( pFileName == NULL ) ||
		( ::wcslen( pFileName ) == 0 ) )
	{
		return false;
	}

	/*
		新規に作成
	*/

	Mix::Tool::Win32::Graphics::CubeTexture* pTexture = NULL;
	Mix::Tool::Win32::File::InputStream input;
	unsigned char* pDst;

	/*
		インターフェースを作成
	*/

	pTexture = Mix::Tool::Win32::Graphics::CubeTexture::CreateInstance();
	if( pTexture == NULL )
	{
		return NULL;
	}

	/*
		バッファにファイルを読み込む
	*/

	if( input.Open( pFileName ) == false )
	{
		MIX_RELEASE( pTexture );
		return false;
	}

	pDst = static_cast<unsigned char*>( pTexture->AllocateBuffer( input.GetSize() ) );
	if( pDst == NULL )
	{
		MIX_RELEASE( pTexture );
		input.Close();
		return false;
	}

	if( input.Read( pDst, pTexture->GetBufferSize() ) == false )
	{
		MIX_RELEASE( pTexture );
		input.Close();
		return false;
	}

	input.Close();

	/*
		インターフェースを有効にする
	*/

	pTexture->OnValidate();

	return pTexture;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Private : マテリアルエフェクトパッケージ
////////////////////////////////////////////////////////////////////////////////////////////////////

void Manager::MEP_Release( void )
{
	if( m_MSVertexShaderMap.size() > 0 )
	{
		for( Manager::MSVertexShaderMap::iterator it = m_MSVertexShaderMap.begin(); it != m_MSVertexShaderMap.end(); ++it )
		{
			MIX_RELEASE( it->second.pCommonVL );
			MIX_RELEASE( it->second.pColorVS );
			MIX_RELEASE( it->second.pMaskVS );
			MIX_RELEASE( it->second.pSelectVS );
		}

		m_MSVertexShaderMap.clear();
	}

	if( m_MSPixelShaderMap.size() > 0 )
	{
		for( Manager::MSPixelShaderMap::iterator it = m_MSPixelShaderMap.begin(); it != m_MSPixelShaderMap.end(); ++it )
		{
			MIX_RELEASE( it->second.pColorPS );
			MIX_RELEASE( it->second.pMaskPS );
			MIX_RELEASE( it->second.pSelectPS );
		}

		m_MSPixelShaderMap.clear();
	}
}

int Manager::MEP_Load( const wchar_t* pFileName )
{
	Mix::Tool::Win32::File::InputStream input;

	Manager::MEP_FILE_HEADER fileHeader;
	Manager::MEP_DATA_HEADER dataHeader;

	/*
		ファイルを開く
	*/

	if( input.Open( pFileName ) == false )
	{
		return 0;
	}

	/*
		ファイルヘッダ
	*/

	if( input.Read( &fileHeader, sizeof( fileHeader ) ) == false )
	{
		input.Close();
		return -1;
	}

	if( fileHeader.magicNumber != Manager::MEP_MAGIC_NUMBER )
	{
		input.Close();
		return -1;
	}

	/*
		データヘッダー
	*/

	if( fileHeader.version == MEP_VERSION )
	{
		if( input.Read( &dataHeader, sizeof( dataHeader ) ) == false )
		{
			input.Close();
			return -1;
		}
	}
	else if( fileHeader.version == MEP_VERSION_OLD )
	{
		//レンダラータイプ
		dataHeader.rendererType = Manager::MEP_RT_STANDARD;

		//プロセスフラグ
		if( input.Read( &( dataHeader.processFlags ), sizeof( dataHeader.processFlags ) ) == false )
		{
			input.Close();
			return -1;
		}

		//バーテックスシェーダーの数
		if( input.Read( &( dataHeader.vertexShaderNum ), sizeof( dataHeader.vertexShaderNum ) ) == false )
		{
			input.Close();
			return -1;
		}

		//ピクセルシェーダーの数
		if( input.Read( &( dataHeader.pixelShaderNum ), sizeof( dataHeader.pixelShaderNum ) ) == false )
		{
			input.Close();
			return -1;
		}
	}
	else
	{
		//直前のバージョンより古いものは失敗
		input.Close();
		return -1;
	}

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

	{
		const unsigned int VLE_STRUCT_SIZE = sizeof( Mix::Tool::Win32::Graphics::VERTEX_ELEMENT );

		for( unsigned int i = 0; i < dataHeader.vertexShaderNum; i++ )
		{
			Manager::MEP_VS_HEADER vsDesc;

			if( input.Read( &vsDesc, sizeof( vsDesc ) ) == false )
			{
				input.Close();
				return -1;
			}

			unsigned int skipSize =	vsDesc.buffSize[Manager::MEP_MTL_COLOR] +
									vsDesc.buffSize[Manager::MEP_MTL_MASK] +
									vsDesc.buffSize[Manager::MEP_MTL_SHADOW] +
									( VLE_STRUCT_SIZE * vsDesc.elementNum );


			input.Skip( skipSize );

			m_MSVertexShaderMap.insert( std::pair<unsigned int, Manager::MS_VERTEX_SHADER>( vsDesc.id, Manager::MS_VERTEX_SHADER( Manager::MS_STATE_EXIST ) ) );

			LogPrint( LT_INFO, L"  VS[0x%08x] : Color[○] Refract[%s] Shadow[%s]",
				vsDesc.id,
				( vsDesc.buffSize[Manager::MEP_MTL_MASK] > 0 )? L"○" : L"×",
				( vsDesc.buffSize[Manager::MEP_MTL_SHADOW] > 0 )? L"○" : L"×" );
		}
	}

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

	{
		for( unsigned int i = 0; i < dataHeader.pixelShaderNum; i++ )
		{
			Manager::MEP_PS_HEADER psDesc;

			if( input.Read( &psDesc, sizeof( psDesc ) ) == false )
			{
				input.Close();
				return -1;
			}

			unsigned int skipSize = psDesc.buffSize[Manager::MEP_MTL_COLOR] +
									psDesc.buffSize[Manager::MEP_MTL_MASK] +
									psDesc.buffSize[Manager::MEP_MTL_SHADOW];

			input.Skip( skipSize );

			m_MSPixelShaderMap.insert( std::pair<unsigned int, Manager::MS_PIXEL_SHADER>( psDesc.id, Manager::MS_PIXEL_SHADER( Manager::MS_STATE_EXIST ) ) );

			LogPrint( LT_INFO, L"  PS[0x%08x] : Color[○] Refract[%s] Shadow[%s]",
				psDesc.id,
				( psDesc.buffSize[Manager::MEP_MTL_MASK] > 0 )? L"○" : L"×",
				( psDesc.buffSize[Manager::MEP_MTL_SHADOW] > 0 )? L"○" : L"×" );
		}
	}

	/*
		ファイルを閉じる
	*/

	input.Close();

	return 1;
}

bool Manager::MEP_CreateVertexShader(	unsigned int compileFlags,
										unsigned int& id, Mix::Tool::Win32::Graphics::VertexLayout** ppCommonVL,
										Mix::Tool::Win32::Graphics::VertexShader** ppColorVS,
										Mix::Tool::Win32::Graphics::VertexShader** ppMaskVS,
										Mix::Tool::Win32::Graphics::VertexShader** ppSelectVS )
{
	MIX_ASSERT( MIX_TEST_BIT( compileFlags, ( MCF_SIMPLE_VERTEX | MCF_BLEND_VERTEX ) ) != ( MCF_SIMPLE_VERTEX | MCF_BLEND_VERTEX ) );
	MIX_ASSERT( MIX_TEST_BIT( compileFlags, ( MCF_SIMPLE_VERTEX | MCF_BLEND_VERTEX ) ) != 0 );

	unsigned int tempID;
	Manager::MSVertexShaderMap::iterator it;
	bool bNew;

	/*
		識別子を作成
	*/

	tempID = MIX_TEST_BIT( compileFlags, MCF_ID_VERTEX_SHADER_MASK );

	/*
		イテレータを取得
	*/

	it = m_MSVertexShaderMap.find( tempID );

	if( it == m_MSVertexShaderMap.end() )
	{
		m_MSVertexShaderMap.insert( std::pair<unsigned int, Manager::MS_VERTEX_SHADER>( tempID, Manager::MS_VERTEX_SHADER( Manager::MS_STATE_EDITING ) ) );

		it = m_MSVertexShaderMap.find( tempID );
		if( it == m_MSVertexShaderMap.end() )
		{
			return false;
		}
	}

	bNew = ( it->second.pCommonVL == NULL );

	/*
		バーテックスレイアウトインターフェースを取得
	*/

	if( bNew == true )
	{
		std::vector<D3DVERTEXELEMENT9> elementList;

		//エレメントリストを作成
		CreateVertexElementList( compileFlags, elementList );

		//バーテックスレイアウトを作成
		it->second.pCommonVL = CreateVertexLayout( &( elementList[0] ) );
		if( it->second.pCommonVL == NULL )
		{
			return false;
		}
	}

	/*
		バーテックスシェーダーインターフェースを取得
	*/

	if( bNew == true )
	{
		std::vector<Manager::SHADER_MACRO> macroList;
		std::vector<unsigned char> buffer;

		//コンパイル用マクロリストを作成
		CreateCompileMacroList( compileFlags, false, macroList );

		//コンパイル( カラーモデル )
		if( CompileShader( Manager::SHADER_PROFILE_VS_3, &( macroList[0] ), Manager::MEP_MTL_COLOR, buffer ) == true )
		{
			it->second.pColorVS = CreateVertexShader( &( buffer[0] ), buffer.size() );
			if( it->second.pColorVS == NULL )
			{
				MIX_RELEASE( it->second.pCommonVL );
				return false;
			}
		}
		else
		{
			MIX_RELEASE( it->second.pCommonVL );
			return false;
		}

		//コンパイル( マスクモデル )
		if( CompileShader( Manager::SHADER_PROFILE_VS_3, &( macroList[0] ), Manager::MEP_MTL_MASK, buffer ) == true )
		{
			it->second.pMaskVS = CreateVertexShader( &( buffer[0] ), buffer.size() );
			if( it->second.pMaskVS == NULL )
			{
				MIX_RELEASE( it->second.pColorVS );
				MIX_RELEASE( it->second.pCommonVL );
				return false;
			}
		}
		else
		{
			MIX_RELEASE( it->second.pColorVS );
			MIX_RELEASE( it->second.pCommonVL );
			return false;
		}

		//コンパイル( セレクトモデル )
		if( CompileShader( "Material(Standard)",
			Manager::SHADER_PROFILE_VS_3,
			&( macroList[0] ),
			reinterpret_cast<const char*>( &( MANAGER_MATERIAL_STANDARD_VS[0] ) ),
			sizeof( MANAGER_MATERIAL_STANDARD_VS ),
			"mainSelectModel",
			buffer ) == true )
		{
			it->second.pSelectVS = CreateVertexShader( &( buffer[0] ), buffer.size() );
			if( it->second.pSelectVS == NULL )
			{
				MIX_RELEASE( it->second.pMaskVS );
				MIX_RELEASE( it->second.pColorVS );
				MIX_RELEASE( it->second.pCommonVL );
				return false;
			}
		}
		else
		{
			MIX_RELEASE( it->second.pMaskVS );
			MIX_RELEASE( it->second.pColorVS );
			MIX_RELEASE( it->second.pCommonVL );
			return false;
		}
	}

	/*
		譲渡
	*/

	id = tempID;

	MIX_ADD_REF( it->second.pCommonVL );
	( *ppCommonVL ) = it->second.pCommonVL;

	MIX_ADD_REF( it->second.pColorVS );
	( *ppColorVS ) = it->second.pColorVS;

	MIX_ADD_REF( it->second.pMaskVS );
	( *ppMaskVS ) = it->second.pMaskVS;

	MIX_ADD_REF( it->second.pSelectVS );
	( *ppSelectVS ) = it->second.pSelectVS;

	return true;
}

bool Manager::MEP_CreatePixelShader(	unsigned int compileFlags,
										unsigned int& id,
										Mix::Tool::Win32::Graphics::PixelShader** ppColorPS,
										Mix::Tool::Win32::Graphics::PixelShader** ppMaskPS,
										Mix::Tool::Win32::Graphics::PixelShader** ppSelectPS )
{
	unsigned int tempID;
	Manager::MSPixelShaderMap::iterator it;
	bool bNew;

	/*
		識別子を作成
	*/

	tempID = MIX_TEST_BIT( compileFlags, MCF_ID_PIXEL_SHADER_MASK );

	/*
		イテレータを取得
	*/

	it = m_MSPixelShaderMap.find( tempID );
	if( it == m_MSPixelShaderMap.end() )
	{
		m_MSPixelShaderMap.insert( std::pair<unsigned int, Manager::MS_PIXEL_SHADER>( tempID, Manager::MS_PIXEL_SHADER( Manager::MS_STATE_EDITING ) ) );

		it = m_MSPixelShaderMap.find( tempID );
		if( it == m_MSPixelShaderMap.end() )
		{
			return false;
		}
	}

	bNew = ( it->second.pColorPS == NULL );

	/*
		インターフェースを取得
	*/

	if( bNew == true )
	{
		std::vector<Manager::SHADER_MACRO> macroList;
		std::vector<unsigned char> buffer;

		//コンパイル用マクロリストを作成
		CreateCompileMacroList( compileFlags, false, macroList );

		//コンパイル( カラーモデル )
		if( CompileShader( Manager::SHADER_PROFILE_PS_3, &( macroList[0] ), Manager::MEP_MTL_COLOR, buffer ) == true )
		{
			it->second.pColorPS = CreatePixelShader( &( buffer[0] ), buffer.size() );
			if( it->second.pColorPS == NULL )
			{
				return false;
			}
		}
		else
		{
			return false;
		}

		//コンパイル( マスクモデル )
		if( CompileShader( Manager::SHADER_PROFILE_PS_3, &( macroList[0] ), Manager::MEP_MTL_MASK, buffer ) == true )
		{
			it->second.pMaskPS = CreatePixelShader( &( buffer[0] ), buffer.size() );
			if( it->second.pMaskPS == NULL )
			{
				MIX_RELEASE( it->second.pColorPS );
				return false;
			}
		}
		else
		{
			MIX_RELEASE( it->second.pColorPS );
			return false;
		}

		//コンパイル( セレクトモデル )
		if( CompileShader( "Material(Standard)",
			Manager::SHADER_PROFILE_PS_3,
			&( macroList[0] ),
			reinterpret_cast<const char*>( &( MANAGER_MATERIAL_STANDARD_PS[0] ) ),
			sizeof( MANAGER_MATERIAL_STANDARD_PS ),
			"mainSelectModel",
			buffer ) == true )
		{
			it->second.pSelectPS = CreatePixelShader( &( buffer[0] ), buffer.size() );
			if( it->second.pSelectPS == NULL )
			{
				MIX_RELEASE( it->second.pMaskPS );
				MIX_RELEASE( it->second.pColorPS );
				return false;
			}
		}
		else
		{
			MIX_RELEASE( it->second.pMaskPS );
			MIX_RELEASE( it->second.pColorPS );
			return false;
		}
	}

	/*
		譲渡
	*/

	id = tempID;

	MIX_ADD_REF( it->second.pColorPS );
	( *ppColorPS ) = it->second.pColorPS;

	MIX_ADD_REF( it->second.pMaskPS );
	( *ppMaskPS ) = it->second.pMaskPS;

	MIX_ADD_REF( it->second.pSelectPS );
	( *ppSelectPS ) = it->second.pSelectPS;

	return true;
}

void Manager::MEP_RegisterVertexShader( unsigned int id )
{
	Manager::MSVertexShaderMap::iterator it = m_MSVertexShaderMap.find( id );
	MIX_ASSERT( it != m_MSVertexShaderMap.end() );

	if( it->second.state == Manager::MS_STATE_EDITING )
	{
		it->second.state = Manager::MS_STATE_NEW;
	}
}

void Manager::MEP_RegisterPixelShader( unsigned int id )
{
	Manager::MSPixelShaderMap::iterator it = m_MSPixelShaderMap.find( id );
	MIX_ASSERT( it != m_MSPixelShaderMap.end() );

	if( it->second.state == Manager::MS_STATE_EDITING )
	{
		it->second.state = Manager::MS_STATE_NEW;
	}
}

bool Manager::MEP_CreateWorkFromFile(	const wchar_t* pFileName,
										std::map<unsigned int, Manager::MEP_MTL_VS_WORK>& vsMap,
										std::map<unsigned int, Manager::MEP_MTL_PS_WORK>& psMap )
{
	Mix::Tool::Win32::File::InputStream input;

	/*
		クリア
	*/

	vsMap.clear();
	psMap.clear();

	/*
		読み込む
	*/

	if( input.Open( pFileName ) == true )
	{
		Manager::MEP_FILE_HEADER fileHeader;
		Manager::MEP_DATA_HEADER dataHeader;

		// ファイルヘッダ

		if( input.Read( &fileHeader, sizeof( fileHeader ) ) == false )
		{
			input.Close();
			return false;
		}

		if( fileHeader.magicNumber != Manager::MEP_MAGIC_NUMBER )
		{
			input.Close();
			return false;
		}

		// データヘッダ

		if( fileHeader.version == MEP_VERSION )
		{
			// 最新バージョン
			if( input.Read( &dataHeader, sizeof( dataHeader ) ) == false )
			{
				input.Close();
				return false;
			}
		}
		else if( fileHeader.version == MEP_VERSION_OLD )
		{
			// 旧バージョン
			dataHeader.rendererType = Manager::MEP_RT_STANDARD;

			if( input.Read( &( dataHeader.processFlags ), sizeof( dataHeader.processFlags ) ) == false )
			{
				input.Close();
				return false;
			}

			if( input.Read( &( dataHeader.vertexShaderNum ), sizeof( dataHeader.vertexShaderNum ) ) == false )
			{
				input.Close();
				return false;
			}

			if( input.Read( &( dataHeader.pixelShaderNum ), sizeof( dataHeader.pixelShaderNum ) ) == false )
			{
				input.Close();
				return false;
			}
		}
		else
		{
			input.Close();
			return false;
		}

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

		{
			const unsigned int VLE_STRUCT_SIZE = sizeof( Mix::Tool::Win32::Graphics::VERTEX_ELEMENT );

			for( unsigned int i = 0; i < dataHeader.vertexShaderNum; i++ )
			{
				Manager::MEP_VS_HEADER vsDesc;

				if( input.Read( &vsDesc, sizeof( vsDesc ) ) == false )
				{
					input.Close();
					return false;
				}

				std::map<unsigned int, Manager::MEP_MTL_VS_WORK>::iterator it = vsMap.find( vsDesc.id );
				if( it == vsMap.end() )
				{
					vsMap.insert( std::pair<unsigned int, Manager::MEP_MTL_VS_WORK>( vsDesc.id, Manager::MEP_MTL_VS_WORK() ) );
					it = vsMap.find( vsDesc.id );
					if( it == vsMap.end() )
					{
						input.Close();
						return false;
					}
				}

				unsigned int skipSize = vsDesc.buffSize[Manager::MEP_MTL_COLOR] +
										vsDesc.buffSize[Manager::MEP_MTL_MASK] +
										vsDesc.buffSize[Manager::MEP_MTL_SHADOW] +
										VLE_STRUCT_SIZE * vsDesc.elementNum;

				input.Skip( skipSize );
			}
		}

		// ピクセルシェーダー

		{
			for( unsigned int i = 0; i < dataHeader.pixelShaderNum; i++ )
			{
				Manager::MEP_PS_HEADER psDesc;

				if( input.Read( &psDesc, sizeof( psDesc ) ) == false )
				{
					input.Close();
					return false;
				}

				std::map<unsigned int, Manager::MEP_MTL_PS_WORK>::iterator it = psMap.find( psDesc.id );
				if( it == psMap.end() )
				{
					psMap.insert( std::pair<unsigned int, Manager::MEP_MTL_PS_WORK>( psDesc.id, Manager::MEP_MTL_PS_WORK() ) );

					it = psMap.find( psDesc.id );
					if( it == psMap.end() )
					{
						input.Close();
						return false;
					}
				}


				unsigned int skipSize = psDesc.buffSize[Manager::MEP_MTL_COLOR] +
										psDesc.buffSize[Manager::MEP_MTL_MASK] +
										psDesc.buffSize[Manager::MEP_MTL_SHADOW];

				input.Skip( skipSize );
			}
		}

		input.Close();
	}

	return true;
}

bool Manager::MEP_CreateWorkFromDirectory(	const wchar_t* pDirPath,
											std::map<unsigned int, Manager::MEP_MTL_VS_WORK>& vsMap,
											std::map<unsigned int, Manager::MEP_MTL_PS_WORK>& psMap )
{
	std::wstring searchPath;
	HANDLE hFind = INVALID_HANDLE_VALUE;
	WIN32_FIND_DATA wfd;

	/*
		検索パスの作成
	*/

	if( Mix::Tool::Win32::Path::Combine( pDirPath, L"*.*", searchPath ) == false )
	{
		LogPrint( LT_ERROR, L"    検索パスの作成に失敗 : ParentDirectory[%s]", pDirPath );
		return false;
	}

	/*
		検索
	*/

	::ZeroMemory( &wfd, sizeof( wfd ) );

	hFind = ::FindFirstFile( searchPath.c_str(), &wfd );
	if( hFind != INVALID_HANDLE_VALUE )
	{
		do
		{
			if( MIX_TEST_BIT( wfd.dwFileAttributes, FILE_ATTRIBUTE_DIRECTORY ) == FILE_ATTRIBUTE_DIRECTORY )
			{
				if( ( ::wcscmp( wfd.cFileName, L"." ) != 0 ) &&
					( ::wcscmp( wfd.cFileName, L".." ) != 0 ) )
				{
					std::wstring dirPath;

					if( Mix::Tool::Win32::Path::Combine( pDirPath, wfd.cFileName, dirPath ) == true )
					{
						if( MEP_CreateWorkFromDirectory( dirPath.c_str(), vsMap, psMap ) == false )
						{
							::FindClose( hFind );
							return false;
						}
					}
					else
					{
						LogPrint( LT_ERROR, L"    ディレクトリパスの作成に失敗 : ParentDirectory[%s] ChildDirectory[%s]", pDirPath, wfd.cFileName );
						::FindClose( hFind );
						return false;
					}
				}
			}
			else
			{
				size_t len = ::wcslen( wfd.cFileName );

				if( len >= 8 )
				{
					const wchar_t* pExt = &( wfd.cFileName[len - 4] );

					if( ::wcscmp( pExt, L".mtl" ) == 0 )
					{
						std::wstring filePath;

						if( Mix::Tool::Win32::Path::Combine( pDirPath, wfd.cFileName, filePath ) == true )
						{
							MEP_WorkFromMTL( filePath.c_str(), vsMap, psMap );
						}
					}
					else if( ::wcscmp( pExt, L".mam" ) == 0 )
					{
						std::wstring filePath;

						if( Mix::Tool::Win32::Path::Combine( pDirPath, wfd.cFileName, filePath ) == true )
						{
							MEP_WorkFromMAM( filePath.c_str(), vsMap, psMap );
						}
					}
					else if( ::wcscmp( pExt, L".mtm" ) == 0 )
					{
						std::wstring filePath;

						if( Mix::Tool::Win32::Path::Combine( pDirPath, wfd.cFileName, filePath ) == true )
						{
							MEP_WorkFromMTM( filePath.c_str(), vsMap, psMap );
						}
					}
				}
			}
		}
		while( ::FindNextFile( hFind, &wfd ) == TRUE );

		::FindClose( hFind );
	}

	return true;
}

bool Manager::MEP_WorkFromMTL(	const wchar_t* pFilePath, 
								std::map<unsigned int, Manager::MEP_MTL_VS_WORK>& vsMap,
								std::map<unsigned int, Manager::MEP_MTL_PS_WORK>& psMap )
{
	Mix::Tool::Win32::File::InputStream input;
	Mix::Tool::Win32::File::TemporaryStream output;
	unsigned int magicNumber;
	unsigned int version;

	/*
		ファイルを開く
	*/

	if( input.Open( pFilePath ) == false )
	{
		LogPrint( LT_ERROR, L"    MTL : ファイルが開けません : FilePath[%s]", pFilePath );
		return false;
	}

	if( output.Open( pFilePath ) == false )
	{
		LogPrint( LT_ERROR, L"    MTL : システムメモリが不足しています : FilePath[%s]", pFilePath );
		return false;
	}

	/*
		マジックナンバー
	*/

	if( input.Read( &magicNumber, sizeof( magicNumber ) ) == false )
	{
		LogPrint( LT_ERROR, L"    MTL : 読み込みに失敗しました : FilePath[%s]", pFilePath );
		return false;
	}

	if( magicNumber != Material::MTL_MAGIC_NUMBER )
	{
		LogPrint( LT_ERROR, L"    MTL : ファイルフォーマットが不正です : FilePath[%s]", pFilePath );
		return false;
	}

	// output : マジックナンバー
	if( output.Write( &magicNumber, sizeof( magicNumber ) ) == false )
	{
		LogPrint( LT_ERROR, L"    MTL : システムメモリが不足しています : FilePath[%s]", pFilePath );
		return false;
	}

	/*
		ワークマップを作成
	*/

	if( MEP_WorkFromMTL( L"MTL", pFilePath, input, output, vsMap, psMap, &version ) == false )
	{
		return false;
	}

	/*
		ファイルを閉じる
	*/

	if( MEP_WorkSkip( L"MTL", pFilePath, input.GetSize() - input.GetPosition(), input, output ) == false )
	{
		return false;
	}

	input.Close();

	if( output.Close() == false )
	{
		LogPrint( LT_ERROR, L"    MTL : クローズに失敗しました : FilePath[%s]", pFilePath );
		return false;
	}

	/*
		ログ
	*/

	LogPrint( LT_INFO, L"    MTL : Version[0x%08x] FilePath[%s]", version, pFilePath );

	return true;
}

bool Manager::MEP_WorkFromMTL(	const wchar_t* pTypeName,
								const wchar_t* pFilePath,
								Mix::Tool::Win32::File::InputStream& input, 
								Mix::Tool::Win32::File::TemporaryStream& output,
								std::map<unsigned int, Manager::MEP_MTL_VS_WORK>& vsMap,
								std::map<unsigned int, Manager::MEP_MTL_PS_WORK>& psMap,
								unsigned int* pVersion )
{
	unsigned int version;
	unsigned int dhFlags;
	unsigned int i;

	/*
		ファイルヘッダ : バージョンを取得
	*/

	if( input.Read( &version, sizeof( version ) ) == false )
	{
		LogPrint( LT_ERROR, L"    %s : 読み込みに失敗しました : File[%s]", pTypeName, pFilePath );
		return false;
	}

	if( pVersion != NULL )
	{
		*pVersion = version;
	}

	// output : バージョン
	if( output.Write( &version, sizeof( version ) ) == false )
	{
		return false;
	}

	/*
		インフォヘッダ and データヘッダ
	*/

	if( version == Mix::Tool::Win32::Graphics::Material::MTL_VERSION_CUR )
	{
		Material::MTL_INFO_HEADER_1_1_0_0 infoHeader;
		Material::MTL_DATA_HEADER_1_1_0_0 dataHeader;

		if( input.Read( &infoHeader, sizeof( infoHeader ) ) == false )
		{
			LogPrint( LT_ERROR, L"    %s : 読み込みに失敗しました : File[%s]", pTypeName, pFilePath );
			return false;
		}

		if( input.Read( &dataHeader, sizeof( dataHeader ) ) == false )
		{
			LogPrint( LT_ERROR, L"    %s : 読み込みに失敗しました : File[%s]", pTypeName, pFilePath );
			return false;
		}

		// フラグ
		dhFlags = dataHeader.flags;

		// 現在のプロセスフラグに合わせて、シェーダーIDを更新
		MEP_UpdateShaderID( infoHeader, dataHeader );

		// バーテックスシェーダーのIDを登録
		for( i = 0; i < Mix::Tool::Win32::Graphics::VERTEX_TYPE_MAX; i++ )
		{
			unsigned int id = infoHeader.vertexShaderID[i];

			if( ( id != 0 ) &&
				( vsMap.find( id ) == vsMap.end() ) )
			{
				vsMap.insert( std::pair<unsigned int, Manager::MEP_MTL_VS_WORK>( id, Manager::MEP_MTL_VS_WORK() ) );
			}
		}

		// ピクセルシェーダーのIDを登録
		{
			unsigned int id = infoHeader.pixelShaderID;

			if( ( id != 0 ) &&
				( psMap.find( id ) == psMap.end() ) )
			{
				psMap.insert( std::pair<unsigned int, Manager::MEP_MTL_PS_WORK>( id, Manager::MEP_MTL_PS_WORK() ) );
			}
		}

		// output : インフォヘッダ
		if( output.Write( &infoHeader, sizeof( infoHeader ) ) == false )
		{
			return false;
		}

		// output : データヘッダ
		if( output.Write( &dataHeader, sizeof( dataHeader ) ) == false )
		{
			return false;
		}
	}
	else
	{
		LogPrint( LT_ERROR, L"    %s : サポートされないバージョンのマテリアルです : FilePath[%s] MaterialVersion[0x%08x]", pTypeName, pFilePath, version );
		return false;
	}

	/*
		テクスチャをスキップ
	*/

	static const unsigned int FLAG_TABLE[4] =
	{
		Material::MTL_DIFFUSE_TEXTURE,
		Material::MTL_SPECULAR_TEXTURE,
		Material::MTL_EMISSIVE_TEXTURE,
		Material::MTL_BUMP_TEXTURE,
	};

	static const unsigned int FLAG_COUNT = sizeof( FLAG_TABLE ) / sizeof( unsigned int );

	for( i = 0; i < FLAG_COUNT; i++ )
	{
		unsigned int flag = FLAG_TABLE[i];

		if( MIX_TEST_BIT( dhFlags, flag ) == flag )
		{
			unsigned int size;

			if( input.Read( &size, sizeof( size ) ) == false )
			{
				return false;
			}

			//output : テクスチャサイズ
			if( output.Write( &size, sizeof( size ) ) == false )
			{
				return false;
			}

			//output : テクスチャデータ
			if( MEP_WorkSkip( pTypeName, pFilePath, size, input, output ) == false )
			{
				return false;
			}
		}
	}

	return true;
}

bool Manager::MEP_WorkFromMAM(	const wchar_t* pFilePath, 
								std::map<unsigned int, Manager::MEP_MTL_VS_WORK>& vsMap,
								std::map<unsigned int, Manager::MEP_MTL_PS_WORK>& psMap )
{
	Mix::Tool::Win32::File::InputStream input;
	Mix::Tool::Win32::File::TemporaryStream output;
	Mix::Tool::Win32::Graphics::MAM_FILE_HEADER_1_0_0_0 fileHeader;
	unsigned int materialNum = 0;

	/*
		ファイルを開く
	*/

	if( input.Open( pFilePath ) == false )
	{
		LogPrint( LT_ERROR, L"    MAM : ファイルが開けません : FilePath[%s]", pFilePath );
		return false;
	}

	if( output.Open( pFilePath ) == false )
	{
		LogPrint( LT_ERROR, L"    MAM : システムメモリが不足しています : FilePath[%s]", pFilePath );
		return false;
	}

	/*
		ファイルヘッダ
	*/

	if( input.Read( &fileHeader, sizeof( fileHeader ) ) == false )
	{
		LogPrint( LT_ERROR, L"    MAM : 読み込みに失敗しました : FilePath[%s]", pFilePath );
		return false;
	}

	if( fileHeader.magicNumber != MAM_MAGICNUMBER )
	{
		LogPrint( LT_ERROR, L"    MAM : ファイルフォーマットが不正です : FilePath[%s]", pFilePath );
		return false;
	}

	if( fileHeader.version != MAM_VERSION_1_0_0_0 )
	{
		LogPrint( LT_ERROR, L"    MAM : サポートされないバージョンです : FilePath[%s] Version[0x%08x]", pFilePath, fileHeader.version );
		return false;
	}

	// output : ファイルヘッダ
	if( output.Write( &fileHeader, sizeof( fileHeader ) ) == false )
	{
		LogPrint( LT_ERROR, L"    MAM : システムメモリが不足しています : FilePath[%s]", pFilePath );
		return false;
	}

	/*
		マテリアル
	*/

	if( input.Read( &materialNum, sizeof( materialNum ) ) == false )
	{
		LogPrint( LT_ERROR, L"    MAM : 読み込みに失敗しました : FilePath[%s]", pFilePath );
		return false;
	}

	// output : マテリアル数
	if( output.Write( &materialNum, sizeof( materialNum ) ) == false )
	{
		LogPrint( LT_ERROR, L"    MAM : システムメモリが不足しています : FilePath[%s]", pFilePath );
		return false;
	}

	// output : スキップ
	if( MEP_WorkSkip( L"MAM", pFilePath, 36, input, output ) == false )
	{
		return false;
	}

	for( unsigned int i = 0; i < materialNum; i++ )
	{
		// output : スロット名をスキップ
		if( MEP_WorkSkip( L"MAM", pFilePath, sizeof( wchar_t ) * Mix::Tool::Win32::Graphics::MAX_NAME_SIZE, input, output ) == false )
		{
			return false;
		}

		if( MEP_WorkFromMTL( L"MAM", pFilePath, input, output, vsMap, psMap ) == false )
		{
			return false;
		}
	}

	/*
		ファイルを閉じる
	*/

	if( MEP_WorkSkip( L"MAM", pFilePath, input.GetSize() - input.GetPosition(), input, output ) == false )
	{
		return false;
	}

	input.Close();
	
	if( output.Close() == false )
	{
		LogPrint( LT_ERROR, L"    MAM : クローズに失敗しました : FilePath[%s]", pFilePath );
		return false;
	}

	/*
		ログ
	*/

	LogPrint( LT_INFO, L"    MAM : Version[0x%08x] FilePath[%s]", fileHeader.version, pFilePath );

	return true;
}

bool Manager::MEP_WorkFromMTM(	const wchar_t* pFilePath, 
								std::map<unsigned int, Manager::MEP_MTL_VS_WORK>& vsMap,
								std::map<unsigned int, Manager::MEP_MTL_PS_WORK>& psMap )
{
	Mix::Tool::Win32::File::InputStream input;
	Mix::Tool::Win32::File::TemporaryStream output;
	MTM_FILE_HEADER_1_0_0_0 fileHeader;
	unsigned int materialNum = 0;

	/*
		ファイルを開く
	*/

	if( input.Open( pFilePath ) == false )
	{
		LogPrint( LT_ERROR, L"    MTM : ファイルが開けません : FilePath[%s]", pFilePath );
		return false;
	}

	if( output.Open( pFilePath ) == false )
	{
		LogPrint( LT_ERROR, L"    MTM : システムメモリが不足しています : FilePath[%s]", pFilePath );
		return false;
	}

	/*
		ファイルヘッダ
	*/

	if( input.Read( &fileHeader, sizeof( fileHeader ) ) == true )
	{
		if( ( fileHeader.magicNumber != MTM_MAGICNUMBER ) ||
			( fileHeader.version != MTM_VERSION_1_0_0_0 ) )
		{
			LogPrint( LT_ERROR, L"    MTM : 読み込みに失敗しました : FilePath[%s]", pFilePath );
			return false;
		}
	}
	else
	{
		LogPrint( LT_ERROR, L"    MTM : 読み込みに失敗しました : FilePath[%s]", pFilePath );
		return false;
	}

	// output : ファイルヘッダ
	if( output.Write( &fileHeader, sizeof( fileHeader ) ) == false )
	{
		LogPrint( LT_ERROR, L"    MTM : システムメモリが不足しています : FilePath[%s]", pFilePath );
		return false;
	}

	if( input.Read( &materialNum, sizeof( materialNum ) ) == false )
	{
		return false;
	}

	// output : マテリアル数
	if( output.Write( &materialNum, sizeof( materialNum ) ) == false )
	{
		LogPrint( LT_ERROR, L"    MTM : システムメモリが不足しています : FilePath[%s]", pFilePath );
		return false;
	}

	// output : スキップ(20)
	if( MEP_WorkSkip( L"MTM", pFilePath, 20, input, output ) == false )
	{
		return false;
	}

	/*
		マテリアル
	*/

	for( unsigned int i = 0; i < materialNum; i++ )
	{
		//output : スロット名のスキップ
		if( MEP_WorkSkip( L"MTM", pFilePath, sizeof( wchar_t ) * Mix::Tool::Win32::Graphics::MAX_NAME_SIZE, input, output ) == false )
		{
			return false;
		}

		if( MEP_WorkFromMTL( L"MTM", pFilePath, input, output, vsMap, psMap ) == false )
		{
			return false;
		}
	}

	/*
		ファイルを閉じる
	*/

	if( MEP_WorkSkip( L"MTM", pFilePath, input.GetSize() - input.GetPosition(), input, output ) == false )
	{
		return false;
	}

	input.Close();

	if( output.Close() == false )
	{
		LogPrint( LT_ERROR, L"    MTM : クローズに失敗しました : FilePath[%s]", pFilePath );
		return false;
	}

	/*
		ログ
	*/

	LogPrint( LT_INFO, L"    MTM : Version[0x%08x] FilePath[%s]", fileHeader.version, pFilePath );

	return true;
}

bool Manager::MEP_WorkSkip(	const wchar_t* pTypeName,
							const wchar_t* pFilePath,
							unsigned int rwSize,
							Mix::Tool::Win32::File::InputStream& input,
							Mix::Tool::Win32::File::TemporaryStream& output )
{
	if( rwSize != 0 )
	{
		void* pWrite = output.Write( rwSize );
		if( pWrite == NULL )
		{
			LogPrint( LT_ERROR, L"    %s : システムメモリが不足しています : FilePath[%s]", pTypeName, pFilePath );
			return false;
		}

		if( input.Read( pWrite, rwSize ) == false )
		{
			LogPrint( LT_ERROR, L"    %s : 読み込みに失敗しました : FilePath[%s]", pTypeName, pFilePath );
			return false;
		}
	}

	return true;
}

void Manager::MEP_UpdateShaderID(	Mix::Tool::Win32::Graphics::Material::MTL_INFO_HEADER_1_1_0_0& infoHeader,
									Mix::Tool::Win32::Graphics::Material::MTL_DATA_HEADER_1_1_0_0& dataHeader )
{
	unsigned int procFlags = MEP_GetProcessFlags();

	bool bRefractMapping;
	bool bShadowOutput;
	bool bShadowReceive;
	bool bSSAO;

	/*
		判定材料の作成
	*/

	//屈折マッピング
	if( dataHeader.shaderType == Mix::Tool::Win32::Graphics::SHADER_WATER )
	{
		if( ( MIX_TEST_BIT( procFlags, SHADER_PROCESS_REFRACT ) == SHADER_PROCESS_REFRACT ) &&
			( MIX_TEST_BIT( dataHeader.flags, Mix::Tool::Win32::Graphics::Material::MTL_TRANSPARENCY ) == Mix::Tool::Win32::Graphics::Material::MTL_TRANSPARENCY ) &&
			( MIX_TEST_BIT( dataHeader.flags, Mix::Tool::Win32::Graphics::Material::MTL_BUMP_TEXTURE ) == Mix::Tool::Win32::Graphics::Material::MTL_BUMP_TEXTURE ) &&
			( dataHeader.waveType == Mix::Tool::Win32::Graphics::WAVE_REFRACT ) )
		{
			bRefractMapping = true;
		}
		else
		{
			bRefractMapping = false;
		}
	}
	else
	{
		bRefractMapping = false;
	}

	//シャドウマッピング
	if( MIX_TEST_BIT( procFlags, SHADER_PROCESS_SHADOW ) == SHADER_PROCESS_SHADOW )
	{
		bShadowOutput = true;

		if( MIX_TEST_BIT( dataHeader.flags, Material::MTL_SHADOW_RECEIVE ) == Material::MTL_SHADOW_RECEIVE )
		{
			bShadowReceive = true;
		}
		else
		{
			bShadowReceive = false;
		}
	}
	else
	{
		bShadowOutput = false;
		bShadowReceive = false;
	}

	//SSAO
	if( MIX_TEST_BIT( procFlags, SHADER_PROCESS_SSAO ) == SHADER_PROCESS_SSAO )
	{
		bSSAO = true;
	}
	else
	{
		bSSAO = false;
	}

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

	for( unsigned int i = 0; i < Mix::Tool::Win32::Graphics::VERTEX_TYPE_MAX; i++ )
	{
		//屈折マッピング
		if( bRefractMapping == true )
		{
			MIX_SET_BIT( infoHeader.vertexShaderID[i], Mix::Tool::Win32::Graphics::MCF_REFRACT_MAPPING );
		}
		else
		{
			MIX_RESET_BIT( infoHeader.vertexShaderID[i], Mix::Tool::Win32::Graphics::MCF_REFRACT_MAPPING );
		}

		//シャドウマッピング ( レシーブのみ )
		if( bShadowReceive == true )
		{
			MIX_SET_BIT( infoHeader.vertexShaderID[i], Mix::Tool::Win32::Graphics::MCF_SHADOW_RECEIVE );
		}
		else
		{
			//IDとフラグを見てシャドウマッピングをするかどうかを判定するためフラグは消さない
//			MIX_RESET_BIT( dataHeader.flags, Mix::Tool::Win32::Graphics::Material::MTL_SHADOW_RECEIVE );
			MIX_RESET_BIT( infoHeader.vertexShaderID[i], Mix::Tool::Win32::Graphics::MCF_SHADOW_RECEIVE );
		}

		//SSAO
		if( bSSAO == true )
		{
			MIX_SET_BIT( infoHeader.vertexShaderID[i], Mix::Tool::Win32::Graphics::MCF_SSAO );
		}
		else
		{
			MIX_RESET_BIT( infoHeader.vertexShaderID[i], Mix::Tool::Win32::Graphics::MCF_SSAO );
		}
	}

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

	//半透明の屈折クリップ
	if( ( MIX_TEST_BIT( procFlags, SHADER_PROCESS_REFRACT ) == SHADER_PROCESS_REFRACT ) &&
		( dataHeader.shaderType != Mix::Tool::Win32::Graphics::SHADER_WATER ) &&
		( MIX_TEST_BIT( dataHeader.flags, Mix::Tool::Win32::Graphics::Material::MTL_TRANSPARENCY ) == Mix::Tool::Win32::Graphics::Material::MTL_TRANSPARENCY ) )
	{
		MIX_SET_BIT( infoHeader.pixelShaderID, Mix::Tool::Win32::Graphics::MCF_REFRACT_CLIP );
	}
	else
	{
		MIX_RESET_BIT( infoHeader.pixelShaderID, Mix::Tool::Win32::Graphics::MCF_REFRACT_CLIP );
	}

	//屈折マッピング
	if( bRefractMapping == true )
	{
		MIX_SET_BIT( infoHeader.pixelShaderID, Mix::Tool::Win32::Graphics::MCF_REFRACT_MAPPING );
	}
	else
	{
		MIX_RESET_BIT( infoHeader.pixelShaderID, Mix::Tool::Win32::Graphics::MCF_REFRACT_MAPPING );
	}

	//ソフトパーティクル
//	if( ( MIX_TEST_BIT( procFlags, SHADER_PROCESS_SOFTPARTICLE ) == SHADER_PROCESS_SOFTPARTICLE ) &&
//		( MIX_TEST_BIT( dataHeader.flags, Mix::Tool::Win32::Graphics::Material::MTL_TRANSPARENCY ) == Mix::Tool::Win32::Graphics::Material::MTL_TRANSPARENCY ) &&
//		( MIX_TEST_BIT( dataHeader.flags, Mix::Tool::Win32::Graphics::Material::MTL_SOFTPARTICLE ) == Mix::Tool::Win32::Graphics::Material::MTL_SOFTPARTICLE ) )
	if( ( MIX_TEST_BIT( dataHeader.flags, Mix::Tool::Win32::Graphics::Material::MTL_TRANSPARENCY ) == Mix::Tool::Win32::Graphics::Material::MTL_TRANSPARENCY ) &&
		( MIX_TEST_BIT( dataHeader.flags, Mix::Tool::Win32::Graphics::Material::MTL_SOFTPARTICLE ) == Mix::Tool::Win32::Graphics::Material::MTL_SOFTPARTICLE ) )
	{
		MIX_SET_BIT( infoHeader.pixelShaderID, Mix::Tool::Win32::Graphics::MCF_SOFTPARTICLE );
	}
	else
	{
		//IDとフラグを見てソフトパーティクルかどうかを判定するためフラグは消さない
//		MIX_RESET_BIT( dataHeader.flags, Mix::Tool::Win32::Graphics::Material::MTL_SOFTPARTICLE );
		MIX_RESET_BIT( infoHeader.pixelShaderID, Mix::Tool::Win32::Graphics::MCF_SOFTPARTICLE );
	}

	//フォグ
	if( MIX_TEST_BIT( procFlags, SHADER_PROCESS_FOG ) == SHADER_PROCESS_FOG )
	{
		MIX_SET_BIT( infoHeader.pixelShaderID, Mix::Tool::Win32::Graphics::MCF_FOG );
	}
	else
	{
		MIX_RESET_BIT( infoHeader.pixelShaderID, Mix::Tool::Win32::Graphics::MCF_FOG );
	}

	//シャドウマッピング
	if( bShadowOutput == true )
	{
		MIX_SET_BIT( infoHeader.pixelShaderID, Mix::Tool::Win32::Graphics::MCF_SHADOW );

		if( bShadowReceive == true )
		{
			MIX_SET_BIT( infoHeader.pixelShaderID, Mix::Tool::Win32::Graphics::MCF_SHADOW_RECEIVE );
		}
		else
		{
			//IDとフラグを見てシャドウマッピングをするかどうかを判定するためフラグは消さない
//			MIX_RESET_BIT( dataHeader.flags, Mix::Tool::Win32::Graphics::Material::MTL_SHADOW_RECEIVE );
			MIX_RESET_BIT( infoHeader.pixelShaderID, Mix::Tool::Win32::Graphics::MCF_SHADOW_RECEIVE );
		}
	}
	else
	{
		//IDとフラグを見てシャドウマッピングをするかどうかを判定するためフラグは消さない
//		MIX_RESET_BIT( dataHeader.flags, Mix::Tool::Win32::Graphics::Material::MTL_SHADOW_RECEIVE );
		MIX_RESET_BIT( infoHeader.pixelShaderID, Mix::Tool::Win32::Graphics::MCF_SHADOW_RECEIVE );
		MIX_RESET_BIT( infoHeader.pixelShaderID, Mix::Tool::Win32::Graphics::MCF_SHADOW );
	}

	//大気散乱シミュレーション
	if( MIX_TEST_BIT( procFlags, SHADER_PROCESS_ATMOSPHERE ) == SHADER_PROCESS_ATMOSPHERE )
	{
		MIX_SET_BIT( infoHeader.pixelShaderID, Mix::Tool::Win32::Graphics::MCF_ATMOSPHERE );
	}
	else
	{
		MIX_RESET_BIT( infoHeader.pixelShaderID, Mix::Tool::Win32::Graphics::MCF_ATMOSPHERE );
	}

	//SSAO
	if( bSSAO == true )
	{
		MIX_SET_BIT( infoHeader.pixelShaderID, Mix::Tool::Win32::Graphics::MCF_SSAO );
	}
	else
	{
		MIX_RESET_BIT( infoHeader.pixelShaderID, Mix::Tool::Win32::Graphics::MCF_SSAO );
	}
}

bool Manager::MEP_CreateFileInfoList( std::vector<MEP_FILE_INFO>& fileInfoList )
{
	/*
		初期化
	*/

	fileInfoList.clear();
	fileInfoList.reserve( Manager::MEP_SAVE_INFO_COUNT );

	/*
		リストアップ
	*/

	for( unsigned int i = 0; i < Manager::MEP_SAVE_INFO_COUNT; i++ )
	{
		const Manager::MEP_SAVE_INFO* pSI = &( Manager::MEP_SAVE_INFO_TABLE[i] );

		std::wstringstream fileName;
		Manager::MEP_FILE_INFO fileInfo;

		if( MIX_TEST_BIT( m_MSPShaderModels, pSI->shaderModel ) != pSI->shaderModel )
		{
			continue;
		}

		fileName << m_MSPName.c_str() << L"_" << pSI->number << Manager::MEP_EXT;

		if( Mix::Tool::Win32::Path::Combine( m_RootDirectoryPath.c_str(), m_MSPDirectoryName.c_str(), fileInfo.path ) == false )
		{
			LogPrint( LT_ERROR, L" セーブに失敗 : ファイルパスの作成中にエラーが発生しました : RootDirectory[%s] MEPDirectory[%s]",
				m_RootDirectoryPath.c_str(),
				m_MSPDirectoryName.c_str() );

			continue;
		}

		if( Mix::Tool::Win32::Path::Combine( fileInfo.path.c_str(), fileName.str().c_str(), fileInfo.path ) == false )
		{
			LogPrint( LT_ERROR, L" セーブに失敗 : ファイルパスの作成中にエラーが発生しました : MEPDirectory[%s] MEPFile[%s]",
				fileInfo.path.c_str(),
				fileName.str().c_str() );

			continue;
		}

		fileInfo.vsProf = pSI->vsProf;
		fileInfo.psProf = pSI->psProf;

		fileInfoList.push_back( fileInfo );
	}

	return fileInfoList.size() > 0;
}

bool Manager::MEP_Compile(	Manager::SHADER_PROFILE vsProf,
							Manager::SHADER_PROFILE psProf,
							std::map<unsigned int, Manager::MEP_MTL_VS_WORK>& vsMap,
							std::map<unsigned int, Manager::MEP_MTL_PS_WORK>& psMap )
{
	/*
		マテリアル : バーテックスシェーダーをコンパイル
	*/

	{
		std::map<unsigned int, Manager::MEP_MTL_VS_WORK>::iterator it_begin = vsMap.begin();
		std::map<unsigned int, Manager::MEP_MTL_VS_WORK>::iterator it_end = vsMap.end();
		std::map<unsigned int, Manager::MEP_MTL_VS_WORK>::iterator it;

		for( it = it_begin; it != it_end; ++it )
		{
			if( it->second.macros.size() == 0 )
			{
				continue;
			}

			const Manager::SHADER_MACRO* pShaderMacros = &( it->second.macros[0] );

			bool bRefract = MIX_TEST_BIT( it->first, Mix::Tool::Win32::Graphics::MCF_REFRACT_MAPPING ) == Mix::Tool::Win32::Graphics::MCF_REFRACT_MAPPING;
			bool bShadow = MIX_TEST_BIT( m_MSPProcFlags, Mix::Tool::Win32::Graphics::SHADER_PROCESS_SHADOW ) == Mix::Tool::Win32::Graphics::SHADER_PROCESS_SHADOW;

			if( CompileShader( vsProf, pShaderMacros, Manager::MEP_MTL_COLOR, it->second.buff[Manager::MEP_MTL_COLOR] ) == false )
			{
				return false;
			}

			if( bRefract == true )
			{
				if( CompileShader( vsProf, pShaderMacros, Manager::MEP_MTL_MASK, it->second.buff[Manager::MEP_MTL_MASK] ) == false )
				{
					return false;
				}
			}

			if( bShadow == true )
			{
				if( CompileShader( vsProf, pShaderMacros, Manager::MEP_MTL_SHADOW, it->second.buff[Manager::MEP_MTL_SHADOW] ) == false )
				{
					return false;
				}
			}

			LogPrint( LT_INFO, L"  VS_%d[0x%08x] : Color[○] Refract[%s] Shadow[%s]",
				Manager::SHADER_PROFILE_NUMBER_TABLE[vsProf],
				it->first,
				( bRefract == true )? L"○" : L"×",
				( bShadow == true )? L"○" : L"×" );
		}
	}

	/*
		マテリアル : ピクセルシェーダーをコンパイル
	*/

	{
		std::map<unsigned int, Manager::MEP_MTL_PS_WORK>::iterator it_begin = psMap.begin();
		std::map<unsigned int, Manager::MEP_MTL_PS_WORK>::iterator it_end = psMap.end();
		std::map<unsigned int, Manager::MEP_MTL_PS_WORK>::iterator it;

		for( it = it_begin; it != it_end; ++it )
		{
			if( it->second.macros.size() == 0 )
			{
				continue;
			}

			const Manager::SHADER_MACRO* pShaderMacros = &( it->second.macros[0] );

			bool bRefract = MIX_TEST_BIT( it->first, Mix::Tool::Win32::Graphics::MCF_REFRACT_MAPPING ) == Mix::Tool::Win32::Graphics::MCF_REFRACT_MAPPING;
			bool bShadow = MIX_TEST_BIT( m_MSPProcFlags, Mix::Tool::Win32::Graphics::SHADER_PROCESS_SHADOW ) == Mix::Tool::Win32::Graphics::SHADER_PROCESS_SHADOW;

			if( CompileShader( psProf, pShaderMacros, Manager::MEP_MTL_COLOR, it->second.buff[Manager::MEP_MTL_COLOR] ) == false )
			{
				return false;
			}

			if( bRefract == true )
			{
				if( CompileShader( psProf, pShaderMacros, Manager::MEP_MTL_MASK, it->second.buff[Manager::MEP_MTL_MASK] ) == false )
				{
					return false;
				}
			}

			if( bShadow == true )
			{
				if( CompileShader( psProf, pShaderMacros, Manager::MEP_MTL_SHADOW, it->second.buff[Manager::MEP_MTL_SHADOW] ) == false )
				{
					return false;
				}
			}

			LogPrint( LT_INFO, L"  PS_%d[0x%08x] : Color[○] Refract[%s] Shadow[%s]",
				Manager::SHADER_PROFILE_NUMBER_TABLE[psProf],
				it->first,
				( bRefract == true )? L"○" : L"×",
				( bShadow == true )? L"○" : L"×" );
		}
	}

	return true;
}

bool Manager::MEP_Save(	const wchar_t* pFilePath, 
						std::map<unsigned int, Manager::MEP_MTL_VS_WORK>& vsMap,
						std::map<unsigned int, Manager::MEP_MTL_PS_WORK>& psMap )
{
	Mix::Tool::Win32::File::OutputStream output;

	/*
		書き込み先ファイルを開く
	*/

	if( Mix::Tool::Win32::Directory::Create( pFilePath, true ) == false )
	{
		return false;
	}

	/*
		書き込み先ファイルを開く
	*/

	if( output.Open( pFilePath ) == false )
	{
		return false;
	}

	/*
		ファイルヘッダ
	*/

	{
		Manager::MEP_FILE_HEADER fileHeader;

		fileHeader.magicNumber = Manager::MEP_MAGIC_NUMBER;
		fileHeader.version = Manager::MEP_VERSION;

		if( output.Write( &fileHeader, sizeof( fileHeader ) ) == false )
		{
			output.Close();
			return false;
		}
	}

	/*
		データヘッダ
	*/

	{
		Manager::MEP_DATA_HEADER dataHeader;

		dataHeader.rendererType = Manager::MEP_RT_STANDARD;
		dataHeader.processFlags = m_MSPProcFlags;
		dataHeader.vertexShaderNum = vsMap.size();
		dataHeader.pixelShaderNum = psMap.size();

		if( output.Write( &dataHeader, sizeof( dataHeader ) ) == false )
		{
			output.Close();
			return false;
		}
	}

	/*
		バーテックスシェーダーを書き込む
	*/

	{
		std::map<unsigned int, Manager::MEP_MTL_VS_WORK>::iterator it_begin = vsMap.begin();
		std::map<unsigned int, Manager::MEP_MTL_VS_WORK>::iterator it_end = vsMap.end();
		std::map<unsigned int, Manager::MEP_MTL_VS_WORK>::iterator it;

		for( it = it_begin; it != it_end; ++it )
		{
			MEP_VS_HEADER desc;

			MIX_ASSERT( it->second.elements.size() > 0 );
			MIX_ASSERT( it->second.buff[Manager::MEP_MTL_COLOR].size() > 0 );

			desc.id = it->first;
			desc.buffSize[Manager::MEP_MTL_COLOR] = it->second.buff[Manager::MEP_MTL_COLOR].size();
			desc.buffSize[Manager::MEP_MTL_MASK] = it->second.buff[Manager::MEP_MTL_MASK].size();
			desc.buffSize[Manager::MEP_MTL_SHADOW] = it->second.buff[Manager::MEP_MTL_SHADOW].size();
			desc.elementNum = it->second.elements.size();
			desc.reserve = 0;

			if( output.Write( &desc, sizeof( desc ) ) == false )
			{
				output.Close();
				return false;
			}

			for( unsigned int i = 0; i < Manager::MEP_MTL_TYPE_MAX; i++ )
			{
				const std::vector<unsigned char>& buff = it->second.buff[i];
				unsigned int buffSize = buff.size();

				if( buffSize > 0 )
				{
					if( output.Write( &( buff[0] ), buffSize ) == false )
					{
						output.Close();
						return false;
					}
				}
			}

			if( output.Write( &( it->second.elements[0] ), sizeof( Mix::Tool::Win32::Graphics::VERTEX_ELEMENT) * it->second.elements.size() ) == false )
			{
				output.Close();
				return false;
			}
		}
	}

	/*
		ピクセルシェーダーを書き込む
	*/

	{
		std::map<unsigned int, Manager::MEP_MTL_PS_WORK>::iterator it_begin = psMap.begin();
		std::map<unsigned int, Manager::MEP_MTL_PS_WORK>::iterator it_end = psMap.end();
		std::map<unsigned int, Manager::MEP_MTL_PS_WORK>::iterator it;

		for( it = it_begin; it != it_end; ++it )
		{
			MEP_PS_HEADER desc;

			MIX_ASSERT( it->second.buff[Manager::MEP_MTL_COLOR].size() > 0 );

			desc.id = it->first;
			desc.buffSize[Manager::MEP_MTL_COLOR] = it->second.buff[Manager::MEP_MTL_COLOR].size();
			desc.buffSize[Manager::MEP_MTL_MASK] = it->second.buff[Manager::MEP_MTL_MASK].size();
			desc.buffSize[Manager::MEP_MTL_SHADOW] = it->second.buff[Manager::MEP_MTL_SHADOW].size();

			if( output.Write( &desc, sizeof( desc ) ) == false )
			{
				output.Close();
				return false;
			}

			for( unsigned i = 0; i < Manager::MEP_MTL_TYPE_MAX; i++ )
			{
				const std::vector<unsigned char>& buff = it->second.buff[i];
				unsigned int buffSize = buff.size();

				if( buffSize > 0 )
				{
					if( output.Write( &( buff[0] ), buffSize ) == false )
					{
						output.Close();
						return false;
					}
				}
			}
		}
	}

	/*
		書き込み先ファイルを閉じる
	*/

	output.Close();

	return true;
}

bool Manager::CompileShader(	Manager::SHADER_PROFILE profile,
								const Manager::SHADER_MACRO* pDefs,
								Manager::MEP_MTL_TYPE type,
								std::vector<unsigned char>& buffer )
{
	std::string entryFunction;
	const char* pSrc = NULL;
	unsigned int srcSize = 0;

	/*
		エントリーファンクション
	*/

	switch( type )
	{
	case Manager::MEP_MTL_COLOR:
		entryFunction = "mainColorModel";
		break;
	case Manager::MEP_MTL_MASK:
		entryFunction = "mainMaskModel";
		break;
	case Manager::MEP_MTL_SHADOW:
		entryFunction = "mainShadowModel";
		break;
	default:
		return false;
	}

	/*
		ソース
	*/

	switch( profile )
	{
	case Manager::SHADER_PROFILE_VS_3:
	case Manager::SHADER_PROFILE_VS_4:
	case Manager::SHADER_PROFILE_VS_5:
		pSrc = reinterpret_cast<const char*>( &( MANAGER_MATERIAL_STANDARD_VS[0] ) );
		srcSize = sizeof( MANAGER_MATERIAL_STANDARD_VS );
		break;

	case Manager::SHADER_PROFILE_PS_3:
	case Manager::SHADER_PROFILE_PS_4:
	case Manager::SHADER_PROFILE_PS_5:
		pSrc = reinterpret_cast<const char*>( &( MANAGER_MATERIAL_STANDARD_PS[0] ) );
		srcSize = sizeof( MANAGER_MATERIAL_STANDARD_PS );
		break;
	};
/*
	switch( profile )
	{
	case Manager::SHADER_PROFILE_VS_3:
		pSrc = reinterpret_cast<const char*>( &( MANAGER_STANDARD_VS_3[0] ) );
		srcSize = sizeof( MANAGER_STANDARD_VS_3 );
		break;
	case Manager::SHADER_PROFILE_PS_3:
		pSrc = reinterpret_cast<const char*>( &( MANAGER_STANDARD_PS_3[0] ) );
		srcSize = sizeof( MANAGER_STANDARD_PS_3 );
		break;

	case Manager::SHADER_PROFILE_VS_4:
		pSrc = reinterpret_cast<const char*>( &( MANAGER_STANDARD_VS_4[0] ) );
		srcSize = sizeof( MANAGER_STANDARD_VS_4 );
		break;
	case Manager::SHADER_PROFILE_PS_4:
		pSrc = reinterpret_cast<const char*>( &( MANAGER_STANDARD_PS_4[0] ) );
		srcSize = sizeof( MANAGER_STANDARD_PS_4 );
		break;

	case Manager::SHADER_PROFILE_VS_5:
		pSrc = reinterpret_cast<const char*>( &( MANAGER_STANDARD_VS_5[0] ) );
		srcSize = sizeof( MANAGER_STANDARD_VS_5 );
		break;
	case Manager::SHADER_PROFILE_PS_5:
		pSrc = reinterpret_cast<const char*>( &( MANAGER_STANDARD_PS_5[0] ) );
		srcSize = sizeof( MANAGER_STANDARD_PS_5 );
		break;
	};
*/
	return CompileShader( "Material(Standard)", profile, pDefs, pSrc, srcSize, entryFunction.c_str(), buffer );
}

bool Manager::CompileShader(	const char* pName,
								Manager::SHADER_PROFILE profile,
								const Manager::SHADER_MACRO* pDefs,
								const char* pSrc,
								unsigned int srcSize,
								const char* pEntryFunction,
								std::vector<unsigned char>& buffer )
{
	////////////////////////////////////////////////////////////////////////////////////////////////////
	// シェーダーモデルのサポートチェック
	////////////////////////////////////////////////////////////////////////////////////////////////////

	if( ( MIX_TEST_BIT( m_SupportShaderModels, SHADER_MODEL_3 ) != SHADER_MODEL_3 ) &&
		( ( profile == Manager::SHADER_PROFILE_VS_3 ) || ( profile == Manager::SHADER_PROFILE_PS_3 ) ) )
	{
		return false;
	}

	if( ( MIX_TEST_BIT( m_SupportShaderModels, SHADER_MODEL_4 ) != SHADER_MODEL_4 ) &&
		( ( profile == Manager::SHADER_PROFILE_VS_4 ) || ( profile == Manager::SHADER_PROFILE_PS_4 ) ) )
	{
		return false;
	}

	if( ( MIX_TEST_BIT( m_SupportShaderModels, SHADER_MODEL_5 ) != SHADER_MODEL_5 ) &&
		( ( profile == Manager::SHADER_PROFILE_VS_5 ) || ( profile == Manager::SHADER_PROFILE_PS_5 ) ) )
	{
		return false;
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// コンパイル
	////////////////////////////////////////////////////////////////////////////////////////////////////

	bool bSuccess = false;

	if( ( profile == Manager::SHADER_PROFILE_VS_3 ) ||
		( profile == Manager::SHADER_PROFILE_PS_3 ) )
	{
		//シェーダーモデル 3

		D3DXMACRO macroStart;
		D3DXMACRO macroEnd;
		std::vector<D3DXMACRO> macroList;

		LPD3DXBUFFER pBuffer = NULL;
		LPD3DXBUFFER pError = NULL;

		HRESULT ret;

		/*
			マクロリストの作成
		*/

		macroStart.Name = Manager::SHADER_DEFMODEL_TABLE[profile];
		macroStart.Definition = Manager::SHADER_DEFONE;
		macroList.push_back( macroStart );

		if( pDefs != NULL )
		{
			const Manager::SHADER_MACRO* pSrcMacro = &( pDefs[0] );

			while( ( pSrcMacro->name.size() != 0 ) && ( pSrcMacro->def.size() != 0 ) )
			{
				D3DXMACRO dst;

				dst.Name = pSrcMacro->name.c_str();
				dst.Definition = pSrcMacro->def.c_str();

				macroList.push_back( dst );

				pSrcMacro++;
			}

		}

		macroEnd.Name = NULL;
		macroEnd.Definition = NULL;
		macroList.push_back( macroEnd );

		/*
			実行
		*/

		ret = D3DXCompileShader(	pSrc,
									srcSize,
									&( macroList[0] ),
									NULL,
									pEntryFunction,
									Manager::SHADER_PROFILE_TABLE[profile],
									0,
									&pBuffer,
									&pError,
									NULL );
		if( ret != D3D_OK )
		{
			std::stringstream msgStream;
			std::wstring msg;

			msgStream << "シェーダーのコンパイルに失敗 : ";
			msgStream << "Name[" << pName << "] ";
			msgStream << "Profile[" << Manager::SHADER_PROFILE_TABLE[profile] << "] ";
			msgStream << "EntryFunction[" << pEntryFunction << "]\n";
			msgStream << static_cast<const char*>( pError->GetBufferPointer() );

			AnsiToWide( msgStream.str().c_str(), msg );
			LogPrint( LT_ERROR, msg.c_str() );

			MIX_RELEASE( pBuffer );
			return false;
		}

		buffer.clear();
		buffer.resize( pBuffer->GetBufferSize() );
		::CopyMemory( &( buffer[0] ), pBuffer->GetBufferPointer(), pBuffer->GetBufferSize() );

		bSuccess = true;
	}
	else
	{
		const UINT scFlags = D3D10_SHADER_OPTIMIZATION_LEVEL3 | D3D10_SHADER_PACK_MATRIX_COLUMN_MAJOR | D3D10_SHADER_ENABLE_STRICTNESS;
//		const UINT scFlags = D3D10_SHADER_ENABLE_STRICTNESS;
//		const UINT scFlags = 0;

		D3D10_SHADER_MACRO macroStart;
		D3D10_SHADER_MACRO macroEnd;
		std::vector<D3D10_SHADER_MACRO> macroList;

		ID3D10Blob* pBuffer;
		ID3D10Blob* pError;

		HRESULT ret;

		/*
			マクロリストの作成
		*/

		macroStart.Name = Manager::SHADER_DEFMODEL_TABLE[profile];
		macroStart.Definition = Manager::SHADER_DEFONE;
		macroList.push_back( macroStart );

		if( pDefs != NULL )
		{
			const Manager::SHADER_MACRO* pSrcMacro = &( pDefs[0] );

			while( ( pSrcMacro->name.size() != 0 ) && ( pSrcMacro->def.size() != 0 ) )
			{
				D3D10_SHADER_MACRO dst;

				dst.Name = pSrcMacro->name.c_str();
				dst.Definition = pSrcMacro->def.c_str();

				macroList.push_back( dst );

				pSrcMacro++;
			}
		}

		macroEnd.Name = NULL;
		macroEnd.Definition = NULL;
		macroList.push_back( macroEnd );

		/*
			実行
		*/

		ret = m_pShaderCompile(	pSrc,
								srcSize,
								NULL,
								&( macroList[0] ),
								NULL,
								pEntryFunction,
								Manager::SHADER_PROFILE_TABLE[profile],
								scFlags,
								0,
								NULL,
								&pBuffer,
								&pError,
								NULL );

		if( ret != S_OK )
		{
			std::stringstream msgStream;
			std::wstring msg;

			msgStream << "シェーダーのコンパイルに失敗 : ";
			msgStream << "Name[" << pName << "] ";
			msgStream << "Profile[" << Manager::SHADER_PROFILE_TABLE[profile] << "] ";
			msgStream << "EntryFunction[" << pEntryFunction << "]\n";
			msgStream << static_cast<const char*>( pError->GetBufferPointer() );

			AnsiToWide( msgStream.str().c_str(), msg );
			LogPrint( LT_ERROR, msg.c_str() );

			MIX_RELEASE( pBuffer );

			return false;
		}

		buffer.clear();
		buffer.resize( pBuffer->GetBufferSize() );
		::CopyMemory( &( buffer[0] ), pBuffer->GetBufferPointer(), pBuffer->GetBufferSize() );

		bSuccess = true;
	}

	return bSuccess;
}

void Manager::CreateCompileMacroList( unsigned int compileFlags, bool bEngine, std::vector<Manager::SHADER_MACRO>& macroList )
{
	//法線
	if( MIX_TEST_BIT( compileFlags, MCF_NORMAL ) == MCF_NORMAL )
	{
		macroList.push_back( Manager::SHADER_MACRO( "ENABLE_NORMAL", "1" ) );
	}

	//接線空間
	if( MIX_TEST_BIT( compileFlags, MCF_TANGENT_SPACE ) == MCF_TANGENT_SPACE )
	{
		macroList.push_back( Manager::SHADER_MACRO( "ENABLE_TANGENT_SPACE", "1" ) );
	}

	//テクスチャ座標
	if( MIX_TEST_BIT( compileFlags, MCF_TEXTURE ) == MCF_TEXTURE )
	{
		macroList.push_back( Manager::SHADER_MACRO( "ENABLE_TEXTURE", "1" ) );
	}

	//スキニング
	if( MIX_TEST_BIT( compileFlags, MCF_BLEND_VERTEX ) == MCF_BLEND_VERTEX )
	{
		macroList.push_back( Manager::SHADER_MACRO( "ENABLE_SKINNING", "1" ) );
	}

	//ライティング
	if( MIX_TEST_BIT( compileFlags, MCF_LIGHTING ) == MCF_LIGHTING )
	{
		macroList.push_back( Manager::SHADER_MACRO( "ENABLE_LIGHTING", "1" ) );

		if( MIX_TEST_BIT( compileFlags, MCF_BOTH_LIGHTING ) == MCF_BOTH_LIGHTING )
		{
			macroList.push_back( Manager::SHADER_MACRO( "ENABLE_BOTH_LIGHTING", "1" ) );
		}
	}

	//半透明の屈折クリップ
	if( MIX_TEST_BIT( compileFlags, MCF_REFRACT_CLIP ) == MCF_REFRACT_CLIP )
	{
		macroList.push_back( Manager::SHADER_MACRO( "ENABLE_REFRACT_CLIP", "1" ) );
	}

	//ディフューズ
	{
		if( MIX_TEST_BIT( compileFlags, MCF_LIGHTING ) == MCF_LIGHTING )
		{
			//ハーフランバート
			if( MIX_TEST_BIT( compileFlags, MCF_DIFFUSE_HALF_LAMBERT ) == MCF_DIFFUSE_HALF_LAMBERT )
			{
				macroList.push_back( Manager::SHADER_MACRO( "ENABLE_HALF_LAMBERT", "1" ) );
			}

			//フレネル
			if( MIX_TEST_BIT( compileFlags, MCF_DIFFUSE_FRESNEL ) == MCF_DIFFUSE_FRESNEL )
			{
				macroList.push_back( Manager::SHADER_MACRO( "ENABLE_DIFFUSE_FRESNEL", "1" ) );
			}

			//リムライティング
			if( MIX_TEST_BIT( compileFlags, MCF_DIFFUSE_RIM_LIGHTING ) == MCF_DIFFUSE_RIM_LIGHTING )
			{
				macroList.push_back( Manager::SHADER_MACRO( "ENABLE_RIM_LIGHTING", "1" ) );
			}
		}

		//ディフューズマッピング
		if( MIX_TEST_BIT( compileFlags, MCF_DIFFUSE_MAPPING ) == MCF_DIFFUSE_MAPPING )
		{
			macroList.push_back( Manager::SHADER_MACRO( "ENABLE_DIFFUSE_MAPPING", "1" ) );
		}
	}

	//スペキュラー
	if( ( MIX_TEST_BIT( compileFlags, MCF_LIGHTING ) == MCF_LIGHTING ) &&
		( MIX_TEST_BIT( compileFlags, MCF_SPECULAR_MASK ) != 0 ) )
	{
		//スペキュラータイプ
		if( MIX_TEST_BIT( compileFlags, MCF_SPECULAR_PHONG ) == MCF_SPECULAR_PHONG )
		{
			macroList.push_back( Manager::SHADER_MACRO( "ENABLE_PHONG", "1" ) );
		}
		else if( MIX_TEST_BIT( compileFlags, MCF_SPECULAR_BLINN_PHONG ) == MCF_SPECULAR_BLINN_PHONG )
		{
			macroList.push_back( Manager::SHADER_MACRO( "ENABLE_BLINN_PHONG", "1" ) );
		}
		else if( MIX_TEST_BIT( compileFlags, MCF_SPECULAR_COOK_TORRANCE ) == MCF_SPECULAR_COOK_TORRANCE )
		{
			macroList.push_back( Manager::SHADER_MACRO( "ENABLE_COOK_TORRANCE", "1" ) );
		}

		//スペキュラーマッピング
		if( MIX_TEST_BIT( compileFlags, MCF_SPECULAR_MAPPING ) == MCF_SPECULAR_MAPPING )
		{
			macroList.push_back( Manager::SHADER_MACRO( "ENABLE_SPECULAR_MAPPING", "1" ) );
		}

		//リフレクションマッピング
		if( MIX_TEST_BIT( compileFlags, MCF_REFLECT_MAPPING ) == MCF_REFLECT_MAPPING )
		{
			macroList.push_back( Manager::SHADER_MACRO( "ENABLE_REFLECT_MAPPING", "1" ) );

			//フレネル
			if( MIX_TEST_BIT( compileFlags, MCF_REFLECT_FRESNEL ) == MCF_REFLECT_FRESNEL )
			{
				macroList.push_back( Manager::SHADER_MACRO( "ENABLE_REFLECT_FRESNEL", "1" ) );
			}
		}
	}

	//エミッシブマッピング
	if( MIX_TEST_BIT( compileFlags, MCF_EMISSIVE_MAPPING ) == MCF_EMISSIVE_MAPPING )
	{
		macroList.push_back( Manager::SHADER_MACRO( "ENABLE_EMISSIVE_MAPPING", "1" ) );
	}

	//バンプマッピング
	if( MIX_TEST_BIT( compileFlags, MCF_BUMP_MAPPING ) == MCF_BUMP_MAPPING )
	{
		macroList.push_back( Manager::SHADER_MACRO( "ENABLE_BUMP", "1" ) );

		//視差
		if( MIX_TEST_BIT( compileFlags, MCF_PARALLAX ) == MCF_PARALLAX )
		{
			macroList.push_back( Manager::SHADER_MACRO( "ENABLE_PARALLAX_MAPPING", "1" ) );
		}
	}

	//ウォーター
	if( MIX_TEST_BIT( compileFlags, MCF_WATER ) == MCF_WATER )
	{
		macroList.push_back( Manager::SHADER_MACRO( "ENABLE_WATER", "1" ) );

		if( MIX_TEST_BIT( compileFlags, MCF_BUMP_MAPPING ) == MCF_BUMP_MAPPING )
		{
			//ウェーブアニメーション( インバート )
			if( MIX_TEST_BIT( compileFlags, MCF_WAVE_INVERT ) == MCF_WAVE_INVERT )
			{
				macroList.push_back( Manager::SHADER_MACRO( "ENABLE_WAVE_INVERT", "1" ) );
			}

			//屈折マッピング
			if( MIX_TEST_BIT( compileFlags, MCF_REFRACT_MAPPING ) == MCF_REFRACT_MAPPING )
			{
				macroList.push_back( Manager::SHADER_MACRO( "ENABLE_REFRACT_MAPPING", "1" ) );
			}
		}
/*
		//屈折マッピング
		if( ( MIX_TEST_BIT( compileFlags, MCF_BUMP_MAPPING ) == MCF_BUMP_MAPPING ) &&
			( MIX_TEST_BIT( compileFlags, MCF_REFRACT_MAPPING ) == MCF_REFRACT_MAPPING ) )
		{
			macroList.push_back( Manager::SHADER_MACRO( "ENABLE_REFRACT_MAPPING", "1" ) );
		}
*/
	}

	//ソフトパーティクル
	if( MIX_TEST_BIT( compileFlags, MCF_SOFTPARTICLE ) == MCF_SOFTPARTICLE )
	{
		macroList.push_back( Manager::SHADER_MACRO( "ENABLE_SOFTPARTICLE", "1" ) );
	}

	//フォグ
	if( bEngine == true )
	{
		if( MIX_TEST_BIT( compileFlags, MCF_FOG ) == MCF_FOG )
		{
			macroList.push_back( Manager::SHADER_MACRO( "ENABLE_FOG", "1" ) );
		}
	}

	//シャドウマッピング
	if( bEngine == true )
	{
		if( MIX_TEST_BIT( compileFlags, MCF_SHADOW ) == MCF_SHADOW )
		{
			macroList.push_back( Manager::SHADER_MACRO( "ENABLE_SHADOW", "1" ) );
		}

		if( MIX_TEST_BIT( compileFlags, MCF_SHADOW_RECEIVE ) == MCF_SHADOW_RECEIVE )
		{
			macroList.push_back( Manager::SHADER_MACRO( "ENABLE_SHADOW_RECEIVE", "1" ) );
		}
	}

	//大気散乱シミュレーション
	if( bEngine == true )
	{
		if( MIX_TEST_BIT( compileFlags, ( MCF_LIGHTING | MCF_ATMOSPHERE ) ) == ( MCF_LIGHTING | MCF_ATMOSPHERE ) )
		{
			macroList.push_back( Manager::SHADER_MACRO( "ENABLE_ATMOSPHERE", "1" ) );
		}
	}

	//SSAO
	if( bEngine == true )
	{
		if( MIX_TEST_BIT( compileFlags, MCF_SSAO ) == MCF_SSAO )
		{
			macroList.push_back( Manager::SHADER_MACRO( "ENABLE_SSAO", "1" ) );
		}
	}

	//クローズ
	macroList.push_back( Manager::SHADER_MACRO( NULL, NULL ) );
}

void Manager::CreateVertexElementList( unsigned int compileFlags, std::vector<D3DVERTEXELEMENT9>& elementList )
{
	/*
		クリア
	*/

	elementList.clear();

	/*
		作成
	*/

	//座標
	PushVertexElement( elementList, D3DDECLTYPE_FLOAT3, D3DDECLUSAGE_POSITION );

	//頂点カラー
	PushVertexElement( elementList, D3DDECLTYPE_FLOAT4, D3DDECLUSAGE_COLOR );

	//法線
	if( MIX_TEST_BIT( compileFlags, MCF_NORMAL ) == MCF_NORMAL )
	{
		PushVertexElement( elementList, D3DDECLTYPE_FLOAT3, D3DDECLUSAGE_NORMAL );
	}

	//接線空間
	if( MIX_TEST_BIT( compileFlags, MCF_TANGENT_SPACE ) == Graphics::MCF_TANGENT_SPACE )
	{
		PushVertexElement( elementList, D3DDECLTYPE_FLOAT3, D3DDECLUSAGE_TANGENT );
		PushVertexElement( elementList, D3DDECLTYPE_FLOAT3, D3DDECLUSAGE_BINORMAL );
	}

	//テクスチャ座標
	if( MIX_TEST_BIT( compileFlags, MCF_TEXTURE ) == MCF_TEXTURE )
	{
		PushVertexElement( elementList, D3DDECLTYPE_FLOAT2, D3DDECLUSAGE_TEXCOORD );
	}

	//ブレンド
	if( MIX_TEST_BIT( compileFlags, MCF_BLEND_VERTEX ) == MCF_BLEND_VERTEX )
	{
		//ブレンドインデックス
		PushVertexElement( elementList, D3DDECLTYPE_UBYTE4, D3DDECLUSAGE_BLENDINDICES );

		//ブレンドウェイト
		PushVertexElement( elementList, D3DDECLTYPE_FLOAT4, D3DDECLUSAGE_BLENDWEIGHT );
	}

	//閉じる
	CloseVertexElement( elementList );
}

void Manager::ConvertVertexElementList( const std::vector<D3DVERTEXELEMENT9>& srcList, std::vector<Mix::Tool::Win32::Graphics::VERTEX_ELEMENT>& dstList )
{
	std::vector<D3DVERTEXELEMENT9>::const_iterator it_begin;
	std::vector<D3DVERTEXELEMENT9>::const_iterator it_end;
	std::vector<D3DVERTEXELEMENT9>::const_iterator it;

	dstList.clear();
	if( srcList.size() == 0 )
	{
		return;
	}

	dstList.reserve( srcList.size() - 1 );

	it_begin = srcList.begin();
	it_end = srcList.end() - 1;

	for( it = it_begin; it != it_end; ++it )
	{
		const D3DVERTEXELEMENT9* pD3DElm = &( *it );
		Mix::Tool::Win32::Graphics::VERTEX_ELEMENT elm;

		elm.semanticType = Manager::D3D_VE_SEMANTIC_TABLE[pD3DElm->Usage];
		elm.semanticIndex = pD3DElm->UsageIndex;
		elm.format = Manager::D3D_VE_FORMAT_TABLE[pD3DElm->Type];
		elm.offset = pD3DElm->Offset;

		dstList.push_back( elm );
	}
}

void Manager::PushVertexElement( std::vector<D3DVERTEXELEMENT9>& elementList, BYTE type, BYTE usage )
{
	const bool bEmpty = ( elementList.size() == 0 );

	WORD offset = 0;
	BYTE usageIndex = 0;

	D3DVERTEXELEMENT9 elm;

	/*
		オフセットを決定
	*/

	if( bEmpty == false )
	{
		const D3DVERTEXELEMENT9& preElm = elementList[elementList.size() - 1];
		offset = preElm.Offset + Manager::D3D_VE_FORMAT_SIZE_TABLE[preElm.Type];
	}

	/*
		使用方法を決定
	*/

	if( bEmpty == false )
	{
		const D3DVERTEXELEMENT9* pElm = &( elementList[0] );
		const D3DVERTEXELEMENT9* pElmEnd = pElm + elementList.size();

		while( pElm != pElmEnd )
		{
			if( pElm->Usage == usage ) { usageIndex++; }

			pElm++;
		}
	}

	/*
		追加
	*/

	elm.Stream = 0;
	elm.Offset = offset;
	elm.Type = type;
	elm.Method = D3DDECLMETHOD_DEFAULT;
	elm.Usage = usage;
	elm.UsageIndex = usageIndex;

	elementList.push_back( elm );
}

void Manager::CloseVertexElement( std::vector<D3DVERTEXELEMENT9>& elementList )
{
	D3DVERTEXELEMENT9 elm = D3DDECL_END();
	elementList.push_back( elm );
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Private : シーン
////////////////////////////////////////////////////////////////////////////////////////////////////

void Manager::AddScene( Mix::Tool::Win32::Graphics::Scene* pScene )
{
	m_SceneList.push_back( pScene );
}

void Manager::RemoveScene( Mix::Tool::Win32::Graphics::Scene* pScene )
{
	m_SceneList.remove( pScene );
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Private : ウォーターマテリアル( 波アニメーションの更新用 )
////////////////////////////////////////////////////////////////////////////////////////////////////

void Manager::AddWaveMaterial( Mix::Tool::Win32::Graphics::Material* pMaterial )
{
	m_WaveMaterialList.push_back( pMaterial );
}

void Manager::RemoveWaveMaterial( Mix::Tool::Win32::Graphics::Material* pMaterial )
{
	m_WaveMaterialList.remove( pMaterial );
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Private : マウスの操作( 感度を反映した値を返します )
////////////////////////////////////////////////////////////////////////////////////////////////////

float Manager::GetDistation( int d )
{
	return static_cast<float>( d ) * m_MouseOption.scalingSensitivity;
}

float Manager::GetScaling( const D3DXVECTOR2& basePos, const D3DXVECTOR2& pos )
{
	float h = pos.x - basePos.x;
	float v = pos.y - basePos.y;

	return ::sqrtf( h * h + v * v ) * m_MouseOption.scalingSensitivity;
}

D3DXVECTOR3 Manager::GetRotation( int h, int v )
{
	return D3DXVECTOR3( static_cast<float>( h ) * m_MouseOption.rotationSensitivity, static_cast<float>( v ) * m_MouseOption.rotationSensitivity, 0.0f );
}

D3DXVECTOR3 Manager::GetTranslation( int h, int v )
{
	return D3DXVECTOR3( static_cast<float>( h ) * m_MouseOption.translationSensitivity, static_cast<float>( v ) * m_MouseOption.translationSensitivity, 0.0f );
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Private : ディフューズテクスチャの名前から各テクスチャの名前への変換
////////////////////////////////////////////////////////////////////////////////////////////////////

bool Manager::GetSpecularTextureFileName( const wchar_t* pDiffuseTextureFileName, std::wstring& output )
{
	return FindTextureFile( pDiffuseTextureFileName, m_TextureOption.specular.c_str(), output );
}

bool Manager::GetEmissiveTextureFileName( const wchar_t* pDiffuseTextureFileName, std::wstring& output )
{
	return FindTextureFile( pDiffuseTextureFileName, m_TextureOption.emissive.c_str(), output );
}

bool Manager::GetBumpTextureFileName( const wchar_t* pDiffuseTextureFileName, std::wstring& output )
{
	return FindTextureFile( pDiffuseTextureFileName, m_TextureOption.bump.c_str(), output );
}

bool Manager::FindTextureFile( const wchar_t* pDiffuseTextureFileName, const wchar_t* pFormat, std::wstring& output )
{
	CONVERT_FILENAME_DATA cfd;
	unsigned int i;
	std::wstring baseFileName;
	std::wstring tempFileName;

	if( CreateConvertFileNameData( pDiffuseTextureFileName, cfd ) == false )
	{
		return false;
	}

	if( ConvertFileName( cfd, pFormat, baseFileName ) == false )
	{
		return false;
	}

	for( i = 0; i < Manager::TEXTURE_EXT_COUNT; i++ )
	{
		HANDLE hFile;

		tempFileName = baseFileName;
		tempFileName += Manager::TEXTURE_EXT_TABLE[i];

		hFile = ::CreateFile( tempFileName.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
		if( hFile != INVALID_HANDLE_VALUE )
		{
			output = tempFileName;
			::CloseHandle( hFile );
			return true;
		}
	}

	return false;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Private : その他
////////////////////////////////////////////////////////////////////////////////////////////////////

unsigned int Manager::ToColorUI( const D3DXVECTOR4& src )
{
	unsigned int ret = 0;

	ret |= MIX_CLAMP( static_cast<unsigned int>( src.w * 255.0f ), 0, 255 ) << 24;
	ret |= MIX_CLAMP( static_cast<unsigned int>( src.x * 255.0f ), 0, 255 ) << 16;
	ret |= MIX_CLAMP( static_cast<unsigned int>( src.y * 255.0f ), 0, 255 ) << 8;
	ret |= MIX_CLAMP( static_cast<unsigned int>( src.z * 255.0f ), 0, 255 );

	return ret;
}

}}}}
