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

#include <algorithm>
#include <sstream>

#include "Mix/Tool/Win32/Core/Dynamics/World.h"
#include "Mix/Tool/Win32/Core/Dynamics/Design/Actor.h"

#include "Mix/Tool/Win32/Core/Graphics/Manager.h"
#include "Mix/Tool/Win32/Core/Graphics/VertexBuffer.h"
#include "Mix/Tool/Win32/Core/Graphics/IndexBuffer.h"
#include "Mix/Tool/Win32/Core/Graphics/SwapChain.h"
#include "Mix/Tool/Win32/Core/Graphics/TargetTexture.h"
#include "Mix/Tool/Win32/Core/Graphics/CubeTexture.h"
#include "Mix/Tool/Win32/Core/Graphics/Camera.h"
#include "Mix/Tool/Win32/Core/Graphics/Material.h"
#include "Mix/Tool/Win32/Core/Graphics/DrawObject.h"

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

// 背景 //

const D3DXVECTOR4 Scene::DEF_BACKGROUND_COLOR = D3DXVECTOR4( 0.1f, 0.1f, 0.1f, 1.0f );

// グリッド //

const D3DXVECTOR4 Scene::DEF_GRID_COLOR = D3DXVECTOR4( 0.5f, 0.5f, 0.5f, 1.0f );
const float Scene::DEF_GRID_PITCH = 1.0f;
const float Scene::DEF_GRID_EXTENT = 20.0f;

// 全般 //

const D3DXVECTOR4 Scene::DEF_TEXT_COLOR = D3DXVECTOR4( 1.0f, 1.0f, 1.0f, 1.0f );
const D3DXVECTOR4 Scene::DEF_VIEWVOLUME_COLOR = D3DXVECTOR4( 1.0f, 1.0f, 0.0f, 1.0f );
const D3DXVECTOR4 Scene::DEF_BONE_COLOR = D3DXVECTOR4( 1.0f, 0.0f, 1.0f, 1.0f );
const D3DXVECTOR4 Scene::DEF_SELECTED_COLOR = D3DXVECTOR4( 1.0f, 0.5f, 0.1f, 0.3f );
const float Scene::DEF_AXIS_SCALE = 0.1f;

// ダイナミクス //

const D3DXVECTOR4 Scene::DEF_KC_COLOR = D3DXVECTOR4( 0.5f, 0.5f, 1.0f, 1.0f );
const D3DXVECTOR4 Scene::DEF_SENSOR_COLOR = D3DXVECTOR4( 1.0f, 0.5f, 0.5f, 1.0f );
const D3DXVECTOR4 Scene::DEF_COLLISION_COLOR = D3DXVECTOR4( 1.0f, 1.0f, 1.0f, 1.0f );
const D3DXVECTOR4 Scene::DEF_JAXIS_COLOR = D3DXVECTOR4( 0.5f, 1.0f, 0.5f, 1.0f );
const D3DXVECTOR4 Scene::DEF_JBALL_COLOR = D3DXVECTOR4( 1.0f, 1.0f, 0.5f, 1.0f );
const D3DXVECTOR4 Scene::DEF_JLIMIT_COLOR = D3DXVECTOR4( 0.5f, 0.5f, 1.0f, 1.0f );
const float Scene::DEF_JSCALE = 0.1f;

// グローバルアンビエント  //

const D3DXVECTOR4 Scene::DEF_GLOBAL_AMBIENT_COLOR = D3DXVECTOR4( 0.0f, 0.0f, 0.0f, 1.0f );

// ライト //

const D3DXVECTOR4 Scene::DEF_DIR_LIGHT_COLOR = D3DXVECTOR4( 1.0f, 1.0f, 1.0f, 1.0f );
const float Scene::DEF_DIR_LIGHT_LINE_Z = 100.0f;
const float Scene::DEF_DIR_LIGHT_DRAW_SCALE = 0.1f;
const float Scene::DEF_DIR_LIGHT_ROT_X = D3DXToRadian( -45.0f );
const float Scene::DEF_DIR_LIGHT_ROT_Y = D3DXToRadian( -135.0f );

// ディレクショナルライトの矢印のバーテックステーブル
const D3DXVECTOR4 Scene::DIR_LIGHT_VERTEX_TABLE[4] =
{
	D3DXVECTOR4(  0.0f,  0.0f, 0.0f, 1.0f ),
	D3DXVECTOR4(  0.0f,  1.0f, 4.0f, 1.0f ),
	D3DXVECTOR4( -1.0f, -1.0f, 4.0f, 1.0f ),
	D3DXVECTOR4(  1.0f, -1.0f, 4.0f, 1.0f ),
};

// ディレクショナルライトの矢印のインデックステーブル
const unsigned int Scene::DIR_LIGHT_INDEX_TABLE[6][2] =
{
	{ 0, 1, },
	{ 0, 2, },
	{ 0, 3, },

	{ 1, 2, },
	{ 2, 3, },
	{ 3, 1, },
};

////////////////////////////////////////////////////////////////////////////////////////////////////
// Scene::DepthTextureHelper
////////////////////////////////////////////////////////////////////////////////////////////////////

Scene::DepthTextureHelper::DepthTextureHelper( void ) :
m_CurrentIndex( 0 ),
m_NextIndex( 1 )
{
	for( unsigned int i = 0; i < Scene::DepthTextureHelper::TEX_MAX; i++ )
	{
		m_pTex[i] = NULL;
	}
}

Scene::DepthTextureHelper::~DepthTextureHelper( void )
{
	for( unsigned int i = 0; i < DepthTextureHelper::TEX_MAX; i++ )
	{
		MIX_RELEASE( m_pTex[i] );
	}
}

bool Scene::DepthTextureHelper::Initialize( D3DFORMAT d3dFormat )
{
	Mix::Tool::Win32::Graphics::Manager* pManager = Manager::GetInstance();
	if( pManager == NULL )
	{
		return false;
	}

	for( unsigned int i = 0; i < DepthTextureHelper::TEX_MAX; i++ )
	{
		m_pTex[i] = pManager->CreateTargetTexture( d3dFormat );
		if( m_pTex[i] == NULL )
		{
			return false;
		}
	}

	return true;
}

void Scene::DepthTextureHelper::Flip( void )
{
	Mix::Tool::Win32::Graphics::Manager* pManager = Manager::GetInstance();
	if( pManager == NULL )
	{
		return;
	}

	Mix::Tool::Win32::Graphics::Texture* pSource = m_pTex[m_NextIndex];
	Mix::Tool::Win32::Graphics::Texture* pTarget = m_pTex[m_CurrentIndex];

	unsigned int width = pTarget->GetWidth();
	unsigned int height = pTarget->GetHeight();

	pManager->SetTarget( pTarget, NULL, NULL, NULL );
	pManager->SetViewport( width, height );
	pManager->SetScissorRect( width, height );
	pManager->SetDepthState( false, false );
	pManager->SetRasterizerState( D3DFILL_SOLID, D3DCULL_NONE, true );
	pManager->SetBlendState( Mix::Tool::Win32::Graphics::BLEND_COPY );
	pManager->SetTexture( Mix::Tool::Win32::Graphics::TS_DEPTH_TEXTURE, D3DTEXF_POINT,  D3DTADDRESS_CLAMP, NULL );
	pManager->DrawQuad( pSource );

	m_CurrentIndex = ( m_CurrentIndex + 1 ) % DepthTextureHelper::TEX_MAX;
	m_NextIndex = ( m_NextIndex + 1 ) % DepthTextureHelper::TEX_MAX;
}

Mix::Tool::Win32::Graphics::Texture* Scene::DepthTextureHelper::GetCurrentPtr( void )
{
	return m_pTex[m_CurrentIndex];
}

Mix::Tool::Win32::Graphics::Texture* Scene::DepthTextureHelper::GetNextPtr( void )
{
	return m_pTex[m_NextIndex];
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Scene
////////////////////////////////////////////////////////////////////////////////////////////////////

Scene::Scene( void ) :
m_pColorTex( NULL ),
m_pDepthTex( NULL ),
m_pRefractTex( NULL ),
m_pDrawObject( NULL ),
m_pDynamicsActorDesigner( NULL ),
m_pDynamicsWorld( NULL ),
m_ReflectionTexFilePath( L"" ),
m_pRelrectionTex( NULL ),
m_DrawPrimitiveCount( 0 ),
m_BackgroundColor( Scene::DEF_BACKGROUND_COLOR ),
m_GridColor( Scene::DEF_GRID_COLOR ),
m_TextColor( Scene::DEF_TEXT_COLOR ),
m_ViewVolumeColor( Scene::DEF_VIEWVOLUME_COLOR ),
m_BoneColor( Scene::DEF_BONE_COLOR ),
m_KinematicCharacterColor( Scene::DEF_KC_COLOR ),
m_SensorColor( Scene::DEF_SENSOR_COLOR ),
m_CollisionColor( Scene::DEF_COLLISION_COLOR ),
m_JointAxisColor( Scene::DEF_JAXIS_COLOR ),
m_JointBallColor( Scene::DEF_JBALL_COLOR ),
m_JointLimitColor( Scene::DEF_JLIMIT_COLOR ),
m_JointScale( Scene::DEF_JSCALE ),
m_SelectedColor( Scene::DEF_SELECTED_COLOR ),
m_AxisScale( Scene::DEF_AXIS_SCALE ),
m_LightAmbientColor( Scene::DEF_GLOBAL_AMBIENT_COLOR ),
m_LightDiffuseColor( Scene::DEF_DIR_LIGHT_COLOR ),
m_LightDrawScale( Scene::DEF_DIR_LIGHT_DRAW_SCALE )
{
	Mix::Tool::Win32::Graphics::Manager* pManager = Manager::GetInstance();

	// グリッド //

	m_GridParam.pitch = Scene::DEF_GRID_PITCH;
	m_GridParam.extent = Scene::DEF_GRID_EXTENT;

	UpdateGridLineList();

	// ライト //

	ResetLightPoseMatrix();

	m_LightArrow.reserve( 12 );
	for( unsigned int j = 0; j < 6; j++ )
	{
		const D3DXVECTOR4& p0 = DIR_LIGHT_VERTEX_TABLE[ DIR_LIGHT_INDEX_TABLE[j][0] ];
		const D3DXVECTOR4& p1 = DIR_LIGHT_VERTEX_TABLE[ DIR_LIGHT_INDEX_TABLE[j][1] ];

		m_LightArrow.push_back( LINE_VERTEX( p0, Scene::DEF_DIR_LIGHT_COLOR ) );
		m_LightArrow.push_back( LINE_VERTEX( p1, Scene::DEF_DIR_LIGHT_COLOR ) );
	}

	m_LightLine.reserve( 2 );
	m_LightLine.push_back( LINE_VERTEX( D3DXVECTOR4( 0.0f, 0.0f, 0.0f, 1.0f ), Scene::DEF_DIR_LIGHT_COLOR ) );
	m_LightLine.push_back( LINE_VERTEX( D3DXVECTOR4( 0.0f, 0.0f, Scene::DEF_DIR_LIGHT_LINE_Z, 1.0f ), Scene::DEF_DIR_LIGHT_COLOR ) );

	// 完了 //

	if( pManager != NULL )
	{
		pManager->AddScene( this );
	}
}

Scene::~Scene( void )
{
	Mix::Tool::Win32::Graphics::Manager* pManager = Manager::GetInstance();

	if( pManager != NULL )
	{
		pManager->RemoveScene( this );
	}

	for( Scene::CameraList::iterator it = m_CameraList.begin(); it != m_CameraList.end(); ++it )
	{
		( *it )->SetScenePtr( NULL );
	}

	if( m_pDrawObject != NULL )
	{
		m_pDrawObject->SetScenePtr( NULL );
	}

	MIX_RELEASE( m_pColorTex );
	MIX_DELETE( m_pDepthTex );
	MIX_RELEASE( m_pRefractTex );
	MIX_RELEASE( m_pRelrectionTex );
}

bool Scene::Initialize( void )
{
	////////////////////////////////////////////////////////////////////////////////////////////////////
	// マネージャを取得
	////////////////////////////////////////////////////////////////////////////////////////////////////

	Mix::Tool::Win32::Graphics::Manager* pManager = Manager::GetInstance();
	if( pManager == NULL )
	{
		return false;
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// デプステクスチャを作成
	////////////////////////////////////////////////////////////////////////////////////////////////////

#ifdef _DEBUG
	const D3DFORMAT DEPTH_TEX_FORMAT_TABLE[2] = { D3DFMT_A32B32G32R32F, D3DFMT_A16B16G16R16F, };
#else //_DEBUG
	const D3DFORMAT DEPTH_TEX_FORMAT_TABLE[2] = { D3DFMT_R32F, D3DFMT_R16F, };
#endif //_DEBUG

	const unsigned int DEPTH_TEX_FORMAT_COUNT = sizeof( DEPTH_TEX_FORMAT_TABLE ) / sizeof( D3DFORMAT );

	D3DFORMAT depthTexFormat = D3DFMT_UNKNOWN;

	for( unsigned int i = 0; ( i < DEPTH_TEX_FORMAT_COUNT ) && ( depthTexFormat == D3DFMT_UNKNOWN ); i++ )
	{
		D3DFORMAT tempFormat = DEPTH_TEX_FORMAT_TABLE[i];

		if( pManager->CheckTargetTextureFormat( tempFormat ) == true )
		{
			depthTexFormat = tempFormat;
		}
	}

	if( depthTexFormat == D3DFMT_UNKNOWN )
	{
		return false;
	}

	m_pDepthTex = new Scene::DepthTextureHelper();
	if( m_pDepthTex == NULL )
	{
		return false;
	}

	if( m_pDepthTex->Initialize( depthTexFormat ) == false )
	{
		return false;
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// カラーテクスチャを作成
	////////////////////////////////////////////////////////////////////////////////////////////////////

	m_pColorTex = pManager->CreateTargetTexture( D3DFMT_A8R8G8B8 );
//	m_pColorTex = pManager->CreateTargetTexture( D3DFMT_A32B32G32R32F );
	if( m_pColorTex == NULL )
	{
		return false;
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// リフラクトテクスチャを作成
	////////////////////////////////////////////////////////////////////////////////////////////////////

	const D3DFORMAT REFRACT_TEX_FORMAT_TABLE[2] = { D3DFMT_A32B32G32R32F, D3DFMT_A16B16G16R16F, };
	const unsigned int REFRACT_TEX_FORMAT_COUNT = sizeof( REFRACT_TEX_FORMAT_TABLE ) / sizeof( D3DFORMAT );

	D3DFORMAT refractTexFormat = D3DFMT_UNKNOWN;

	for( unsigned int i = 0; ( i < REFRACT_TEX_FORMAT_COUNT ) && ( refractTexFormat == D3DFMT_UNKNOWN ); i++ )
	{
		D3DFORMAT tempFormat = REFRACT_TEX_FORMAT_TABLE[i];

		if( pManager->CheckTargetTextureFormat( tempFormat ) == true )
		{
			refractTexFormat = tempFormat;
		}
	}

	if( refractTexFormat == D3DFMT_UNKNOWN )
	{
		return false;
	}

	m_pRefractTex = pManager->CreateTargetTexture( refractTexFormat );
	if( m_pRefractTex == NULL )
	{
		return false;
	}

	return true;
}

const D3DXVECTOR4& Scene::GetBackgroundColor( void ) const
{
	return m_BackgroundColor;
}

void Scene::SetBackgroundColor( const D3DXVECTOR4& color )
{
	m_BackgroundColor = color;
}

const D3DXVECTOR4& Scene::GetGridColor( void ) const
{
	return m_GridColor;
}

void Scene::SetGridColor( const D3DXVECTOR4& color )
{
	m_GridColor = color;

	for( std::vector<Mix::Tool::Win32::Graphics::LINE_VERTEX>::iterator it = m_GridLineList.begin(); it != m_GridLineList.end(); ++it )
	{
		( *it ).color = color;
	}
}

float Scene::GetGridPitch( void ) const
{
	return m_GridParam.pitch;
}

void Scene::SetGridPitch( float pitch )
{
	if( m_GridParam.pitch == pitch )
	{
		return;
	}

	m_GridParam.pitch = pitch;

	UpdateGridLineList();
}

float Scene::GetGridExtent( void ) const
{
	return m_GridParam.extent;
}

void Scene::SetGridExtent( float extent )
{
	if( m_GridParam.extent == extent )
	{
		return;
	}

	m_GridParam.extent = extent;

	UpdateGridLineList();
}

const D3DXVECTOR4& Scene::GetTextColor( void ) const
{
	return m_TextColor;
}

void Scene::SetTextColor( const D3DXVECTOR4& color )
{
	m_TextColor = color;
}

const D3DXVECTOR4& Scene::GetViewVolumeColor( void ) const
{
	return m_ViewVolumeColor;
}

void Scene::SetViewVolumeColor( const D3DXVECTOR4& color )
{
	m_ViewVolumeColor = color;
}

const D3DXVECTOR4& Scene::GetBoneColor( void ) const
{
	return m_BoneColor;
}

void Scene::SetBoneColor( const D3DXVECTOR4& color )
{
	m_BoneColor = color;
}

const D3DXVECTOR4& Scene::GetKinematicCharacterColor( void ) const
{
	return m_KinematicCharacterColor;
}

void Scene::SetKinematicCharacterColor( const D3DXVECTOR4& color )
{
	m_KinematicCharacterColor = color;
}

const D3DXVECTOR4& Scene::GetSensorColor( void ) const
{
	return m_SensorColor;
}

void Scene::SetSensorColor( const D3DXVECTOR4& color )
{
	m_SensorColor = color;
}

const D3DXVECTOR4& Scene::GetCollisionColor( void ) const
{
	return m_CollisionColor;
}

void Scene::SetCollisionColor( const D3DXVECTOR4& color )
{
	m_CollisionColor = color;
}

const D3DXVECTOR4& Scene::GetJointAxisColor( void ) const
{
	return m_JointAxisColor;
}

void Scene::SetJointAxisColor( const D3DXVECTOR4& color )
{
	m_JointAxisColor = color;
}

const D3DXVECTOR4& Scene::GetJointBallColor( void ) const
{
	return m_JointBallColor;
}

void Scene::SetJointBallColor( const D3DXVECTOR4& color )
{
	m_JointBallColor = color;
}

const D3DXVECTOR4& Scene::GetJointLimitColor( void ) const
{
	return m_JointLimitColor;
}

void Scene::SetJointLimitColor( const D3DXVECTOR4& color )
{
	m_JointLimitColor = color;
}

float Scene::GetJointScale( void ) const
{
	return m_JointScale;
}

void Scene::SetJointScale( float scale )
{
	m_JointScale = max( 0.0f, scale );
}

const D3DXVECTOR4& Scene::GetSelectedColor( void ) const
{
	return m_SelectedColor;
}

void Scene::SetSelectedColor( const D3DXVECTOR4& color )
{
	m_SelectedColor = color;
}

float Scene::GetAxisScale( void ) const
{
	return m_AxisScale;
}

void Scene::SetAxisScale( float scale )
{
	m_AxisScale = max( 0.0f, scale );
}

bool Scene::AddCamera( Mix::Tool::Win32::Graphics::Camera* pCamera )
{
	if( ( pCamera != NULL ) &&
		( pCamera->GetScenePtr() == NULL ) )
	{
		pCamera->SetScenePtr( this );
		m_CameraList.push_back( pCamera );
	}
	else
	{
		return false;
	}

	return true;
}

bool Scene::RemoveCamera( Mix::Tool::Win32::Graphics::Camera* pCamera )
{
	if( ( pCamera != NULL ) &&
		( pCamera->GetScenePtr() == this ) )
	{
		pCamera->SetScenePtr( NULL );
		m_CameraList.remove( pCamera );
	}
	else
	{
		return false;
	}

	return true;
}

const D3DXVECTOR4& Scene::GetLightAmbientColor( void ) const
{
	return m_LightAmbientColor;
}

void Scene::SetLightAmbientColor( const D3DXVECTOR4& color )
{
	m_LightAmbientColor = color;
}

void Scene::ResetLightPoseMatrix( void )
{
	D3DXMATRIX m0;
	D3DXMATRIX m1;

	::D3DXMatrixRotationX( &m0, Scene::DEF_DIR_LIGHT_ROT_X );
	::D3DXMatrixRotationY( &m1, Scene::DEF_DIR_LIGHT_ROT_Y );

	SetLightPoseMatrix( m0 * m1 );
}

const D3DXMATRIX& Scene::GetLightPoseMatrix( void ) const
{
	return m_LightPoseMatrix;
}

void Scene::SetLightPoseMatrix( const D3DXMATRIX& mat )
{
	m_LightPoseMatrix = mat;
	D3DXQuaternionRotationMatrix( &m_LightPoseQuat, &mat );

	UpdateLightDir( m_LightPoseMatrix );
}

const D3DXQUATERNION& Scene::GetLightPoseQuat( void ) const
{
	return m_LightPoseQuat;
}

void Scene::SetLightPoseQuat( const D3DXQUATERNION& quat )
{
	::D3DXMatrixRotationQuaternion( &m_LightPoseMatrix, &quat );
	m_LightPoseQuat = quat;

	UpdateLightDir( m_LightPoseMatrix );
}

const D3DXVECTOR3& Scene::GetLightDirection( void ) const
{
	return m_LightDirection;
}

const D3DXVECTOR4& Scene::GetLightDiffuseColor( void ) const
{
	return m_LightDiffuseColor;
}

void Scene::SetLightDiffuseColor( const D3DXVECTOR4& color )
{
	if( m_LightDiffuseColor == color )
	{
		return;
	}

	m_LightDiffuseColor = color;

	for( std::vector<Mix::Tool::Win32::Graphics::LINE_VERTEX>::iterator it = m_LightArrow.begin(); it != m_LightArrow.end(); ++it )
	{
		( *it ).color = color;
	}

	for( std::vector<Mix::Tool::Win32::Graphics::LINE_VERTEX>::iterator it = m_LightLine.begin(); it != m_LightLine.end(); ++it )
	{
		( *it ).color = color;
	}
}

float Scene::GetLightDrawScale( void ) const
{
	return m_LightDrawScale;
}

void Scene::SetLightDrawScale( float scale )
{
	m_LightDrawScale = scale;
}

Mix::Tool::Win32::Graphics::DrawObject* Scene::GetDrawObject( void ) const
{
	return m_pDrawObject;
}

void Scene::SetDrawObject( Mix::Tool::Win32::Graphics::DrawObject* pDrawObject )
{
	if( m_pDrawObject != NULL )
	{
		m_pDrawObject->SetScenePtr( NULL );
	}

	m_pDrawObject = pDrawObject;

	if( m_pDrawObject != NULL )
	{
		m_pDrawObject->SetScenePtr( this );
	}

	m_pDynamicsActorDesigner = NULL;

	m_pDynamicsWorld = NULL;
}

Mix::Tool::Win32::Dynamics::Design::Actor* Scene::GetDynamicsActorDesigner( void ) const
{
	return m_pDynamicsActorDesigner;
}

void Scene::SetDynamicsActorDesigner( Mix::Tool::Win32::Dynamics::Design::Actor* pDynamicsActorDesigner )
{
	if( m_pDrawObject != NULL )
	{
		m_pDrawObject->SetScenePtr( NULL );
		m_pDrawObject = NULL;
	}

	m_pDynamicsActorDesigner = pDynamicsActorDesigner;

	m_pDynamicsWorld = NULL;
}

Mix::Tool::Win32::Dynamics::World* Scene::GetDynamicsWorld( void ) const
{
	return m_pDynamicsWorld;
}

void Scene::SetDynamicsWorld( Mix::Tool::Win32::Dynamics::World* pDynamicsWorld )
{
	if( m_pDrawObject != NULL )
	{
		m_pDrawObject->SetScenePtr( NULL );
		m_pDrawObject = NULL;
	}

	m_pDynamicsActorDesigner = NULL;

	m_pDynamicsWorld = pDynamicsWorld;
}

const wchar_t* Scene::GetReflectionTexture( void ) const
{
	return m_ReflectionTexFilePath.c_str();
}

void Scene::SetReflectionTexture( const wchar_t* pFileName )
{
	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 解放
	////////////////////////////////////////////////////////////////////////////////////////////////////

	m_ReflectionTexFilePath = L"";
	MIX_RELEASE( m_pRelrectionTex );

	if( ( pFileName == NULL ) ||
		( ::wcslen( pFileName ) == 0 ) )
	{
		return;
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// マネージャを取得
	////////////////////////////////////////////////////////////////////////////////////////////////////

	Mix::Tool::Win32::Graphics::Manager* pManager = Manager::GetInstance();
	if( pManager == NULL )
	{
		return;
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// テクスチャを読み込む
	////////////////////////////////////////////////////////////////////////////////////////////////////

	m_pRelrectionTex = pManager->CreateCubeTexture( pFileName );
	if( m_pRelrectionTex != NULL )
	{
		m_ReflectionTexFilePath = pFileName;
	}
}

void Scene::OnUpdate( void )
{
	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 描画オブジェクトを更新
	////////////////////////////////////////////////////////////////////////////////////////////////////

	if( ( m_pDrawObject != NULL ) &&
		( m_pDrawObject->GetDisableCount() <= 0 ) )
	{
		m_pDrawObject->OnUpdate();
	}
}

void Scene::OnRefresh( void )
{
	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 描画オブジェクトを更新
	////////////////////////////////////////////////////////////////////////////////////////////////////

	if( ( m_pDrawObject != NULL ) &&
		( m_pDrawObject->GetDisableCount() <= 0 ) )
	{
		m_pDrawObject->OnRefresh();
	}
}

bool Scene::OnDraw( void )
{
	////////////////////////////////////////////////////////////////////////////////////////////////////
	// マネージャを取得
	////////////////////////////////////////////////////////////////////////////////////////////////////

	Mix::Tool::Win32::Graphics::Manager* pManager = Manager::GetInstance();
	if( pManager == NULL )
	{
		return true;
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 変数宣言
	////////////////////////////////////////////////////////////////////////////////////////////////////

	const D3DXMATRIX& projMat = pManager->GetProjectionMatrix();

	Scene::CameraList::iterator it_camera_begin = m_CameraList.begin();
	Scene::CameraList::iterator it_camera_end = m_CameraList.end();
	Scene::CameraList::iterator it_camera;

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// カメラ毎に描画
	////////////////////////////////////////////////////////////////////////////////////////////////////

	for( it_camera = it_camera_begin; it_camera != it_camera_end; ++it_camera )
	{
		Mix::Tool::Win32::Graphics::Camera* pCamera = ( *it_camera );
		Mix::Tool::Win32::Graphics::SwapChain* pSwapChain = pCamera->GetSwapChainPtr();

		if( ( pSwapChain != NULL ) &&
			( pCamera->IsActive() == true ) )
		{
			pCamera->Update();

			if( pSwapChain->Begin() == true )
			{
				BeginDraw( pCamera );

				DrawSelectMap( pManager, pCamera );
				DrawColor( pManager, pCamera, pSwapChain );

				EndDraw();

				pSwapChain->End();
			}

			if( pSwapChain->Present() == false )
			{
				return false;
			}
		}
	}

	return true;
}

void Scene::BeginDraw( Mix::Tool::Win32::Graphics::Camera* pCamera )
{
	unsigned int drawFlags = pCamera->GetDrawFlags();

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 初期化
	////////////////////////////////////////////////////////////////////////////////////////////////////

	m_DrawPrimitiveCount = 0;

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 描画オブジェクトの事前処理( 描画データの収集 )
	////////////////////////////////////////////////////////////////////////////////////////////////////

	if( ( m_pDrawObject != NULL ) &&
		( m_pDrawObject->GetDisableCount() <= 0 ) )
	{
		DrawObject::DRAW_EVENT_ARGS deArgs;

		if( MIX_TEST_BIT( drawFlags, Camera::DRAW_BODY                 ) == Camera::DRAW_BODY                 ) { deArgs.flags |= DrawObject::DF_BODY; }
		if( MIX_TEST_BIT( drawFlags, Camera::DRAW_VIEWVOLUME           ) == Camera::DRAW_VIEWVOLUME           ) { deArgs.flags |= DrawObject::DF_VIEWVOLUME; }
		if( MIX_TEST_BIT( drawFlags, Camera::DRAW_BONE                 ) == Camera::DRAW_BONE                 ) { deArgs.flags |= DrawObject::DF_BONE; }
		if( MIX_TEST_BIT( drawFlags, Camera::DRAW_KINEMATIC_CHARACTER  ) == Camera::DRAW_KINEMATIC_CHARACTER  ) { deArgs.flags |= DrawObject::DF_KINEMATIC_CHARACTER; }
		if( MIX_TEST_BIT( drawFlags, Camera::DRAW_COLLISION            ) == Camera::DRAW_COLLISION            ) { deArgs.flags |= DrawObject::DF_COLLISION; }
		if( MIX_TEST_BIT( drawFlags, Camera::DRAW_JOINT                ) == Camera::DRAW_JOINT                ) { deArgs.flags |= DrawObject::DF_JOINT; }
		deArgs.selectColor = m_SelectedColor;
		deArgs.axisScale = m_AxisScale;
		deArgs.viewVolumeColor = m_ViewVolumeColor;
		deArgs.boneColor = m_BoneColor;
		deArgs.kinematicCharacterColor = m_KinematicCharacterColor;
		deArgs.sensorColor = m_SensorColor;
		deArgs.collisionColor = m_CollisionColor;
		deArgs.jointAxisColor = m_JointAxisColor;
		deArgs.jointBallColor = m_JointBallColor;
		deArgs.jointLimitColor = m_JointLimitColor;
		deArgs.jointScale = m_JointScale;
		deArgs.pCamera = pCamera;
		deArgs.pLineHelper = &m_LineHelper;
		deArgs.pOpacitySubsets = &m_OpacitySubsets;
		deArgs.pTransparencySubsets = &m_TransparencySubsets;
		deArgs.pRefractSubsets = &m_RefractSubsets;
		deArgs.pSelectMapSubsets = &m_SelectMapSubsets;
		deArgs.pSelectSubsets = &m_SelectColorSubsets;

		m_pDrawObject->OnDraw( deArgs );

		std::sort( m_OpacitySubsets.begin(), m_OpacitySubsets.end(), Mix::Tool::Win32::Graphics::OPACITY_SUBSET() );
		std::sort( m_TransparencySubsets.begin(), m_TransparencySubsets.end(), Mix::Tool::Win32::Graphics::TRANSPARENCY_SUBSET() );
		std::sort( m_RefractSubsets.begin(), m_RefractSubsets.end(), Mix::Tool::Win32::Graphics::REFRACT_SUBSET() );
		std::sort( m_SelectColorSubsets.begin(), m_SelectColorSubsets.end(), Mix::Tool::Win32::Graphics::TRANSPARENCY_SUBSET() );
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// ダイナミクス : ユニバーサルデザイナーの事前処理( 描画データの収集 )
	////////////////////////////////////////////////////////////////////////////////////////////////////

	if( m_pDynamicsActorDesigner != NULL )
	{
		m_pDynamicsActorDesigner->Draw( &m_LineHelper,
											( MIX_TEST_BIT( drawFlags, Camera::DRAW_KINEMATIC_CHARACTER  ) == Camera::DRAW_KINEMATIC_CHARACTER ),
											( MIX_TEST_BIT( drawFlags, Camera::DRAW_COLLISION ) == Camera::DRAW_COLLISION ),
											( MIX_TEST_BIT( drawFlags, Camera::DRAW_COLLISION ) == Camera::DRAW_COLLISION ),
											( MIX_TEST_BIT( drawFlags, Camera::DRAW_JOINT ) == Camera::DRAW_JOINT ),
											m_SelectedColor,
											m_KinematicCharacterColor,
											m_SensorColor,
											m_CollisionColor,
											m_JointAxisColor,
											m_JointBallColor,
											m_JointLimitColor,
											m_JointScale,
											m_AxisScale,
											true );
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// ダイナミクス : ワールドの事前処理( 描画データの収集 )
	////////////////////////////////////////////////////////////////////////////////////////////////////

	if( m_pDynamicsWorld != NULL )
	{
		m_pDynamicsWorld->Draw( &m_LineHelper );
	}
}

void Scene::EndDraw( void )
{
	m_OpacitySubsets.clear();
	m_TransparencySubsets.clear();
	m_RefractSubsets.clear();
	m_SelectMapSubsets.clear();
	m_SelectColorSubsets.clear();
	m_LineHelper.Clear();
}

void Scene::DrawSelectMap(	Mix::Tool::Win32::Graphics::Manager* pManager,
							Mix::Tool::Win32::Graphics::Camera* pCamera )
{
	////////////////////////////////////////////////////////////////////////////////////////////////////
	// セレクトマップのテクスチャの取得
	////////////////////////////////////////////////////////////////////////////////////////////////////

	Mix::Tool::Win32::Graphics::TargetTexture* pSelectMapTex = pCamera->GetSelectMapTexPtr();
	if( pSelectMapTex == NULL )
	{
		return;
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 描画準備
	////////////////////////////////////////////////////////////////////////////////////////////////////

	pManager->SetTarget( pSelectMapTex, NULL, NULL, NULL );
	pManager->SetViewport( pSelectMapTex->GetWidth(), pSelectMapTex->GetHeight() );
	pManager->SetScissorRect( pSelectMapTex->GetWidth(), pSelectMapTex->GetHeight() );
	pManager->Clear( true, true, D3DXVECTOR4( 0.0f, 0.0f, 0.0f, 0.0f ) );

	pManager->SetBlendState( Mix::Tool::Win32::Graphics::BLEND_COPY );
	pManager->SetDepthState( true, true );
	pManager->SetRasterizerState( D3DFILL_SOLID, ( pCamera->GetInvisibleSelection() == true )? D3DCULL_NONE : D3DCULL_CCW, true );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// セレクトマップを作成
	////////////////////////////////////////////////////////////////////////////////////////////////////

	std::vector<Mix::Tool::Win32::Graphics::OPACITY_SUBSET>::const_iterator it_s_begin = m_SelectMapSubsets.begin();
	std::vector<Mix::Tool::Win32::Graphics::OPACITY_SUBSET>::const_iterator it_s_end = m_SelectMapSubsets.end();
	std::vector<Mix::Tool::Win32::Graphics::OPACITY_SUBSET>::const_iterator it_s;

	for( it_s = it_s_begin; it_s != it_s_end; ++it_s )
	{
		const Mix::Tool::Win32::Graphics::OPACITY_SUBSET* pSubset = &( *it_s );

		CommitTransform( pManager, pCamera, pSubset );

		pManager->SetPixelShaderConstant( Mix::Tool::Win32::Graphics::PSR_DIFFUSE_COLOR, pSubset->selectColor );

		pManager->SetVertexLayout( pSubset->pCommonVL );
		pManager->SetVertexShader( pSubset->pSelectVS );
		pManager->SetPixelShader( pSubset->pSelectPS );
		pManager->SetVertexBuffer( pSubset->pVertexBuffer );
		pManager->SetIndexBuffer( pSubset->pIndexBuffer );

		pManager->DrawIndexedTL( pSubset->vertexStart, pSubset->vertexNum, pSubset->indexStart, pSubset->indexNum );
	}
}

void Scene::DrawColor( Mix::Tool::Win32::Graphics::Manager* pManager, Mix::Tool::Win32::Graphics::Camera* pCamera, Mix::Tool::Win32::Graphics::SwapChain* pSwapChain )
{
	unsigned int dispFlags = pCamera->GetDrawFlags();
	const D3DXMATRIX& vpMat = pCamera->GetViewProjMatrix();

	D3DFILLMODE fillMode = pCamera->GetFillMode();
	D3DXVECTOR4 camInvFarZ( MIX_FLOAT_DIV( 1.0f, pManager->GetPerspectiveFarZ() ), 0.0f, 0.0f, 0.0f );
	D3DXVECTOR4 fogParam( 0.0f, 0.0f, 0.0f, 0.0f );
	D3DXVECTOR4 hsLightDir( 0.0f, 0.0f, 0.0f, 0.0f );
	D3DXVECTOR4 localLight( 0.0f, 0.0f, 0.0f, 0.0f );

	std::vector<Mix::Tool::Win32::Graphics::OPACITY_SUBSET>::const_iterator it_o_begin = m_OpacitySubsets.begin();
	std::vector<Mix::Tool::Win32::Graphics::OPACITY_SUBSET>::const_iterator it_o_end = m_OpacitySubsets.end();
	std::vector<Mix::Tool::Win32::Graphics::OPACITY_SUBSET>::const_iterator it_o;

	std::vector<Mix::Tool::Win32::Graphics::TRANSPARENCY_SUBSET>::const_iterator it_t_begin = m_TransparencySubsets.begin();
	std::vector<Mix::Tool::Win32::Graphics::TRANSPARENCY_SUBSET>::const_iterator it_t_end = m_TransparencySubsets.end();
	std::vector<Mix::Tool::Win32::Graphics::TRANSPARENCY_SUBSET>::const_iterator it_t;

	std::vector<Mix::Tool::Win32::Graphics::REFRACT_SUBSET>::const_iterator it_r_begin = m_RefractSubsets.begin();
	std::vector<Mix::Tool::Win32::Graphics::REFRACT_SUBSET>::const_iterator it_r_end = m_RefractSubsets.end();
	std::vector<Mix::Tool::Win32::Graphics::REFRACT_SUBSET>::const_iterator it_r;

	std::vector<Mix::Tool::Win32::Graphics::TRANSPARENCY_SUBSET>::const_iterator it_s_begin = m_SelectColorSubsets.begin();
	std::vector<Mix::Tool::Win32::Graphics::TRANSPARENCY_SUBSET>::const_iterator it_s_end = m_SelectColorSubsets.end();
	std::vector<Mix::Tool::Win32::Graphics::TRANSPARENCY_SUBSET>::const_iterator it_s;

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 初期化
	////////////////////////////////////////////////////////////////////////////////////////////////////

	pManager->SetTarget( m_pColorTex, NULL, NULL, NULL );
	pManager->SetViewport( m_pColorTex->GetWidth(), m_pColorTex->GetHeight() );
	pManager->SetScissorRect( m_pColorTex->GetWidth(), m_pColorTex->GetHeight() );
	pManager->Clear( true, true, m_BackgroundColor );

	pManager->SetTarget( m_pDepthTex->GetNextPtr(), NULL, NULL, NULL );
	pManager->SetViewport( m_pDepthTex->GetNextPtr()->GetWidth(), m_pDepthTex->GetNextPtr()->GetHeight() );
	pManager->SetScissorRect( m_pDepthTex->GetNextPtr()->GetWidth(), m_pDepthTex->GetNextPtr()->GetHeight() );
	pManager->Clear( true, false, D3DXVECTOR4( 1.0, 1.0, 1.0, 1.0 ) );

	pManager->SetPixelShaderConstant( Mix::Tool::Win32::Graphics::PSR_CAMERA_INV_FARZ, camInvFarZ );
	pManager->SetPixelShaderConstant( Mix::Tool::Win32::Graphics::PSR_EYE_POS, pCamera->GetPosition() );
	pManager->SetPixelShaderConstant( Mix::Tool::Win32::Graphics::PSR_AMBIENT_LIGHT_COLOR, m_LightAmbientColor );
	pManager->SetPixelShaderConstant( Mix::Tool::Win32::Graphics::PSR_SUN_LIGHT_DIR, m_LightDirection );
	pManager->SetPixelShaderConstant( Mix::Tool::Win32::Graphics::PSR_SUN_LIGHT_COLOR, m_LightDiffuseColor );
	pManager->SetPixelShaderConstant( Mix::Tool::Win32::Graphics::PSR_FOG_PARAM, fogParam );
//	pManager->SetPixelShaderConstant( Mix::Tool::Win32::Graphics::PSR_SHADOW_PARAM, m_LightShading );
	pManager->SetPixelShaderConstant( Mix::Tool::Win32::Graphics::PSR_HS_LIGHT_AXIS, hsLightDir );
	pManager->SetPixelShaderConstant( Mix::Tool::Win32::Graphics::PSR_LOCAL_LIGHT, localLight );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 不透明サブセットの描画
	////////////////////////////////////////////////////////////////////////////////////////////////////

	pManager->SetTarget( m_pColorTex, m_pDepthTex->GetNextPtr(), NULL, NULL );
	pManager->SetViewport( m_pColorTex->GetWidth(), m_pColorTex->GetHeight() );
	pManager->SetScissorRect( m_pColorTex->GetWidth(), m_pColorTex->GetHeight() );

	pManager->SetTexture( Mix::Tool::Win32::Graphics::TS_DEPTH_TEXTURE,   D3DTEXF_POINT,  D3DTADDRESS_CLAMP, m_pDepthTex->GetCurrentPtr() );
	pManager->SetTexture( Mix::Tool::Win32::Graphics::TS_SHADOW_TEXTURE,  D3DTEXF_POINT,  D3DTADDRESS_CLAMP, NULL );
	pManager->SetTexture( Mix::Tool::Win32::Graphics::TS_REFRACT_TEXTURE, D3DTEXF_POINT,  D3DTADDRESS_CLAMP, NULL );
	pManager->SetTexture( Mix::Tool::Win32::Graphics::TS_REFRECT_TEXTURE, D3DTEXF_LINEAR, D3DTADDRESS_CLAMP, m_pRelrectionTex );

	for( it_o = it_o_begin; it_o != it_o_end; ++it_o )
	{
		const OPACITY_SUBSET* pSubset = &( *it_o );
		Mix::Tool::Win32::Graphics::Material* pMaterial = pSubset->pMaterial;
		D3DCULL cullMode = ( pMaterial->GetBackculling() == true )? D3DCULL_CCW : D3DCULL_NONE;

		////////////////////////////////////////////////////////////////////////////////////////////////////
		// 描画の準備
		////////////////////////////////////////////////////////////////////////////////////////////////////

		pManager->SetBlendState( pMaterial->GetBlendMode() );
		pManager->SetDepthState( true, true );
		pManager->SetRasterizerState( fillMode, cullMode, true );

		CommitTransform( pManager, pCamera, pSubset );
		CommitMaterial( pManager, pMaterial );

		////////////////////////////////////////////////////////////////////////////////////////////////////
		// 描画
		////////////////////////////////////////////////////////////////////////////////////////////////////

		DrawSubset( pManager, pSubset );
	}

	m_pDepthTex->Flip();

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 屈折処理
	////////////////////////////////////////////////////////////////////////////////////////////////////

	if( m_RefractSubsets.size() > 0 )
	{
		////////////////////////////////////////////////////////////////////////////////////////////////////
		// リフラクトサブセットの描画( RGB=深度 A=マスク )
		////////////////////////////////////////////////////////////////////////////////////////////////////

		pManager->SetTarget( m_pRefractTex, NULL, NULL, NULL );
		pManager->SetViewport( m_pRefractTex->GetWidth(), m_pRefractTex->GetHeight() );
		pManager->SetScissorRect( m_pRefractTex->GetWidth(), m_pRefractTex->GetHeight() );
		pManager->Clear( true, false, D3DXVECTOR4( 1.0f, 1.0f, 1.0f, 0.0f ) );

		pManager->SetDepthState( true, false );
		pManager->SetRasterizerState( D3DFILL_SOLID, D3DCULL_NONE, true );
		pManager->SetBlendState( Mix::Tool::Win32::Graphics::BLEND_COPY );

		for( it_r = it_r_begin; it_r != it_r_end; ++it_r )
		{
			const Mix::Tool::Win32::Graphics::REFRACT_SUBSET* pSubset = &( *it_r );

			////////////////////////////////////////////////////////////////////////////////////////////////////
			// 描画の準備
			////////////////////////////////////////////////////////////////////////////////////////////////////

			CommitTransform( pManager, pCamera, pSubset );

			////////////////////////////////////////////////////////////////////////////////////////////////////
			// 描画
			////////////////////////////////////////////////////////////////////////////////////////////////////

			pManager->SetVertexLayout( pSubset->pCommonVL );
			pManager->SetVertexShader( pSubset->pMaskVS );
			pManager->SetPixelShader( pSubset->pMaskPS );
			pManager->SetVertexBuffer( pSubset->pVertexBuffer );
			pManager->SetIndexBuffer( pSubset->pIndexBuffer );

			pManager->DrawIndexedTL( pSubset->vertexStart, pSubset->vertexNum, pSubset->indexStart, pSubset->indexNum );
		}

		////////////////////////////////////////////////////////////////////////////////////////////////////
		// 屈折面( 水面 )の奥にある半透明サブセットの描画( デプステクスチャに深度は出力しない )
		////////////////////////////////////////////////////////////////////////////////////////////////////

		pManager->SetTarget( m_pColorTex, NULL, NULL, NULL );
		pManager->SetViewport( m_pColorTex->GetWidth(), m_pColorTex->GetHeight() );
		pManager->SetScissorRect( m_pColorTex->GetWidth(), m_pColorTex->GetHeight() );

		pManager->SetTexture( Mix::Tool::Win32::Graphics::TS_DEPTH_TEXTURE,   D3DTEXF_POINT,  D3DTADDRESS_CLAMP, m_pDepthTex->GetCurrentPtr() );
		pManager->SetTexture( Mix::Tool::Win32::Graphics::TS_SHADOW_TEXTURE,  D3DTEXF_POINT,  D3DTADDRESS_CLAMP, NULL );
		pManager->SetTexture( Mix::Tool::Win32::Graphics::TS_REFRACT_TEXTURE, D3DTEXF_POINT,  D3DTADDRESS_CLAMP, m_pRefractTex );
		pManager->SetTexture( Mix::Tool::Win32::Graphics::TS_REFRECT_TEXTURE, D3DTEXF_LINEAR, D3DTADDRESS_CLAMP, m_pRelrectionTex );

		for( it_t = it_t_begin; it_t != it_t_end; ++it_t )
		{
			const Mix::Tool::Win32::Graphics::TRANSPARENCY_SUBSET* pSubset = &( *it_t );
			Mix::Tool::Win32::Graphics::Material* pMaterial = pSubset->pMaterial;
			D3DCULL cullMode = ( pMaterial->GetBackculling() == true )? D3DCULL_CCW : D3DCULL_NONE;

			////////////////////////////////////////////////////////////////////////////////////////////////////
			// 描画の準備
			////////////////////////////////////////////////////////////////////////////////////////////////////

			pManager->SetBlendState( pMaterial->GetBlendMode() );
//			pManager->SetDepthState( true, false );
			pManager->SetDepthState( true, pMaterial->GetZWrite() );
			pManager->SetRasterizerState( fillMode, cullMode, true );

			CommitTransform( pManager, pCamera, pSubset );
			CommitMaterial( pManager, pMaterial );

			////////////////////////////////////////////////////////////////////////////////////////////////////
			// 描画
			////////////////////////////////////////////////////////////////////////////////////////////////////

			DrawSubset( pManager, pSubset, false );
		}

		////////////////////////////////////////////////////////////////////////////////////////////////////
		// カラーテクスチャのRGBをリフラクトテクスチャにコピー( RGB=背景色 A=マスク )
		////////////////////////////////////////////////////////////////////////////////////////////////////

		pManager->SetTarget( m_pRefractTex, NULL, NULL, NULL );
		pManager->SetViewport( m_pRefractTex->GetWidth(), m_pRefractTex->GetHeight() );
		pManager->SetScissorRect( m_pRefractTex->GetWidth(), m_pRefractTex->GetHeight() );

		pManager->SetDepthState( false, false );
		pManager->SetRasterizerState( D3DFILL_SOLID, D3DCULL_NONE, false );
		pManager->SetBlendState( Mix::Tool::Win32::Graphics::BLEND_COPY, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE );

		pManager->SetTexture( Mix::Tool::Win32::Graphics::TS_REFRACT_TEXTURE, D3DTEXF_POINT, D3DTADDRESS_CLAMP, NULL );

		pManager->DrawQuad( m_pColorTex );

		////////////////////////////////////////////////////////////////////////////////////////////////////
		// リフラクトサブセットを描画
		////////////////////////////////////////////////////////////////////////////////////////////////////

		pManager->SetTarget( m_pColorTex, m_pDepthTex->GetNextPtr(), NULL, NULL );
		pManager->SetViewport( m_pColorTex->GetWidth(), m_pColorTex->GetHeight() );
		pManager->SetScissorRect( m_pColorTex->GetWidth(), m_pColorTex->GetHeight() );

		pManager->SetTexture( Mix::Tool::Win32::Graphics::TS_DEPTH_TEXTURE,   D3DTEXF_POINT,  D3DTADDRESS_CLAMP, m_pDepthTex->GetCurrentPtr() );
		pManager->SetTexture( Mix::Tool::Win32::Graphics::TS_SHADOW_TEXTURE,  D3DTEXF_POINT,  D3DTADDRESS_CLAMP, NULL );
		pManager->SetTexture( Mix::Tool::Win32::Graphics::TS_REFRACT_TEXTURE, D3DTEXF_POINT,  D3DTADDRESS_CLAMP, m_pRefractTex );
		pManager->SetTexture( Mix::Tool::Win32::Graphics::TS_REFRECT_TEXTURE, D3DTEXF_LINEAR, D3DTADDRESS_CLAMP, m_pRelrectionTex );

		for( it_r = it_r_begin; it_r != it_r_end; ++it_r )
		{
			const Mix::Tool::Win32::Graphics::REFRACT_SUBSET* pSubset = &( *it_r );
			Mix::Tool::Win32::Graphics::Material* pMaterial = pSubset->pMaterial;
			D3DCULL cullMode = ( pMaterial->GetBackculling() == true )? D3DCULL_CCW : D3DCULL_NONE;

			////////////////////////////////////////////////////////////////////////////////////////////////////
			// 描画の準備
			////////////////////////////////////////////////////////////////////////////////////////////////////

			pManager->SetBlendState( Mix::Tool::Win32::Graphics::BLEND_COPY );
			pManager->SetDepthState( true, true );
			pManager->SetRasterizerState( fillMode, cullMode, true );

			CommitTransform( pManager, pCamera, pSubset );
			CommitMaterial( pManager, pMaterial );

			////////////////////////////////////////////////////////////////////////////////////////////////////
			// 描画
			////////////////////////////////////////////////////////////////////////////////////////////////////

			DrawSubset( pManager, pSubset );

			////////////////////////////////////////////////////////////////////////////////////////////////////
			// 描画プリミティブ数をカウント
			////////////////////////////////////////////////////////////////////////////////////////////////////

			m_DrawPrimitiveCount += ( pSubset->indexNum / 3 );
		}

		m_pDepthTex->Flip();
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// リフラクトテクスチャをクリア
	////////////////////////////////////////////////////////////////////////////////////////////////////

	pManager->SetTarget( m_pRefractTex, NULL, NULL, NULL );
	pManager->SetViewport( m_pRefractTex->GetWidth(), m_pRefractTex->GetHeight() );
	pManager->SetScissorRect( m_pRefractTex->GetWidth(), m_pRefractTex->GetHeight() );
	pManager->Clear( true, false, D3DXVECTOR4( 0.0f, 0.0f, 0.0f, 0.0f ) );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 屈折面の手前にある半透明サブセットを描画
	// ( デプステクスチャをフリップした際に、シェーダー定数を変更されてしまっているので、再設定する )
	////////////////////////////////////////////////////////////////////////////////////////////////////

	pManager->SetTarget( m_pColorTex, m_pDepthTex->GetNextPtr(), NULL, NULL );
	pManager->SetViewport( m_pColorTex->GetWidth(), m_pColorTex->GetHeight() );
	pManager->SetScissorRect( m_pColorTex->GetWidth(), m_pColorTex->GetHeight() );

	pManager->SetTexture( Mix::Tool::Win32::Graphics::TS_DEPTH_TEXTURE,   D3DTEXF_POINT,  D3DTADDRESS_CLAMP, m_pDepthTex->GetCurrentPtr() );
	pManager->SetTexture( Mix::Tool::Win32::Graphics::TS_SHADOW_TEXTURE,  D3DTEXF_POINT,  D3DTADDRESS_CLAMP, NULL );
	pManager->SetTexture( Mix::Tool::Win32::Graphics::TS_REFRACT_TEXTURE, D3DTEXF_POINT,  D3DTADDRESS_CLAMP, m_pRefractTex );
	pManager->SetTexture( Mix::Tool::Win32::Graphics::TS_REFRECT_TEXTURE, D3DTEXF_LINEAR, D3DTADDRESS_CLAMP, m_pRelrectionTex );

	for( it_t = it_t_begin; it_t != it_t_end; ++it_t )
	{
		const Mix::Tool::Win32::Graphics::TRANSPARENCY_SUBSET* pSubset = &( *it_t );
		Mix::Tool::Win32::Graphics::Material* pMaterial = pSubset->pMaterial;
		D3DCULL cullMode = ( pMaterial->GetBackculling() == true )? D3DCULL_CCW : D3DCULL_NONE;

		////////////////////////////////////////////////////////////////////////////////////////////////////
		// 描画の準備
		////////////////////////////////////////////////////////////////////////////////////////////////////

		pManager->SetBlendState( pMaterial->GetBlendMode() );
//		pManager->SetDepthState( true, false );
		pManager->SetDepthState( true, pMaterial->GetZWrite() );
		pManager->SetRasterizerState( fillMode, cullMode, true );

		CommitTransform( pManager, pCamera, pSubset );
		CommitMaterial( pManager, pMaterial );

		////////////////////////////////////////////////////////////////////////////////////////////////////
		// 描画
		////////////////////////////////////////////////////////////////////////////////////////////////////

		DrawSubset( pManager, pSubset );

		////////////////////////////////////////////////////////////////////////////////////////////////////
		// 描画プリミティブ数をカウント
		////////////////////////////////////////////////////////////////////////////////////////////////////

		m_DrawPrimitiveCount += ( pSubset->indexNum / 3 );
	}

	m_pDepthTex->Flip();

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 選択されているメッシュを描画
	////////////////////////////////////////////////////////////////////////////////////////////////////

	pManager->SetTarget( m_pColorTex, NULL, NULL, NULL );
	pManager->SetViewport( m_pColorTex->GetWidth(), m_pColorTex->GetHeight() );
	pManager->SetScissorRect( m_pColorTex->GetWidth(), m_pColorTex->GetHeight() );

	pManager->SetBlendState( Mix::Tool::Win32::Graphics::BLEND_NORMAL);
	pManager->SetDepthState( false, false );
	pManager->SetRasterizerState( D3DFILL_WIREFRAME, D3DCULL_NONE, true );

	pManager->SetPixelShaderConstant( Mix::Tool::Win32::Graphics::PSR_DIFFUSE_COLOR, m_SelectedColor );

	for( it_s = it_s_begin; it_s != it_s_end; ++it_s )
	{
		const Mix::Tool::Win32::Graphics::TRANSPARENCY_SUBSET* pSubset = &( *it_s );

		////////////////////////////////////////////////////////////////////////////////////////////////////
		// 描画の準備
		////////////////////////////////////////////////////////////////////////////////////////////////////

		CommitTransform( pManager, pCamera, pSubset );

		////////////////////////////////////////////////////////////////////////////////////////////////////
		// 描画
		////////////////////////////////////////////////////////////////////////////////////////////////////

		DrawSubset( pManager, pSubset, false );
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// ラインの描画
	////////////////////////////////////////////////////////////////////////////////////////////////////

	pManager->SetTarget( m_pColorTex, NULL, NULL, NULL );
	pManager->SetViewport( m_pColorTex->GetWidth(), m_pColorTex->GetHeight() );

	pManager->SetBlendState( Mix::Tool::Win32::Graphics::BLEND_NORMAL );
	pManager->SetDepthState( true, true );
	pManager->SetRasterizerState( D3DFILL_SOLID, D3DCULL_NONE, false );

	//グリッド
	if( MIX_TEST_BIT( dispFlags, Camera::DRAW_GRID ) == Camera::DRAW_GRID )
	{
		pManager->DrawLine( pCamera->GetViewProjMatrix(), m_GridLineList );
	}

	//ライト
	if( MIX_TEST_BIT( dispFlags, Camera::DRAW_LIGHT ) == Camera::DRAW_LIGHT )
	{
		D3DXMATRIX scaleMat;
		D3DXMATRIX transMat;
		D3DXMATRIX midMat;

		::D3DXMatrixScaling( &scaleMat, m_LightDrawScale, m_LightDrawScale, m_LightDrawScale );

		if( m_pDrawObject != NULL )
		{
			const Mix::Tool::Win32::Geometry::SPHERE& rotVolume = m_pDrawObject->GetRotationLightVolume();
			m_LightLine.back().pos = D3DXVECTOR4( 0.0f, 0.0f, rotVolume.radius, 1.0f );
			::D3DXMatrixTranslation( &transMat, rotVolume.pos.x, rotVolume.pos.y, rotVolume.pos.z );
		}
		else
		{
			m_LightLine.back().pos = D3DXVECTOR4( 0.0f, 0.0f, Scene::DEF_DIR_LIGHT_LINE_Z, 1.0f );
			::D3DXMatrixTranslation( &transMat, 0.0f, 0.0f, 0.0f );
		}

		midMat = m_LightPoseMatrix * transMat * pCamera->GetViewProjMatrix();

		pManager->DrawLine( scaleMat * midMat, m_LightArrow );
		pManager->DrawLine( midMat, m_LightLine );
	}

	//ライン
	pManager->DrawLine( pCamera->GetViewProjMatrix(), m_LineHelper.GetVertexList() );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// テキストの描画
	////////////////////////////////////////////////////////////////////////////////////////////////////

	if( MIX_TEST_BIT( dispFlags, Camera::DRAW_TEXT_MASK ) != 0 )
	{
		unsigned int step = pManager->GetTextHeight();
		const RECT& bounds = pSwapChain->GetBounds();
		POINT pos;

		pos.x = bounds.left + step;
		pos.y = bounds.top + step;

		std::wostringstream string;

		pManager->SetTarget( m_pColorTex, NULL, NULL, NULL );
		pManager->SetViewport( m_pColorTex->GetWidth(), m_pColorTex->GetHeight() );

		pManager->SetBlendState( Mix::Tool::Win32::Graphics::BLEND_NORMAL );
		pManager->SetDepthState( false, false );
		pManager->SetRasterizerState( D3DFILL_SOLID, D3DCULL_NONE, false );

		if( MIX_TEST_BIT( dispFlags, Camera::DRAW_FRAMES_PER_SEC ) == Camera::DRAW_FRAMES_PER_SEC )
		{
			string.str( L"" );
			string << L"Fps " << pManager->GetFramesPerSec();

			pManager->DrawText( m_TextColor, pos, string.str().c_str() );
			pos.y += step;
		}

		if( MIX_TEST_BIT( dispFlags, Camera::DRAW_PRIMITIVE_COUNT ) == Camera::DRAW_PRIMITIVE_COUNT )
		{
			string.str( L"" );
			string << L"PrimitiveCount " << m_DrawPrimitiveCount;

			pManager->DrawText( m_TextColor, pos, string.str().c_str() );
			pos.y += step;
		}
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// カラーテクスチャの内容をバックバッファへコピー
	////////////////////////////////////////////////////////////////////////////////////////////////////

	pManager->SetTarget( pSwapChain->GetBackBufferPtr(), NULL, NULL, NULL );
	pManager->SetViewport( pSwapChain->GetViewport() );
	pManager->SetScissorRect( pSwapChain->GetBounds() );
	pManager->Clear( true, false, D3DXVECTOR4( 0.0f, 0.0f, 0.0f, 1.0f ) );

	pManager->SetDepthState( false, false );
	pManager->SetRasterizerState( D3DFILL_SOLID, D3DCULL_NONE, true );

	pManager->SetTexture( Mix::Tool::Win32::Graphics::TS_DIFFUSE_TEXTURE,  D3DTEXF_POINT, D3DTADDRESS_CLAMP, NULL );
	pManager->SetTexture( Mix::Tool::Win32::Graphics::TS_SPEUCLAR_TEXTURE, D3DTEXF_POINT, D3DTADDRESS_CLAMP, NULL );
	pManager->SetTexture( Mix::Tool::Win32::Graphics::TS_EMISSIVE_TEXTURE, D3DTEXF_POINT, D3DTADDRESS_CLAMP, NULL );
	pManager->SetTexture( Mix::Tool::Win32::Graphics::TS_BUMP_TEXTURE,     D3DTEXF_POINT, D3DTADDRESS_CLAMP, NULL );
	pManager->SetTexture( Mix::Tool::Win32::Graphics::TS_DEPTH_TEXTURE,    D3DTEXF_POINT, D3DTADDRESS_CLAMP, NULL );
	pManager->SetTexture( Mix::Tool::Win32::Graphics::TS_SHADOW_TEXTURE,   D3DTEXF_POINT, D3DTADDRESS_CLAMP, NULL );
	pManager->SetTexture( Mix::Tool::Win32::Graphics::TS_REFRACT_TEXTURE,  D3DTEXF_POINT, D3DTADDRESS_CLAMP, NULL );
	pManager->SetTexture( Mix::Tool::Win32::Graphics::TS_REFRECT_TEXTURE,  D3DTEXF_POINT, D3DTADDRESS_CLAMP, NULL );

	pManager->SetBlendState( Mix::Tool::Win32::Graphics::BLEND_COPY );
	pManager->DrawQuad( m_pColorTex );
}

void Scene::CommitTransform( Mix::Tool::Win32::Graphics::Manager* pManager, const Mix::Tool::Win32::Graphics::Camera* pCamera, const Mix::Tool::Win32::Graphics::BASE_SUBSET* pSubset )
{
	const D3DXMATRIX& vMat = pCamera->GetViewMatrix();
	const D3DXMATRIX& vpMat = pCamera->GetViewProjMatrix();

	pManager->SetVertexShaderConstant( Mix::Tool::Win32::Graphics::VSR_V_MAT, vMat );
	pManager->SetVertexShaderConstant( Mix::Tool::Win32::Graphics::VSR_VP_MAT, vpMat );
	pManager->SetVertexShaderConstant( Mix::Tool::Win32::Graphics::VSR_WORLD_MAT, pSubset->boneMatTable, pSubset->boneCount );
}

void Scene::CommitMaterial( Mix::Tool::Win32::Graphics::Manager* pManager, Mix::Tool::Win32::Graphics::Material* pMaterial )
{
	D3DTEXTUREFILTERTYPE texFilterType = pMaterial->GetTextureFilterType();
	D3DTEXTUREADDRESS texAddressType = pMaterial->GetTextureAddressType();

	pManager->SetPixelShaderConstant( Mix::Tool::Win32::Graphics::PSR_AMBIENT_COLOR,      pMaterial->GetAmbientColor() );
	pManager->SetPixelShaderConstant( Mix::Tool::Win32::Graphics::PSR_DIFFUSE_COLOR,      pMaterial->GetDiffuseColor() );
	pManager->SetPixelShaderConstant( Mix::Tool::Win32::Graphics::PSR_DIFFUSE_PARAM,      pMaterial->GetDiffuseParam() );
	pManager->SetPixelShaderConstant( Mix::Tool::Win32::Graphics::PSR_SPEUCLAR_COLOR,     pMaterial->GetSpecularColor() );
	pManager->SetPixelShaderConstant( Mix::Tool::Win32::Graphics::PSR_SPEUCLAR_PARAM0,    pMaterial->GetSpecularParam0() );
	pManager->SetPixelShaderConstant( Mix::Tool::Win32::Graphics::PSR_SPEUCLAR_PARAM1,    pMaterial->GetSpecularParam1() );
	pManager->SetPixelShaderConstant( Mix::Tool::Win32::Graphics::PSR_REFLECT_PARAM,      pMaterial->GetReflectParam() );
	pManager->SetPixelShaderConstant( Mix::Tool::Win32::Graphics::PSR_EMISSIVE_COLOR,     pMaterial->GetEmissiveColor() );
	pManager->SetPixelShaderConstant( Mix::Tool::Win32::Graphics::PSR_EMISSIVE_PARAM,     pMaterial->GetEmissiveParam() );
	pManager->SetPixelShaderConstant( Mix::Tool::Win32::Graphics::PSR_BUMP_PARAM0,        pMaterial->GetBumpParam0() );
	pManager->SetPixelShaderConstant( Mix::Tool::Win32::Graphics::PSR_BUMP_PARAM1,        pMaterial->GetBumpParam1() );
	pManager->SetPixelShaderConstant( Mix::Tool::Win32::Graphics::PSR_TRANSPARENCY_PARAM, pMaterial->GetTransparencyParam() );

	pManager->SetTexture( Mix::Tool::Win32::Graphics::TS_DIFFUSE_TEXTURE,  texFilterType, texAddressType, pMaterial->GetDiffuseTexture() );
	pManager->SetTexture( Mix::Tool::Win32::Graphics::TS_SPEUCLAR_TEXTURE, texFilterType, texAddressType, pMaterial->GetSpecularTexture() );
	pManager->SetTexture( Mix::Tool::Win32::Graphics::TS_EMISSIVE_TEXTURE, texFilterType, texAddressType, pMaterial->GetEmissiveTexture() );
	pManager->SetTexture( Mix::Tool::Win32::Graphics::TS_BUMP_TEXTURE,     D3DTEXF_POINT, texAddressType, pMaterial->GetBumpTexture() );
}

void Scene::DrawSubset( Mix::Tool::Win32::Graphics::Manager* pManager, const Mix::Tool::Win32::Graphics::BASE_SUBSET* pSubset, bool bCountPrmitive )
{
	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 描画
	////////////////////////////////////////////////////////////////////////////////////////////////////

	pManager->SetVertexLayout( pSubset->pCommonVL );
	pManager->SetVertexBuffer( pSubset->pVertexBuffer );
	pManager->SetIndexBuffer( pSubset->pIndexBuffer );
	pManager->SetVertexShader( pSubset->pColorVS );
	pManager->SetPixelShader( pSubset->pColorPS );

	pManager->DrawIndexedTL( pSubset->vertexStart, pSubset->vertexNum, pSubset->indexStart, pSubset->indexNum );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 描画したプリミティブをカウント
	////////////////////////////////////////////////////////////////////////////////////////////////////

	if( bCountPrmitive == true )
	{
		m_DrawPrimitiveCount += ( pSubset->indexNum / 3 );
	}
}

void Scene::UpdateLightDir( const D3DXMATRIX& mat )
{
	D3DXVECTOR4 temp = D3DXVECTOR4( 0.0f, 0.0f, -1.0f, 1.0f );

	::D3DXVec4Transform( &temp, &temp, &mat );

	m_LightDirection = D3DXVECTOR3( temp.x, temp.y, temp.z );
	::D3DXVec3Normalize( &m_LightDirection, &m_LightDirection );
}

void Scene::UpdateGridLineList( void )
{
	Mix::Tool::Win32::Graphics::Manager* pManager = Manager::GetInstance();
	if( pManager == NULL )
	{
		return;
	}

	int i;
	int iLength;
	int iInterval;
	int lineCount;
	float halfLength;

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// クリア
	////////////////////////////////////////////////////////////////////////////////////////////////////

	m_GridLineList.clear();

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// ライン数を決定
	////////////////////////////////////////////////////////////////////////////////////////////////////

	iLength = static_cast<int>( m_GridParam.extent * 10000.0f );
	iInterval = static_cast<int>( m_GridParam.pitch * 10000.0f );

	lineCount = ( iLength / iInterval );
	if( lineCount == 0 )
	{
		return;
	}

	if( ( lineCount % 2 ) == 0 )
	{
		lineCount++;
	}

	halfLength = ( ( static_cast<float>( lineCount - 1 ) * m_GridParam.pitch ) * 0.5f );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// ラインを追加していく
	////////////////////////////////////////////////////////////////////////////////////////////////////

	for( i = 0; i < lineCount; i++ )
	{
		float pos = ( -halfLength + ( m_GridParam.pitch * static_cast<float>( i ) ) );

		m_GridLineList.push_back( LINE_VERTEX( D3DXVECTOR4(  pos,        0.0f, -halfLength, 1.0f ), m_GridColor ) );
		m_GridLineList.push_back( LINE_VERTEX( D3DXVECTOR4(  pos,        0.0f,  halfLength, 1.0f ), m_GridColor ) );
		m_GridLineList.push_back( LINE_VERTEX( D3DXVECTOR4( -halfLength, 0.0f,  pos,        1.0f ), m_GridColor ) );
		m_GridLineList.push_back( LINE_VERTEX( D3DXVECTOR4(  halfLength, 0.0f,  pos,        1.0f ), m_GridColor ) );
	}
}

Mix::Tool::Win32::Object::TYPE Scene::GetType( void ) const
{
	return Mix::Tool::Win32::Object::GRAPHICS__SCENE;
}

bool Scene::QueryType( Mix::Tool::Win32::Object::TYPE type ) const
{
	if( type == Mix::Tool::Win32::Object::GRAPHICS__SCENE )
	{
		return true;
	}

	return Object::QueryType( type );
}

}}}}
