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

#include "Mix/IEngine.h"
#include "Mix/Geometry.h"

#include "Mix/Dynamics/IManager.h"
#include "Mix/Dynamics/IWorld.h"
#include "Mix/Dynamics/IObjectDragger.h"

#include "Mix/Graphics/IDevice.h"
#include "Mix/Graphics/IVertexLayout.h"
#include "Mix/Graphics/IVertexShader.h"
#include "Mix/Graphics/IPixelShader.h"
#include "Mix/Graphics/IVertexBuffer.h"
#include "Mix/Graphics/IIndexBuffer.h"
#include "Mix/Graphics/ITexture.h"
#include "Mix/Graphics/Utility/ITargetTextureChain.h"
#include "Mix/Graphics/Utility/IPerspectiveRenderer.h"
#include "Mix/Scene/ICamera.h"
#include "Mix/Scene/IMaterial.h"
#include "Mix/Scene/IDefaultMaterial.h"

#include "Mix/Private/Graphics/Common/Manager.h"
#include "Mix/Private/Scene/Common/Manager.h"
#include "Mix/Private/Scene/Common/ResourceManager.h"
#include "Mix/Private/Scene/Common/UniversalCamera.h"
#include "Mix/Private/Scene/Common/ViewCamera.h"
#include "Mix/Private/Scene/Common/HemisphereLight.h"
#include "Mix/Private/Scene/Common/DirectionalLight.h"
#include "Mix/Private/Scene/Common/SpotLight.h"
#include "Mix/Private/Scene/Common/PointLight.h"
#include "Mix/Private/Scene/Common/LightShaftsCaster.h"
#include "Mix/Private/Scene/Common/WaterPool.h"
#include "Mix/Private/Scene/Common/LeavingParticle.h"
#include "Mix/Private/Scene/Common/ScatterParticle.h"
#include "Mix/Private/Scene/Common/ActorModel.h"
#include "Mix/Private/Scene/Common/ActorNode.h"
#include "Mix/Private/Scene/Common/ActorMesh.h"
#include "Mix/Private/Scene/Common/TerrainModel.h"
#include "Mix/Private/Scene/Common/TerrainNode.h"
#include "Mix/Private/Scene/Common/TerrainMesh.h"
#include "Mix/Private/Scene/Common/Planter.h"
#include "Mix/Private/Scene/Common/Floor.h"
#include "Mix/Private/Scene/Common/BasisGhost.h"
#include "Mix/Private/Scene/Common/KinematicGhost.h"
#include "Mix/Private/Scene/Common/DynamicsWorld.h"
#include "Mix/Private/Scene/Common/AtmosphereScatter.h"

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

#ifdef _DEBUG

	#include "Mix/Dynamics/IObject.h"
	#include "Mix/Dynamics/IJoint.h"
	#include "Mix/Graphics.h"
	#include "Mix/Private/Scene/Common/Debug.h"

	#define SCENE_DEB( method ) method

#else //_DEBUG

	#define SCENE_DEB( method )

#endif //_DEBUG


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

////////////////////////////////////////////////////////////////////////////////////////////////////
// 定数
////////////////////////////////////////////////////////////////////////////////////////////////////

const wchar_t* Renderer::FAILED_CHANGE_CFG = L"シーンレンダラーの設定変更に失敗";
const wchar_t* Renderer::FAILED_ADD_CAMERA = L"カメラの追加に失敗";

//デプスバッファフォーマットテーブル
const Mix::Graphics::FORMAT Renderer::DEPTH_BUFF_FORMAT_TABLE[Renderer::DEPTH_BUFF_FORMAT_COUNT] =
{
	Mix::Graphics::FMT_D32,
	Mix::Graphics::FMT_D24S8,
	Mix::Graphics::FMT_D16,
};

//被写界深度のサンプリングテーブル
const Mix::Vector4 Renderer::DOF_SAMPLING_OFFSET_TABLE[Renderer::DOF_SAMPLING_NUM] =
{
	Mix::Vector4(  0.0f, -1.5f, 0.0f, 0.0f ),

	Mix::Vector4( -1.0f, -1.0f, 0.0f, 0.0f ),
	Mix::Vector4(  0.0f, -1.0f, 0.0f, 0.0f ),
	Mix::Vector4( +1.0f, -1.0f, 0.0f, 0.0f ),

	Mix::Vector4( -1.5f,  0.0f, 0.0f, 0.0f ),
	Mix::Vector4( -1.0f,  0.0f, 0.0f, 0.0f ),
	Mix::Vector4( +1.0f,  0.0f, 0.0f, 0.0f ),
	Mix::Vector4( +1.5f,  0.0f, 0.0f, 0.0f ),

	Mix::Vector4( -1.0f, +1.0f, 0.0f, 0.0f ),
	Mix::Vector4(  0.0f, +1.0f, 0.0f, 0.0f ),
	Mix::Vector4( +1.0f, +1.0f, 0.0f, 0.0f ),

	Mix::Vector4(  0.0f, +1.5f, 0.0f, 0.0f ),
};

////////////////////////////////////////////////////////////////////////////////////////////////////
// Renderer::TransparencyObjectSorter
////////////////////////////////////////////////////////////////////////////////////////////////////

Renderer::TransparencyObjectSorter::TransparencyObjectSorter( UInt32 defStackCapacity, UInt32 resizeStep ) :
m_LeftStack( NULL ),
m_RightStack( NULL )
{
	MIX_ASSERT( defStackCapacity > 0 );
	MIX_ASSERT( resizeStep > 0 );

	m_LeftStack = MIX_LIB_MALLOC_T( Mix::Memory::SECTION_SCENE, Int32, defStackCapacity );
	MIX_ASSERT( m_LeftStack != NULL );

	m_RightStack = MIX_LIB_MALLOC_T( Mix::Memory::SECTION_SCENE, Int32, defStackCapacity );
	MIX_ASSERT( m_RightStack != NULL );

	m_StackCapacity = defStackCapacity;
	m_ResizeStep = resizeStep;
}

Renderer::TransparencyObjectSorter::~TransparencyObjectSorter( void )
{
	MIX_LIB_FREE( m_LeftStack );
	MIX_LIB_FREE( m_RightStack );
}

void Renderer::TransparencyObjectSorter::Execute( Renderer::TRANSPARENCY_OBJECT** list, Int32 left, Int32 right )
{
	MIX_ASSERT( list != NULL );
	MIX_ASSERT( left >= 0 );
	MIX_ASSERT( right >= 0 );
	MIX_ASSERT( left <= right );

	UInt32 count = right - left + 1;

	Int32 p;
	Int32 r;
	Int32 iPos;
	Int32 jPos;
	Renderer::TRANSPARENCY_OBJECT* pivot;
	Renderer::TRANSPARENCY_OBJECT* temp;
	Renderer::TRANSPARENCY_OBJECT** i;
	Renderer::TRANSPARENCY_OBJECT** j;

	if( count > m_StackCapacity )
	{
		MIX_LIB_FREE( m_LeftStack );
		MIX_LIB_FREE( m_RightStack );

		UInt32 remCount = ( ( count % m_ResizeStep ) > 0 )? 1 : 0;
		UInt32 addCapacity = ( ( count / m_ResizeStep ) + remCount ) * m_ResizeStep;
		UInt32 nextCapacity = m_StackCapacity + addCapacity;

		m_LeftStack = MIX_LIB_MALLOC_T( Mix::Memory::SECTION_SCENE, Int32, nextCapacity );
		m_RightStack = MIX_LIB_MALLOC_T( Mix::Memory::SECTION_SCENE, Int32, nextCapacity );

		m_StackCapacity = nextCapacity;
	}

	m_LeftStack[0] = left;
	m_RightStack[0] = right;

	p = 1;

	while( p > 0 )
	{
		p--;

		left = m_LeftStack[p];
		right = m_RightStack[p];

		while( left < right )
		{
			r = ( left + right ) >> 1;
			pivot = list[r];

			i = &list[left];
			j = &list[right];
			iPos = left;
			jPos = right;

			for( ;; )
			{
				while( TransparencyObjectSorter::Compare( ( *i ), pivot ) > 0 ) { i++; iPos++; }
				while( TransparencyObjectSorter::Compare( ( *j ), pivot ) < 0 ) { j--; jPos--; }

				if( jPos <= iPos )
				{
					break;
				}

				temp = *i;
				*i = *j;
				*j = temp;

				i++; iPos++;
				j--; jPos--;
			}

			if( ( iPos - left ) < ( right - jPos ) )
			{
				if( left < iPos )
				{
					m_LeftStack[p] = iPos;
					m_RightStack[p] = right;

					p++;
				}

				right = iPos - 1;
			}
			else
			{
				if( jPos < right )
				{
					m_LeftStack[p] = left;
					m_RightStack[p] = jPos;

					p++;
				}

				left = jPos + 1;
			}
		}
	}
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Mix::Scene::Standard::Renderer
////////////////////////////////////////////////////////////////////////////////////////////////////

Renderer::Renderer( Mix::Scene::Standard::Common::EffectPackage* pEffectPackage, const wchar_t* pName ) :
m_pEngine( NULL ),
m_pGraphicsMgr( NULL ),
m_pGraphicsDev( NULL ),
m_pEffectPackage( NULL ),
m_pResourceMgr( NULL ),
m_pOctree( NULL ),
m_Name( pName ),
m_bDynamicsAvailable( False ),
m_bAtmosphereAvailable( False ),
m_bFogAvailable( False ),
m_bWidgetAvailable( False ),
m_bShadowMappingAvailable( False ),
m_bAmbientOcclusionAvailable( False ),
m_bLuminosityAvailable( False ),
m_bBloomAvailable( False ),
m_bLightShaftsAvailable( False ),
m_bLensFlareAvailable( False ),
m_bChromatismAvailable( False ),
m_bDepthOfFieldAvailable( False ),
m_pEnvTex( NULL ),
m_pLightShaftsCaster( NULL ),
m_pDynamicsWorld( NULL ),
m_pAtmosphereScatter( NULL ),
m_QuadOffset( 0 ),
m_pQuadBuffer( NULL ),
m_WidgetLightingMode( Mix::Scene::IRenderer::WL_DEFAULT ),
m_WidgetQuadCount( 0 ),
m_pWidgetBuffer( NULL ),
m_TransparencyObjSorter( Renderer::TR_OBJ_DEF_COUNT, Renderer::TR_OBJ_RESIZE_STEP ),
m_pSkyDomeVL( NULL ),
m_pSkyDomeVS( NULL ),
m_pPanoramaVL( NULL ),
m_pSamplingVL( NULL ),
m_pSamplingVS( NULL ),
m_pGaussianBlurExPS( NULL ),
m_pLumAdaptedPS( NULL ),
m_pUnderWaterPS( NULL ),
m_pGammaPS( NULL ),
m_pDofPS( NULL ),
m_pVignettePS( NULL ),
m_pAntiAliasingPS( NULL ),
m_bFogEnabled( False ),
m_pHemisphereLight( NULL ),
m_pDirectionalLight( NULL ),
m_pFloor( NULL ),
m_pSkyDome( NULL ),
m_pCamera( NULL ),
m_BackgroundColor( 0.0f, 0.0f, 0.0f, 0.0f ),
m_Viewport( 0, 0, 0, 0 ),
m_pDepthBuff( NULL ),
m_pColorTexChain( NULL ),
m_pDepthTexChain( NULL ),
m_pDataTex( NULL ),
m_pRefractTex( NULL ),
m_AOSamplingType( Mix::Scene::Common::RST_COPY ),
m_pAOTex( NULL ),
m_pAOTexChain( NULL ),
m_SdwViewport( 0, 0, 0, 0 ),
m_SdwMapSamplingType( Mix::Scene::Common::RST_COPY ),
m_pSdwDepthBuff( NULL ),
m_pSdwDepthTex( NULL ),
m_pSdwMapTex( NULL ),
m_pSdwMapTexChain( NULL ),
m_pLumInitalTex( NULL ),
m_pLumFinalTex( NULL ),
m_pLumIterateTexList( NULL ),
m_pLumAdaptedTexChain( NULL ),
m_BloomSamplingType( Mix::Scene::Common::RST_COPY ),
m_pBloomTexChainList( NULL ),
m_LSViewport( 0, 0, 0, 0 ),
m_pLSTexChain( NULL ),
m_LFViewport( 0, 0, 0, 0 ),
m_LFSamplingType( Mix::Scene::Common::RST_COPY ),
m_pLFTexChain( NULL ),
m_CAViewport( 0, 0, 0, 0 ),
m_CASamplingType( Mix::Scene::Common::RST_COPY ),
m_pCATexChain( NULL ),
m_DofSamplingType( Mix::Scene::Common::RST_COPY ),
m_pDofSamplingTable( NULL ),
m_pDofBokehTex0( NULL ),
m_pDofBokehTex1( NULL ),
m_pDofTempTex( NULL )
{
	MIX_ASSERT( pEffectPackage != NULL );

	UInt32 i;
	UInt32 j;
	UInt32 k;

	Mix::IEngine* pEngine;
	Mix::Graphics::IManager* pGraphicsMgr;
	Mix::Scene::Common::Manager* pSceneMgr;
	Mix::Scene::IRenderer::FOG_SETTINGS fogParam;

	////////////////////////////////////////////////////////////////////////////////////////////////////

	MIX_ADD_REF( pEffectPackage );
	m_pEffectPackage = pEffectPackage;

	////////////////////////////////////////////////////////////////////////////////////////////////////

	pEngine = Mix::GetEnginePtr();
	MIX_ASSERT( pEngine != NULL );

	MIX_ADD_REF( pEngine );
	m_pEngine = pEngine;

	////////////////////////////////////////////////////////////////////////////////////////////////////

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

	MIX_ADD_REF( pGraphicsMgr );
	m_pGraphicsMgr = pGraphicsMgr;

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

	////////////////////////////////////////////////////////////////////////////////////////////////////

	pSceneMgr = Mix::Scene::GetInternalManagerPtr();
	MIX_ASSERT( pSceneMgr != NULL );

	pSceneMgr->AddRenderer( this );

	////////////////////////////////////////////////////////////////////////////////////////////////////

	for( i = 0; i < Mix::Scene::Common::RST_MAX; i++ )
	{
		m_pSamplingPS[i] = NULL;
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////

	for( i = 0; i < Renderer::BLUR_TYPE_MAX; i++ )
	{
		for( j = 0; j < Renderer::BLUR_DIR_MAX; j++ )
		{
			m_pBlurPS[i][j] = NULL;
		}
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////

	m_GaussianBlurCache.width = 0;
	m_GaussianBlurCache.height = 0;
	m_GaussianBlurCache.dispersion = 0.0f;
	Mix::Memory::Zero( m_GaussianBlurCache.args.weights, sizeof( m_GaussianBlurCache.args.weights ) );

	for( i = 0; i < Renderer::BLUR_DIR_MAX; i++ )
	{
		m_pGaussianBlurVS[i] = NULL;
		m_pGaussianBlurPS[i] = NULL;
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////

	for( i = 0; i < Renderer::SD_BASE_MAX; i++ )
	{
		for( j = 0; j < Renderer::SD_CLOUD_L_MAX; j++ )
		{
			for( k = 0; k < Renderer::SD_CLOUD_S_MAX; k++ )
			{
				m_pSkyDomePS[i][j][k] = NULL;
			}
		}
	}

	for( i = 0; i < Renderer::SD_PR_MAX; i++ )
	{
		m_pPanoramaVS[i] = NULL;
		m_pPanoramaPS[i] = NULL;
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////

	for( i = 0; i < Renderer::SSAO_TYPE_MAX; i++ )
	{
		m_pAmbOcclPS[i] = NULL;
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////

	for( i = 0; i < Renderer::SM_FINISH_R_MAX; i++ )
	{
		for( j = 0; j < Renderer::SM_FINISH_B_MAX; j++ )
		{
			m_pSdwMapFinishPS[i][j] = NULL;
		}
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////

	for( i = 0; i < Renderer::LUM_TF_MAX; i++ )
	{
		m_pLumTransformPS[i] = NULL;
	}

	for( i = 0; i < Renderer::LUM_OP_TA_MAX; i++ )
	{
		for( j = 0; j < Renderer::LUM_OP_B_MAX; j++ )
		{
			m_pLumOperatorPS[i][j] = NULL;
		}
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////

	for( i = 0; i < Renderer::BP_L_MAX; i++ )
	{
		for( j = 0; j < Renderer::BP_A_MAX; j++ )
		{
			m_pBrightPassPS[i][j] = NULL;
		}
	}

	for( i = 0; i < Renderer::LD_K_MAX; i++ )
	{
		m_pLensDistortionPS[i] = NULL;
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////

	for( i = 0; i < Renderer::LS_INIT_A_MAX; i++ )
	{
		m_pLSInitPS[i] = NULL;
	}

	for( i = 0; i < Renderer::LS_BLUR_TYPE_MAX; i++ )
	{
		m_pLSBlurPS[i] = NULL;
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////

	for( i = 0; i < Renderer::LF_I_G_MAX; i++ )
	{
		for( j = 0; j < Renderer::LF_I_H_MAX; j++ )
		{
			m_pLFImagePS[i][j] = NULL;
		}
	}

	for( i = 0; i < Renderer::LF_M_D_MAX; i++ )
	{
		for( j = 0; j < Renderer::LF_M_B_MAX; j++ )
		{
			m_pLFModifyPS[i][j] = NULL;
		}
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////

	for( i = 0; i < Mix::Scene::Common::Camera::FI_MAX; i++ )
	{
		m_pFilmicPS[i] = NULL;
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////

	for( i = 0; i < Renderer::CMB_Q_MAX; i++ )
	{
		m_pCamMotionBlurPS[i] = NULL;
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////

	for( i = 0; i < Renderer::CA_I_K_MAX; i++ )
	{
		m_pCAImagePS[i] = NULL;
	}

	for( i = 0; i < Renderer::CA_F_D_MAX; i++ )
	{
		m_pCAFinishPS[i] = NULL;
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////

	fogParam.start = 0.0f;
	fogParam.end = 1000.0f;
	fogParam.color = Mix::Vector4( 1.0f, 1.0f, 1.0f, 1.0f );

	SetFogSettings( fogParam );

	////////////////////////////////////////////////////////////////////////////////////////////////////

	m_WaterVisual.color = Mix::Vector4::Zero();
	m_WaterVisual.density = 0.0f;
	m_WaterVisual.intensity = 0.0f;
	m_WaterVisual.threshold = 0.0f;
	m_WaterVisual.offset = 0.0f;

	////////////////////////////////////////////////////////////////////////////////////////////////////

	Renderer::VIEW INIT_VIEW = { 0 };

	m_ViewList.resize( Mix::Scene::Common::OCTREE_VIEW_MAX, INIT_VIEW );

	////////////////////////////////////////////////////////////////////////////////////////////////////

#ifdef _DEBUG
	Mix::String tempStr;

	tempStr.Sprintf( L"Scene/%s/WidgetSubsetList", m_Name.GetConstPtr() );
	m_WidgetSubsetList.Initialize( Renderer::WIDGET_SUBSET_DEF_COUNT, WIDGET_SUBSET_RESIZE_STEP, tempStr.GetConstPtr() );

	tempStr.Sprintf( L"Scene/%s/WidgetObjectList", m_Name.GetConstPtr() );
	m_WidgetObjectList.Initialize( Renderer::WIDGET_OBJECT_DEF_COUNT, WIDGET_OBJECT_RESIZE_STEP, tempStr.GetConstPtr() );

	tempStr.Sprintf( L"Scene/%s/VisibleLocalLightList", m_Name.GetConstPtr() );
	m_VisibleLocalLightList.Initialize( Renderer::VISIBLE_LOCALLIGHT__DEF_SIZE, Renderer::VISIBLE_LOCALLIGHT__RESIZE_STEP, tempStr.GetConstPtr() );

	tempStr.Sprintf( L"Scene/%s/LocalLightList", m_Name.GetConstPtr() );
	m_LocalLightList.Initialize( Renderer::LOCALLIGHT__DEF_SIZE, Renderer::LOCALLIGHT__RESIZE_STEP, tempStr.GetConstPtr() );

	tempStr.Sprintf( L"Scene/%s/VisibleWaterPoolList", m_Name.GetConstPtr() );
	m_VisibleWaterPoolList.Initialize( Renderer::VISIBLE_WATERPOOL__DEF_SIZE, Renderer::VISIBLE_WATERPOOL__RESIZE_STEP, tempStr.GetConstPtr() );

	tempStr.Sprintf( L"Scene/%s/WorldMatrixList", m_Name.GetConstPtr() );
	m_WorldMatrixList.Initialize( Renderer::WORLDMAT__DEF_SIZE, Renderer::WORLDMAT__RESIZE_STEP, tempStr.GetConstPtr() );

	tempStr.Sprintf( L"Scene/%s/TransparencyObjList", m_Name.GetConstPtr() );
	m_TransparencyObjList.Initialize( Renderer::TR_OBJ_DEF_COUNT, Renderer::TR_OBJ_RESIZE_STEP, tempStr.GetConstPtr() );

	tempStr.Sprintf( L"Scene/%s/ShadowComList", m_Name.GetConstPtr() );
	m_ShadowComList.Initialize( Renderer::COM_SHADOW_DEFCOUNT, Renderer::COM_SHADOW_RESIZESTEP, tempStr.GetConstPtr() );

	tempStr.Sprintf( L"Scene/%s/OpacityComList", m_Name.GetConstPtr() );
	m_OpacityComList.Initialize( Renderer::COM_OPACITY_DEFCOUNT, Renderer::COM_OPACITY_RESIZESTEP, tempStr.GetConstPtr() );

	tempStr.Sprintf( L"Scene/%s/TransparencyComList", m_Name.GetConstPtr() );
	m_TransparencyComList.Initialize( Renderer::COM_TRANSPARENCY_DEFCOUNT, Renderer::COM_TRANSPARENCY_RESIZESTEP, tempStr.GetConstPtr() );

	tempStr.Sprintf( L"Scene/%s/TransparencyBackComList", m_Name.GetConstPtr() );
	m_TransparencyBackComList.Initialize( Renderer::COM_TRANSPARENCY_DEFCOUNT, Renderer::COM_TRANSPARENCY_RESIZESTEP, tempStr.GetConstPtr() );

	tempStr.Sprintf( L"Scene/%s/TransparencyFrontComList", m_Name.GetConstPtr() );
	m_TransparencyFrontComList.Initialize( Renderer::COM_TRANSPARENCY_DEFCOUNT, Renderer::COM_TRANSPARENCY_RESIZESTEP, tempStr.GetConstPtr() );

	tempStr.Sprintf( L"Scene/%s/RefractMaskComList", m_Name.GetConstPtr() );
	m_RefractMaskComList.Initialize( Renderer::COM_REFRACTMASK_DEFCOUNT, Renderer::COM_REFRACTMASK_RESIZESTEP, tempStr.GetConstPtr() );

	tempStr.Sprintf( L"Scene/%s/RefractComList", m_Name.GetConstPtr() );
	m_RefractComList.Initialize( Renderer::COM_REFRACT_DEFCOUNT, Renderer::COM_REFRACT_RESIZESTEP, tempStr.GetConstPtr() );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// デバッグ
	////////////////////////////////////////////////////////////////////////////////////////////////////

	tempStr.Sprintf( L"Scene/%s/Debug/SpotLightList", m_Name.GetConstPtr() );
	m_DebSpotLightList.Initialize( Renderer::VISIBLE_LOCALLIGHT__DEF_SIZE, Renderer::VISIBLE_LOCALLIGHT__RESIZE_STEP, tempStr.GetConstPtr() );

	tempStr.Sprintf( L"Scene/%s/Debug/PointLightList", m_Name.GetConstPtr() );
	m_DebPointLightList.Initialize( Renderer::VISIBLE_LOCALLIGHT__DEF_SIZE, Renderer::VISIBLE_LOCALLIGHT__RESIZE_STEP, tempStr.GetConstPtr() );

	tempStr.Sprintf( L"Scene/%s/Debug/WaterPoolList", m_Name.GetConstPtr() );
	m_DebWaterPoolList.Initialize( Renderer::VISIBLE_WATERPOOL__DEF_SIZE, Renderer::VISIBLE_WATERPOOL__RESIZE_STEP, tempStr.GetConstPtr() );

	tempStr.Sprintf( L"Scene/%s/Debug/VisiblePlanterList", m_Name.GetConstPtr() );
	m_DebVisiblePlanterList.Initialize( Renderer::DEB__DEF_SIZE, Renderer::DEB__RESIZE_STEP, tempStr.GetConstPtr() );

	tempStr.Sprintf( L"Scene/%s/Debug/LeavingParticleList", m_Name.GetConstPtr() );
	m_DebLeavingParticleList.Initialize( Renderer::DEB__DEF_SIZE, Renderer::DEB__RESIZE_STEP, tempStr.GetConstPtr() );

	tempStr.Sprintf( L"Scene/%s/Debug/ScatterParticleList", m_Name.GetConstPtr() );
	m_DebScatterParticleUnitList.Initialize( Renderer::DEB__DEF_SIZE, Renderer::DEB__RESIZE_STEP, tempStr.GetConstPtr() );

	tempStr.Sprintf( L"Scene/%s/Debug/DebWidgetBoundsList", m_Name.GetConstPtr() );
	m_DebWidgetBoundsList.Initialize( Renderer::DEB__DEF_SIZE, Renderer::DEB__RESIZE_STEP, tempStr.GetConstPtr() );

	tempStr.Sprintf( L"Scene/%s/Debug/ActorModelList", m_Name.GetConstPtr() );
	m_DebActorModelList.Initialize( Renderer::DEB__DEF_SIZE, Renderer::DEB__RESIZE_STEP, tempStr.GetConstPtr() );

	tempStr.Sprintf( L"Scene/%s/Debug/TerrainBoundsList", m_Name.GetConstPtr() );
	m_DebTerrainBoundsList.Initialize( Renderer::DEB__DEF_SIZE, Renderer::DEB__RESIZE_STEP, tempStr.GetConstPtr() );

	m_pDebBloomBrightPassTex = NULL;
	m_pDebLSBrightPassTex = NULL;
	m_pDebLFBrightPassTex = NULL;

	m_DebRProfGeneIndex = 1;
	m_pDebRProfGeneralCur = &( m_DebRProfGeneral[0] );
	m_pDebRProfGeneral = &( m_DebRProfGeneral[1] );
	Mix::Memory::Zero( m_pDebRProfGeneralCur, sizeof( Mix::Scene::DEBUG_PROFILE_RENDERER_GENERAL ) );
	Mix::Memory::Zero( m_pDebRProfGeneral, sizeof( Mix::Scene::DEBUG_PROFILE_RENDERER_GENERAL ) );
	Mix::Memory::Zero( &m_DebRProfOctree, sizeof( Mix::Scene::DEBUG_PROFILE_RENDERER_OCTREE ) );
	Mix::Memory::Zero( &m_DebRProfDynamics, sizeof( Mix::Scene::DEBUG_PROFILE_RENDERER_DYNAMICS ) );

	m_pDebCProfGeneral = NULL;
	m_pDebCProfOctree = NULL;
	m_pDebCProfLight = NULL;
	m_pDebCProfWaterPool = NULL;
	m_pDebCProfWidget = NULL;
	m_pDebCProfActorModel = NULL;
	m_pDebCProfTerrainModel = NULL;
	m_pDebCProfProjShadow = NULL;
	m_pDebCProfDrawOpacity = NULL;
	m_pDebCProfDrawNeut = NULL;
	m_pDebCProfDrawRefract = NULL;
	m_pDebCProfDrawTransp = NULL;
	m_pDebCProfPostProc = NULL;

	m_pDebPerspectiveRenderer = NULL;
	m_pDebCanvasRenderer = NULL;

#else //_DEBUG

	m_WidgetSubsetList.Initialize( Renderer::WIDGET_SUBSET_DEF_COUNT, WIDGET_SUBSET_RESIZE_STEP );
	m_WidgetObjectList.Initialize( Renderer::WIDGET_OBJECT_DEF_COUNT, WIDGET_OBJECT_RESIZE_STEP );
	m_VisibleLocalLightList.Initialize( Renderer::VISIBLE_LOCALLIGHT__DEF_SIZE, Renderer::VISIBLE_LOCALLIGHT__RESIZE_STEP );
	m_LocalLightList.Initialize( Renderer::LOCALLIGHT__DEF_SIZE, Renderer::LOCALLIGHT__RESIZE_STEP );
	m_VisibleWaterPoolList.Initialize( Renderer::VISIBLE_WATERPOOL__DEF_SIZE, Renderer::VISIBLE_LOCALLIGHT__RESIZE_STEP );
	m_WorldMatrixList.Initialize( Renderer::WORLDMAT__DEF_SIZE, Renderer::WORLDMAT__RESIZE_STEP );
	m_TransparencyObjList.Initialize( Renderer::TR_OBJ_DEF_COUNT, Renderer::TR_OBJ_RESIZE_STEP );
	m_ShadowComList.Initialize( Renderer::COM_SHADOW_DEFCOUNT, Renderer::COM_SHADOW_RESIZESTEP );
	m_OpacityComList.Initialize( Renderer::COM_OPACITY_DEFCOUNT, Renderer::COM_OPACITY_RESIZESTEP );
	m_TransparencyComList.Initialize( Renderer::COM_TRANSPARENCY_DEFCOUNT, Renderer::COM_TRANSPARENCY_RESIZESTEP );
	m_TransparencyBackComList.Initialize( Renderer::COM_TRANSPARENCY_DEFCOUNT, Renderer::COM_TRANSPARENCY_RESIZESTEP );
	m_TransparencyFrontComList.Initialize( Renderer::COM_TRANSPARENCY_DEFCOUNT, Renderer::COM_TRANSPARENCY_RESIZESTEP );
	m_RefractMaskComList.Initialize( Renderer::COM_REFRACTMASK_DEFCOUNT, Renderer::COM_REFRACTMASK_RESIZESTEP );
	m_RefractComList.Initialize( Renderer::COM_REFRACT_DEFCOUNT, Renderer::COM_REFRACT_RESIZESTEP );

#endif //_DEBUG
}

Renderer::~Renderer( void )
{
	Mix::Scene::Common::Manager* pSceneMgr = Mix::Scene::GetInternalManagerPtr();
	MIX_ASSERT( pSceneMgr != NULL );

	UInt32 i;
	UInt32 j;
	UInt32 k;

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 事前に処理しておく必要があるもの
	////////////////////////////////////////////////////////////////////////////////////////////////////

	// ダイナミクス

	Mix::Dynamics::IWorld* pInternalWorld = m_pDynamicsWorld->GetInternalWorldPtr();
	Mix::Dynamics::IObjectListener* pInternalObjectListener = m_pDynamicsWorld->GetInternalObjectListenerPtr();

	if( IsDynamicsAvailable() == True )
	{
		MIX_ASSERT( pInternalWorld != NULL );
		MIX_ASSERT( pInternalObjectListener != NULL );

		if( m_pFloor != NULL )
		{
			m_pFloor->DetachDynamics( pInternalWorld );
		}

		for( Renderer::GhostList::iterator it = m_GhostList.begin(); it != m_GhostList.end(); ++it )
		{
			( *it )->DetachDynamics( pInternalWorld );
		}

		for( Renderer::ActorModelList::iterator it = m_ActorModelList.begin(); it != m_ActorModelList.end(); ++it )
		{
			( *it )->DetachDynamics( pInternalWorld );
		}

		for( Renderer::TerrainModelList::iterator it = m_TerrainModelList.begin(); it != m_TerrainModelList.end(); ++it )
		{
			( *it )->DetachDynamics( pInternalWorld );
		}
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// エフェクト、テクスチャの解放
	////////////////////////////////////////////////////////////////////////////////////////////////////

	// クワッド

	MIX_RELEASE( m_pQuadBuffer );

	// サンプリング

	MIX_RELEASE( m_pSamplingVL );
	MIX_RELEASE( m_pSamplingVS );

	for( i = 0; i < Mix::Scene::Common::RST_MAX; i++ )
	{
		MIX_RELEASE( m_pSamplingPS[i] );
	}

	// ブラー

	for( i = 0; i < Renderer::BLUR_TYPE_MAX; i++ )
	{
		for( j = 0; j < Renderer::BLUR_DIR_MAX; j++ )
		{
			MIX_RELEASE( m_pBlurPS[i][j] );
		}
	}

	// ガウシアンブラー

	for( i = 0; i < Renderer::BLUR_DIR_MAX; i++ )
	{
		MIX_RELEASE( m_pGaussianBlurVS[i] );
		MIX_RELEASE( m_pGaussianBlurPS[i] );
	}

	// ガウシアンブラー EX
	MIX_RELEASE( m_pGaussianBlurExPS );

	// ブライトパス

	for( i = 0; i < Renderer::BP_L_MAX; i++ )
	{
		for( j = 0; j < Renderer::BP_A_MAX; j++ )
		{
			MIX_RELEASE( m_pBrightPassPS[i][j] );
		}
	}

	// アンビエントオクルージョン

	for( i = 0; i < Renderer::SSAO_TYPE_MAX; i++ )
	{
		MIX_RELEASE( m_pAmbOcclPS[i] );
	}

	// シャドウマッピング

	for( i = 0; i < Renderer::SM_FINISH_R_MAX; i++ )
	{
		for( j = 0; j < Renderer::SM_FINISH_B_MAX; j++ )
		{
			MIX_RELEASE( m_pSdwMapFinishPS[i][j] );
		}
	}

	// アンダーウォーター

	MIX_RELEASE( m_pUnderWaterPS );

	// 輝度

	for( i = 0; i < Renderer::LUM_OP_TA_MAX; i++ )
	{
		for( j = 0; j < Renderer::LUM_OP_B_MAX; j++ )
		{
			MIX_RELEASE( m_pLumOperatorPS[i][j] );
		}
	}

	for( i = 0; i < Renderer::LUM_TF_MAX; i++ )
	{
		MIX_RELEASE( m_pLumTransformPS[i] );
	}

	MIX_RELEASE( m_pLumAdaptedPS );

	// ライトシャフト

	for( i = 0; i < Renderer::LS_INIT_A_MAX; i++ )
	{
		MIX_RELEASE( m_pLSInitPS[i] );
	}

	for( i = 0; i < Renderer::LS_BLUR_TYPE_MAX; i++ )
	{
		MIX_RELEASE( m_pLSBlurPS[i] );
	}

	// レンズフレア

	for( i = 0; i < Renderer::LF_I_G_MAX; i++ )
	{
		for( j = 0; j < Renderer::LF_I_H_MAX; j++ )
		{
			MIX_RELEASE( m_pLFImagePS[i][j] );
		}
	}

	for( i = 0; i < Renderer::LF_M_D_MAX; i++ )
	{
		for( j = 0; j < Renderer::LF_M_B_MAX; j++ )
		{
			MIX_RELEASE( m_pLFModifyPS[i][j] );
		}
	}

	// フィルミック

	for( i = 0; i < Mix::Scene::Common::Camera::FI_MAX; i++ )
	{
		MIX_RELEASE( m_pFilmicPS[i] );
	}

	// ガンマ補正

	MIX_RELEASE( m_pGammaPS );

	// カメラモーションブラー

	for( i = 0; i < Renderer::CMB_Q_MAX; i++ )
	{
		MIX_RELEASE( m_pCamMotionBlurPS[i] );
	}

	// 色収差

	for( i = 0; i < Renderer::CA_I_K_MAX; i++ )
	{
		MIX_RELEASE( m_pCAImagePS[i] );
	}

	for( i = 0; i < Renderer::CA_F_D_MAX; i++ )
	{
		MIX_RELEASE( m_pCAFinishPS[i] );
	}

	// 被写界深度

	MIX_RELEASE( m_pDofPS );

	// 歪曲収差

	for( i = 0; i < Renderer::LD_K_MAX; i++ )
	{
		MIX_RELEASE( m_pLensDistortionPS[i] );
	}

	// ビネット

	MIX_RELEASE( m_pVignettePS );

	// アンチエイリアス

	MIX_RELEASE( m_pAntiAliasingPS );

	// ウィジェット

	MIX_RELEASE( m_pWidgetBuffer );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// オブジェクトの解放
	////////////////////////////////////////////////////////////////////////////////////////////////////

	// カメラ
	// 破棄する再に OctreeView でオブジェクトを無効にする操作をしているため、
	// パーティクル、アクターモデルを破棄する前に解放する。

	for( Renderer::CameraList::iterator it = m_CameraList.begin(); it != m_CameraList.end(); ++it )
	{
		Renderer::CAMERA* pCamera = &( *it );

		pCamera->pInternalInterface->Detach();
		MIX_RELEASE( pCamera->pInterface );
	}

	// 環境テクスチャ

	MIX_RELEASE( m_pEnvTex );

	// ライトシャフトキャスター

	if( m_pLightShaftsCaster != NULL )
	{
		m_pLightShaftsCaster->Detach();
	}

	MIX_RELEASE( m_pLightShaftsCaster );

	// 大気スキャッター

	if( m_pAtmosphereScatter != NULL )
	{
		m_pAtmosphereScatter->Dispose();
	}

	MIX_RELEASE( m_pAtmosphereScatter );

	// ダイナミクスワールド

	if( m_pDynamicsWorld != NULL )
	{
		m_pDynamicsWorld->Dispose();
	}

	MIX_RELEASE( m_pDynamicsWorld );

	// ディレクショナルライト

	if( m_pDirectionalLight != NULL )
	{
		m_pDirectionalLight->Detach();
	}

	MIX_RELEASE( m_pDirectionalLight );

	// 半球ライト

	if( m_pHemisphereLight != NULL )
	{
		m_pHemisphereLight->Detach();
	}

	MIX_RELEASE( m_pHemisphereLight );

	// ポイントライト

	for( Renderer::PointLightList::iterator it = m_PointLightList.begin(); it != m_PointLightList.end(); ++it )
	{
		Mix::Scene::Common::PointLight* pPointLight = ( *it );

		pPointLight->Detach();
		MIX_RELEASE( pPointLight );
	}

	// スポットライト

	for( Renderer::SpotLightList::iterator it = m_SpotLightList.begin(); it != m_SpotLightList.end(); ++it )
	{
		Mix::Scene::Common::SpotLight* pSpotLight = ( *it );

		pSpotLight->Detach();
		MIX_RELEASE( pSpotLight );
	}

	// スカイドーム

	MIX_RELEASE( m_pSkyDomeVL );
	MIX_RELEASE( m_pSkyDomeVS );

	for( i = 0; i < Renderer::SD_BASE_MAX; i++ )
	{
		for( j = 0; j < Renderer::SD_CLOUD_L_MAX; j++ )
		{
			for( k = 0; k < Renderer::SD_CLOUD_S_MAX; k++ )
			{
				MIX_RELEASE( m_pSkyDomePS[i][j][k] );
			}
		}
	}

	MIX_RELEASE( m_pPanoramaVL );

	for( i = 0; i < Renderer::SD_PR_MAX; i++ )
	{
		MIX_RELEASE( m_pPanoramaVS[i] );
		MIX_RELEASE( m_pPanoramaPS[i] );
	}

	if( m_pSkyDome != NULL )
	{
		m_pSkyDome->Detach();
	}

	MIX_RELEASE( m_pSkyDome );

	// ウォータープール

	for( Renderer::WaterPoolList::iterator it = m_WaterPoolList.begin(); it != m_WaterPoolList.end(); ++it )
	{
		Mix::Scene::Common::WaterPool* pWaterPool = ( *it );

		pWaterPool->Detach();
		MIX_RELEASE( pWaterPool );
	}

	// リービングパーティクル

	for( Renderer::LeavingParticleList::iterator it = m_LeavingParticleList.begin(); it != m_LeavingParticleList.end(); ++it )
	{
		Mix::Scene::Common::LeavingParticle* pParticle = ( *it );

		pParticle->Detach();
		MIX_RELEASE( pParticle );
	}

	// スキャッターパーティクル

	for( Renderer::ScatterParticleList::iterator it = m_ScatterParticleList.begin(); it != m_ScatterParticleList.end(); ++it )
	{
		Mix::Scene::Common::ScatterParticle* pParticle = ( *it );

		pParticle->Detach();
		MIX_RELEASE( pParticle );
	}

	// アクターモデル

	for( Renderer::ActorModelList::iterator it = m_ActorModelList.begin(); it != m_ActorModelList.end(); ++it )
	{
		Mix::Scene::Common::ActorModel* pActorModel = ( *it );

		pActorModel->Detach();
		pActorModel->DetachUpdateMaterials();
		MIX_RELEASE( pActorModel );
	}

	// テラインモデル

	for( Renderer::TerrainModelList::iterator it = m_TerrainModelList.begin(); it != m_TerrainModelList.end(); ++it )
	{
		Mix::Scene::Common::TerrainModel* pTerrainModel = ( *it );

		pTerrainModel->Detach();
		pTerrainModel->DetachUpdateMaterials();
		MIX_RELEASE( pTerrainModel );
	}

	// プランター

	for( Renderer::PlanterList::iterator it = m_PlanterList.begin(); it != m_PlanterList.end(); ++it )
	{
		Mix::Scene::Common::Planter* pPlanter = ( *it );

		pPlanter->Detach();
		MIX_RELEASE( pPlanter );
	}

	// フロア

	if( m_pFloor != NULL )
	{
		m_pFloor->Detach();
	}

	MIX_RELEASE( m_pFloor );

	// ゴースト

	for( Renderer::GhostList::iterator it = m_GhostList.begin(); it != m_GhostList.end(); ++it )
	{
		Mix::Scene::Common::Ghost* pGhost = ( *it );

		pGhost->Detach();
		MIX_RELEASE( pGhost );
	}

	// 八分木

	MIX_LIB_DELETE_T( Octree, m_pOctree );

	// リソースマネージャ

	MIX_LIB_DELETE_T( ResourceManager, m_pResourceMgr );

	// シーン

	pSceneMgr->RemoveRenderer( this );

	// グラフィックス

	MIX_RELEASE( m_pGraphicsDev );
	MIX_RELEASE( m_pGraphicsMgr );

	// エンジン

	MIX_RELEASE( m_pEngine );

	// エフェクトパッケージ

	MIX_RELEASE( m_pEffectPackage );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// デバッグ
	////////////////////////////////////////////////////////////////////////////////////////////////////

#ifdef _DEBUG
	MIX_RELEASE( m_pDebPerspectiveRenderer );
	MIX_RELEASE( m_pDebCanvasRenderer );
#endif //_DEBUG
}

Boolean Renderer::Initialize( const Mix::Scene::RENDERER_CONFIG& config, const void* pData )
{
	EffectPackage::VERTEX_EFFECT* pVertexEffect;
	EffectPackage::PIXEL_EFFECT* pPixelEffect;

	Mix::StringW tempStr;

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// リソースマネージャ
	////////////////////////////////////////////////////////////////////////////////////////////////////

	MIX_ASSERT( m_pResourceMgr == NULL );

	tempStr.Sprintf( L"Scene/Renderer(%s)", m_Name.GetConstPtr() );

	m_pResourceMgr = MIX_LIB_NEW_T( Mix::Memory::SECTION_SCENE, Mix::Scene::Common::ResourceManager, tempStr.GetConstPtr(), m_pGraphicsMgr );
	if( m_pResourceMgr == NULL )
	{
		MIX_LOG_ERROR( L"%s : %s : Name[%s]", Renderer::FAILED_CREATE, Mix::STR_OUTOFMEMORY, m_Name.GetConstPtr() );
		return False;
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// オクトリー
	//   初期化は ApplyConfig で行う
	////////////////////////////////////////////////////////////////////////////////////////////////////

	MIX_ASSERT( m_pOctree == NULL );

	tempStr.Sprintf( L"Scene/Renderer/%s/Octree", m_Name.GetConstPtr() );

	m_pOctree = MIX_LIB_NEW_T( Mix::Memory::SECTION_SCENE, Mix::Scene::Common::Octree, tempStr.GetConstPtr() );
	if( m_pOctree == NULL )
	{
		MIX_LOG_ERROR( L"%s : %s : Name[%s]", Renderer::FAILED_CREATE, Mix::STR_OUTOFMEMORY, m_Name.GetConstPtr() );
		return False;
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 共通のリソース
	////////////////////////////////////////////////////////////////////////////////////////////////////

	/*
		四角形の描画
	*/

	//頂点オフセット
	switch( m_pGraphicsDev->GetShaderModel() )
	{
	case Mix::Graphics::SHADER_MODEL_3:
		m_QuadOffset = 0.5f;
		break;
	case Mix::Graphics::SHADER_MODEL_4:
	case Mix::Graphics::SHADER_MODEL_5:
		m_QuadOffset = 0.0f;
		break;
	}

	//バーテックスバッファ
	tempStr.Sprintf( L"Scene/%s/Quad", m_Name.GetConstPtr() );
	if( m_pGraphicsDev->CreateVertexBuffer(	Renderer::QUAD_VERTEX_NUM,
											Renderer::QUAD_VERTEX_STRIDE,
											True,
											0,
											NULL,
											&m_pQuadBuffer,
											tempStr.GetConstPtr() ) == False )
	{
		return False;
	}

	/*
		エフェクト : サンプリング
	*/

	pVertexEffect = m_pEffectPackage->GetVertexEffectPtr( EffectPackage::E_RESIDENT, EffectPackage::ER_SAMPLING );
	if( pVertexEffect != NULL )
	{
		//VL : 共通
		MIX_ADD_REF( pVertexEffect->pLayout );
		m_pSamplingVL = pVertexEffect->pLayout;

		//VS : 共通
		MIX_ADD_REF( pVertexEffect->pShader[EffectPackage::VES_DEFAULT] );
		m_pSamplingVS = pVertexEffect->pShader[EffectPackage::VES_DEFAULT];
	}
	else
	{
		MIX_LOG_ERROR( L"%s : %s : Name[%s]", Renderer::FAILED_CREATE, Mix::STR_OUTOFMEMORY, m_Name.GetConstPtr() );
		return False;
	}

	pPixelEffect = m_pEffectPackage->GetPixelEffectPtr( EffectPackage::E_RESIDENT, EffectPackage::ER_SAMPLING );
	if( pPixelEffect != NULL )
	{
		//PS : コピー
		MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_SAMPLING_COPY] );
		m_pSamplingPS[Mix::Scene::Common::RST_COPY] = pPixelEffect->pShader[EffectPackage::PES_SAMPLING_COPY];

		//PS : 1/2ダウンサンプリング
		MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_SAMPLING_DOWN2X] );
		m_pSamplingPS[Mix::Scene::Common::RST_DOWN2x] = pPixelEffect->pShader[EffectPackage::PES_SAMPLING_DOWN2X];

		//PS : 1/4ダウンサンプリング
		MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_SAMPLING_DOWN4X] );
		m_pSamplingPS[Mix::Scene::Common::RST_DOWN4x] = pPixelEffect->pShader[EffectPackage::PES_SAMPLING_DOWN4X];
	}
	else
	{
		return False;
	}

	/*
		エフェクト : 水中
	*/

	pPixelEffect = m_pEffectPackage->GetPixelEffectPtr( EffectPackage::E_RESIDENT, EffectPackage::ER_UNDER_WATER );
	if( pPixelEffect != NULL )
	{
		MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_DEFAULT] );
		m_pUnderWaterPS = pPixelEffect->pShader[EffectPackage::PES_DEFAULT];
	}
	else
	{
		return False;
	}

	/*
		エフェクト : フィルミック
	*/

	pPixelEffect = m_pEffectPackage->GetPixelEffectPtr( EffectPackage::E_RESIDENT, EffectPackage::ER_FILMIC );
	if( pPixelEffect != NULL )
	{
		MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_FI_HEJL] );
		MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_FI_HABLE] );

		m_pFilmicPS[Mix::Scene::ICamera::FI_HEJL] = pPixelEffect->pShader[EffectPackage::PES_FI_HEJL];
		m_pFilmicPS[Mix::Scene::ICamera::FI_HABLE] = pPixelEffect->pShader[EffectPackage::PES_FI_HABLE];
	}
	else
	{
		return False;
	}

	/*
		エフェクト : ガンマ
	*/

	pPixelEffect = m_pEffectPackage->GetPixelEffectPtr( EffectPackage::E_RESIDENT, EffectPackage::ER_GAMMA );
	if( pPixelEffect != NULL )
	{
		MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_DEFAULT] );
		m_pGammaPS = pPixelEffect->pShader[EffectPackage::PES_DEFAULT];
	}
	else
	{
		return False;
	}

	/*
		エフェクト : カメラモーションブラー
	*/

	pPixelEffect = m_pEffectPackage->GetPixelEffectPtr( EffectPackage::E_RESIDENT, EffectPackage::ER_CAM_MOTION_BLUR );
	if( pPixelEffect != NULL )
	{
		MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_CMB_L] );
		MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_CMB_M] );
		MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_CMB_H] );

		m_pCamMotionBlurPS[Renderer::CMB_Q_L] = pPixelEffect->pShader[EffectPackage::PES_CMB_L];
		m_pCamMotionBlurPS[Renderer::CMB_Q_M] = pPixelEffect->pShader[EffectPackage::PES_CMB_M];
		m_pCamMotionBlurPS[Renderer::CMB_Q_H] = pPixelEffect->pShader[EffectPackage::PES_CMB_H];
	}
	else
	{
		return False;
	}

	/*
		エフェクト : 歪曲収差
	*/

	pPixelEffect = m_pEffectPackage->GetPixelEffectPtr( EffectPackage::E_RESIDENT, EffectPackage::ER_LENS_DIST );
	if( pPixelEffect != NULL )
	{
		MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_LD__] );
		MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_LD_K] );

		m_pLensDistortionPS[0] = pPixelEffect->pShader[EffectPackage::PES_LD__];
		m_pLensDistortionPS[1] = pPixelEffect->pShader[EffectPackage::PES_LD_K];
	}
	else
	{
		return False;
	}

	/*
		エフェクト : ビネット
	*/

	pPixelEffect = m_pEffectPackage->GetPixelEffectPtr( EffectPackage::E_RESIDENT, EffectPackage::ER_VIGNETTE );
	if( pPixelEffect != NULL )
	{
		MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_DEFAULT] );
		m_pVignettePS = pPixelEffect->pShader[EffectPackage::PES_DEFAULT];
	}
	else
	{
		return False;
	}

	/*
		エフェクト : アンチエイリアス( FXAA )
	*/

	pPixelEffect = m_pEffectPackage->GetPixelEffectPtr( EffectPackage::E_RESIDENT, EffectPackage::ER_FXAA );
	if( pPixelEffect != NULL )
	{
		MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_DEFAULT] );
		m_pAntiAliasingPS = pPixelEffect->pShader[EffectPackage::PES_DEFAULT];
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 各種インターフェースの作成
	////////////////////////////////////////////////////////////////////////////////////////////////////

	/*
		大気スキャッター
	*/

	m_pAtmosphereScatter = Mix::Scene::Common::AtmosphereScatter::CreateInstance();
	if( m_pAtmosphereScatter == NULL )
	{
		MIX_LOG_ERROR( L"%s : %s : Name[%s]", Renderer::FAILED_CREATE, Mix::STR_OUTOFMEMORY, m_Name.GetConstPtr() );
		return False;
	}

	// ダイナミクスワールド

	m_pDynamicsWorld = Mix::Scene::Common::DynamicsWorld::CreateInstance( config.dynamics );
	if( m_pDynamicsWorld == NULL )
	{
		MIX_LOG_ERROR( L"%s : %s : Name[%s]", Renderer::FAILED_CREATE, Mix::STR_OUTOFMEMORY, m_Name.GetConstPtr() );
		return False;
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 初期化を通知
	////////////////////////////////////////////////////////////////////////////////////////////////////

	if( OnInitialize( config ) == False )
	{
		return False;
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 設定の更新
	////////////////////////////////////////////////////////////////////////////////////////////////////

	if( UpdateConfig( Renderer::FAILED_CREATE, config ) == True )
	{
		m_Config = config;
	}
	else
	{
		return False;
	}

	return True;
}

Boolean Renderer::UpdateConfig( const wchar_t* pErrorTitle, const Mix::Scene::RENDERER_CONFIG& config )
{
	MIX_ASSERT( ( pErrorTitle != NULL ) && ( ::wcslen( pErrorTitle ) > 0 ) );
	MIX_ASSERT( m_pEffectPackage != NULL );
	MIX_ASSERT( m_ViewList.size() > 0 );

	Boolean bOldDynamicsAvailable = IsDynamicsAvailable();
	const Mix::Point& screenSize = m_pGraphicsDev->GetScreenSize();
	UInt32 caps = m_pEffectPackage->ModifyRendererCaps( config.caps );
	UInt32 mepProcFlags = m_pEffectPackage->GetProcessFlags();

	Mix::Scene::RENDERER_CONFIG updConfig = config; updConfig.caps = caps;

	const Mix::Scene::RENDERER_OCTREE_CONFIG& octree = config.octree;
	Mix::Vector3 octMin = Mix::Vector3::Min( octree.minAABB, octree.maxAABB );
	Mix::Vector3 octMax = Mix::Vector3::Max( octree.minAABB, octree.maxAABB );
	UInt32 octLevel = min( octree.subdivisionLevel, Mix::Scene::Common::Octree::MAX_LEVEL );

	EffectPackage::VERTEX_EFFECT* pVertexEffect;
	EffectPackage::PIXEL_EFFECT* pPixelEffect;

	Mix::StringW tempStr;

	UInt32 i;
	UInt32 j;
	UInt32 k;

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// リソースの解放
	////////////////////////////////////////////////////////////////////////////////////////////////////

	// スカイドーム

	MIX_RELEASE( m_pSkyDomeVL );
	MIX_RELEASE( m_pSkyDomeVS );

	for( i = 0; i < Renderer::SD_BASE_MAX; i++ )
	{
		for( j = 0; j < Renderer::SD_CLOUD_L_MAX; j++ )
		{
			for( k = 0; k < Renderer::SD_CLOUD_S_MAX; k++ )
			{
				MIX_RELEASE( m_pSkyDomePS[i][j][k] );
			}
		}
	}

	MIX_RELEASE( m_pPanoramaVL );

	for( i = 0; i < Renderer::SD_PR_MAX; i++ )
	{
		MIX_RELEASE( m_pPanoramaVS[i] );
		MIX_RELEASE( m_pPanoramaPS[i] );
	}

	// ブラー

	for( i = 0; i < Renderer::BLUR_TYPE_MAX; i++ )
	{
		for( j = 0; j < Renderer::BLUR_DIR_MAX; j++ )
		{
			MIX_RELEASE( m_pBlurPS[i][j] );
		}
	}

	// ガウシアンブラー

	m_GaussianBlurCache.width = 0;
	m_GaussianBlurCache.height = 0;
	m_GaussianBlurCache.dispersion = 0.0f;
	Mix::Memory::Zero( m_GaussianBlurCache.args.weights, sizeof( m_GaussianBlurCache.args.weights ) );

	for( i = 0; i < Renderer::BLUR_DIR_MAX; i++ )
	{
		MIX_RELEASE( m_pGaussianBlurVS[i] );
		MIX_RELEASE( m_pGaussianBlurPS[i] );
	}

	// ガウシアンブラー EX

	MIX_RELEASE( m_pGaussianBlurExPS );

	// ブライトパス

	for( i = 0; i < Renderer::BP_L_MAX; i++ )
	{
		for( j = 0; j < Renderer::BP_A_MAX; j++ )
		{
			MIX_RELEASE( m_pBrightPassPS[i][j] );
		}
	}

	// アンビエントオクルージョン

	for( i = 0; i < Renderer::SSAO_TYPE_MAX; i++ )
	{
		MIX_RELEASE( m_pAmbOcclPS[i] );
	}

	// シャドウマッピング

	for( i = 0; i < Renderer::SM_FINISH_R_MAX; i++ )
	{
		for( j = 0; j < Renderer::SM_FINISH_B_MAX; j++ )
		{
			MIX_RELEASE( m_pSdwMapFinishPS[i][j] );
		}
	}

	// 輝度

	for( i = 0; i < Renderer::LUM_TF_MAX; i++ )
	{
		MIX_RELEASE( m_pLumTransformPS[i] );
	}

	MIX_RELEASE( m_pLumAdaptedPS );

	for( i = 0; i < Renderer::LUM_OP_TA_MAX; i++ )
	{
		for( j = 0; j < Renderer::LUM_OP_B_MAX; j++ )
		{
			MIX_RELEASE( m_pLumOperatorPS[i][j] );
		}
	}

	// ライトシャフト

	for( i = 0; i < Renderer::LS_INIT_A_MAX; i++ )
	{
		MIX_RELEASE( m_pLSInitPS[i] );
	}

	for( i = 0; i < Renderer::LS_BLUR_TYPE_MAX; i++ )
	{
		MIX_RELEASE( m_pLSBlurPS[i] );
	}

	// レンズフレア

	for( i = 0; i < Renderer::LF_I_G_MAX; i++ )
	{
		for( j = 0; j < Renderer::LF_I_H_MAX; j++ )
		{
			MIX_RELEASE( m_pLFImagePS[i][j] );
		}
	}

	for( i = 0; i < Renderer::LF_M_D_MAX; i++ )
	{
		for( j = 0; j < Renderer::LF_M_B_MAX; j++ )
		{
			MIX_RELEASE( m_pLFModifyPS[i][j] );
		}
	}

	// 色収差

	for( i = 0; i < Renderer::CA_I_K_MAX; i++ )
	{
		MIX_RELEASE( m_pCAImagePS[i] );
	}

	for( i = 0; i < Renderer::CA_F_D_MAX; i++ )
	{
		MIX_RELEASE( m_pCAFinishPS[i] );
	}

	// 被写界深度

	MIX_RELEASE( m_pDofPS );

	// ウィジェット

	MIX_RELEASE( m_pWidgetBuffer );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// リソースの取得、作成
	////////////////////////////////////////////////////////////////////////////////////////////////////

	/*
		スカイドーム
	*/

	MIX_ASSERT( m_pSkyDomeVL == NULL );
	MIX_ASSERT( m_pSkyDomeVS == NULL );
	MIX_ASSERT( m_pSkyDomePS[Renderer::SD_BASE_0][Renderer::SD_CLOUD_L0][0] == NULL );
	MIX_ASSERT( m_pSkyDomePS[Renderer::SD_BASE_0][Renderer::SD_CLOUD_L1][0] == NULL );
	MIX_ASSERT( m_pSkyDomePS[Renderer::SD_BASE_0][Renderer::SD_CLOUD_L1][1] == NULL );
	MIX_ASSERT( m_pSkyDomePS[Renderer::SD_BASE_0][Renderer::SD_CLOUD_L2][0] == NULL );
	MIX_ASSERT( m_pSkyDomePS[Renderer::SD_BASE_0][Renderer::SD_CLOUD_L2][1] == NULL );
	MIX_ASSERT( m_pSkyDomePS[Renderer::SD_BASE_1][Renderer::SD_CLOUD_L0][0] == NULL );
	MIX_ASSERT( m_pSkyDomePS[Renderer::SD_BASE_1][Renderer::SD_CLOUD_L1][0] == NULL );
	MIX_ASSERT( m_pSkyDomePS[Renderer::SD_BASE_1][Renderer::SD_CLOUD_L1][1] == NULL );
	MIX_ASSERT( m_pSkyDomePS[Renderer::SD_BASE_1][Renderer::SD_CLOUD_L2][0] == NULL );
	MIX_ASSERT( m_pSkyDomePS[Renderer::SD_BASE_1][Renderer::SD_CLOUD_L2][1] == NULL );
	
	MIX_ASSERT( m_pPanoramaVL == NULL );
	MIX_ASSERT( m_pPanoramaVS[Renderer::SD_PR] == NULL );
	MIX_ASSERT( m_pPanoramaVS[Renderer::SD_PR_FOG] == NULL );
	MIX_ASSERT( m_pPanoramaPS[Renderer::SD_PR] == NULL );
	MIX_ASSERT( m_pPanoramaPS[Renderer::SD_PR_FOG] == NULL );

	if( MIX_TESTBIT( caps, Mix::Scene::RCAP_ATMOSPHERE ) == Mix::Scene::RCAP_ATMOSPHERE )
	{
		// ドーム : バーテックスシェーダー
		pVertexEffect = m_pEffectPackage->GetVertexEffectPtr( EffectPackage::E_RESIDENT, EffectPackage::ER_SKYDOME_ATMOSPHERE );
		if( pVertexEffect != NULL )
		{
			MIX_ADD_REF( pVertexEffect->pLayout );
			MIX_ADD_REF( pVertexEffect->pShader[EffectPackage::VES_DEFAULT] );

			m_pSkyDomeVL = pVertexEffect->pLayout;
			m_pSkyDomeVS = pVertexEffect->pShader[EffectPackage::VES_DEFAULT];
		}
		else
		{
			return False;
		}

		// ドーム : ピクセルシェーダー
		pPixelEffect = m_pEffectPackage->GetPixelEffectPtr( EffectPackage::E_RESIDENT, EffectPackage::ER_SKYDOME_ATMOSPHERE );
		if( pPixelEffect != NULL )
		{
			MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_SD_ASS_____] );
			MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_SD_ASS__C__] );
			MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_SD_ASS__C_L] );
			MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_SD_ASS__C2_] );
			MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_SD_ASS__C2L] );
			MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_SD_ASS_B___] );
			MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_SD_ASS_BC__] );
			MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_SD_ASS_BC_L] );
			MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_SD_ASS_BC2_] );
			MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_SD_ASS_BC2L] );

			m_pSkyDomePS[Renderer::SD_BASE_0][Renderer::SD_CLOUD_L0][0] = pPixelEffect->pShader[EffectPackage::PES_SD_ASS_____];
			m_pSkyDomePS[Renderer::SD_BASE_0][Renderer::SD_CLOUD_L1][0] = pPixelEffect->pShader[EffectPackage::PES_SD_ASS__C__];
			m_pSkyDomePS[Renderer::SD_BASE_0][Renderer::SD_CLOUD_L1][1] = pPixelEffect->pShader[EffectPackage::PES_SD_ASS__C_L];
			m_pSkyDomePS[Renderer::SD_BASE_0][Renderer::SD_CLOUD_L2][0] = pPixelEffect->pShader[EffectPackage::PES_SD_ASS__C2_];
			m_pSkyDomePS[Renderer::SD_BASE_0][Renderer::SD_CLOUD_L2][1] = pPixelEffect->pShader[EffectPackage::PES_SD_ASS__C2L];
			m_pSkyDomePS[Renderer::SD_BASE_1][Renderer::SD_CLOUD_L0][0] = pPixelEffect->pShader[EffectPackage::PES_SD_ASS_B___];
			m_pSkyDomePS[Renderer::SD_BASE_1][Renderer::SD_CLOUD_L1][0] = pPixelEffect->pShader[EffectPackage::PES_SD_ASS_BC__];
			m_pSkyDomePS[Renderer::SD_BASE_1][Renderer::SD_CLOUD_L1][1] = pPixelEffect->pShader[EffectPackage::PES_SD_ASS_BC_L];
			m_pSkyDomePS[Renderer::SD_BASE_1][Renderer::SD_CLOUD_L2][0] = pPixelEffect->pShader[EffectPackage::PES_SD_ASS_BC2_];
			m_pSkyDomePS[Renderer::SD_BASE_1][Renderer::SD_CLOUD_L2][1] = pPixelEffect->pShader[EffectPackage::PES_SD_ASS_BC2L];
		}
		else
		{
			return False;
		}

		// パノラマ : バーテックスシェーダー
		pVertexEffect = m_pEffectPackage->GetVertexEffectPtr( EffectPackage::E_RESIDENT, EffectPackage::ER_SKYDOME_PANORAMA_A );
		if( pVertexEffect != NULL )
		{
			MIX_ADD_REF( pVertexEffect->pLayout );
			MIX_ADD_REF( pVertexEffect->pShader[EffectPackage::VES_SKYDOME_PANORAMA] );
			MIX_ADD_REF( pVertexEffect->pShader[EffectPackage::VES_SKYDOME_PANORAMA_F] );

			m_pPanoramaVL = pVertexEffect->pLayout;
			m_pPanoramaVS[Renderer::SD_PR] = pVertexEffect->pShader[EffectPackage::VES_SKYDOME_PANORAMA];
			m_pPanoramaVS[Renderer::SD_PR_FOG] = pVertexEffect->pShader[EffectPackage::VES_SKYDOME_PANORAMA_F];
		}
		else
		{
			return False;
		}

		// パノラマ : ピクセルシェーダー
		pPixelEffect = m_pEffectPackage->GetPixelEffectPtr( EffectPackage::E_RESIDENT, EffectPackage::ER_SKYDOME_PANORAMA_A );
		if( pPixelEffect != NULL )
		{
			MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_SD_PANORAMA] );
			MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_SD_PANORAMA_F] );

			m_pPanoramaPS[Renderer::SD_PR] = pPixelEffect->pShader[EffectPackage::PES_SD_PANORAMA];
			m_pPanoramaPS[Renderer::SD_PR_FOG] = pPixelEffect->pShader[EffectPackage::PES_SD_PANORAMA_F];
		}
		else
		{
			return False;
		}
	}
	else
	{
		// ドーム : バーテックスシェーダー
		pVertexEffect = m_pEffectPackage->GetVertexEffectPtr( EffectPackage::E_RESIDENT, EffectPackage::ER_SKYDOME_DEFAULT );
		if( pVertexEffect != NULL )
		{
			MIX_ADD_REF( pVertexEffect->pLayout );
			MIX_ADD_REF( pVertexEffect->pShader[EffectPackage::VES_DEFAULT] );

			m_pSkyDomeVL = pVertexEffect->pLayout;
			m_pSkyDomeVS = pVertexEffect->pShader[EffectPackage::VES_DEFAULT];
		}
		else
		{
			return False;
		}

		// ドーム : ピクセルシェーダー
		pPixelEffect = m_pEffectPackage->GetPixelEffectPtr( EffectPackage::E_RESIDENT, EffectPackage::ER_SKYDOME_DEFAULT );
		if( pPixelEffect != NULL )
		{
			MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_SD_DEF_____] );
			MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_SD_DEF__C__] );
			MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_SD_DEF__C2_] );
			MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_SD_DEF_B___] );
			MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_SD_DEF_BC__] );
			MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_SD_DEF_BC2_] );

			m_pSkyDomePS[Renderer::SD_BASE_0][Renderer::SD_CLOUD_L0][0] = pPixelEffect->pShader[EffectPackage::PES_SD_DEF_____];
			m_pSkyDomePS[Renderer::SD_BASE_0][Renderer::SD_CLOUD_L1][0] = pPixelEffect->pShader[EffectPackage::PES_SD_DEF__C__];
			m_pSkyDomePS[Renderer::SD_BASE_0][Renderer::SD_CLOUD_L2][0] = pPixelEffect->pShader[EffectPackage::PES_SD_DEF__C2_];
			m_pSkyDomePS[Renderer::SD_BASE_1][Renderer::SD_CLOUD_L0][0] = pPixelEffect->pShader[EffectPackage::PES_SD_DEF_B___];
			m_pSkyDomePS[Renderer::SD_BASE_1][Renderer::SD_CLOUD_L1][0] = pPixelEffect->pShader[EffectPackage::PES_SD_DEF_BC__];
			m_pSkyDomePS[Renderer::SD_BASE_1][Renderer::SD_CLOUD_L2][0] = pPixelEffect->pShader[EffectPackage::PES_SD_DEF_BC2_];
		}
		else
		{
			return False;
		}

		// パノラマ : バーテックスシェーダー
		pVertexEffect = m_pEffectPackage->GetVertexEffectPtr( EffectPackage::E_RESIDENT, EffectPackage::ER_SKYDOME_PANORAMA_D );
		if( pVertexEffect != NULL )
		{
			MIX_ADD_REF( pVertexEffect->pLayout );
			MIX_ADD_REF( pVertexEffect->pShader[EffectPackage::VES_SKYDOME_PANORAMA] );
			MIX_ADD_REF( pVertexEffect->pShader[EffectPackage::VES_SKYDOME_PANORAMA_F] );

			m_pPanoramaVL = pVertexEffect->pLayout;
			m_pPanoramaVS[Renderer::SD_PR] = pVertexEffect->pShader[EffectPackage::VES_SKYDOME_PANORAMA];
			m_pPanoramaVS[Renderer::SD_PR_FOG] = pVertexEffect->pShader[EffectPackage::VES_SKYDOME_PANORAMA_F];
		}
		else
		{
			return False;
		}

		// パノラマ : ピクセルシェーダー
		pPixelEffect = m_pEffectPackage->GetPixelEffectPtr( EffectPackage::E_RESIDENT, EffectPackage::ER_SKYDOME_PANORAMA_D );
		if( pPixelEffect != NULL )
		{
			MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_SD_PANORAMA] );
			MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_SD_PANORAMA_F] );

			m_pPanoramaPS[Renderer::SD_PR] = pPixelEffect->pShader[EffectPackage::PES_SD_PANORAMA];
			m_pPanoramaPS[Renderer::SD_PR_FOG] = pPixelEffect->pShader[EffectPackage::PES_SD_PANORAMA_F];
		}
		else
		{
			return False;
		}
	}

	/*
		ブラー
	*/

	MIX_ASSERT( m_pBlurPS[Renderer::BLUR_3x3][Renderer::BLUR_X] == NULL );
	MIX_ASSERT( m_pBlurPS[Renderer::BLUR_3x3][Renderer::BLUR_Y] == NULL );
	MIX_ASSERT( m_pBlurPS[Renderer::BLUR_5x5][Renderer::BLUR_X] == NULL );
	MIX_ASSERT( m_pBlurPS[Renderer::BLUR_5x5][Renderer::BLUR_Y] == NULL );
	MIX_ASSERT( m_pGaussianBlurVS[Renderer::BLUR_X] == NULL );
	MIX_ASSERT( m_pGaussianBlurVS[Renderer::BLUR_Y] == NULL );
	MIX_ASSERT( m_pGaussianBlurPS[Renderer::BLUR_X] == NULL );
	MIX_ASSERT( m_pGaussianBlurPS[Renderer::BLUR_Y] == NULL );
	MIX_ASSERT( m_pGaussianBlurExPS == NULL );

	if( ( MIX_TESTBIT( caps, Mix::Scene::RCAP_SHADOW_MAPPING ) == Mix::Scene::RCAP_SHADOW_MAPPING ) ||
		( MIX_TESTBIT( caps, Mix::Scene::RCAP_AMBIENT_OCCLUSION ) == Mix::Scene::RCAP_AMBIENT_OCCLUSION ) ||
		( MIX_TESTBIT( caps, Mix::Scene::RCAP_BLOOM ) == Mix::Scene::RCAP_BLOOM ) ||
		( MIX_TESTBIT( caps, Mix::Scene::RCAP_LENS_FLARE ) == Mix::Scene::RCAP_LENS_FLARE ) ||
		( MIX_TESTBIT( caps, Mix::Scene::RCAP_CHROMATISM ) == Mix::Scene::RCAP_CHROMATISM ) ||
		( MIX_TESTBIT( caps, Mix::Scene::RCAP_DEPTH_OF_FIELD ) == Mix::Scene::RCAP_DEPTH_OF_FIELD ) )
	{
		// 3x3 ブラー
		pPixelEffect = m_pEffectPackage->GetPixelEffectPtr( EffectPackage::E_RESIDENT, EffectPackage::ER_BLUR3X );
		if( pPixelEffect != NULL )
		{
			MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_COMMON_BLUR_X] );
			MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_COMMON_BLUR_Y] );

			m_pBlurPS[Renderer::BLUR_3x3][Renderer::BLUR_X] = pPixelEffect->pShader[EffectPackage::PES_COMMON_BLUR_X];
			m_pBlurPS[Renderer::BLUR_3x3][Renderer::BLUR_Y] = pPixelEffect->pShader[EffectPackage::PES_COMMON_BLUR_Y];
		}
		else
		{
			return False;
		}

		// 5x5 ブラー
		pPixelEffect = m_pEffectPackage->GetPixelEffectPtr( EffectPackage::E_RESIDENT, EffectPackage::ER_BLUR5X );
		if( pPixelEffect != NULL )
		{
			MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_COMMON_BLUR_X] );
			MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_COMMON_BLUR_Y] );

			m_pBlurPS[Renderer::BLUR_5x5][Renderer::BLUR_X] = pPixelEffect->pShader[EffectPackage::PES_COMMON_BLUR_X];
			m_pBlurPS[Renderer::BLUR_5x5][Renderer::BLUR_Y] = pPixelEffect->pShader[EffectPackage::PES_COMMON_BLUR_Y];
		}
		else
		{
			return False;
		}

		// ガウシアンブラー( VS )
		pVertexEffect = m_pEffectPackage->GetVertexEffectPtr( EffectPackage::E_RESIDENT, EffectPackage::ER_GAUSSIAN_BLUR );
		if( pVertexEffect != NULL )
		{
			MIX_ADD_REF( pVertexEffect->pShader[EffectPackage::VES_GAUSSIAN_BLUR_X] );
			MIX_ADD_REF( pVertexEffect->pShader[EffectPackage::VES_GAUSSIAN_BLUR_Y] );

			m_pGaussianBlurVS[Renderer::BLUR_X] = pVertexEffect->pShader[EffectPackage::VES_GAUSSIAN_BLUR_X];
			m_pGaussianBlurVS[Renderer::BLUR_Y] = pVertexEffect->pShader[EffectPackage::VES_GAUSSIAN_BLUR_Y];
		}
		else
		{
			return False;
		}

		// ガウシアンブラー( PS )
		pPixelEffect = m_pEffectPackage->GetPixelEffectPtr( EffectPackage::E_RESIDENT, EffectPackage::ER_GAUSSIAN_BLUR );
		if( pPixelEffect != NULL )
		{
			MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_COMMON_BLUR_X] );
			MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_COMMON_BLUR_Y] );

			m_pGaussianBlurPS[Renderer::BLUR_X] = pPixelEffect->pShader[EffectPackage::PES_COMMON_BLUR_X];
			m_pGaussianBlurPS[Renderer::BLUR_Y] = pPixelEffect->pShader[EffectPackage::PES_COMMON_BLUR_Y];
		}
		else
		{
			return False;
		}

		// ガウシアンブラー EX
		pPixelEffect = m_pEffectPackage->GetPixelEffectPtr( EffectPackage::E_RESIDENT, EffectPackage::ER_GAUSSIAN_BLUR_EX );
		if( pPixelEffect != NULL )
		{
			MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_DEFAULT] );
			m_pGaussianBlurExPS = pPixelEffect->pShader[EffectPackage::PES_DEFAULT];
		}
		else
		{
			return False;
		}
	}

	/*
		ブライトパス
	*/

	MIX_ASSERT( m_pBrightPassPS[0][0] == NULL );
	MIX_ASSERT( m_pBrightPassPS[1][0] == NULL );
	MIX_ASSERT( m_pBrightPassPS[1][1] == NULL );

	if( ( MIX_TESTBIT( caps, Mix::Scene::RCAP_BLOOM ) == Mix::Scene::RCAP_BLOOM ) ||
		( MIX_TESTBIT( caps, Mix::Scene::RCAP_LIGHT_SHAFTS ) == Mix::Scene::RCAP_LIGHT_SHAFTS ) ||
		( MIX_TESTBIT( caps, Mix::Scene::RCAP_LENS_FLARE ) == Mix::Scene::RCAP_LENS_FLARE ) )
	{
		pPixelEffect = m_pEffectPackage->GetPixelEffectPtr( EffectPackage::E_RESIDENT, EffectPackage::ER_BRIGHTPASS );
		if( pPixelEffect != NULL )
		{
			MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_BP___] );
			MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_BP_L_] );
			MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_BP_LA] );

			m_pBrightPassPS[0][0] = pPixelEffect->pShader[EffectPackage::PES_BP___];
			m_pBrightPassPS[1][0] = pPixelEffect->pShader[EffectPackage::PES_BP_L_];
			m_pBrightPassPS[1][1] = pPixelEffect->pShader[EffectPackage::PES_BP_LA];
		}
		else
		{
			return False;
		}
	}

	/*
		アンビエントオクルージョン
	*/

	MIX_ASSERT( m_pAmbOcclPS[Renderer::SSAO_SIMPLE] == NULL );
	MIX_ASSERT( m_pAmbOcclPS[Renderer::SSAO_TEX] == NULL );

	if( MIX_TESTBIT( caps, Mix::Scene::RCAP_AMBIENT_OCCLUSION ) == Mix::Scene::RCAP_AMBIENT_OCCLUSION )
	{
		pPixelEffect = m_pEffectPackage->GetPixelEffectPtr( EffectPackage::E_RESIDENT, EffectPackage::ER_SSAO );
		if( pPixelEffect != NULL )
		{
			MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_SSAO] );
			MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_SSAO_TEX] );

			m_pAmbOcclPS[Renderer::SSAO_SIMPLE] = pPixelEffect->pShader[EffectPackage::PES_SSAO];
			m_pAmbOcclPS[Renderer::SSAO_TEX] = pPixelEffect->pShader[EffectPackage::PES_SSAO_TEX];
		}
		else
		{
			return False;
		}
	}

	/*
		シャドウマッピング
	*/

	MIX_ASSERT( m_pSdwMapFinishPS[0][Renderer::SM_FINISH_B_HARD] == NULL );
	MIX_ASSERT( m_pSdwMapFinishPS[0][Renderer::SM_FINISH_B_SOFT] == NULL );
	MIX_ASSERT( m_pSdwMapFinishPS[1][Renderer::SM_FINISH_B_HARD] == NULL );
	MIX_ASSERT( m_pSdwMapFinishPS[1][Renderer::SM_FINISH_B_SOFT] == NULL );

	if( MIX_TESTBIT( caps, Mix::Scene::RCAP_SHADOW_MAPPING ) == Mix::Scene::RCAP_SHADOW_MAPPING )
	{
		pPixelEffect = m_pEffectPackage->GetPixelEffectPtr( EffectPackage::E_RESIDENT, EffectPackage::ER_SM );
		if( pPixelEffect != NULL )
		{
			MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_SM_FINISH___] );
			MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_SM_FINISH__B] );
			MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_SM_FINISH_R_] );
			MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_SM_FINISH_RB] );

			m_pSdwMapFinishPS[0][Renderer::SM_FINISH_B_HARD] = pPixelEffect->pShader[EffectPackage::PES_SM_FINISH___];
			m_pSdwMapFinishPS[0][Renderer::SM_FINISH_B_SOFT] = pPixelEffect->pShader[EffectPackage::PES_SM_FINISH__B];
			m_pSdwMapFinishPS[1][Renderer::SM_FINISH_B_HARD] = pPixelEffect->pShader[EffectPackage::PES_SM_FINISH_R_];
			m_pSdwMapFinishPS[1][Renderer::SM_FINISH_B_SOFT] = pPixelEffect->pShader[EffectPackage::PES_SM_FINISH_RB];
		}
		else
		{
			return False;
		}
	}


	/*
		ルミノシティ
	*/

	MIX_ASSERT( m_pLumTransformPS[Renderer::LUM_INITAL] == NULL );
	MIX_ASSERT( m_pLumTransformPS[Renderer::LUM_ITERATE] == NULL );
	MIX_ASSERT( m_pLumTransformPS[Renderer::LUM_FINAL] == NULL );
	MIX_ASSERT( m_pLumAdaptedPS == NULL );
	MIX_ASSERT( m_pLumOperatorPS[0][0] == NULL ); //常に NULL のはず
	MIX_ASSERT( m_pLumOperatorPS[0][1] == NULL );
	MIX_ASSERT( m_pLumOperatorPS[1][0] == NULL );
	MIX_ASSERT( m_pLumOperatorPS[1][1] == NULL );
	MIX_ASSERT( m_pLumOperatorPS[2][0] == NULL );
	MIX_ASSERT( m_pLumOperatorPS[2][1] == NULL );

	if( MIX_TESTBIT( caps, Mix::Scene::RCAP_LUMINOSITY ) == Mix::Scene::RCAP_LUMINOSITY )
	{
		pPixelEffect = m_pEffectPackage->GetPixelEffectPtr( EffectPackage::E_RESIDENT, EffectPackage::ER_LUMINANCE );
		if( pPixelEffect != NULL )
		{
			MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_LUM_TR_INITAL] );
			MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_LUM_TR_ITERATE] );
			MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_LUM_TR_FINAL] );
			MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_LUM_ADAPTED] );
			MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_LUM_OP___B] );
			MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_LUM_OP_T__] );
			MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_LUM_OP_T_B] );
			MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_LUM_OP_TA_] );
			MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_LUM_OP_TAB] );

			m_pLumTransformPS[Renderer::LUM_INITAL] = pPixelEffect->pShader[EffectPackage::PES_LUM_TR_INITAL];
			m_pLumTransformPS[Renderer::LUM_ITERATE] = pPixelEffect->pShader[EffectPackage::PES_LUM_TR_ITERATE];
			m_pLumTransformPS[Renderer::LUM_FINAL] = pPixelEffect->pShader[EffectPackage::PES_LUM_TR_FINAL];

			m_pLumAdaptedPS = pPixelEffect->pShader[EffectPackage::PES_LUM_ADAPTED];

			m_pLumOperatorPS[0][0] = NULL; //無し
			m_pLumOperatorPS[0][1] = pPixelEffect->pShader[EffectPackage::PES_LUM_OP___B];
			m_pLumOperatorPS[1][0] = pPixelEffect->pShader[EffectPackage::PES_LUM_OP_T__];
			m_pLumOperatorPS[1][1] = pPixelEffect->pShader[EffectPackage::PES_LUM_OP_T_B];
			m_pLumOperatorPS[2][0] = pPixelEffect->pShader[EffectPackage::PES_LUM_OP_TA_];
			m_pLumOperatorPS[2][1] = pPixelEffect->pShader[EffectPackage::PES_LUM_OP_TAB];
		}
		else
		{
			return False;
		}
	}

	/*
		ライトシャフト
	*/

	MIX_ASSERT( m_pLSInitPS[0] == NULL );
	MIX_ASSERT( m_pLSInitPS[1] == NULL );
	MIX_ASSERT( m_pLSBlurPS[Renderer::LS_BLUR_L] == NULL );
	MIX_ASSERT( m_pLSBlurPS[Renderer::LS_BLUR_M] == NULL );
	MIX_ASSERT( m_pLSBlurPS[Renderer::LS_BLUR_H] == NULL );

	if( MIX_TESTBIT( caps, Mix::Scene::RCAP_LIGHT_SHAFTS ) == Mix::Scene::RCAP_LIGHT_SHAFTS )
	{
		// エフェクト
		pPixelEffect = m_pEffectPackage->GetPixelEffectPtr( EffectPackage::E_RESIDENT, EffectPackage::ER_LIGHT_SHAFTS );
		if( pPixelEffect != NULL )
		{
			MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_LS_INIT__] );
			MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_LS_INIT_A] );
			MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_LS_BLUR_L] );
			MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_LS_BLUR_M] );
			MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_LS_BLUR_H] );

			m_pLSInitPS[0] = pPixelEffect->pShader[EffectPackage::PES_LS_INIT__];
			m_pLSInitPS[1] = pPixelEffect->pShader[EffectPackage::PES_LS_INIT_A];
			m_pLSBlurPS[Renderer::LS_BLUR_L] = pPixelEffect->pShader[EffectPackage::PES_LS_BLUR_L];
			m_pLSBlurPS[Renderer::LS_BLUR_M] = pPixelEffect->pShader[EffectPackage::PES_LS_BLUR_M];
			m_pLSBlurPS[Renderer::LS_BLUR_H] = pPixelEffect->pShader[EffectPackage::PES_LS_BLUR_H];
		}
		else
		{
			return False;
		}
	}

	/*
		レンズフレア
	*/

	MIX_ASSERT( m_pLFImagePS[0][0] == NULL );
	MIX_ASSERT( m_pLFImagePS[0][1] == NULL );
	MIX_ASSERT( m_pLFImagePS[1][0] == NULL );
	MIX_ASSERT( m_pLFImagePS[1][1] == NULL );
	MIX_ASSERT( m_pLFModifyPS[0][0] == NULL );
	MIX_ASSERT( m_pLFModifyPS[1][0] == NULL );
	MIX_ASSERT( m_pLFModifyPS[0][1] == NULL );
	MIX_ASSERT( m_pLFModifyPS[1][1] == NULL );

	if( MIX_TESTBIT( caps, Mix::Scene::RCAP_LENS_FLARE ) == Mix::Scene::RCAP_LENS_FLARE )
	{
		// エフェクト
		pPixelEffect = m_pEffectPackage->GetPixelEffectPtr( EffectPackage::E_RESIDENT, EffectPackage::ER_LENS_FLARE );
		if( pPixelEffect != NULL )
		{
			MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_LF_IMAGE___] );
			MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_LF_IMAGE__H] );
			MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_LF_IMAGE_G_] );
			MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_LF_IMAGE_GH] );
			MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_LF_MODIFY___] );
			MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_LF_MODIFY_D_] );
			MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_LF_MODIFY__B] );
			MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_LF_MODIFY_DB] );

			m_pLFImagePS[0][0] = pPixelEffect->pShader[EffectPackage::PES_LF_IMAGE___];
			m_pLFImagePS[0][1] = pPixelEffect->pShader[EffectPackage::PES_LF_IMAGE__H];
			m_pLFImagePS[1][0] = pPixelEffect->pShader[EffectPackage::PES_LF_IMAGE_G_];
			m_pLFImagePS[1][1] = pPixelEffect->pShader[EffectPackage::PES_LF_IMAGE_GH];

			m_pLFModifyPS[0][0] = pPixelEffect->pShader[EffectPackage::PES_LF_MODIFY___];
			m_pLFModifyPS[1][0] = pPixelEffect->pShader[EffectPackage::PES_LF_MODIFY_D_];
			m_pLFModifyPS[0][1] = pPixelEffect->pShader[EffectPackage::PES_LF_MODIFY__B];
			m_pLFModifyPS[1][1] = pPixelEffect->pShader[EffectPackage::PES_LF_MODIFY_DB];
		}
		else
		{
			return False;
		}
	}

	/*
		色収差
	*/

	MIX_ASSERT( m_pCAImagePS[0] == NULL );
	MIX_ASSERT( m_pCAImagePS[1] == NULL );
	MIX_ASSERT( m_pCAFinishPS[0] == NULL );
	MIX_ASSERT( m_pCAFinishPS[1] == NULL );

	if( MIX_TESTBIT( caps, Mix::Scene::RCAP_CHROMATISM ) == Mix::Scene::RCAP_CHROMATISM )
	{
		// エフェクト
		pPixelEffect = m_pEffectPackage->GetPixelEffectPtr( EffectPackage::E_RESIDENT, EffectPackage::ER_CHROMATISM );
		if( pPixelEffect != NULL )
		{
			MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_CA_IMAGE__] );
			MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_CA_IMAGE_K] );
			MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_CA_FINISH__] );
			MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_CA_FINISH_D] );

			m_pCAImagePS[0] = pPixelEffect->pShader[EffectPackage::PES_CA_IMAGE__];
			m_pCAImagePS[1] = pPixelEffect->pShader[EffectPackage::PES_CA_IMAGE_K];
			m_pCAFinishPS[0] = pPixelEffect->pShader[EffectPackage::PES_CA_FINISH__];
			m_pCAFinishPS[1] = pPixelEffect->pShader[EffectPackage::PES_CA_FINISH_D];
		}
		else
		{
			return False;
		}
	}

	/*
		被写界深度
	*/

	MIX_ASSERT( m_pDofPS == NULL );

	if( MIX_TESTBIT( caps, Mix::Scene::RCAP_DEPTH_OF_FIELD ) == Mix::Scene::RCAP_DEPTH_OF_FIELD )
	{
		pPixelEffect = m_pEffectPackage->GetPixelEffectPtr( EffectPackage::E_RESIDENT, EffectPackage::ER_DOF );
		if( pPixelEffect != NULL )
		{
			MIX_ADD_REF( pPixelEffect->pShader[EffectPackage::PES_DEFAULT] );

			m_pDofPS = pPixelEffect->pShader[EffectPackage::PES_DEFAULT];
		}
		else
		{
			return False;
		}
	}

	/*
		ウィジェット
	*/

	MIX_ASSERT( m_pWidgetBuffer == NULL );

	if( MIX_TESTBIT( caps, Mix::Scene::RCAP_WIDGET ) == Mix::Scene::RCAP_WIDGET )
	{
		tempStr.Sprintf( L"Scene/%s/WidgetBuffer", m_Name.GetConstPtr() );

		if( m_pGraphicsDev->CreateVertexBuffer(	Renderer::WIDGET_VB_DEF_PRIMITIVE_COUNT, Mix::Scene::Common::WIDGET_VERTEX_STRIDE,
												True, Renderer::WIDGET_VB_RESIZE_STEP,
												NULL,
												&m_pWidgetBuffer,
												tempStr.GetConstPtr() ) == False )
		{
			return False;
		}
	}

	/*
		ダイナミクスワールド
	*/

	if( MIX_TESTBIT( caps, Mix::Scene::RCAP_DYNAMICS ) == Mix::Scene::RCAP_DYNAMICS )
	{
		if( bOldDynamicsAvailable == False )
		{
			if( m_pDynamicsWorld->Initialize( m_Name.GetConstPtr() ) == True )
			{
				Mix::Dynamics::IWorld* pInternalWorld = m_pDynamicsWorld->GetInternalWorldPtr();
				Mix::Dynamics::IObjectListener* pInternalObjectListener = m_pDynamicsWorld->GetInternalObjectListenerPtr();

				MIX_ASSERT( pInternalWorld != NULL );
				MIX_ASSERT( pInternalObjectListener != NULL );

				if( m_pFloor != NULL )
				{
					m_pFloor->AttachDynamics( pInternalWorld, pInternalObjectListener );
				}

				for( Renderer::GhostList::iterator it = m_GhostList.begin(); it != m_GhostList.end(); ++it )
				{
					( *it )->AttachDynamics( pInternalWorld, pInternalObjectListener );
				}

				for( Renderer::ActorModelList::iterator it = m_ActorModelList.begin(); it != m_ActorModelList.end(); ++it )
				{
					( *it )->AttachDynamics( pInternalWorld, pInternalObjectListener );
				}

				for( Renderer::TerrainModelList::iterator it = m_TerrainModelList.begin(); it != m_TerrainModelList.end(); ++it )
				{
					( *it )->AttachDynamics( pInternalWorld, pInternalObjectListener );
				}
			}
			else
			{
				return False;
			}
		}
	}
	else
	{
		if( bOldDynamicsAvailable == True )
		{
			Mix::Dynamics::IWorld* pInternalWorld = m_pDynamicsWorld->GetInternalWorldPtr();

			MIX_ASSERT( pInternalWorld != NULL );

			if( m_pFloor != NULL )
			{
				m_pFloor->DetachDynamics( pInternalWorld );
			}

			for( Renderer::GhostList::iterator it = m_GhostList.begin(); it != m_GhostList.end(); ++it )
			{
				( *it )->DetachDynamics( pInternalWorld );
			}

			for( Renderer::ActorModelList::iterator it = m_ActorModelList.begin(); it != m_ActorModelList.end(); ++it )
			{
				( *it )->DetachDynamics( pInternalWorld );
			}

			for( Renderer::TerrainModelList::iterator it = m_TerrainModelList.begin(); it != m_TerrainModelList.end(); ++it )
			{
				( *it )->DetachDynamics( pInternalWorld );
			}

			m_pDynamicsWorld->Dispose();
		}
	}

	/*
		八分木
	*/

	MIX_ASSERT( m_pOctree != NULL );

	if( m_pOctree->NeedsInitialize( octMin, octMax, octLevel ) == True )
	{
		Renderer::PointLightList::iterator it_pl_begin = m_PointLightList.begin();
		Renderer::PointLightList::iterator it_pl_end = m_PointLightList.end();
		Renderer::PointLightList::iterator it_pl;

		Renderer::SpotLightList::iterator it_sl_begin = m_SpotLightList.begin();
		Renderer::SpotLightList::iterator it_sl_end = m_SpotLightList.end();
		Renderer::SpotLightList::iterator it_sl;

		Renderer::LeavingParticleList::iterator it_lpc_begin = m_LeavingParticleList.begin();
		Renderer::LeavingParticleList::iterator it_lpc_end = m_LeavingParticleList.end();
		Renderer::LeavingParticleList::iterator it_lpc;

		Renderer::ScatterParticleList::iterator it_spc_begin = m_ScatterParticleList.begin();
		Renderer::ScatterParticleList::iterator it_spc_end = m_ScatterParticleList.end();
		Renderer::ScatterParticleList::iterator it_spc;

		Renderer::ActorModelList::iterator it_am_begin = m_ActorModelList.begin();
		Renderer::ActorModelList::iterator it_am_end = m_ActorModelList.end();
		Renderer::ActorModelList::iterator it_am;

		Renderer::WaterPoolList::iterator it_wp_begin = m_WaterPoolList.begin();
		Renderer::WaterPoolList::iterator it_wp_end = m_WaterPoolList.end();
		Renderer::WaterPoolList::iterator it_wp;

		Renderer::PlanterList::iterator it_pt_begin = m_PlanterList.begin();
		Renderer::PlanterList::iterator it_pt_end = m_PlanterList.end();
		Renderer::PlanterList::iterator it_pt;

		// オブジェクトの破棄

		for( it_pl = it_pl_begin; it_pl != it_pl_end; ++it_pl )
		{
			Mix::Scene::Common::PointLight* pPointLight = ( *it_pl );
			pPointLight->Detach();
		}

		for( it_sl = it_sl_begin; it_sl != it_sl_end; ++it_sl )
		{
			Mix::Scene::Common::SpotLight* pSpotLight = ( *it_sl );
			pSpotLight->Detach();
		}

		for( it_lpc = it_lpc_begin; it_lpc != it_lpc_end; ++it_lpc )
		{
			Mix::Scene::Common::LeavingParticle* pParticle = ( *it_lpc );
			pParticle->Detach();
		}

		for( it_spc = it_spc_begin; it_spc != it_spc_end; ++it_spc )
		{
			Mix::Scene::Common::ScatterParticle* pParticle = ( *it_spc );
			pParticle->Detach();
		}

		for( it_am = it_am_begin; it_am != it_am_end; ++it_am )
		{
			Mix::Scene::Common::ActorModel* pActorModel = ( *it_am );
			pActorModel->Detach();
		}

		for( it_wp = it_wp_begin; it_wp != it_wp_end; ++it_wp )
		{
			Mix::Scene::Common::WaterPool* pWaterPool = ( *it_wp );
			pWaterPool->Detach();
		}

		for( it_pt = it_pt_begin; it_pt != it_pt_end; ++it_pt )
		{
			Mix::Scene::Common::Planter* pPlanter = ( *it_pt );
			pPlanter->Detach();
		}

		// 解放

		m_pOctree->Release();

		// 初期化

		m_pOctree->Initialize( octMin, octMax, octLevel );

		// オブジェクトの再設定

		for( it_pl = it_pl_begin; it_pl != it_pl_end; ++it_pl )
		{
			Mix::Scene::Common::PointLight* pPointLight = ( *it_pl );
			pPointLight->Attach( m_pOctree->AddLocalLight( pPointLight ) );
		}

		for( it_sl = it_sl_begin; it_sl != it_sl_end; ++it_sl )
		{
			Mix::Scene::Common::SpotLight* pSpotLight = ( *it_sl );
			pSpotLight->Attach( m_pOctree->AddLocalLight( pSpotLight ) );
		}

		for( it_lpc = it_lpc_begin; it_lpc != it_lpc_end; ++it_lpc )
		{
			Mix::Scene::Common::LeavingParticle* pParticle = ( *it_lpc );
			pParticle->Attach( m_pOctree->AddLeavingParticle( pParticle ) );
		}

		for( it_spc = it_spc_begin; it_spc != it_spc_end; ++it_spc )
		{
			Mix::Scene::Common::ScatterParticle* pParticle = ( *it_spc );
			pParticle->Attach( m_pOctree );
		}

		for( it_am = it_am_begin; it_am != it_am_end; ++it_am )
		{
			Mix::Scene::Common::ActorModel* pActorModel = ( *it_am );
			pActorModel->Attach( m_pOctree->AddActorModel( pActorModel ) );
		}

		for( it_wp = it_wp_begin; it_wp != it_wp_end; ++it_wp )
		{
			Mix::Scene::Common::WaterPool* pWaterPool = ( *it_wp );
			pWaterPool->Attach( m_pOctree->AddWaterPool( pWaterPool ) );
		}

		for( it_pt = it_pt_begin; it_pt != it_pt_end; ++it_pt )
		{
			Mix::Scene::Common::Planter* pPlanter = ( *it_pt );
			pPlanter->Attach( m_pOctree->AddPlanter( pPlanter ) );
		}
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 設定の更新を通知
	////////////////////////////////////////////////////////////////////////////////////////////////////

	if( OnUpdateConfig( updConfig ) == False )
	{
		return False;
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 利用可能状態の設定
	////////////////////////////////////////////////////////////////////////////////////////////////////

	m_bDynamicsAvailable = ( MIX_TESTBIT( caps, Mix::Scene::RCAP_DYNAMICS ) == Mix::Scene::RCAP_DYNAMICS );
	m_bAtmosphereAvailable = ( MIX_TESTBIT( caps, Mix::Scene::RCAP_ATMOSPHERE ) == Mix::Scene::RCAP_ATMOSPHERE );
	m_bFogAvailable = ( MIX_TESTBIT( mepProcFlags, EffectPackage::EP_FOG ) == EffectPackage::EP_FOG );
	m_bWidgetAvailable = ( MIX_TESTBIT( caps, Mix::Scene::RCAP_WIDGET ) == Mix::Scene::RCAP_WIDGET );
	m_bAmbientOcclusionAvailable = ( MIX_TESTBIT( caps, Mix::Scene::RCAP_AMBIENT_OCCLUSION ) == Mix::Scene::RCAP_AMBIENT_OCCLUSION );
	m_bShadowMappingAvailable = ( MIX_TESTBIT( caps, Mix::Scene::RCAP_SHADOW_MAPPING ) == Mix::Scene::RCAP_SHADOW_MAPPING );
	m_bLuminosityAvailable = ( MIX_TESTBIT( caps, Mix::Scene::RCAP_LUMINOSITY ) == Mix::Scene::RCAP_LUMINOSITY );
	m_bBloomAvailable = ( MIX_TESTBIT( caps, Mix::Scene::RCAP_BLOOM ) == Mix::Scene::RCAP_BLOOM );
	m_bLightShaftsAvailable = ( MIX_TESTBIT( caps, Mix::Scene::RCAP_LIGHT_SHAFTS ) == Mix::Scene::RCAP_LIGHT_SHAFTS );
	m_bLensFlareAvailable = ( MIX_TESTBIT( caps, Mix::Scene::RCAP_LENS_FLARE ) == Mix::Scene::RCAP_LENS_FLARE );
	m_bChromatismAvailable = ( MIX_TESTBIT( caps, Mix::Scene::RCAP_CHROMATISM ) == Mix::Scene::RCAP_CHROMATISM );
	m_bDepthOfFieldAvailable = ( MIX_TESTBIT( caps, Mix::Scene::RCAP_DEPTH_OF_FIELD ) == Mix::Scene::RCAP_DEPTH_OF_FIELD );

	////////////////////////////////////////////////////////////////////////////////////////////////////

	return True;
}

void Renderer::ReleaseCameraResource( Renderer::VIEW* pView )
{
	MIX_ASSERT( pView != NULL );

	//クリアはしない
	//pView->resOwner = 0;
	//pView->pInternalCamera = NULL;

	m_pResourceMgr->ReleaseOwner( pView->resOwner );

	MIX_RELEASE( pView->pObjDragger );

	MIX_RELEASE( pView->pDepthBuff );
	MIX_RELEASE( pView->pColorTexChain );
	MIX_RELEASE( pView->pDepthTexChain );
	MIX_RELEASE( pView->pDataTex );
	MIX_RELEASE( pView->pRefractTex );

	MIX_RELEASE( pView->pAOTex );
	MIX_RELEASE( pView->pAOTexChain );

	MIX_RELEASE( pView->pSdwDepthBuff );
	MIX_RELEASE( pView->pSdwDepthTex );
	MIX_RELEASE( pView->pSdwMapTex );
	MIX_RELEASE( pView->pSdwMapTexChain );

	MIX_RELEASE( pView->pLumInitalTex );

	if( pView->LumIterateTexList.size() > 0 )
	{
		Renderer::TextureList::iterator it_begin = pView->LumIterateTexList.begin();
		Renderer::TextureList::iterator it_end = pView->LumIterateTexList.end();
		Renderer::TextureList::iterator it;

		for( it = it_begin; it != it_end; ++it )
		{
			MIX_RELEASE( ( *it ) );
		}

		pView->LumIterateTexList.clear();
	}

	MIX_RELEASE( pView->pLumFinalTex );
	MIX_RELEASE( pView->pLumAdaptedTexChain );

	if( pView->BloomTexChainList.size() > 0 )
	{
		Renderer::TextureChainList::iterator it_begin = pView->BloomTexChainList.begin();
		Renderer::TextureChainList::iterator it_end = pView->BloomTexChainList.end();
		Renderer::TextureChainList::iterator it;

		for( it = it_begin; it != it_end; ++it )
		{
			MIX_RELEASE( ( *it ) );
		}

		pView->BloomTexChainList.clear();
	}

	MIX_RELEASE( pView->pLSTexChain );

	MIX_RELEASE( pView->pLFTexChain );

	MIX_RELEASE( pView->pCATexChain );

	MIX_RELEASE( pView->pDofBokehTex0 );
	MIX_RELEASE( pView->pDofBokehTex1 );
	MIX_RELEASE( pView->pDofTempTex );

#ifdef _DEBUG
	MIX_RELEASE( pView->pDebBloomBrightPassTex );
	MIX_RELEASE( pView->pDebLSBrightPassTex );
	MIX_RELEASE( pView->pDebLFBrightPassTex );
#endif //_DEBUG
}

void Renderer::CancelDragObject( Renderer::VIEW* pView )
{
	MIX_ASSERT( pView != NULL );

	if( pView->pObjDragger != NULL )
	{
		pView->pObjDragger->Free();
	}

	pView->bDragObj = False;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Mix::Scene::Common::Renderer
////////////////////////////////////////////////////////////////////////////////////////////////////

void Renderer::AddCameraView( Mix::Scene::Common::Camera* pInternalCamera )
{
	MIX_ASSERT( pInternalCamera != NULL );
	MIX_ASSERT( pInternalCamera->GetID() < Mix::Scene::Common::OCTREE_VIEW_MAX );

	UInt32 viewId = pInternalCamera->GetID();
	Renderer::VIEW* pView;

	//セット
	pView = &( m_ViewList[viewId] );
	pView->pInternalCamera = pInternalCamera;
	pView->resOwner = Mix::Scene::Common::ResourceManager::CameraOwner( viewId );

	//リソースの作成は UpdateCameraConfig で行う
}

void Renderer::RemoveCameraView( UInt32 viewID )
{
	Renderer::VIEW* pView = &( m_ViewList[viewID] );

	//ドラッグのキャンセル
	CancelDragObject( pView );

	//リソースの解放
	ReleaseCameraResource( pView );

	//クリア
	pView->pInternalCamera = NULL;
	pView->resOwner = 0;
}

Boolean Renderer::UpdateCameraConfig( UInt32 viewID, const Mix::Scene::CAMERA_CONFIG& config, UInt32& modCaps )
{
	MIX_ASSERT( viewID < m_ViewList.size() );
	MIX_ASSERT( m_pEffectPackage != NULL );
	MIX_ASSERT( m_pResourceMgr != NULL );

	UInt32 mepProcFlags = m_pEffectPackage->GetProcessFlags();

	UInt32 caps = m_Config.caps & config.caps;
	const Mix::Point& targetSize = config.targetSize;

	Renderer::VIEW* pView = &( m_ViewList[viewID] );
	const UInt32& resOwner = pView->resOwner;

	Mix::Graphics::FORMAT depthBuffFormat;
	Mix::Graphics::FORMAT colorTexFormat;
	Mix::Graphics::FORMAT depthTexFormat;
	Mix::Graphics::FORMAT dataTexFormat;
	Mix::Graphics::FORMAT refractTexFormat;

	Mix::Graphics::FORMAT smDepthTexFormat;
	Mix::Point smDepthTexSize;
	Mix::Graphics::FORMAT smTexFormat;
	Mix::Point smTexSize;
	Mix::Scene::Common::RENDERER_SAMPLING_TYPE smSamplingType;

	Mix::Graphics::FORMAT aoTexFormat;
	Mix::Point aoTexSize;
	Mix::Scene::Common::RENDERER_SAMPLING_TYPE aoSamplingType;

	Mix::Graphics::FORMAT lumTexFormat;
	Mix::Scene::Common::RENDERER_SAMPLING_TYPE bloomSamplingType;
	UInt32 bloomOverflowNum;
	Int32 bloomTexScale;

	Mix::Scene::Common::RENDERER_SAMPLING_TYPE lfSamplingType;
	Mix::Point lfTexSize;

	Mix::Scene::Common::RENDERER_SAMPLING_TYPE caSamplingType;
	Mix::Point caTexSize;
	Mix::Graphics::FORMAT caTexFormat;

	Mix::Scene::Common::RENDERER_SAMPLING_TYPE dofSamplingType;
	Mix::Point dofTexSize;
	Mix::Graphics::FORMAT dofTexFormat;

	Mix::StringW tempStr;
	UInt32 i;

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

	// スクリーン

	if( ( targetSize.x <= 0 ) || ( targetSize.y <= 0 ) )
	{
		MIX_LOG_ERROR( L"ターゲットのサイズが不正です : Size(%d, %d)", config.targetSize.x, config.targetSize.y );
		return False;
	}

	// 能力

	modCaps = 0;

	/*
		デプスバッファ
	*/

	// フォーマット
	switch( config.depthBuffFormat )
	{
	case Mix::Graphics::FMT_D16:
	case Mix::Graphics::FMT_D24S8:
	case Mix::Graphics::FMT_D32:
		depthBuffFormat = config.depthBuffFormat;
		break;

	default:
		MIX_LOG_ERROR( L"デプスバッファのフォーマットが不正です" );
		return False;
	}

	/*
		カラーテクスチャ
	*/

	// フォーマット
	switch( config.colorTexFormat )
	{
	case Mix::Graphics::FMT_R8G8B8A8:
	case Mix::Graphics::FMT_R16G16B16A16F:
	case Mix::Graphics::FMT_R32G32B32A32F:
		colorTexFormat = config.colorTexFormat;
		break;

	default:
		MIX_LOG_ERROR( L"カラーテクスチャのフォーマットが不正です" );
		return False;
	}

	/*
		デプステクスチャ
	*/

	// フォーマット
#ifdef _DEBUG
	switch( config.depthTexFormat )
	{
	case Mix::Graphics::FMT_R16F:
		depthTexFormat = Mix::Graphics::FMT_R16G16B16A16F;
		break;
	case Mix::Graphics::FMT_R32F:
		depthTexFormat = Mix::Graphics::FMT_R32G32B32A32F;
		break;

	default:
		MIX_LOG_ERROR( L"デプステクスチャのフォーマットが不正です" );
		return False;
	}
#else //_DEBUG
	switch( config.depthTexFormat )
	{
	case Mix::Graphics::FMT_R16F:
	case Mix::Graphics::FMT_R32F:
		depthTexFormat = config.depthTexFormat;
		break;

	default:
		MIX_LOG_ERROR( L"デプステクスチャのフォーマットが不正です" );
		return False;
	}
#endif //_DEBUG

	/*
		データテクスチャ
	*/

	//フォーマット(固定)
	dataTexFormat = Mix::Graphics::FMT_R8G8B8A8;

	/*
		リフラクトテクスチャ
	*/

	// フォーマット
	switch( config.refractTexFormat )
	{
	case Mix::Graphics::FMT_R16G16B16A16F:
	case Mix::Graphics::FMT_R32G32B32A32F:
		refractTexFormat = config.refractTexFormat;
		break;

	default:
		MIX_LOG_ERROR( L"リフラクトテクスチャのフォーマットが不正です" );
		return False;
	}

	/*
		シャドウマッピング
	*/

	// デプステクスチャ : フォーマット
	switch( config.smDepthTexFormat )
	{
	case Mix::Graphics::FMT_R16G16B16A16F:
	case Mix::Graphics::FMT_R32G32B32A32F:
		smDepthTexFormat = config.smDepthTexFormat;
		break;

	default:
		MIX_LOG_ERROR( L"シャドウテクスチャのフォーマットが不正です" );
		return False;
	}

	// デプステクスチャ : サイズ
	if( MIX_TESTBIT( mepProcFlags, EffectPackage::EP_SHADOW ) == EffectPackage::EP_SHADOW )
	{
		smDepthTexSize.x = config.smDepthTexSize;
		smDepthTexSize.y = config.smDepthTexSize;
	}
	else
	{
		smDepthTexSize.x = 1;
		smDepthTexSize.y = 1;
	}

	// カラーテクスチャ : フォーマット( 固定 )
	smTexFormat = Mix::Graphics::FMT_R8G8B8A8;

	// カラーテクスチャ : サイズ
	switch( config.smSmplRes )
	{
	case Mix::Scene::RSMPL_DEFAULT:
		smTexSize = targetSize;
		smSamplingType = Mix::Scene::Common::RST_COPY;
		break;
	case Mix::Scene::RSMPL_DOWN2X:
		smTexSize = targetSize / 2;
		smSamplingType = Mix::Scene::Common::RST_DOWN2x;
		break;
	case Mix::Scene::RSMPL_DOWN4X:
		smTexSize = targetSize / 4;
		smSamplingType = Mix::Scene::Common::RST_DOWN4x;
		break;
	}

	/*
		アンビエントオクルージョン
	*/

	// カラーテクスチャ : フォーマット( 固定 )
	aoTexFormat = Mix::Graphics::FMT_R8G8B8A8;

	// カラーテクスチャ : サイズ
	switch( config.aoSmplRes )
	{
	case Mix::Scene::RSMPL_DEFAULT:
		aoTexSize = targetSize;
		aoSamplingType = Mix::Scene::Common::RST_COPY;
		break;
	case Mix::Scene::RSMPL_DOWN2X:
		aoTexSize = targetSize / 2;
		aoSamplingType = Mix::Scene::Common::RST_DOWN2x;
		break;
	case Mix::Scene::RSMPL_DOWN4X:
		aoTexSize = targetSize / 4;
		aoSamplingType = Mix::Scene::Common::RST_DOWN4x;
		break;
	}

	/*
		ルミノシティ
	*/

	// フォーマット
#ifdef _DEBUG
	switch( config.lumTexFormat )
	{
	case Mix::Graphics::FMT_R16F:
		lumTexFormat = Mix::Graphics::FMT_R16G16B16A16F;
		break;
	case Mix::Graphics::FMT_R32F:
		lumTexFormat = Mix::Graphics::FMT_R32G32B32A32F;
		break;

	default:
		MIX_LOG_ERROR( L"ルミナンステクスチャのフォーマットが不正です" );
		return False;
	}
#else //_DEBUG
	switch( config.lumTexFormat )
	{
	case Mix::Graphics::FMT_R16F:
	case Mix::Graphics::FMT_R32F:
		lumTexFormat = config.lumTexFormat;
		break;

	default:
		MIX_LOG_ERROR( L"ルミナンステクスチャのフォーマットが不正です" );
		return False;
	}
#endif //_DEBUG

	/*
		ブルーム
	*/

	// オーバーフロー : 数
	bloomOverflowNum = ( config.bloomOverflowNum > 0 )? config.bloomOverflowNum : 1;

	// オーバーフロー : テクスチャのスケール
	switch( config.bloomSmplRes )
	{
	case Mix::Scene::RSMPL_DEFAULT:
	case Mix::Scene::RSMPL_DOWN2X:
		bloomSamplingType = Mix::Scene::Common::RST_DOWN2x;
		bloomTexScale = 2;
		break;
	case Mix::Scene::RSMPL_DOWN4X:
		bloomSamplingType = Mix::Scene::Common::RST_DOWN4x;
		bloomTexScale = 4;
		break;
	default:
		MIX_LOG_ERROR( L"ブルームテクスチャの解像度が不正です" );
		return False;
	}

	/*
		レンズフレア
	*/

	// テクスチャのサイズ
	switch( config.lfSmplRes )
	{
	case Mix::Scene::RSMPL_DEFAULT:
		lfSamplingType = Mix::Scene::Common::RST_COPY;
		lfTexSize = targetSize;
		break;
	case Mix::Scene::RSMPL_DOWN2X:
		lfSamplingType = Mix::Scene::Common::RST_DOWN2x;
		lfTexSize = targetSize / 2;
		break;
	case Mix::Scene::RSMPL_DOWN4X:
		lfSamplingType = Mix::Scene::Common::RST_DOWN4x;
		lfTexSize = targetSize / 4;
		break;
	default:
		MIX_LOG_ERROR( L"レンズフレアテクスチャの解像度が不正です" );
		return False;
	}

	/*
		色収差
	*/

	// テクスチャ : サイズ
	switch( config.caSmplRes )
	{
	case Mix::Scene::RSMPL_DEFAULT:
		caSamplingType = Mix::Scene::Common::RST_COPY;
		caTexSize = targetSize;
		break;
	case Mix::Scene::RSMPL_DOWN2X:
		caSamplingType = Mix::Scene::Common::RST_DOWN2x;
		caTexSize = targetSize / 2;
		break;
	case Mix::Scene::RSMPL_DOWN4X:
		caSamplingType = Mix::Scene::Common::RST_DOWN4x;
		caTexSize = targetSize / 4;
		break;
	default:
		MIX_LOG_ERROR( L"色収差テクスチャの解像度が不正です" );
		return False;
	}

	//テクスチャ : フォーマット
	caTexFormat = Mix::Graphics::FMT_R8G8B8A8;

	/*
		被写界深度
	*/

	// テクスチャ : サイズ
	switch( config.dofSmplRes )
	{
	case Mix::Scene::RSMPL_DEFAULT:
		dofSamplingType = Mix::Scene::Common::RST_COPY;
		dofTexSize = targetSize;
		break;
	case Mix::Scene::RSMPL_DOWN2X:
		dofSamplingType = Mix::Scene::Common::RST_DOWN2x;
		dofTexSize = targetSize / 2;
		break;
	case Mix::Scene::RSMPL_DOWN4X:
		dofSamplingType = Mix::Scene::Common::RST_DOWN4x;
		dofTexSize = targetSize / 4;
		break;
	default:
		MIX_LOG_ERROR( L"被写界深度テクスチャの解像度が不正です" );
		return False;
	}

	//テクスチャ : フォーマット
	dofTexFormat = Mix::Graphics::FMT_R8G8B8A8;

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 解放
	////////////////////////////////////////////////////////////////////////////////////////////////////

	ReleaseCameraResource( pView );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 作成( ダイナミクス )
	////////////////////////////////////////////////////////////////////////////////////////////////////

	MIX_ASSERT( pView->pObjDragger == NULL );

	if( MIX_TESTBIT( caps, Mix::Scene::RCAP_DYNAMICS ) == Mix::Scene::RCAP_DYNAMICS )
	{
		pView->pObjDragger = m_pDynamicsWorld->CreateObjectDragger( L"ObjDragger" );
	}

	pView->bDragObj = False;
	
	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 作成( 全般 )
	////////////////////////////////////////////////////////////////////////////////////////////////////

	MIX_ASSERT( pView->pDepthBuff == NULL );
	MIX_ASSERT( pView->pColorTexChain == NULL );
	MIX_ASSERT( pView->pDepthTexChain == NULL );
	MIX_ASSERT( pView->pDataTex == NULL );
	MIX_ASSERT( pView->pRefractTex == NULL );

	// 共通のビューポート
	pView->viewport.x = 0;
	pView->viewport.y = 0;
	pView->viewport.width = targetSize.x;
	pView->viewport.height = targetSize.y;

	// デプスバッファ
	pView->pDepthBuff = m_pResourceMgr->CreateDepthTexture( resOwner, Renderer::RTAG_DEPTH_BUFF, targetSize, depthBuffFormat, L"DepthBuff" );
	if( pView->pDepthBuff == NULL )
	{
		ReleaseCameraResource( pView );
		return False;
	}

	// カラーテクスチャ
	pView->pColorTexChain = m_pResourceMgr->CreateTargetTextureChain( resOwner, Renderer::RTAG_COLOR_TEX_CHAIN, targetSize, colorTexFormat, L"ColorTexChain" );
	if( pView->pColorTexChain == NULL )
	{
		ReleaseCameraResource( pView );
		return False;
	}

	// デプステクスチャ
	pView->pDepthTexChain = m_pResourceMgr->CreateTargetTextureChain( resOwner, Renderer::RTAG_DEPTH_TEX_CHAIN, targetSize, depthTexFormat, L"DepthTex" );
	if( pView->pDepthTexChain == NULL )
	{
		ReleaseCameraResource( pView );
		return False;
	}

	// データテクスチャ
	pView->pDataTex = m_pResourceMgr->CreateTargetTexture( resOwner, Renderer::RTAG_DATA_TEX, targetSize, dataTexFormat, L"DataTex" );
	if( pView->pDataTex == NULL )
	{
		ReleaseCameraResource( pView );
		return False;
	}

	// リフラクトテクスチャ
	if( MIX_TESTBIT( mepProcFlags, EffectPackage::EP_REFRACT ) == EffectPackage::EP_REFRACT )
	{
		pView->pRefractTex = m_pResourceMgr->CreateTargetTexture( resOwner, Renderer::RTAG_REFFRACT_TEX, targetSize, refractTexFormat, L"RefractTex" );
		if( pView->pRefractTex == NULL )
		{
			ReleaseCameraResource( pView );
			return False;
		}
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// アンビエントオクルージョン
	////////////////////////////////////////////////////////////////////////////////////////////////////

	MIX_ASSERT( pView->pAOTex == NULL );
	MIX_ASSERT( pView->pAOTexChain == NULL );

	if( MIX_TESTBIT( caps, Mix::Scene::RCAP_AMBIENT_OCCLUSION ) == Mix::Scene::RCAP_AMBIENT_OCCLUSION )
	{
		//テクスチャ : カラー
		pView->pAOTex = m_pResourceMgr->CreateTargetTexture( resOwner, Renderer::RTAG_TEMP_TEX_0, targetSize, aoTexFormat, L"AmbientOcclusion/ColorTex" );
		if( pView->pAOTex == NULL )
		{
			ReleaseCameraResource( pView );
			return False;
		}

		//ターゲットテクスチャチェイン : ブラー
		pView->pAOTexChain = m_pResourceMgr->CreateTargetTextureChain( resOwner, Renderer::RTAG_TEMP_TEX_CHAIN_0, aoTexSize, aoTexFormat, L"AmbientOcclusion/BlurTexChain" );
		if( pView->pAOTexChain == NULL )
		{
			ReleaseCameraResource( pView );
			return False;
		}

		pView->AOSamplingType = aoSamplingType;
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// シャドウマッピング
	////////////////////////////////////////////////////////////////////////////////////////////////////

	MIX_ASSERT( pView->pSdwDepthBuff == NULL );
	MIX_ASSERT( pView->pSdwDepthTex == NULL );
	MIX_ASSERT( pView->pSdwMapTex == NULL );
	MIX_ASSERT( pView->pSdwMapTexChain == NULL );

	if( MIX_TESTBIT( mepProcFlags, EffectPackage::EP_SHADOW ) == EffectPackage::EP_SHADOW )
	{
		if( MIX_TESTBIT( caps, Mix::Scene::RCAP_SHADOW_MAPPING ) == Mix::Scene::RCAP_SHADOW_MAPPING )
		{
			//テクスチャ : デプスバッファ
			pView->pSdwDepthBuff = m_pResourceMgr->CreateDepthTexture( resOwner, Renderer::RTAG_SDW_DEPTH_BUFF, smDepthTexSize, depthBuffFormat, L"Shadow/DepthBuff" );
			if( pView->pSdwDepthBuff == NULL )
			{
				ReleaseCameraResource( pView );
				return False;
			}

			//テクスチャチェイン : ブラー
			pView->pSdwMapTexChain = m_pResourceMgr->CreateTargetTextureChain( resOwner, Renderer::RTAG_TEMP_TEX_CHAIN_0, smTexSize, smTexFormat, L"Shadow/BlurTexChain" );
			if( pView->pSdwMapTexChain == NULL )
			{
				ReleaseCameraResource( pView );
				return False;
			}
		}

		//デプス : ビューポート
		pView->SdwDepthViewport.x = 0;
		pView->SdwDepthViewport.y = 0;
		pView->SdwDepthViewport.width = smDepthTexSize.x;
		pView->SdwDepthViewport.height = smDepthTexSize.y;

		//デプステクスチャ : バイアス
		pView->SdwBiasMat.m00 = 0.5f;
		pView->SdwBiasMat.m01 = 0.0f;
		pView->SdwBiasMat.m02 = 0.0f;
		pView->SdwBiasMat.m03 = 0.0f;
		pView->SdwBiasMat.m10 = 0.0f;
		pView->SdwBiasMat.m11 = -0.5f;
		pView->SdwBiasMat.m12 = 0.0f;
		pView->SdwBiasMat.m13 = 0.0f;
		pView->SdwBiasMat.m20 = 0.0f;
		pView->SdwBiasMat.m21 = 0.0f;
		pView->SdwBiasMat.m22 = 0.0f;
		pView->SdwBiasMat.m23 = 0.0f;
		pView->SdwBiasMat.m30 = 0.5f + MIX_FLOAT_DIV( 0.5f, static_cast<Float32>( targetSize.x ) );
		pView->SdwBiasMat.m31 = 0.5f + MIX_FLOAT_DIV( 0.5f, static_cast<Float32>( targetSize.y ) );
		pView->SdwBiasMat.m32 = 0.0f;
		pView->SdwBiasMat.m33 = 1.0f;

		//テクスチャ : デプス( レンダラーの設定で無効にされている場合は 1x1 で作成する )
		pView->pSdwDepthTex = m_pResourceMgr->CreateTargetTexture( resOwner, Renderer::RTAG_SDW_DEPTH_TEX, smDepthTexSize, smDepthTexFormat, L"Shadow/DepthTex" );
		if( pView->pSdwDepthTex == NULL )
		{
			ReleaseCameraResource( pView );
			return False;
		}

		//ターゲットテクスチャ : カラー( レンダラーの設定で無効にされていても作成する )
		pView->pSdwMapTex = m_pResourceMgr->CreateTargetTexture( resOwner, Renderer::RTAG_SDW_MAP_TEX, targetSize, smTexFormat, L"Shadow/MapTex" );
		if( pView->pSdwMapTex == NULL )
		{
			ReleaseCameraResource( pView );
			return False;
		}

		//サンプリング : タイプ
		pView->SdwMapSamplingType = smSamplingType;
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// ルミノシティ
	////////////////////////////////////////////////////////////////////////////////////////////////////

	MIX_ASSERT( pView->pLumInitalTex == NULL );
	MIX_ASSERT( pView->LumIterateTexList.size() == 0 );
	MIX_ASSERT( pView->pLumFinalTex == NULL );
	MIX_ASSERT( pView->pLumAdaptedTexChain == NULL );

	if( MIX_TESTBIT( caps, Mix::Scene::RCAP_LUMINOSITY ) == Mix::Scene::RCAP_LUMINOSITY )
	{
		Mix::Point texSize;
		Mix::Graphics::ITexture* pTex;

		//最初のトランスフォームテクスチャのサイズ( 無いとは思うけど、念のため )
		texSize = targetSize / Mix::Scene::Common::RENDERER_LUM_TRANSFORM_SCALE;
		if( ( texSize.x <= 1 ) ||
			( texSize.y <= 1 ) )
		{
			ReleaseCameraResource( pView );
			return False;
		}

		//最初のトランスフォームテクスチャ
		tempStr.Sprintf( L"Luminosity/Transform/Inital(%dx%d)", texSize.x, texSize.y );
		pView->pLumInitalTex = m_pResourceMgr->CreateTargetTexture( resOwner, Renderer::RTAG_LUM_INITIAL_TEX, texSize, lumTexFormat, tempStr.GetConstPtr() );
		if( pView->pLumInitalTex == NULL )
		{
			ReleaseCameraResource( pView );
			return False;
		}

		//繰り返しのトランスフォームテクスチャのサイズ
		texSize = texSize / Mix::Scene::Common::RENDERER_LUM_TRANSFORM_SCALE;
		if( ( texSize.x <= 1 ) || ( texSize.y <= 1 ) )
		{
			ReleaseCameraResource( pView );
			return False;
		}

		//テクスチャ : トランスフォーム( 繰り返し )
		do
		{
			tempStr.Sprintf( L"Luminosity/Transform/Iterate(%dx%d)", texSize.x, texSize.y );
			pTex = m_pResourceMgr->CreateTargetTexture( resOwner, Renderer::RTAG_LUM_ITEXRATE_TEX, texSize, lumTexFormat, tempStr.GetConstPtr() );
			if( pTex != NULL )
			{
				pView->LumIterateTexList.push_back( pTex );
			}
			else
			{
				ReleaseCameraResource( pView );
				return False;
			}

			texSize /= Mix::Scene::Common::RENDERER_LUM_TRANSFORM_SCALE;
			if( texSize.x < 1 ) { texSize.x = 1; }
			if( texSize.y < 1 ) { texSize.y = 1; }
		}
		while( ( texSize.x > 1 ) && ( texSize.y > 1 ) );

		//テクスチャ : トランスフォーム( 最後 )
		pView->pLumFinalTex = m_pResourceMgr->CreateTargetTexture( resOwner, Renderer::RTAG_LUM_FINAL_TEX, Mix::Point( 1, 1 ), lumTexFormat, L"Luminosity/Transform/Final(1x1)" );
		if( pView->pLumFinalTex == NULL )
		{
			ReleaseCameraResource( pView );
			return False;
		}

		//テクスチャチェイン : 順応した輝度
		pView->pLumAdaptedTexChain = m_pResourceMgr->CreateTargetTextureChain( resOwner, Renderer::RTAG_LUM_ADAPTED_TEX_CHAIN, Mix::Point( 1, 1 ), lumTexFormat, L"Luminosity/Adaptation(1x1)" );
		if( pView->pLumAdaptedTexChain == NULL )
		{
			ReleaseCameraResource( pView );
			return False;
		}
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// ブルーム
	////////////////////////////////////////////////////////////////////////////////////////////////////

	MIX_ASSERT( pView->pDebBloomBrightPassTex == NULL );
	MIX_ASSERT( pView->BloomTexChainList.size() == 0 );

	if( MIX_TESTBIT( caps, Mix::Scene::RCAP_BLOOM ) == Mix::Scene::RCAP_BLOOM )
	{
#ifdef _DEBUG
		// ターゲットテクスチャ : ブライトパス
		pView->pDebBloomBrightPassTex = m_pResourceMgr->CreateTargetTexture( resOwner, Renderer::RTAG_DEBUG_TEX, targetSize / bloomTexScale, colorTexFormat, L"Bloom/BrightPass" );
		if( pView->pDebBloomBrightPassTex == NULL )
		{
			ReleaseCameraResource( pView );
			return False;
		}
#endif //_DEBUG

		// ターゲットテクスチャチェイン : オーバーフロー
		for( i = 0; i < bloomOverflowNum; i++ )
		{
			Mix::Point texSize = Mix::Point::Max( Mix::Point( 1, 1 ), targetSize / ( bloomTexScale + bloomTexScale * i ) );
			Mix::Graphics::Utility::ITargetTextureChain* pTexChain;

			tempStr.Sprintf( L"Bloom/BlurTexChain(%dx%d)", texSize.x, texSize.y );

			pTexChain = m_pResourceMgr->CreateTargetTextureChain( resOwner, Renderer::RTAG_TEMP_TEX_CHAIN_0, texSize, colorTexFormat, tempStr.GetConstPtr() );
			if( pTexChain == NULL )
			{
				ReleaseCameraResource( pView );
				return False;
			}

			pView->BloomTexChainList.push_back( pTexChain );
		}

		// オーバーフロー : パラメータ
		pView->pInternalCamera->ResizeBloomOverflows( bloomOverflowNum );

		//サンプリング : タイプ
		m_BloomSamplingType = bloomSamplingType;
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// ゴッドレイ
	////////////////////////////////////////////////////////////////////////////////////////////////////

	MIX_ASSERT( pView->pDebLSBrightPassTex == NULL );
	MIX_ASSERT( pView->pLSTexChain == NULL );

	if( MIX_TESTBIT( caps, Mix::Scene::RCAP_LIGHT_SHAFTS ) == Mix::Scene::RCAP_LIGHT_SHAFTS )
	{
#ifdef _DEBUG
		//ターゲットテクスチャ : ブライトパス
		pView->pDebLSBrightPassTex = m_pResourceMgr->CreateTargetTexture( resOwner, Renderer::RTAG_DEBUG_TEX, targetSize, colorTexFormat, L"GodRay/BrightPass" );
		if( pView->pDebLSBrightPassTex == NULL )
		{
			ReleaseCameraResource( pView );
			return False;
		}
#endif //_DEBUG

		// ターゲットテクスチャチェイン : ブラー
		pView->pLSTexChain = m_pResourceMgr->CreateTargetTextureChain( resOwner, Renderer::RTAG_TEMP_TEX_CHAIN_0, targetSize, colorTexFormat, L"GodRay/BlurTexChain" );
		if( pView->pLSTexChain == NULL )
		{
			ReleaseCameraResource( pView );
			return False;
		}

		// ビューポート
		pView->LSViewport.x = 0;
		pView->LSViewport.y = 0;
		pView->LSViewport.width = targetSize.x;
		pView->LSViewport.height = targetSize.y;
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// レンズフレア
	////////////////////////////////////////////////////////////////////////////////////////////////////

	MIX_ASSERT( pView->pDebLFBrightPassTex == NULL );
	MIX_ASSERT( pView->pLFTexChain == NULL );

	if( MIX_TESTBIT( caps, Mix::Scene::RCAP_LENS_FLARE ) == Mix::Scene::RCAP_LENS_FLARE )
	{
#ifdef _DEBUG
		//ターゲットテクスチャ : ブライトパス
		pView->pDebLFBrightPassTex = m_pResourceMgr->CreateTargetTexture( resOwner, Renderer::RTAG_DEBUG_TEX, lfTexSize, colorTexFormat, L"LensFlare/BrightPass" );
		if( pView->pDebLFBrightPassTex == NULL )
		{
			ReleaseCameraResource( pView );
			return False;
		}
#endif //_DEBUG

		// ターゲットテクスチャチェイン
		pView->pLFTexChain = m_pResourceMgr->CreateTargetTextureChain( resOwner, Renderer::RTAG_TEMP_TEX_CHAIN_0, lfTexSize, colorTexFormat, L"LensFlare/BlurTexChain" );
		if( pView->pLFTexChain == NULL )
		{
			ReleaseCameraResource( pView );
			return False;
		}

		// ビューポート
		pView->LFViewport.x = 0;
		pView->LFViewport.y = 0;
		pView->LFViewport.width = lfTexSize.x;
		pView->LFViewport.height = lfTexSize.y;
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 色収差
	////////////////////////////////////////////////////////////////////////////////////////////////////

	MIX_ASSERT( pView->pCATexChain == NULL );

	if( MIX_TESTBIT( caps, Mix::Scene::RCAP_CHROMATISM ) == Mix::Scene::RCAP_CHROMATISM )
	{
		// ターゲットテクスチャチェイン : ブラー
		pView->pCATexChain = m_pResourceMgr->CreateTargetTextureChain( resOwner, Renderer::RTAG_TEMP_TEX_CHAIN_0, caTexSize, caTexFormat, L"Chromatism/BlurTexChain" );
		if( pView->pCATexChain == NULL )
		{
			ReleaseCameraResource( pView );
			return False;
		}

		// ビューポート
		pView->CAViewport.x = 0;
		pView->CAViewport.y = 0;
		pView->CAViewport.width = caTexSize.x;
		pView->CAViewport.height = caTexSize.y;

		// サンプリング : タイプ
		pView->CASamplingType = caSamplingType;
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 被写界深度
	////////////////////////////////////////////////////////////////////////////////////////////////////

	MIX_ASSERT( pView->pDofBokehTex0 == NULL );
	MIX_ASSERT( pView->pDofBokehTex1 == NULL );
	MIX_ASSERT( pView->pDofTempTex == NULL );

	if( MIX_TESTBIT( caps, Mix::Scene::RCAP_DEPTH_OF_FIELD ) == Mix::Scene::RCAP_DEPTH_OF_FIELD )
	{
		Mix::Vector4 dofTxS(	MIX_FLOAT_RECIPROCAL( static_cast<Float32>( dofTexSize.x ) ),
								MIX_FLOAT_RECIPROCAL( static_cast<Float32>( dofTexSize.y ) ),
								0.0f,
								0.0f );

		//ターゲットテクスチャ : ぼかし0
		pView->pDofBokehTex0 = m_pResourceMgr->CreateTargetTexture( resOwner, Renderer::RTAG_TEMP_TEX_0, dofTexSize, dofTexFormat, L"Dof/BokehTex0" );
		if( pView->pDofBokehTex0 == NULL )
		{
			ReleaseCameraResource( pView );
			return False;
		}

		//ターゲットテクスチャ : ぼかし1
		pView->pDofBokehTex1 = m_pResourceMgr->CreateTargetTexture( resOwner, Renderer::RTAG_TEMP_TEX_1, dofTexSize, dofTexFormat, L"Dof/BokehTex1" );
		if( pView->pDofBokehTex1 == NULL )
		{
			ReleaseCameraResource( pView );
			return False;
		}

		//ターゲットテクスチャ : テンポラリ
		pView->pDofTempTex = m_pResourceMgr->CreateTargetTexture( resOwner, Renderer::RTAG_TEMP_TEX_2, dofTexSize, dofTexFormat, L"Dof/BokehTemp" );
		if( pView->pDofTempTex == NULL )
		{
			ReleaseCameraResource( pView );
			return False;
		}

		//ビューポート
		pView->DofViewport.x = 0;
		pView->DofViewport.y = 0;
		pView->DofViewport.width = dofTexSize.x;
		pView->DofViewport.height = dofTexSize.y;

		//サンプリングタイプ
		pView->DofSamplingType = dofSamplingType;

		//サンプリングテーブル
		for( i = 0; i < Renderer::DOF_SAMPLING_NUM; i++ )
		{
			pView->DofSamplingTable[i] = Renderer::DOF_SAMPLING_OFFSET_TABLE[i] * dofTxS;
		}
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////

	modCaps = caps;

	////////////////////////////////////////////////////////////////////////////////////////////////////

	return True;
}

Boolean Renderer::DragObject( UInt32 viewID, const Mix::Rectangle& viewRect, const Mix::Point& pos )
{
	MIX_ASSERT( viewID < m_ViewList.size() );

	Renderer::VIEW* pView = &( m_ViewList[viewID] );
	if( pView->pObjDragger == NULL )
	{
		return False;
	}

	MIX_ASSERT( pView->pInternalCamera != NULL );

	Mix::Scene::Common::Camera* pInternalCamera = pView->pInternalCamera;
	Mix::Dynamics::IObjectDragger* pObjDragger = pView->pObjDragger;
	Mix::Vector3 rayTo = pInternalCamera->Unproject( viewRect, pos, 1.0f );

	if( pView->pObjDragger->IsCatch() == False )
	{
		Mix::Vector3 rayFrom = pInternalCamera->Unproject( viewRect, pos, 0.0f );

		if( pObjDragger->CatchStart( pInternalCamera->GetEye(), rayFrom, rayTo ) == True )
		{
			pView->bDragObj = True;
		}
	}
	else
	{
		pObjDragger->CatchContinue( pInternalCamera->GetEye(), rayTo );
		pView->bDragObj = True;
	}

	return pObjDragger->IsCatch();
}

void Renderer::Draw( UInt32 viewID )
{
	MIX_ASSERT( viewID < m_ViewList.size() );

	Renderer::VIEW* pView = &( m_ViewList[viewID] );
	MIX_ASSERT( pView->pInternalCamera != NULL );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// デバッグ : 開始
	///////////////////////////////////////////////////////////////////////////////////////////////////

#ifdef _DEBUG
	m_DebTotalTimer.Reset();
#endif //_DEBUG

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

	// ビューを展開

	m_pCamera = pView->pInternalCamera;
	m_BackgroundColor = m_pCamera->GetBackgroundColor();
	m_Viewport = pView->viewport;
	m_pDepthBuff = pView->pDepthBuff;
	m_pColorTexChain = pView->pColorTexChain;
	m_pDepthTexChain = pView->pDepthTexChain;
	m_pDataTex = pView->pDataTex;
	m_pRefractTex = pView->pRefractTex;
	m_AOSamplingType = pView->AOSamplingType;
	m_pAOTex = pView->pAOTex;
	m_pAOTexChain = pView->pAOTexChain;
	m_SdwViewport = pView->SdwDepthViewport;
	m_SdwBiasMat = pView->SdwBiasMat;
	m_SdwMapSamplingType = pView->SdwMapSamplingType;
	m_pSdwDepthBuff = pView->pSdwDepthBuff;
	m_pSdwDepthTex = pView->pSdwDepthTex;
	m_pSdwMapTex = pView->pSdwMapTex;
	m_pSdwMapTexChain = pView->pSdwMapTexChain;
	m_pLumInitalTex = pView->pLumInitalTex;
	m_pLumFinalTex = pView->pLumFinalTex;
	m_pLumIterateTexList = &( pView->LumIterateTexList );
	m_pLumAdaptedTexChain = pView->pLumAdaptedTexChain;
	m_BloomSamplingType = pView->BloomSamplingType;
	m_pBloomTexChainList = &( pView->BloomTexChainList );
	m_LSViewport = pView->LSViewport;
	m_pLSTexChain = pView->pLSTexChain;
	m_LFViewport = pView->LFViewport;
	m_LFSamplingType = pView->LFSamplingType;
	m_pLFTexChain = pView->pLFTexChain;
	m_CAViewport = pView->CAViewport;
	m_CASamplingType = pView->CASamplingType;
	m_pCATexChain = pView->pCATexChain;
	m_DofSamplingType = pView->DofSamplingType;
	m_pDofSamplingTable = pView->DofSamplingTable;
	m_pDofBokehTex0 = pView->pDofBokehTex0;
	m_pDofBokehTex1 = pView->pDofBokehTex1;
	m_pDofTempTex = pView->pDofTempTex;

#ifdef _DEBUG
	m_pDebBloomBrightPassTex = pView->pDebBloomBrightPassTex;
	m_pDebLSBrightPassTex = pView->pDebLSBrightPassTex;
	m_pDebLFBrightPassTex = pView->pDebLFBrightPassTex;

	m_pDebCProfGeneral = &( pView->debProfGeneral );
	m_pDebCProfOctree = &( pView->debProfOctree );
	m_pDebCProfLight = &( pView->debProfLight );
	m_pDebCProfWaterPool = &( pView->debProfWaterPool );
	m_pDebCProfWidget = &( pView->debProfWidget );
	m_pDebCProfActorModel = &( pView->debProfActorModel );
	m_pDebCProfTerrainModel = &( pView->debProfTerrainModel );
	m_pDebCProfProjShadow = &( pView->debProfProjShadow );
	m_pDebCProfDrawOpacity = &( pView->debProfDrawOpacity );
	m_pDebCProfDrawNeut = &( pView->debProfDrawNeut );
	m_pDebCProfDrawRefract = &( pView->debProfDrawRefract );
	m_pDebCProfDrawTransp = &( pView->debProfDrawTransp );
	m_pDebCProfPostProc = &( pView->debProfPostProc );

	Mix::Memory::Zero( m_pDebCProfGeneral, sizeof( Mix::Scene::DEBUG_PROFILE_CAMERA_GENERAL ) );
	Mix::Memory::Zero( m_pDebCProfOctree, sizeof( Mix::Scene::DEBUG_PROFILE_CAMERA_OCTREE ) );
	Mix::Memory::Zero( m_pDebCProfLight, sizeof( Mix::Scene::DEBUG_PROFILE_CAMERA_LIGHT ) );
	Mix::Memory::Zero( m_pDebCProfWaterPool, sizeof( Mix::Scene::DEBUG_PROFILE_CAMERA_WATER_POOL ) );
	Mix::Memory::Zero( m_pDebCProfWidget, sizeof( Mix::Scene::DEBUG_PROFILE_CAMERA_WIDGET ) );
	Mix::Memory::Zero( m_pDebCProfActorModel, sizeof( Mix::Scene::DEBUG_PROFILE_CAMERA_MODEL ) );
	Mix::Memory::Zero( m_pDebCProfTerrainModel, sizeof( Mix::Scene::DEBUG_PROFILE_CAMERA_MODEL ) );
	Mix::Memory::Zero( m_pDebCProfProjShadow, sizeof( Mix::Scene::DEBUG_PROFILE_CAMERA_PROJ_SHADOW ) );
	Mix::Memory::Zero( m_pDebCProfDrawOpacity, sizeof( Mix::Scene::DEBUG_PROFILE_CAMERA_DRAW_OPACITY ) );
	Mix::Memory::Zero( m_pDebCProfDrawNeut, sizeof( Mix::Scene::DEBUG_PROFILE_CAMERA_DRAW_NEUTRALITY ) );
	Mix::Memory::Zero( m_pDebCProfDrawRefract, sizeof( Mix::Scene::DEBUG_PROFILE_CAMERA_DRAW_REFRACT ) );
	Mix::Memory::Zero( m_pDebCProfDrawTransp, sizeof( Mix::Scene::DEBUG_PROFILE_CAMERA_DRAW_TRANSPARENCY ) );
	Mix::Memory::Zero( m_pDebCProfPostProc, sizeof( Mix::Scene::DEBUG_PROFILE_CAMERA_POST_PROCESS ) );

	m_pDebCProfLight->tSpotCount = MIX_UIT_TO_UI32( m_SpotLightList.size() );
	m_pDebCProfLight->tPointCount = MIX_UIT_TO_UI32( m_PointLightList.size() );
	m_pDebCProfWidget->pl.tCount = MIX_UIT_TO_UI32( m_PlanterList.size() );
	m_pDebCProfWidget->lp.tCount = MIX_UIT_TO_UI32( m_LeavingParticleList.size() );
	m_pDebCProfWidget->sp.tCount = MIX_UIT_TO_UI32( m_ScatterParticleList.size() );
	m_pDebCProfActorModel->tCount = MIX_UIT_TO_UI32( m_ActorModelList.size() );
	m_pDebCProfTerrainModel->tCount = MIX_UIT_TO_UI32( m_TerrainModelList.size() );
#endif //_DEBUG

	// 描画前の状態を取得

	m_pGraphicsDev->GetTarget(	&( m_DeviceState.pTargetTexture[0] ),
								&( m_DeviceState.pTargetTexture[1] ),
								&( m_DeviceState.pTargetTexture[2] ),
								&( m_DeviceState.pTargetTexture[3] ),
								&( m_DeviceState.pDepthTexture ) );

	m_DeviceState.viewport = m_pGraphicsDev->GetViewBounds();
	m_DeviceState.scissor = m_pGraphicsDev->GetScissorBounds();

	m_DeviceState.rasterizer = m_pGraphicsDev->GetRasterizerState();
	m_DeviceState.depth = m_pGraphicsDev->GetDepthState();
	m_DeviceState.blend = m_pGraphicsDev->GetBlendState();

	// 描画の初期化

	m_pGraphicsDev->SetTarget( NULL, NULL, NULL, NULL, NULL );
	m_pGraphicsDev->SetViewBounds( m_Viewport );
	m_pGraphicsDev->SetScissorBounds( m_Viewport );
	m_pGraphicsDev->SetRasterizerState( Mix::Graphics::FILL_SOLID, Mix::Graphics::CULL_BACK, False );
	m_pGraphicsDev->SetDepthState( True, True );
	m_pGraphicsDev->SetBlendState( Mix::Graphics::BLEND_COPY );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 描画の事前処理
	////////////////////////////////////////////////////////////////////////////////////////////////////

	/*
		オクトリー
	*/

	//////////////////////////////////////////////////

	//デバッグ : 計測開始
	SCENE_DEB( m_DebTimer.Reset() );

	//収集を開始
	m_pOctree->RenderBegin();

	//実際に色として描画するオブジェクトを収集
	m_pOctree->RenderColor( m_pCamera->GetFrustum() );

	//デバッグ : 計測終了
	SCENE_DEB( m_pDebCProfOctree->ccElapsedTime = m_DebTimer.GetF32() );

	//////////////////////////////////////////////////

	//影を投影するオブジェクトを収集
	if( ( m_pCamera->IsShadowMappingAvailabled() == True ) &&
		( m_pCamera->IsShadowMappingEnabled() == True ) &&
		( m_pDirectionalLight != NULL ) &&
		( m_pDirectionalLight->IsEnabled() == True ) )
	{
		//デバッグ : 計測開始
		SCENE_DEB( m_DebTimer.Reset() );

		//キャストを初期化( クリップ境界と、キャスト前の初期化 )
		m_pDirectionalLight->Projection_Reset( m_pCamera );

		//対象になるオブジェクトをざっくりと収集
		m_pOctree->RenderShadow( m_pDirectionalLight->Projection_GetClipBounds() );

		//デバッグ : 計測終了
		SCENE_DEB( m_pDebCProfOctree->csElapsedTime = m_DebTimer.GetF32() );
	}

	//////////////////////////////////////////////////

	//デバッグ : 計測開始
	SCENE_DEB( m_DebTimer.Reset() );

	//収集を終了
	m_pOctree->RenderEnd();

	//デバッグ : 計測終了
	SCENE_DEB( m_pDebCProfOctree->fElapsedTime = m_DebTimer.GetF32() );

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

	//シャドウコマンドを収集
	CollectShadowCommand();

	//描画コマンドを収集 
	CollectDrawCommand();

	//コマンドを処理
	ProcessCommand();

	//ポストプロセス
	PostProcess();

	//作業用データのクリア
	CleanupWork();

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 描画前の状態に復帰
	////////////////////////////////////////////////////////////////////////////////////////////////////

	m_pGraphicsDev->SetTarget(	m_DeviceState.pTargetTexture[0],
								m_DeviceState.pTargetTexture[1],
								m_DeviceState.pTargetTexture[2],
								m_DeviceState.pTargetTexture[3],
								m_DeviceState.pDepthTexture );

	m_pGraphicsDev->SetScissorBounds( m_DeviceState.scissor );
	m_pGraphicsDev->SetViewBounds( m_DeviceState.viewport );
	m_pGraphicsDev->SetRasterizerState( m_DeviceState.rasterizer );
	m_pGraphicsDev->SetDepthState( m_DeviceState.depth );
	m_pGraphicsDev->SetBlendState( m_DeviceState.blend );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 後処理
	////////////////////////////////////////////////////////////////////////////////////////////////////

	//ターゲットテクスチャを破棄
	for( UInt32 i = 0; i < Mix::Graphics::TARGET_MAX; i++ )
	{
		MIX_RELEASE( m_DeviceState.pTargetTexture[i] );
	}

	//デプステクスチャを破棄
	MIX_RELEASE( m_DeviceState.pDepthTexture );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// デバッグ : 終了
	///////////////////////////////////////////////////////////////////////////////////////////////////

#ifdef _DEBUG

	m_pDebCProfGeneral->drawElapsedTime = m_DebTotalTimer.GetF32();

	m_pDebRProfGeneral->drawElapsedTime += m_pDebCProfGeneral->drawElapsedTime;
	m_pDebRProfGeneral->drawPrimCount += m_pDebCProfGeneral->drawPrimCount;

	m_DebSpotLightList.Clear();
	m_DebPointLightList.Clear();
	m_DebWaterPoolList.Clear();
	m_DebVisiblePlanterList.Clear();
	m_DebLeavingParticleList.Clear();
	m_DebScatterParticleUnitList.Clear();
	m_DebWidgetBoundsList.Clear();
	m_DebActorModelList.Clear();
	m_DebTerrainBoundsList.Clear();

#endif //_DEBUG
}

void Renderer::Finish( void )
{
	MIX_ASSERT( m_pOctree != NULL );

	// デバッグ : 計測開始
	SCENE_DEB( m_DebTimer.Reset() );

	m_pOctree->Finish();

	// デバッグ : 計測終了
	SCENE_DEB( m_pDebRProfGeneral->finElapsedTime = m_DebTimer.GetF32() );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// デバッグ
	////////////////////////////////////////////////////////////////////////////////////////////////////

#ifdef _DEBUG
	m_DebRProfGeneIndex = ( m_DebRProfGeneIndex + 1 ) % 2;
	m_pDebRProfGeneralCur = m_pDebRProfGeneral;
	m_pDebRProfGeneral = &( m_DebRProfGeneral[m_DebRProfGeneIndex] );
	Mix::Memory::Zero( m_pDebRProfGeneral, sizeof( Mix::Scene::DEBUG_PROFILE_RENDERER_GENERAL ) );
#endif //_DEBUG
}

#ifdef _DEBUG

UInt32 Renderer::Debug_GetCameraProfile( UInt32 viewID, UInt32 type, void* pProf, UInt32 size ) const
{
	MIX_ASSERT( viewID < m_ViewList.size() );
	MIX_ASSERT( m_ViewList[viewID].pInternalCamera != NULL );

	const Renderer::VIEW* pView = &( m_ViewList[viewID] );

	const void* pSrc = NULL;
	UInt32 srcSize = 0;

	switch( type )
	{
	case DPT_GENERAL:
		pSrc = &( pView->debProfGeneral );
		srcSize = sizeof( pView->debProfGeneral );
		break;
	case DPT_OCTREE:
		pSrc = &( pView->debProfOctree );
		srcSize = sizeof( pView->debProfOctree );
		break;
	case DPT_LIGHT:
		pSrc = &( pView->debProfLight );
		srcSize = sizeof( pView->debProfLight );
		break;
	case DPT_WATER_POOL:
		pSrc = &( pView->debProfWaterPool );
		srcSize = sizeof( pView->debProfWaterPool );
		break;
	case DPT_WIDGET:
		pSrc = &( pView->debProfWidget );
		srcSize = sizeof( pView->debProfWidget );
		break;
	case DPT_ACTOR_MODEL:
		pSrc = &( pView->debProfActorModel );
		srcSize = sizeof( pView->debProfActorModel );
		break;
	case DPT_TERRAIN_MODEL:
		pSrc = &( pView->debProfTerrainModel );
		srcSize = sizeof( pView->debProfTerrainModel );
		break;
	case DPT_PROJ_SHADOW:
		pSrc = &( pView->debProfProjShadow );
		srcSize = sizeof( pView->debProfProjShadow );
		break;
	case DPT_DRAW_OPACITY:
		pSrc = &( pView->debProfDrawOpacity );
		srcSize = sizeof( pView->debProfDrawOpacity );
		break;
	case DPT_DRAW_NEUTRALITY:
		pSrc = &( pView->debProfDrawNeut );
		srcSize = sizeof( pView->debProfDrawNeut );
		break;
	case DPT_DRAW_REFRACT:
		pSrc = &( pView->debProfDrawRefract );
		srcSize = sizeof( pView->debProfDrawRefract );
		break;
	case DPT_DRAW_TRANSPARENCY:
		pSrc = &( pView->debProfDrawTransp );
		srcSize = sizeof( pView->debProfDrawTransp );
		break;
	case DPT_POST_PROCESS:
		pSrc = &( pView->debProfPostProc );
		srcSize = sizeof( pView->debProfPostProc );
		break;
	}

	if( ( pSrc == NULL ) || ( srcSize == 0 ) || ( size < srcSize ) )
	{
		return False;
	}

	Mix::Memory::Copy( pProf, pSrc, srcSize );

	return srcSize;
}

UInt32 Renderer::Debug_GetCameraImageNum( UInt32 viewID, UInt32 type ) const
{
	MIX_ASSERT( viewID < m_ViewList.size() );
	MIX_ASSERT( m_ViewList[viewID].pInternalCamera != NULL );

	UInt32 ret;

	switch( type )
	{
	case Mix::Scene::DIT_DEPTH:
	case Mix::Scene::DIT_DATA:
	case Mix::Scene::DIT_CHROMATISM:
		ret = 1;
		break;

	case Mix::Scene::DIT_AMBIENT_OCCLUSION:
	case Mix::Scene::DIT_LUMINOSITY:
	case Mix::Scene::DIT_LIGHT_SHAFTS:
	case Mix::Scene::DIT_LENS_FLARE:
	case Mix::Scene::DIT_DOF:
		ret = 2;
		break;

	case Mix::Scene::DIT_SHADOW_MAPPING:
		ret = 3;
		break;

	case Mix::Scene::DIT_BLOOM:
		ret = 1 + m_ViewList[viewID].pInternalCamera->GetBloomOverflowNum();
		break;

	default:
		ret = 0;
	}

	return ret;
}

Boolean Renderer::Debug_GetCameraImage( UInt32 viewID, UInt32 type, UInt32 index, Mix::Graphics::ITexture** ppTexture )
{
	MIX_ASSERT( viewID < m_ViewList.size() );
	MIX_ASSERT( m_ViewList[viewID].pInternalCamera != NULL );

	Renderer::VIEW* pView = &( m_ViewList[viewID] );
	Mix::Graphics::ITexture* pTexture = NULL;

	if( type == Mix::Scene::DIT_DEPTH )
	{
		if( index == 0 ) { pTexture = pView->pDepthTexChain->GetCurrentPtr(); }
	}
	else if( type == Mix::Scene::DIT_DATA )
	{
		if( index == 0 ) { pTexture = pView->pDataTex; }
	}
	else if( type == Mix::Scene::DIT_AMBIENT_OCCLUSION )
	{
		switch( index )
		{
		case 0:
			pTexture = pView->pAOTex;
			break;
		case 1:
			pTexture = pView->pAOTexChain->GetCurrentPtr();
			break;
		}
	}
	else if( type == Mix::Scene::DIT_SHADOW_MAPPING )
	{
		switch( index )
		{
		case 0:
			pTexture = pView->pSdwDepthTex;
			break;
		case 1:
			pTexture = pView->pSdwMapTex;
			break;
		case 2:
			pTexture = pView->pSdwMapTexChain->GetCurrentPtr();
			break;
		}
	}
	else if( type == Mix::Scene::DIT_LUMINOSITY )
	{
		switch( index )
		{
		case 0:
			pTexture = pView->pLumFinalTex;
			break;
		case 1:
			pTexture = pView->pLumAdaptedTexChain->GetCurrentPtr();
			break;
		}
	}
	else if( type == Mix::Scene::DIT_BLOOM )
	{
		if( index == 0 )
		{
			pTexture = pView->pDebBloomBrightPassTex;
		}
		else if(	( pView->BloomTexChainList.size() > 0 ) &&
					( index >= 1 ) &&
					( index <= pView->BloomTexChainList.size() ) )
		{
			pTexture = pView->BloomTexChainList[index - 1]->GetCurrentPtr();
		}
	}
	else if( type == Mix::Scene::DIT_LIGHT_SHAFTS )
	{
		switch( index )
		{
		case 0:
			pTexture = pView->pDebLSBrightPassTex;
			break;
		case 1:
			pTexture = pView->pLSTexChain->GetCurrentPtr();
			break;
		}
	}
	else if( type == Mix::Scene::DIT_LENS_FLARE )
	{
		switch( index )
		{
		case 0:
			pTexture = pView->pDebLFBrightPassTex;
			break;
		case 1:
			pTexture = pView->pLFTexChain->GetCurrentPtr();
			break;
		}
	}
	else if( type == Mix::Scene::DIT_CHROMATISM )
	{
		if( index == 0 ) { pTexture = pView->pCATexChain->GetCurrentPtr(); }
	}
	else if( type == Mix::Scene::DIT_DOF )
	{
		switch( index )
		{
		case 0:
			pTexture = pView->pDofBokehTex0;
			break;
		case 1:
			pTexture = pView->pDofBokehTex1;
			break;
		}
	}

	MIX_ADD_REF( pTexture );
	( *ppTexture ) = pTexture;

	return ( pTexture != NULL );
}

#endif //_DEBUG

////////////////////////////////////////////////////////////////////////////////////////////////////
// Mix::Scene::IRenderer
////////////////////////////////////////////////////////////////////////////////////////////////////

Mix::Scene::IRenderer::TYPE Renderer::GetType( void ) const
{
	return Mix::Scene::IRenderer::FORWARD;
}

const wchar_t* Renderer::GetName( void ) const
{
	return m_Name.GetConstPtr();
}

const Mix::Scene::RENDERER_CONFIG& Renderer::GetConfig( void ) const
{
	return m_Config;
}

Boolean Renderer::SetConfig( const Mix::Scene::RENDERER_CONFIG& config )
{
	MIX_ASSERT( m_ViewList.size() > 0 );

	Renderer::VIEW* pView = &( m_ViewList[0] );
	Renderer::VIEW* pViewEnd = pView + m_ViewList.size();

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// ログ( 開始 )
	////////////////////////////////////////////////////////////////////////////////////////////////////

	MIX_LOG_INFO_SECT_START( L"レンダラーの設定を変更 : Name[%s]", m_Name.GetConstPtr() );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 処理
	////////////////////////////////////////////////////////////////////////////////////////////////////

	// 自身( レンダラー )

	if( UpdateConfig( Renderer::FAILED_CHANGE_CFG, config ) == False )
	{
		MIX_LOG_INFO( L"" );

		if( UpdateConfig( Renderer::FAILED_CHANGE_CFG, m_Config ) == False )
		{
			MIX_LOG_INFO_SECT_END();
			return False;
		}

		MIX_LOG_INFO( L"" );
		MIX_LOG_INFO( L"エラーが発生したため、設定を元にもどしました。" );
		MIX_LOG_INFO( L"" );
	}

	m_Config = config;

	// ビュー( カメラ )

	while( pView != pViewEnd )
	{
		if( pView->pInternalCamera != NULL )
		{
			pView->pInternalCamera->UpdateConfig();
		}

		pView++;
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// ログ( 終了 )
	////////////////////////////////////////////////////////////////////////////////////////////////////

	MIX_LOG_INFO_SECT_END();

	////////////////////////////////////////////////////////////////////////////////////////////////////

	return True;
}

Boolean Renderer::IsDynamicsAvailable( void ) const
{
	return m_bDynamicsAvailable;
}

Boolean Renderer::IsAtmosphereAvailable( void ) const
{
	return m_bAtmosphereAvailable;
}

Boolean Renderer::IsFogAvailable( void ) const
{
	return m_bFogAvailable;
}

Boolean Renderer::IsWidgetAvailable( void ) const
{
	return m_bWidgetAvailable;
}

Boolean Renderer::IsShadowMappingAvailable( void ) const
{
	return m_bShadowMappingAvailable;
}

Boolean Renderer::IsAmbientOcclusionAvailable( void ) const
{
	return m_bAmbientOcclusionAvailable;
}

Boolean Renderer::IsLuminosityAvailable( void ) const
{
	return m_bLuminosityAvailable;
}

Boolean Renderer::IsBloomAvailable( void ) const
{
	return m_bBloomAvailable;
}

Boolean Renderer::IsLightShaftsAvailable( void ) const
{
	return m_bLightShaftsAvailable;
}

Boolean Renderer::IsLensFlareAvailable( void ) const
{
	return m_bLensFlareAvailable;
}

Boolean Renderer::IsChromatismAvailable( void ) const
{
	return m_bChromatismAvailable;
}

Boolean Renderer::IsDofAvailable( void ) const
{
	return m_bDepthOfFieldAvailable;
}

void Renderer::Update( Float32 dt, Float32 baseDt )
{
	////////////////////////////////////////////////////////////////////////////////////////////////////
	// デバッグ : 計測開始
	////////////////////////////////////////////////////////////////////////////////////////////////////

	SCENE_DEB( m_DebTimer.Reset() );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 処理
	////////////////////////////////////////////////////////////////////////////////////////////////////

	Renderer::VIEW* pView = &( m_ViewList[0] );
	Renderer::VIEW* pViewEnd = pView + m_ViewList.size();

	// オブジェクトのドラッグ
	while( pView != pViewEnd )
	{
		if( pView->pObjDragger != NULL )
		{
			if( ( pView->bDragObj == False ) && ( pView->pObjDragger->IsCatch() == True ) )
			{
				pView->pObjDragger->Free();
			}

			pView->bDragObj = False;
		}

		pView++;
	}

	// スカイドーム
	if( m_pSkyDome != NULL )
	{
		m_pSkyDome->Update( dt );
	}

	// ダイナミクスワールド
	if( IsDynamicsAvailable() == True )
	{
		MIX_ASSERT( m_pDynamicsWorld->GetInternalWorldPtr() != NULL );

		m_pDynamicsWorld->GetInternalWorldPtr()->Update( dt, baseDt );

		SCENE_DEB( const Mix::Dynamics::DEBUG_WORLD_PROFILE& debDynWorldProf = m_pDynamicsWorld->GetInternalWorldPtr()->Debug_GetProfile() );
		SCENE_DEB( m_DebRProfDynamics.ssElapsedTime = debDynWorldProf.ssElapsedTime );
		SCENE_DEB( m_DebRProfDynamics.cpElapsedTime = debDynWorldProf.cpElapsedTime );
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// デバッグ : 計測終了
	////////////////////////////////////////////////////////////////////////////////////////////////////

	SCENE_DEB( m_pDebRProfGeneral->updElapsedTime = m_DebTimer.GetF32() );
}

void Renderer::Refresh( void )
{
	MIX_ASSERT( m_pOctree != NULL );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// デバッグ : 計測開始
	////////////////////////////////////////////////////////////////////////////////////////////////////

	SCENE_DEB( m_DebTimer.Reset() );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 処理
	////////////////////////////////////////////////////////////////////////////////////////////////////

	// 八分木
	m_pOctree->Refresh();

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// デバッグ : 計測終了
	////////////////////////////////////////////////////////////////////////////////////////////////////

	// 八分木
	SCENE_DEB( m_DebRProfOctree.nodeCount = m_pOctree->GetNodeNum() );
	SCENE_DEB( m_DebRProfOctree.nodeMax = m_pOctree->GetNodeMax() );
	SCENE_DEB( m_DebRProfOctree.unitSize = m_pOctree->GetUnit() );
	SCENE_DEB( m_DebRProfOctree.illegalLocalLightNum = m_pOctree->Debug_GetIllegalLocalLightNum() );
	SCENE_DEB( m_DebRProfOctree.illegalLeavingParticleNum = m_pOctree->Debug_GetIllegalLeavingParticleNum() );
	SCENE_DEB( m_DebRProfOctree.illegalScatterParticleUnitNum = m_pOctree->Debug_GetIllegalScatterParticleUnitNum() );
	SCENE_DEB( m_DebRProfOctree.illegalActorModelNum = m_pOctree->Debug_GetIllegalActorModelNum() );

	// ジェネラル
	SCENE_DEB( m_pDebRProfGeneral->refElapsedTime = m_DebTimer.GetF32() );
}

const Mix::Geometry::AABB& Renderer::GetOctreeBounds( void ) const
{
	MIX_ASSERT( m_pOctree != NULL );

	return m_pOctree->GetBounds();
}

const Mix::Vector4& Renderer::GetGlobalAmbientColor( void ) const
{
	return m_GlobalAmbientColor;
}

void Renderer::SetGlobalAmbientColor( const Mix::Vector4& color )
{
	m_GlobalAmbientColor = color.ToSaturate();
}

Boolean Renderer::ExistsEnvironmentTexture( void ) const
{
	return ( m_pEnvTex != NULL );
}

Boolean Renderer::GetEnvironmentTexture( Mix::Graphics::ITexture** ppTex )
{
	MIX_ASSERT( ppTex != NULL );

	if( m_pEnvTex == NULL )
	{
		return False;
	}

	MIX_ADD_REF( m_pEnvTex );
	( *ppTex ) = m_pEnvTex;

	return True;
}

void Renderer::SetEnvironmentTexture( Mix::Graphics::ITexture* pTex )
{
	MIX_RELEASE( m_pEnvTex );

	MIX_ADD_REF( pTex );
	m_pEnvTex = pTex;
}

Boolean Renderer::IsFogEnabled( void ) const
{
	return m_bFogEnabled;
}

void Renderer::SetFogEnabled( Boolean state )
{
	m_bFogEnabled = state;
}

const Mix::Scene::IRenderer::FOG_SETTINGS& Renderer::GetFogSettings( void ) const
{
	return m_FogSettings;
}

void Renderer::SetFogSettings( const Mix::Scene::IRenderer::FOG_SETTINGS& param )
{
	Float32 diff;

	m_FogSettings.start = max( 0.0f, param.start );
	m_FogSettings.end = max( m_FogSettings.start, param.end );
	m_FogSettings.color = param.color.ToSaturate();

	diff = m_FogSettings.end - m_FogSettings.start;

	m_InternalFogSettings.p0 = MIX_FLOAT_DIV( m_FogSettings.end, diff );
	m_InternalFogSettings.p1 = MIX_FLOAT_DIV( -1.0f, diff );
}

Mix::Scene::IRenderer::WIDGET_LIGHTING_MODE Renderer::GetWidgetLightingMode( void ) const
{
	return m_WidgetLightingMode;
}

void Renderer::SetWidgetLightingMode( Mix::Scene::IRenderer::WIDGET_LIGHTING_MODE mode )
{
	m_WidgetLightingMode = mode;
}

UInt32 Renderer::GetCameraCount( void ) const
{
	return MIX_UIT_TO_UI32( m_CameraList.size() );
}

void Renderer::GetCameraByIndex( UInt32 index, Mix::Scene::ICamera** ppCamera )
{
	MIX_ASSERT( m_CameraList.size() > index );
	MIX_ASSERT( ppCamera != NULL );

	Renderer::CAMERA* pCamera = &( m_CameraList[index] );

	MIX_ADD_REF( pCamera->pInterface );
	( *ppCamera ) = pCamera->pInterface;
}

Boolean Renderer::ContainsCamera( Mix::Scene::ICamera* pCamera ) const
{
	return Mix::STL::Vector_Contains( m_CameraList, Renderer::CAMERA( pCamera, NULL ) );
}

Boolean Renderer::AddCamera( Mix::Scene::ICamera* pCamera )
{
	if( ( pCamera == NULL ) ||
		( pCamera->IsRendering() == True ) )
	{
		return False;
	}

	if( m_pOctree->GetViewCount() >= Mix::Scene::Common::OCTREE_VIEW_MAX )
	{
		MIX_LOG_ERROR( L"%s : 追加できるカメラは%d個までです : Name[%s]",
			Renderer::FAILED_ADD_CAMERA,
			Mix::Scene::Common::OCTREE_VIEW_MAX,
			m_Name.GetConstPtr() );

		return False;
	}

	Mix::Scene::Common::Camera* pInternalCamera = dynamic_cast<Mix::Scene::Common::Camera*>( pCamera );
	MIX_ASSERT( pInternalCamera != NULL );

	if( pInternalCamera->Attach( this, m_pOctree->AddView() ) == False )
	{
		pInternalCamera->Detach();
		return False;
	}

	MIX_ADD_REF( pCamera );
	m_CameraList.push_back( Renderer::CAMERA( pCamera, pInternalCamera ) );

	return True;
}

Boolean Renderer::RemoveCamera( Mix::Scene::ICamera* pCamera )
{
	Renderer::CameraList::iterator it = std::find( m_CameraList.begin(), m_CameraList.end(), Renderer::CAMERA( pCamera, NULL ) );
	if( it == m_CameraList.end() )
	{
		return False;
	}

	MIX_ASSERT( ( *it ).pInternalInterface != NULL );

	( *it ).pInternalInterface->Detach();
	MIX_RELEASE( ( *it ).pInterface );

	Mix::STL::Vector_FirstErase( m_CameraList, it );

	return True;
}

void Renderer::RemoveCameraByIndex( UInt32 index )
{
	MIX_ASSERT( m_CameraList.size() > index );

	Renderer::CAMERA* pCamera = &( m_CameraList[index] );

	MIX_ASSERT( pCamera->pInternalInterface != NULL );

	Mix::STL::Vector_FirstErase( m_CameraList, index );
	pCamera->pInternalInterface->Detach();
	MIX_RELEASE( pCamera->pInterface );
}

void Renderer::RemoveAllCamera( void )
{
	if( m_CameraList.size() > 0 )
	{
		Renderer::CameraList::iterator it_begin = m_CameraList.begin();
		Renderer::CameraList::iterator it_end = m_CameraList.end();
		Renderer::CameraList::iterator it;

		for( it = it_begin; it != it_end; ++it )
		{
			Renderer::CAMERA* pCamera = &( *it );

			pCamera->pInternalInterface->Detach();
			MIX_RELEASE( pCamera->pInterface );
		}

		m_CameraList.clear();
	}
}

Boolean Renderer::ExistsHemisphereLight( void ) const
{
	return ( m_pHemisphereLight != NULL );
}

Boolean Renderer::GetHemisphereLight( Mix::Scene::IHemisphereLight** ppHemisphereLight )
{
	MIX_ASSERT( ppHemisphereLight != NULL );

	if( m_pHemisphereLight != NULL )
	{
		MIX_ADD_REF( m_pHemisphereLight );
		( *ppHemisphereLight ) = m_pHemisphereLight;
	}
	else
	{
		return False;
	}

	return True;
}

Boolean Renderer::SetHemisphereLight( Mix::Scene::IHemisphereLight* pHemisphereLight )
{
	if( ( pHemisphereLight != NULL ) &&
		( pHemisphereLight->IsRendering() == True ) )
	{
		return False;
	}

	if( m_pHemisphereLight != NULL )
	{
		m_pHemisphereLight->Detach();
	}

	MIX_RELEASE( m_pHemisphereLight );

	if( pHemisphereLight != NULL )
	{
		MIX_ADD_REF( pHemisphereLight );

		m_pHemisphereLight = static_cast<Mix::Scene::Common::HemisphereLight*>( pHemisphereLight );
		m_pHemisphereLight->Attach();
	}

	return True;
}

Boolean Renderer::ExistsDirectionalLight( void ) const
{
	return ( m_pDirectionalLight != NULL );
}

Boolean Renderer::GetDirectionalLight( Mix::Scene::IDirectionalLight** ppDirectionalLight )
{
	MIX_ASSERT( ppDirectionalLight != NULL );

	if( m_pDirectionalLight != NULL )
	{
		MIX_ADD_REF( m_pDirectionalLight );
		( *ppDirectionalLight ) = m_pDirectionalLight;
	}
	else
	{
		return False;
	}

	return True;
}

Boolean Renderer::SetDirectionalLight( Mix::Scene::IDirectionalLight* pDirectionalLight )
{
	if( ( pDirectionalLight != NULL ) &&
		( pDirectionalLight->IsRendering() == True ) )
	{
		return False;
	}

	if( m_pDirectionalLight != NULL )
	{
		m_pDirectionalLight->Detach();
	}

	MIX_RELEASE( m_pDirectionalLight );

	if( pDirectionalLight != NULL )
	{
		MIX_ADD_REF( pDirectionalLight );
		m_pDirectionalLight = static_cast<Mix::Scene::Common::DirectionalLight*>( pDirectionalLight );
		m_pDirectionalLight->Attach();
	}

	return True;
}

UInt32 Renderer::GetSpotLightCount( void ) const
{
	return MIX_UIT_TO_UI32( m_SpotLightList.size() );
}

void Renderer::GetSpotLightByIndex( UInt32 index, Mix::Scene::ISpotLight** ppSpotLight )
{
	MIX_ASSERT( m_SpotLightList.size() > index );
	MIX_ASSERT( ppSpotLight != NULL );

	Mix::Scene::ISpotLight* pSpotLight = m_SpotLightList[index];

	MIX_ADD_REF( pSpotLight );
	( *ppSpotLight ) = pSpotLight;
}

Boolean Renderer::ContainsSpotLight( Mix::Scene::ISpotLight* pSpotLight ) const
{
	return Mix::STL::Vector_Contains( m_SpotLightList, static_cast<Mix::Scene::Common::SpotLight*>( pSpotLight ) );
}

Boolean Renderer::AddSpotLight( Mix::Scene::ISpotLight* pSpotLight )
{
	if( ( pSpotLight == NULL ) ||
		( pSpotLight->IsRendering() == True ) )
	{
		return False;
	}

	MIX_ASSERT( m_pOctree != NULL );

	Mix::Scene::Common::SpotLight* pObject = static_cast<Mix::Scene::Common::SpotLight*>( pSpotLight );
	if( pObject->IsRendering() == True )
	{
		return False;
	}

	MIX_ADD_REF( pObject );
	pObject->Attach( m_pOctree->AddLocalLight( pObject ) );
	m_SpotLightList.push_back( pObject );

	return True;
}

Boolean Renderer::RemoveSpotLight( Mix::Scene::ISpotLight* pSpotLight )
{
	MIX_ASSERT( pSpotLight != NULL );

	Mix::Scene::Common::SpotLight* pObject = static_cast<Mix::Scene::Common::SpotLight*>( pSpotLight );

	if( Mix::STL::Vector_FirstErase( m_SpotLightList, pObject ) == True )
	{
		pObject->Detach();
		MIX_RELEASE( pObject );
	}
	else
	{
		return False;
	}

	return True;
}

void Renderer::RemoveSpotLightByIndex( UInt32 index )
{
	MIX_ASSERT( m_SpotLightList.size() > index );

	Mix::Scene::Common::SpotLight* pObject = m_SpotLightList[index];

	Mix::STL::Vector_FirstErase( m_SpotLightList, index );
	pObject->Detach();
	MIX_RELEASE( pObject );
}

void Renderer::RemoveAllSpotLight( void )
{
	if( m_SpotLightList.size() > 0 )
	{
		SpotLightList::iterator it_begin = m_SpotLightList.begin();
		SpotLightList::iterator it_end = m_SpotLightList.end();
		SpotLightList::iterator it;

		for( it = it_begin; it != it_end; ++it )
		{
			Mix::Scene::Common::SpotLight* pObject = ( *it );

			pObject->Detach();
			MIX_RELEASE( pObject );
		}

		m_SpotLightList.clear();
	}
}

UInt32 Renderer::GetPointLightCount( void ) const
{
	return MIX_UIT_TO_UI32( m_PointLightList.size() );
}

void Renderer::GetPointLightByIndex( UInt32 index, Mix::Scene::IPointLight** ppPointLight )
{
	MIX_ASSERT( m_PointLightList.size() > index );
	MIX_ASSERT( ppPointLight != NULL );

	Mix::Scene::Common::PointLight* pObject = m_PointLightList[index];

	MIX_ADD_REF( pObject );
	( *ppPointLight ) = pObject;
}

Boolean Renderer::ContainsPointLight( Mix::Scene::IPointLight* pPointLight ) const
{
	return Mix::STL::Vector_Contains( m_PointLightList, static_cast<Mix::Scene::Common::PointLight*>( pPointLight ) );
}

Boolean Renderer::AddPointLight( Mix::Scene::IPointLight* pPointLight )
{
	if( ( pPointLight == NULL ) ||
		( pPointLight->IsRendering() == True ) )
	{
		return False;
	}

	Mix::Scene::Common::PointLight* pObject = static_cast<Mix::Scene::Common::PointLight*>( pPointLight );

	MIX_ADD_REF( pObject );
	pObject->Attach( m_pOctree->AddLocalLight( pObject ) );
	m_PointLightList.push_back( pObject );

	return True;
}

Boolean Renderer::RemovePointLight( Mix::Scene::IPointLight* pPointLight )
{
	MIX_ASSERT( pPointLight != NULL );

	Mix::Scene::Common::PointLight* pObject = static_cast<Mix::Scene::Common::PointLight*>( pPointLight );

	if( Mix::STL::Vector_FirstErase( m_PointLightList, pObject ) == True )
	{
		pObject->Detach();
		MIX_RELEASE( pObject );
	}
	else
	{
		return False;
	}

	return True;
}

void Renderer::RemovePointLightByIndex( UInt32 index )
{
	MIX_ASSERT( m_PointLightList.size() > index );

	Mix::Scene::Common::PointLight* pObject = m_PointLightList[index];

	Mix::STL::Vector_FirstErase( m_PointLightList, index );
	pObject->Detach();
	MIX_RELEASE( pObject );
}

void Renderer::RemoveAllPointLight( void )
{
	if( m_PointLightList.size() > 0 )
	{
		PointLightList::iterator it_begin = m_PointLightList.begin();
		PointLightList::iterator it_end = m_PointLightList.end();
		PointLightList::iterator it;

		for( it = it_begin; it != it_end; ++it )
		{
			Mix::Scene::Common::PointLight* pObject = ( *it );

			pObject->Detach();
			MIX_RELEASE( pObject );
		}

		m_PointLightList.clear();
	}
}

Boolean Renderer::ExistsSkyDome( void ) const
{
	return ( m_pSkyDome != NULL );
}

Boolean Renderer::GetSkyDome( Mix::Scene::ISkyDome** ppSkyDome )
{
	MIX_ASSERT( ppSkyDome != NULL );

	if( m_pSkyDome == NULL )
	{
		return False;
	}

	MIX_ADD_REF( m_pSkyDome );
	( *ppSkyDome ) = m_pSkyDome;

	return True;
}

Boolean Renderer::SetSkyDome( Mix::Scene::ISkyDome* pSkyDome )
{
	if( ( pSkyDome == NULL ) ||
		( pSkyDome->IsRendering() == True ) )
	{
		return False;
	}

	if( m_pSkyDome != NULL )
	{
		m_pSkyDome->Detach();
	}

	MIX_RELEASE( m_pSkyDome );

	if( pSkyDome != NULL )
	{
		MIX_ADD_REF( pSkyDome );

		m_pSkyDome = static_cast<Mix::Scene::Common::SkyDome*>( pSkyDome );
		m_pSkyDome->Attach( m_pAtmosphereScatter );
	}

	return True;
}

Boolean Renderer::ExistsLightShaftsCaster( void ) const
{
	return ( m_pLightShaftsCaster != NULL );
}

Boolean Renderer::GetLightShaftsCaster( Mix::Scene::ILightShaftsCaster** ppLightShaftsCaster )
{
	MIX_ASSERT( ppLightShaftsCaster != NULL );

	if( m_pLightShaftsCaster == NULL )
	{
		return False;
	}

	MIX_ADD_REF( m_pLightShaftsCaster );
	( *ppLightShaftsCaster ) = m_pLightShaftsCaster;

	return True;
}

Boolean Renderer::SetLightShaftsCaster( Mix::Scene::ILightShaftsCaster* pLightShaftsCaster )
{
	if( ( pLightShaftsCaster != NULL ) &&
		( pLightShaftsCaster->IsRendering() == True ) )
	{
		return False;
	}

	if( m_pLightShaftsCaster != NULL )
	{
		m_pLightShaftsCaster->Detach();
	}

	MIX_RELEASE( m_pLightShaftsCaster );

	if( pLightShaftsCaster != NULL )
	{
		MIX_ADD_REF( pLightShaftsCaster );
		m_pLightShaftsCaster = static_cast<Mix::Scene::Common::LightShaftsCaster*>( pLightShaftsCaster );
		m_pLightShaftsCaster->Attach();
	}

	return True;
}

UInt32 Renderer::GetWaterPoolCount( void ) const
{
	return MIX_UIT_TO_UI32( m_WaterPoolList.size() );
}

void Renderer::GetWaterPoolByIndex( UInt32 index, Mix::Scene::IWaterPool** ppWaterPool )
{
	MIX_ASSERT( m_WaterPoolList.size() > index );
	MIX_ASSERT( ppWaterPool != NULL );

	Mix::Scene::Common::WaterPool* pObject = m_WaterPoolList[index];

	MIX_ADD_REF( pObject );
	( *ppWaterPool ) = pObject;
}

Boolean Renderer::ContainsWaterPool( Mix::Scene::IWaterPool* pWaterPool ) const
{
	return Mix::STL::Vector_Contains( m_WaterPoolList, static_cast<Mix::Scene::Common::WaterPool*>( pWaterPool ) );
}

Boolean Renderer::AddWaterPool( Mix::Scene::IWaterPool* pWaterPool )
{
	if( ( pWaterPool == NULL ) ||
		( pWaterPool->IsRendering() == True ) )
	{
		return False;
	}

	MIX_ASSERT( m_pOctree != NULL );

	Mix::Scene::Common::WaterPool* pObject = static_cast<Mix::Scene::Common::WaterPool*>( pWaterPool );

	MIX_ADD_REF( pObject );
	pObject->Attach( m_pOctree->AddWaterPool( pObject ) );
	m_WaterPoolList.push_back( pObject );

	return True;
}

Boolean Renderer::RemoveWaterPool( Mix::Scene::IWaterPool* pWaterPool )
{
	MIX_ASSERT( pWaterPool != NULL );

	Mix::Scene::Common::WaterPool* pObject = static_cast<Mix::Scene::Common::WaterPool*>( pWaterPool );

	if( Mix::STL::Vector_FirstErase( m_WaterPoolList, pObject ) == True )
	{
		pObject->Detach();
		MIX_RELEASE( pObject );
	}
	else
	{
		return False;
	}

	return True;
}

void Renderer::RemoveWaterPoolByIndex( UInt32 index )
{
	MIX_ASSERT( m_WaterPoolList.size() > index );

	Mix::Scene::Common::WaterPool* pObject = m_WaterPoolList[index];

	Mix::STL::Vector_FirstErase( m_WaterPoolList, index );
	pObject->Detach();
	MIX_RELEASE( pObject );
}

void Renderer::RemoveAllWaterPool( void )
{
	if( m_WaterPoolList.size() > 0 )
	{
		WaterPoolList::iterator it_begin = m_WaterPoolList.begin();
		WaterPoolList::iterator it_end = m_WaterPoolList.end();
		WaterPoolList::iterator it;

		for( it = it_begin; it != it_end; ++it )
		{
			Mix::Scene::Common::WaterPool* pObject = ( *it );

			pObject->Detach();
			MIX_RELEASE( pObject );
		}

		m_WaterPoolList.clear();
	}
}

UInt32 Renderer::GetLeavingParticleCount( void ) const
{
	return MIX_UIT_TO_UI32( m_LeavingParticleList.size() );
}

void Renderer::GetLeavingParticleByIndex( UInt32 index, Mix::Scene::IParticle** ppParticle )
{
	MIX_ASSERT( m_LeavingParticleList.size() > index );
	MIX_ASSERT( ppParticle != NULL );

	Mix::Scene::Common::LeavingParticle* pObject = m_LeavingParticleList[index];

	MIX_ADD_REF( pObject );
	( *ppParticle ) = pObject;
}

Boolean Renderer::ContainsLeavingParticle( Mix::Scene::IParticle* pParticle ) const
{
	MIX_ASSERT( pParticle != NULL );

	return Mix::STL::Vector_Contains( m_LeavingParticleList, static_cast<Mix::Scene::Common::LeavingParticle*>( pParticle ) );
}

Boolean Renderer::AddLeavingParticle( Mix::Scene::ILeavingParticle* pParticle )
{
	if( pParticle == NULL )
	{
		return False;
	}

	MIX_ASSERT( m_pOctree != NULL );

	Mix::Scene::Common::LeavingParticle* pObject = static_cast<Mix::Scene::Common::LeavingParticle*>( pParticle );

	if( pObject->IsRendering() == True )
	{
		return False;
	}

	if( Mix::STL::Vector_Contains( m_LeavingParticleList, pObject ) == False )
	{
		MIX_ADD_REF( pObject );
		m_LeavingParticleList.push_back( pObject );

		pObject->Attach( m_pOctree->AddLeavingParticle( pObject ) );
	}
	else
	{
		return False;
	}

	return True;
}

Boolean Renderer::RemoveLeavingParticle( Mix::Scene::IParticle* pParticle )
{
	MIX_ASSERT( pParticle != NULL );

	Mix::Scene::Common::LeavingParticle* pObject = static_cast<Mix::Scene::Common::LeavingParticle*>( pParticle );

	if( Mix::STL::Vector_FirstErase( m_LeavingParticleList, pObject ) == True )
	{
		pObject->Detach();
		MIX_RELEASE( pObject );
	}
	else
	{
		return False;
	}

	return True;
}

void Renderer::RemoveLeavingParticleByIndex( UInt32 index )
{
	MIX_ASSERT( m_LeavingParticleList.size() > index );

	Mix::Scene::Common::LeavingParticle* pObject = m_LeavingParticleList[index];

	Mix::STL::Vector_FirstErase( m_LeavingParticleList, index );
	pObject->Detach();
	MIX_RELEASE( pObject );
}

void Renderer::RemoveAllLeavingParticle( void )
{
	if( m_LeavingParticleList.size() > 0 )
	{
		Renderer::LeavingParticleList::iterator it_begin = m_LeavingParticleList.begin();
		Renderer::LeavingParticleList::iterator it_end = m_LeavingParticleList.end();
		Renderer::LeavingParticleList::iterator it;

		for( it = it_begin; it != it_end; ++it )
		{
			Mix::Scene::Common::LeavingParticle* pObject = ( *it );
		
			pObject->Detach();
			MIX_RELEASE( pObject );
		}

		m_LeavingParticleList.clear();
	}
}

UInt32 Renderer::GetScatterParticleCount( void ) const
{
	return MIX_UIT_TO_UI32( m_ScatterParticleList.size() );
}

void Renderer::GetScatterParticleByIndex( UInt32 index, Mix::Scene::IParticle** ppParticle )
{
	MIX_ASSERT( m_ScatterParticleList.size() > index );
	MIX_ASSERT( ppParticle != NULL );

	Mix::Scene::Common::ScatterParticle* pObject = m_ScatterParticleList[index];

	MIX_ADD_REF( pObject );
	( *ppParticle ) = pObject;
}

Boolean Renderer::ContainsScatterParticle( Mix::Scene::IParticle* pParticle ) const
{
	MIX_ASSERT( pParticle != NULL );

	return Mix::STL::Vector_Contains( m_ScatterParticleList, static_cast<Mix::Scene::Common::ScatterParticle*>( pParticle ) );
}

Boolean Renderer::AddScatterParticle( Mix::Scene::IScatterParticle* pParticle )
{
	if( pParticle == NULL )
	{
		return False;
	}

	MIX_ASSERT( m_pOctree != NULL );

	Mix::Scene::Common::ScatterParticle* pObject = static_cast<Mix::Scene::Common::ScatterParticle*>( pParticle );

	if( pObject->IsRendering() == True )
	{
		return False;
	}

	if( Mix::STL::Vector_Contains( m_ScatterParticleList, pObject ) == False )
	{
		MIX_ADD_REF( pObject );
		pObject->Attach( m_pOctree );
		m_ScatterParticleList.push_back( pObject );
	}
	else
	{
		return False;
	}

	return True;
}

Boolean Renderer::RemoveScatterParticle( Mix::Scene::IParticle* pParticle )
{
	MIX_ASSERT( pParticle != NULL );

	Mix::Scene::Common::ScatterParticle* pObject = static_cast<Mix::Scene::Common::ScatterParticle*>( pParticle );

	if( Mix::STL::Vector_FirstErase( m_ScatterParticleList, pObject ) == True )
	{
		pObject->Detach();
		MIX_RELEASE( pObject );
	}
	else
	{
		return False;
	}

	return True;
}

void Renderer::RemoveScatterParticleByIndex( UInt32 index )
{
	MIX_ASSERT( m_ScatterParticleList.size() > index );

	Mix::Scene::Common::ScatterParticle* pObject = m_ScatterParticleList[index];

	Mix::STL::Vector_FirstErase( m_ScatterParticleList, index );
	pObject->Detach();
	MIX_RELEASE( pObject );
}

void Renderer::RemoveAllScatterParticle( void )
{
	if( m_LeavingParticleList.size() > 0 )
	{
		Renderer::ScatterParticleList::iterator it_begin = m_ScatterParticleList.begin();
		Renderer::ScatterParticleList::iterator it_end = m_ScatterParticleList.end();
		Renderer::ScatterParticleList::iterator it;

		for( it = it_begin; it != it_end; ++it )
		{
			Mix::Scene::Common::ScatterParticle* pObject = ( *it );
		
			pObject->Detach();
			MIX_RELEASE( pObject );
		}

		m_ScatterParticleList.clear();
	}
}

UInt32 Renderer::GetActorModelCount( void ) const
{
	return MIX_UIT_TO_UI32( m_ActorModelList.size() );
}

void Renderer::GetActorModelByIndex( UInt32 index, Mix::Scene::IActorModel** ppActorModel )
{
	MIX_ASSERT( m_ActorModelList.size() > index );
	MIX_ASSERT( ppActorModel != NULL );

	Mix::Scene::Common::ActorModel* pObject = m_ActorModelList[index];

	MIX_ADD_REF( pObject );
	( *ppActorModel ) = pObject;
}

Boolean Renderer::ContainsActorModel( Mix::Scene::IActorModel* pActorModel ) const
{
	MIX_ASSERT( pActorModel != NULL );

	return Mix::STL::Vector_Contains( m_ActorModelList, static_cast<Mix::Scene::Common::ActorModel*>( pActorModel ) );
}

Boolean Renderer::AddActorModel( Mix::Scene::IActorModel* pActorModel )
{
	MIX_ASSERT( pActorModel != NULL );
	MIX_ASSERT( m_pOctree != NULL );

	Mix::Scene::Common::ActorModel* pObject = static_cast<Mix::Scene::Common::ActorModel*>( pActorModel );

	if( Mix::STL::Vector_Contains( m_ActorModelList, pObject ) == False )
	{
		MIX_ADD_REF( pObject );
		m_ActorModelList.push_back( pObject );

		pObject->AttachUpdateMaterials();

		if( IsDynamicsAvailable() == True )
		{
			MIX_ASSERT( m_pDynamicsWorld->GetInternalWorldPtr() != NULL );
			MIX_ASSERT( m_pDynamicsWorld->GetInternalObjectListenerPtr() != NULL );
			pObject->AttachDynamics( m_pDynamicsWorld->GetInternalWorldPtr(), m_pDynamicsWorld->GetInternalObjectListenerPtr() );
		}

		pObject->Attach( m_pOctree->AddActorModel( pObject ) );
	}
	else
	{
		return False;
	}

	return True;
}

Boolean Renderer::RemoveActorModel( Mix::Scene::IActorModel* pActorModel )
{
	MIX_ASSERT( pActorModel != NULL );

	Mix::Scene::Common::ActorModel* pObject = static_cast<Mix::Scene::Common::ActorModel*>( pActorModel );

	if( Mix::STL::Vector_FirstErase( m_ActorModelList, pObject ) == True )
	{
		pObject->Detach();

		if( IsDynamicsAvailable() == True )
		{
			MIX_ASSERT( m_pDynamicsWorld->GetInternalWorldPtr() != NULL );
			pObject->DetachDynamics( m_pDynamicsWorld->GetInternalWorldPtr() );
		}

		pObject->DetachUpdateMaterials();

		MIX_RELEASE( pObject );
	}
	else
	{
		return False;
	}

	return True;
}

void Renderer::RemoveActorModelByIndex( UInt32 index )
{
	MIX_ASSERT( m_ActorModelList.size() > index );

	Mix::Scene::Common::ActorModel* pObject = m_ActorModelList[index];

	Mix::STL::Vector_FirstErase( m_ActorModelList, index );

	pObject->Detach();

	if( IsDynamicsAvailable() == True )
	{
		MIX_ASSERT( m_pDynamicsWorld->GetInternalWorldPtr() != NULL );
		pObject->DetachDynamics( m_pDynamicsWorld->GetInternalWorldPtr() );
	}

	pObject->DetachUpdateMaterials();

	MIX_RELEASE( pObject );
}

void Renderer::RemoveAllActorModel( void )
{
	if( m_ActorModelList.size() > 0 )
	{
		Renderer::ActorModelList::iterator it_begin = m_ActorModelList.begin();
		Renderer::ActorModelList::iterator it_end = m_ActorModelList.end();
		Renderer::ActorModelList::iterator it;

		if( IsDynamicsAvailable() == True )
		{
			Mix::Dynamics::IWorld* pInternalWorld = m_pDynamicsWorld->GetInternalWorldPtr();

			MIX_ASSERT( pInternalWorld != NULL );

			for( it = it_begin; it != it_end; ++it )
			{
				Mix::Scene::Common::ActorModel* pObject = ( *it );

				pObject->Detach();
				pObject->DetachDynamics( pInternalWorld );
				pObject->DetachUpdateMaterials();

				MIX_RELEASE( pObject );
			}
		}
		else
		{
			for( it = it_begin; it != it_end; ++it )
			{
				Mix::Scene::Common::ActorModel* pObject = ( *it );

				pObject->Detach();
				pObject->DetachUpdateMaterials();

				MIX_RELEASE( pObject );
			}
		}

		m_ActorModelList.clear();
	}
}

UInt32 Renderer::GetTerrainModelCount( void ) const
{
	return MIX_UIT_TO_UI32( m_TerrainModelList.size() );
}

void Renderer::GetTerrainModelByIndex( UInt32 index, Mix::Scene::ITerrainModel** ppTerrainModel )
{
	MIX_ASSERT( m_TerrainModelList.size() > index );
	MIX_ASSERT( ppTerrainModel != NULL );

	Mix::Scene::Common::TerrainModel* pObject = m_TerrainModelList[index];

	MIX_ADD_REF( pObject );
	( *ppTerrainModel ) = pObject;
}

Boolean Renderer::ContainsTerrainModel( Mix::Scene::ITerrainModel* pTerrainModel )
{
	MIX_ASSERT( pTerrainModel != NULL );

	return Mix::STL::Vector_Contains( m_TerrainModelList, static_cast<Mix::Scene::Common::TerrainModel*>( pTerrainModel ) );
}

Boolean Renderer::AddTerrainModel( Mix::Scene::ITerrainModel* pTerrainModel )
{
	MIX_ASSERT( pTerrainModel != NULL );

	Mix::Scene::Common::TerrainModel* pObject = static_cast<Mix::Scene::Common::TerrainModel*>( pTerrainModel );

	if( Mix::STL::Vector_Contains( m_TerrainModelList, pObject ) == False )
	{
		MIX_ADD_REF( pObject );

		pObject->Attach();
		pObject->AttachUpdateMaterials();

		if( IsDynamicsAvailable() == True )
		{
			MIX_ASSERT( m_pDynamicsWorld->GetInternalWorldPtr() != NULL );
			MIX_ASSERT( m_pDynamicsWorld->GetInternalObjectListenerPtr() != NULL );
			pObject->AttachDynamics( m_pDynamicsWorld->GetInternalWorldPtr(), m_pDynamicsWorld->GetInternalObjectListenerPtr() );
		}

		m_TerrainModelList.push_back( pObject );
	}
	else
	{
		return False;
	}

	return True;
}

Boolean Renderer::RemoveTerrainModel( Mix::Scene::ITerrainModel* pTerrainModel )
{
	MIX_ASSERT( pTerrainModel != NULL );

	Mix::Scene::Common::TerrainModel* pObject = static_cast<Mix::Scene::Common::TerrainModel*>( pTerrainModel );

	if( Mix::STL::Vector_FirstErase( m_TerrainModelList, pObject ) == True )
	{
		if( IsDynamicsAvailable() == True )
		{
			MIX_ASSERT( m_pDynamicsWorld->GetInternalWorldPtr() != NULL );
			pObject->DetachDynamics( m_pDynamicsWorld->GetInternalWorldPtr() );
		}

		pObject->DetachUpdateMaterials();
		pObject->Detach();

		MIX_RELEASE( pObject );
	}
	else
	{
		return False;
	}

	return True;
}

void Renderer::RemoveTerrainModelByIndex( UInt32 index )
{
	MIX_ASSERT( m_TerrainModelList.size() > index );

	Mix::Scene::Common::TerrainModel* pObject = m_TerrainModelList[index];

	Mix::STL::Vector_FirstErase( m_TerrainModelList, index );

	if( IsDynamicsAvailable() == True )
	{
		MIX_ASSERT( m_pDynamicsWorld->GetInternalWorldPtr() != NULL );
		pObject->DetachDynamics( m_pDynamicsWorld->GetInternalWorldPtr() );
	}

	pObject->DetachUpdateMaterials();
	pObject->Detach();

	MIX_RELEASE( pObject );
}

void Renderer::RemoveAllTerrainModel( void )
{
	if( m_TerrainModelList.size() > 0 )
	{
		Renderer::TerrainModelList::iterator it_begin = m_TerrainModelList.begin();
		Renderer::TerrainModelList::iterator it_end = m_TerrainModelList.end();
		Renderer::TerrainModelList::iterator it;

		if( IsDynamicsAvailable() == True )
		{
			Mix::Dynamics::IWorld* pInternalWorld = m_pDynamicsWorld->GetInternalWorldPtr();

			MIX_ASSERT( pInternalWorld != NULL );

			for( it = it_begin; it != it_end; ++it )
			{
				Mix::Scene::Common::TerrainModel* pObject = ( *it );

				pObject->DetachDynamics( pInternalWorld );
				pObject->DetachUpdateMaterials();
				pObject->Detach();

				MIX_RELEASE( pObject );
			}
		}
		else
		{
			for( it = it_begin; it != it_end; ++it )
			{
				Mix::Scene::Common::TerrainModel* pObject = ( *it );

				pObject->DetachUpdateMaterials();
				pObject->Detach();

				MIX_RELEASE( pObject );
			}
		}

		m_TerrainModelList.clear();
	}
}

UInt32 Renderer::GetPlanterCount( void ) const
{
	return MIX_UIT_TO_UI32( m_PlanterList.size() );
}

void Renderer::GetPlanterByIndex( UInt32 index, Mix::Scene::IPlanter** ppPlanter )
{
	MIX_ASSERT( m_PlanterList.size() > index );
	MIX_ASSERT( ppPlanter != NULL );

	Mix::Scene::Common::Planter* pObject = m_PlanterList[index];

	MIX_ADD_REF( pObject );
	( *ppPlanter ) = pObject;
}

Boolean Renderer::ContainsPlanter( Mix::Scene::IPlanter* pPlanter ) const
{
	return Mix::STL::Vector_Contains( m_PlanterList, static_cast<Mix::Scene::Common::Planter*>( pPlanter ) );
}

Boolean Renderer::AddPlanter( Mix::Scene::IPlanter* pPlanter )
{
	if( ( pPlanter == NULL ) ||
		( pPlanter->IsRendering() == True ) )
	{
		return False;
	}

	Mix::Scene::Common::Planter* pObject = static_cast<Mix::Scene::Common::Planter*>( pPlanter );

	pObject->Attach( m_pOctree->AddPlanter( pObject ) );

	MIX_ADD_REF( pObject );
	m_PlanterList.push_back( pObject );

	return True;
}

Boolean Renderer::RemovePlanter( Mix::Scene::IPlanter* pPlanter )
{
	if( ( pPlanter == NULL ) ||
		( pPlanter->IsRendering() == False ) )
	{
		return False;
	}

	Mix::Scene::Common::Planter* pObject = static_cast<Mix::Scene::Common::Planter*>( pPlanter );

	if( Mix::STL::Vector_FirstErase( m_PlanterList, pObject ) == True )
	{
		pObject->Detach();
		MIX_RELEASE( pObject );
	}
	else
	{
		return False;
	}

	return True;
}

void Renderer::RemovePlanterByIndex( UInt32 index )
{
	MIX_ASSERT( m_PlanterList.size() > index );

	Mix::Scene::Common::Planter* pObject = m_PlanterList[index];

	Mix::STL::Vector_FirstErase( m_PlanterList, index );
	pObject->Detach();
	MIX_RELEASE( pObject );
}

void Renderer::RemoveAllPlanter( void )
{
	if( m_PlanterList.size() > 0 )
	{
		PlanterList::iterator it_begin = m_PlanterList.begin();
		PlanterList::iterator it_end = m_PlanterList.end();
		PlanterList::iterator it;

		for( it = it_begin; it != it_end; ++it )
		{
			Mix::Scene::Common::Planter* pObject = ( *it );
			pObject->Detach();
			MIX_RELEASE( pObject );
		}

		m_PlanterList.clear();
	}
}

Boolean Renderer::ExistsFloor( void ) const
{
	return ( m_pFloor != NULL );
}

Boolean Renderer::GetFloor(Mix::Scene::IFloor** ppFloor )
{
	MIX_ASSERT( ppFloor != NULL );

	MIX_ADD_REF( m_pFloor );
	( *ppFloor ) = m_pFloor;

	return True;
}

Boolean Renderer::SetFloor( Mix::Scene::IFloor* pFloor )
{
	if( ( pFloor == NULL ) ||
		( pFloor->IsRendering() == True ) )
	{
		return False;
	}

	if( m_pFloor != NULL )
	{
		if( IsDynamicsAvailable() == True )
		{
			m_pFloor->DetachDynamics( m_pDynamicsWorld->GetInternalWorldPtr() );
		}

		m_pFloor->Detach();
	}

	MIX_RELEASE( m_pFloor );

	if( pFloor != NULL )
	{
		MIX_ADD_REF( pFloor );
		m_pFloor = static_cast<Mix::Scene::Common::Floor*>( pFloor );

		if( IsDynamicsAvailable() == True )
		{
			m_pFloor->AttachDynamics( m_pDynamicsWorld->GetInternalWorldPtr(), m_pDynamicsWorld->GetInternalObjectListenerPtr() );
		}

		m_pFloor->Attach();
	}

	return True;
}

UInt32 Renderer::GetGhostCount( void ) const
{
	return MIX_UIT_TO_UI32( m_GhostList.size() );
}

void Renderer::GetGhostByIndex( UInt32 index, Mix::Scene::IGhost** ppGhost )
{
	MIX_ASSERT( m_GhostList.size() > index );
	MIX_ASSERT( ppGhost != NULL );

	Mix::Scene::Common::Ghost* pGhost = m_GhostList[index];

	MIX_ADD_REF( pGhost );
	( *ppGhost ) = pGhost;
}

Boolean Renderer::ContainsGhost( Mix::Scene::IGhost* pGhost )  const
{
	MIX_ASSERT( pGhost != NULL );

	return Mix::STL::Vector_Contains( m_GhostList, static_cast<Mix::Scene::Common::Ghost*>( pGhost ) );
}

Boolean Renderer::AddGhost( Mix::Scene::IGhost* pGhost )
{
	if( pGhost == NULL )
	{
		return False;
	}

	Mix::Scene::Common::Ghost* pObject = static_cast<Mix::Scene::Common::Ghost*>( pGhost );

	MIX_ADD_REF( pObject );

	if( IsDynamicsAvailable() == True )
	{
		pObject->AttachDynamics( m_pDynamicsWorld->GetInternalWorldPtr(), m_pDynamicsWorld->GetInternalObjectListenerPtr() );
	}

	pObject->Attach();

	m_GhostList.push_back( pObject );

	return True;
}

Boolean Renderer::RemoveGhost( Mix::Scene::IGhost* pGhost )
{
	MIX_ASSERT( pGhost != NULL );

	Mix::Scene::Common::Ghost* pObject = static_cast<Mix::Scene::Common::Ghost*>( pGhost );

	if( Mix::STL::Vector_FirstErase( m_GhostList, pObject ) == True )
	{
		pObject->DetachDynamics( m_pDynamicsWorld->GetInternalWorldPtr() );
		pObject->Detach();
		MIX_RELEASE( pObject );
	}
	else
	{
		return False;
	}

	return False;
}

void Renderer::RemoveGhostByIndex( UInt32 index )
{
	MIX_ASSERT( m_GhostList.size() > index );

	Mix::Scene::Common::Ghost* pObject = m_GhostList[index];

	Mix::STL::Vector_FirstErase( m_GhostList, index );
	pObject->DetachDynamics( m_pDynamicsWorld->GetInternalWorldPtr() );
	pObject->Detach();
	MIX_RELEASE( pObject );
}

void Renderer::RemoveAllGhost( void )
{
	if( m_GhostList.size() > 0 )
	{
		Mix::Dynamics::IWorld* pInternalWorld = m_pDynamicsWorld->GetInternalWorldPtr();

		Renderer::GhostList::iterator it_begin = m_GhostList.begin();
		Renderer::GhostList::iterator it_end = m_GhostList.end();
		Renderer::GhostList::iterator it;

		for( it = it_begin; it != it_end; ++it )
		{
			Mix::Scene::Common::Ghost* pObject = ( *it );

			pObject->DetachDynamics( pInternalWorld );
			pObject->Detach();
			MIX_RELEASE( pObject );
		}

		m_GhostList.clear();
	}
}

void Renderer::GetDynamicsWorld( Mix::Scene::IDynamicsWorld** ppDynamicsWorld )
{
	MIX_ADD_REF( m_pDynamicsWorld );
	( *ppDynamicsWorld ) = m_pDynamicsWorld;
}

void Renderer::GetAtmosphereScatter( Mix::Scene::IAtmosphereScatter** ppAtmosphereScatter )
{
	MIX_ADD_REF( m_pAtmosphereScatter );
	( *ppAtmosphereScatter ) = m_pAtmosphereScatter;
}

UInt32 Renderer::Debug_GetProfile( UInt32 type, void* pProf, UInt32 size ) const
{
#ifdef _DEBUG
	const void* pSrc = NULL;
	UInt32 srcSize = 0;

	if( type == Mix::Scene::DPT_GENERAL )
	{
		pSrc = m_pDebRProfGeneralCur;
		srcSize = sizeof( Mix::Scene::DEBUG_PROFILE_RENDERER_GENERAL );
	}
	else if( type == Mix::Scene::DPT_OCTREE )
	{
		pSrc = &( m_DebRProfOctree );
		srcSize = sizeof( Mix::Scene::DEBUG_PROFILE_RENDERER_OCTREE );
	}
	else if( type == Mix::Scene::DPT_DYNAMICS )
	{
		pSrc = &( m_DebRProfDynamics );
		srcSize = sizeof( Mix::Scene::DEBUG_PROFILE_RENDERER_DYNAMICS );
	}

	if( ( pSrc == NULL ) || ( srcSize == 0 ) || ( size < srcSize ) )
	{
		return 0;
	}

	Mix::Memory::Copy( pProf, pSrc, srcSize );

	return srcSize;
#else //_DEBUG
	return 0;
#endif //_DEBUG
}

Boolean Renderer::Debug_GetPerspectiveRenderer( Mix::Graphics::Utility::IPerspectiveRenderer** ppPerspectiveRenderer )
{
#ifdef _DEBUG

	if( m_pDebPerspectiveRenderer == NULL )
	{
		return False;
	}

	MIX_ADD_REF( m_pDebPerspectiveRenderer );
	( *ppPerspectiveRenderer ) = m_pDebPerspectiveRenderer;

	return True;

#else //_DEBUG

	return False;

#endif //_DEBUG
}

void Renderer::Debug_SetPerspectiveRenderer( Mix::Graphics::Utility::IPerspectiveRenderer* pPerspectiveRenderer )
{
#ifdef _DEBUG

	MIX_RELEASE( m_pDebPerspectiveRenderer );

	MIX_ADD_REF( pPerspectiveRenderer );
	m_pDebPerspectiveRenderer = pPerspectiveRenderer;

#endif
}

Boolean Renderer::Debug_GetCanvasRenderer( Mix::Graphics::Utility::ICanvasRenderer** ppCanvasRenderer )
{
#ifdef _DEBUG
	if( m_pDebCanvasRenderer == NULL )
	{
		return False;
	}

	MIX_ADD_REF( m_pDebCanvasRenderer );
	( *ppCanvasRenderer ) = m_pDebCanvasRenderer;

	return True;
#else //_DEBUG
	return False;
#endif //_DEBUG
}

void Renderer::Debug_SetCanvasRenderer( Mix::Graphics::Utility::ICanvasRenderer* pCanvasRenderer )
{
#ifdef _DEBUG
	MIX_RELEASE( m_pDebCanvasRenderer );
	MIX_ADD_REF( pCanvasRenderer );
	m_pDebCanvasRenderer = pCanvasRenderer;
#endif //_DEBUG
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Mix::Scene::Standard::Common::Renderer : 影コマンド
////////////////////////////////////////////////////////////////////////////////////////////////////

void Renderer::CollectShadowCommand( void )
{
	MIX_ASSERT( m_pOctree != NULL );
	MIX_ASSERT( m_pCamera != NULL );

	if( ( m_pDirectionalLight == NULL ) ||
		( m_pDirectionalLight->IsEnabled() == False ) ||
		( m_pCamera->IsShadowMappingAvailabled() == False ) ||
		( m_pCamera->IsShadowMappingEnabled() == False ) )
	{
		return;
	}

	MIX_ASSERT( m_pDirectionalLight != NULL );

	const Mix::Geometry::Sphere& clipBounds = m_pDirectionalLight->Projection_GetClipBounds();

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// オクトリーに現在のビュー(シャドウ)が有効であることを通知
	////////////////////////////////////////////////////////////////////////////////////////////////////

	m_pOctree->ValidView( Mix::Scene::Common::OCTREE_VIEW_SHADOW );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 収集
	////////////////////////////////////////////////////////////////////////////////////////////////////

	//アクターモデル
	CollectShadowCommand_ActorModel( clipBounds );

	//テラインモデル
	CollectShadowCommand_TerrainModel( clipBounds );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// フィニッシュ
	////////////////////////////////////////////////////////////////////////////////////////////////////

	m_SdwLightMat = m_pDirectionalLight->Projection_CalculateLightMatrix( m_pCamera );
	m_SdwLightBiasMat = m_SdwLightMat * m_SdwBiasMat;
}

void Renderer::CollectShadowCommand_ActorModel( const Mix::Geometry::Sphere& clipBounds )
{
	const Mix::ContainerT<Mix::Scene::Common::ActorModelObject*, Mix::Memory::SECTION_SCENE>& objList = m_pOctree->GetValidShadowActorModelObjects();

	if( objList.GetCount() == 0 )
	{
		return;
	}

	const Mix::Vector3& eyePos = m_pCamera->GetEye();

	Mix::Scene::Common::ActorModelObject* const* ppObj = objList.GetConstBeginPtr();
	Mix::Scene::Common::ActorModelObject* const* ppObjEnd = objList.GetConstEndPtr();

	//デバッグ : 計測開始
	SCENE_DEB( m_DebTimer.Reset() );

	while( ppObj != ppObjEnd )
	{
		Mix::Scene::Common::ActorModelObject* pObj = *ppObj;
		Mix::Scene::Common::ActorModel* pModel = pObj->GetContentPtr();

		if( pModel->IsDraw() == True )
		{
#ifdef _DEBUG
			if( AddShadowCommand( clipBounds, pModel ) == True )
			{
				pModel->InternalRefresh( eyePos );

				//デバッグ : 影を投影している
				SCENE_DEB( m_pDebCProfActorModel->sCount++ );
			}
			else
			{
				pObj->Invalid( Mix::Scene::Common::OCTREE_VIEW_SHADOW );
			}
#else //_DEBUG
			if( AddShadowCommand( clipBounds, pModel ) == True )
			{
				pModel->InternalRefresh( eyePos );
			}
			else
			{
				pObj->Invalid( Mix::Scene::Common::OCTREE_VIEW_SHADOW );
			}
#endif //_DEBUG
		}
		else
		{
			//描画しないように指定されている
			pObj->Invalid( Mix::Scene::Common::OCTREE_VIEW_SHADOW );
		}

		ppObj++;
	}

	//デバッグ : 計測終了
	SCENE_DEB( m_pDebCProfActorModel->cmElapsedTime += m_DebTimer.GetF32() );
}

Boolean Renderer::AddShadowCommand( const Mix::Geometry::Sphere& clipBounds, Mix::Scene::Common::ActorModel* pModel )
{
	MIX_ASSERT( pModel != NULL );
	MIX_ASSERT( m_pDirectionalLight != NULL );

	const Mix::Scene::Common::ActorModel::MeshList& meshList = pModel->GetMeshList();
	size_t meshNum = meshList.size();

	if( meshNum == 0 )
	{
		return False;
	}

	Mix::Scene::Common::ActorMesh* const* ppMesh = &( meshList[0] );
	Mix::Scene::Common::ActorMesh* const* ppMeshEnd = ppMesh + meshNum;

	UInt32 meshCount = 0;

	while( ppMesh != ppMeshEnd )
	{
		const Mix::Scene::Common::ActorMesh* pMesh = *ppMesh;
		const Mix::Geometry::Sphere& bounds = pMesh->GetBounds();

		if( ( pMesh->IsDraw() == False ) ||
			( Mix::Geometry::IntersectSphereSphere( clipBounds, bounds ) == False ) )
		{
			//描画しないように指定されている
			//視界に入っていない
			ppMesh++;
			continue;
		}

		const Mix::Scene::Common::ActorMesh::WorldMatrixList& worldMatList = pMesh->GetWorldMatrixList();

		const Mix::Scene::Common::ActorMesh::DrawTable& drawTable = pMesh->GetDrawTable();
		MIX_ASSERT( drawTable.size() > 0 );

		const Mix::Scene::Common::ActorMesh::DRAW* pDraw = &( drawTable[0] );
		const Mix::Scene::Common::ActorMesh::DRAW* pDrawEnd = pDraw + drawTable.size();

		Mix::Scene::IMaterial::TRANSFORM_TYPE trType = ( pMesh->GetBoneCount() == 0 )? IMaterial::TR_SIMPLE : IMaterial::TR_SKINNING;

		Mix::Graphics::IVertexBuffer* pVertexBuffer = pMesh->GetVertexBufferPtr();
		Mix::Graphics::IIndexBuffer* pIndexBuffer = pMesh->GetIndexBufferPtr();

		UInt32 worldMatID = 0xFFFFFFFF;
		UInt32 drawCount = 0;

		while( pDraw != pDrawEnd )
		{
			Mix::Scene::IMaterial* pMaterial = pModel->GetMaterialPtr( pDraw->materialSlotIndex );
			if( pMaterial->IsShadowing() == False )
			{
				//影を落とす必要は無い
				pDraw++;
				continue;
			}

			const Mix::Scene::Common::ActorMesh::OpacitySubsetList& subsetList = pDraw->opSubsets;
			if( subsetList.size() == 0 )
			{
				//不透明サブセットを所持していない
				pDraw++;
				continue;
			}

			const Mix::Scene::Common::ActorMesh::OPACITY_SUBSET* pSubset = &( subsetList[0] );
			const Mix::Scene::Common::ActorMesh::OPACITY_SUBSET* pSubsetEnd = pSubset + subsetList.size();

			if( worldMatID == 0xFFFFFFFF )
			{
				worldMatID = AssignWorldMatrix( worldMatList );
			}
			
			while( pSubset != pSubsetEnd )
			{
				Renderer::SHADOW_COMMAND* pCom = m_ShadowComList.Add();

				pCom->bTransparency = pMaterial->IsTransparency();
				pCom->worldMatID = worldMatID + pSubset->boneOffset;
				pCom->worldMatCount = pSubset->boneCount;
				pCom->primitiveType = Mix::Graphics::PRIMITIVE_TRIANGLELIST;
				pCom->vertexStart = pSubset->vertexStart;
				pCom->vertexCount = pSubset->vertexCount;
				pCom->indexStart = pSubset->indexStart;
				pCom->indexCount = pSubset->indexCount;
				pCom->pMaterial = pMaterial;
				pCom->trType = trType;
				pCom->pVertexBuffer = pVertexBuffer;
				pCom->pIndexBuffer = pIndexBuffer;

				pSubset++;
			}

			//シャドウを生成する矩形を結合
			m_pDirectionalLight->Projection_AppendCast( bounds );

			drawCount++;
			pDraw++;
		}

		//メッシュの数
		if( drawCount > 0 ) { meshCount++; }

		ppMesh++;
	}

	return ( meshCount > 0 );
}

void Renderer::CollectShadowCommand_TerrainModel( const Mix::Geometry::Sphere& clipBounds )
{
	if( m_TerrainModelList.size() == 0 )
	{
		return;
	}

	Mix::Scene::Common::TerrainModel** ppModel = &( m_TerrainModelList[0] );
	Mix::Scene::Common::TerrainModel** ppModelEnd = ppModel + m_TerrainModelList.size();

	//デバッグ : 計測開始
	SCENE_DEB( m_DebTimer.Reset() );

	while( ppModel != ppModelEnd )
	{
		Mix::Scene::Common::TerrainModel* pModel = *ppModel;
		Mix::Scene::Common::TerrainNode* pModelNode = pModel->GetRootNodePtr();

		UInt32 worldMatID = ReserveWorldMatrix();
		UInt32 meshCount = 0;

		if( ( pModel->IsDraw() == True ) &&
			( AddShadowCommand( clipBounds, worldMatID, pModel, pModelNode, meshCount ) == True ) )
		{
			AssignWorldMatrix( pModel->GetWorldMatrix(), worldMatID );
			SCENE_DEB( m_pDebCProfTerrainModel->sCount++ );
		}

		ppModel++;
	}

	//デバッグ : 計測終了
	SCENE_DEB( m_pDebCProfTerrainModel->cmElapsedTime += m_DebTimer.GetF32() );
}

Boolean Renderer::AddShadowCommand(	const Mix::Geometry::Sphere& clipBounds,
									UInt32 worldMatID,
									Mix::Scene::Common::TerrainModel* pModel,
									Mix::Scene::Common::TerrainNode* pNode,
									UInt32& meshCount )
{
	MIX_ASSERT( pModel != NULL );
	MIX_ASSERT( pNode != NULL );
	MIX_ASSERT( m_pDirectionalLight != NULL );

	UIntT childCount = pNode->GetChildCount();
	UIntT i;

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// シャドウカメラ内に入っているかチェック
	////////////////////////////////////////////////////////////////////////////////////////////////////

	if( Mix::Geometry::IntersectSphereAABB( clipBounds, pNode->GetBounds() ) == False )
	{
		return False;
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// メッシュを所持している場合はコマンドを追加
	////////////////////////////////////////////////////////////////////////////////////////////////////

	Mix::Scene::Common::TerrainMesh* pMesh = pNode->GetMeshPtr();

	if( pMesh != NULL )
	{
		const Mix::Scene::Common::TerrainMesh::DrawTable& drawTable = pMesh->GetDrawTable();

		MIX_ASSERT( drawTable.size() > 0 );

		const Mix::Scene::Common::TerrainMesh::DRAW* pDraw = &( drawTable[0] );
		const Mix::Scene::Common::TerrainMesh::DRAW* pDrawEnd = pDraw + drawTable.size();

		Mix::Graphics::IVertexBuffer* pVertexBuffer = pMesh->GetVertexBufferPtr();
		Mix::Graphics::IIndexBuffer* pIndexBuffer = pMesh->GetIndexBufferPtr();

		while( pDraw != pDrawEnd )
		{
			Mix::Scene::IMaterial* pMaterial = pModel->GetMaterialPtr( pDraw->materialSlotIndex );
			if( pMaterial->IsShadowing() == False )
			{
				//影を落とす必要は無い
				pDraw++;
				continue;
			}

			const Mix::Scene::Common::TerrainMesh::OpacitySubsetList& subsetList = pDraw->opSubsets;
			if( subsetList.size() == 0 )
			{
				//不透明サブセットを所持していない
				pDraw++;
				continue;
			}

			const Mix::Scene::Common::TerrainMesh::OPACITY_SUBSET* pSubset = &( subsetList[0] );
			const Mix::Scene::Common::TerrainMesh::OPACITY_SUBSET* pSubsetEnd = pSubset + subsetList.size();

			while( pSubset != pSubsetEnd )
			{
				Renderer::SHADOW_COMMAND* pCom = m_ShadowComList.Add();

				pCom->bTransparency = pMaterial->IsTransparency();
				pCom->worldMatID = worldMatID;
				pCom->worldMatCount = 0;
				pCom->primitiveType = Mix::Graphics::PRIMITIVE_TRIANGLELIST;
				pCom->vertexStart = pSubset->vertexStart;
				pCom->vertexCount = pSubset->vertexCount;
				pCom->indexStart = pSubset->indexStart;
				pCom->indexCount = pSubset->indexCount;
				pCom->pMaterial = pMaterial;
				pCom->trType = IMaterial::TR_SIMPLE;
				pCom->pVertexBuffer = pVertexBuffer;
				pCom->pIndexBuffer = pIndexBuffer;

				pSubset++;
			}

			//シャドウを生成する矩形を結合
			m_pDirectionalLight->Projection_AppendCast( pNode->GetBounds() );

			pDraw++;
		}

		meshCount++;
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 子を処理
	////////////////////////////////////////////////////////////////////////////////////////////////////

	for( i = 0; i < childCount; i++ )
	{
		AddShadowCommand( clipBounds, worldMatID, pModel, pNode->GetChildPtr( i ), meshCount );
	}

	return ( meshCount > 0 );
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Mix::Scene::Standard::Common::Renderer : 描画コマンド
////////////////////////////////////////////////////////////////////////////////////////////////////

void Renderer::CollectDrawCommand( void )
{
	MIX_ASSERT( m_pOctree != NULL );
	MIX_ASSERT( m_pCamera != NULL );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// オクトリーに現在のビュー(カラー)が有効であることを通知
	////////////////////////////////////////////////////////////////////////////////////////////////////

	m_pOctree->ValidView( Mix::Scene::Common::OCTREE_VIEW_COLOR );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 収集
	////////////////////////////////////////////////////////////////////////////////////////////////////

	// ローカルライト
	CollectDrawCommand_LocalLight();

	// ウォータープール
	CollectDrawCommand_WaterPool();

	// ウィジェット
	CollectDrawCommand_Widget();

	// アクターモデル
	CollectDrawCommand_ActorModel();

	// テラインモデル
	CollectDrawCommand_TerrainModel();

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 半透明オブジェクト
	////////////////////////////////////////////////////////////////////////////////////////////////////

	if( m_TransparencyObjList.IsEmpty() == False )
	{
		Renderer::TRANSPARENCY_OBJECT* pTRTermObj;

		// ソート
		SCENE_DEB( m_DebTimer.Reset() );
		m_TransparencyObjSorter.Execute( m_TransparencyObjList.GetBeginPtr(), 0, m_TransparencyObjList.GetCount() - 1 );
		SCENE_DEB( m_pDebCProfDrawTransp->soElapsedTime += m_DebTimer.GetF32() );

		// 終端を追加
		pTRTermObj = m_TransparencyObjList.Add();
		pTRTermObj->type = Renderer::TO_TERM;

		// コマンドの生成
		SCENE_DEB( m_DebTimer.Reset() );
		CollectDrawCommand_FinishTransparency();
		SCENE_DEB( m_pDebCProfDrawTransp->gcElapsedTime += m_DebTimer.GetF32() );
	}

	// デバッグ
	SCENE_DEB( m_pDebCProfDrawTransp->objCount += m_TransparencyObjList.GetCount() );
	SCENE_DEB( m_pDebCProfDrawTransp->objCapacity = m_TransparencyObjList.GetCapacity() );
}

void Renderer::CollectDrawCommand_LocalLight( void )
{
	MIX_ASSERT( m_pOctree != NULL );
	MIX_ASSERT( m_pCamera != NULL );
	MIX_ASSERT( m_VisibleLocalLightList.GetCount() == 0 );

	const Mix::ContainerT<Mix::Scene::Common::LocalLightObject*, Mix::Memory::SECTION_SCENE>& list = m_pOctree->GetValidLocalLightObjects();

	if( list.IsEmpty() == True )
	{
		return;
	}

	Mix::Scene::Common::LocalLightObject* const* ppObj = list.GetConstBeginPtr();
	Mix::Scene::Common::LocalLightObject* const* ppObjEnd = list.GetConstEndPtr();

	const Mix::Geometry::Frustum& frustum = m_pCamera->GetFrustum();
	const Mix::Geometry::Plane& nearPlane = frustum.GetPlane( Mix::Geometry::Frustum::PLANE_NEAR );

	const Mix::Scene::ICamera::VISIBILITY_SETTINGS& visiSettings = m_pCamera->GetVisiblitySettings();
	const Mix::Scene::Common::Camera::INTERNAL_VISIBLITY_SETTINGS& internalVisiSettings = m_pCamera->GetInternalVisiblitySettings();

	Float32 foStart = internalVisiSettings.loFalloffStart;
	Float32 foEnd = visiSettings.loLimitDistance;
	Float32 foInvDist = internalVisiSettings.loInvFalloffAmount;

	Mix::Scene::Common::LOCAL_LIGHT* pOut;

	UInt32 visibleCount;

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 視界判定を行いながら収集
	////////////////////////////////////////////////////////////////////////////////////////////////////

	//デバッグ : 計測開始
	SCENE_DEB( m_DebTimer.Reset() );

	while( ppObj != ppObjEnd )
	{
		Mix::Scene::Common::LocalLightObject* pObj = *ppObj;

		const Mix::Geometry::Sphere& objBounds = pObj->GetBounds();
		Float32 objZ = Mix::Vector3::Dot( nearPlane.normal, objBounds.center ) + nearPlane.d;
		Float32 objMinZ = objZ - objBounds.radius;
		Float32 objMaxZ = objZ + objBounds.radius;
		Float32 ratio;

		if( ( 0.0f > objMaxZ ) || ( foEnd < objMinZ ) || ( frustum.ContainsTBLR( objBounds ) == False ) )
		{
			//有効範囲外
			;
		}
		else
		{
			pOut = pObj->Generate( m_VisibleLocalLightList.Add() );

			ratio = ( foStart < objMinZ )? MIX_FLOAT_SATURATE( ( foEnd - objMinZ ) * foInvDist ) : 1.0f;

			pOut->color.a *= ratio;
			pOut->z = objZ;
			pOut->minZ = objMinZ;
			pOut->maxZ = objMaxZ;

#ifdef _DEBUG

			if( pObj->Debug_GetType() == Mix::Scene::IRendererObject::POINT_LIGHT )
			{
				m_DebPointLightList.Add( static_cast<Mix::Scene::Common::PointLight*>( pObj->Debug_GetInternalPtr() ) );
			}
			else if( pObj->Debug_GetType() == Mix::Scene::IRendererObject::SPOT_LIGHT )
			{
				m_DebSpotLightList.Add( static_cast<Mix::Scene::Common::SpotLight*>( pObj->Debug_GetInternalPtr() ) );
			}

#endif //_DEBUG
		}

		ppObj++;
	}

	//デバッグ : 計測終了
	SCENE_DEB( m_pDebCProfLight->vcElapsedTime += m_DebTimer.GetF32() );
	SCENE_DEB( m_pDebCProfLight->vSpotCount += m_DebSpotLightList.GetCount() );
	SCENE_DEB( m_pDebCProfLight->vPointCount += m_DebPointLightList.GetCount() );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 奥から手前へ maxZ でソート
	////////////////////////////////////////////////////////////////////////////////////////////////////

	visibleCount = m_VisibleLocalLightList.GetCount();

	if( visibleCount > 0 )
	{
		SCENE_DEB( m_DebTimer.Reset() );
		Renderer::SortLocalLight( m_VisibleLocalLightList.GetBeginPtr(), 0, visibleCount - 1 );
		SCENE_DEB( m_pDebCProfLight->vsElapsedTime += m_DebTimer.GetF32() );
	}
}

void Renderer::SortLocalLight( Mix::Scene::Common::LOCAL_LIGHT** list, Int32 first, Int32 last )
{
	const Mix::Scene::Common::LOCAL_LIGHT* pCom  = list[( first + last ) >> 1];

	Float32 maxZ = pCom->maxZ;

	Int32 i = first;
	Int32 j = last;

	do
	{
		while( list[i]->maxZ > maxZ ) { i++; }
		while( list[j]->maxZ < maxZ ) { j--; }

		if( i <= j )
		{
			MIX_ASSERT( ( i <= last ) && ( j >= first ) );

			Mix::Scene::Common::LOCAL_LIGHT* pTemp = list[i];

			list[i] = list[j];
			list[j] = pTemp;

			i++;
			j--;
		}

	}while( i <= j );

	if( first < j ) { Renderer::SortLocalLight( list, first, j ); }
	if( i < last ) { Renderer::SortLocalLight( list, i, last ); }
}

void Renderer::CollectDrawCommand_WaterPool( void )
{
	MIX_ASSERT( m_pOctree != NULL );
	MIX_ASSERT( m_pCamera != NULL );
	MIX_ASSERT( m_VisibleWaterPoolList.GetCount() == 0 );

	const Mix::ContainerT<Mix::Scene::Common::WaterPoolObject*, Mix::Memory::SECTION_SCENE>& list = m_pOctree->GetValidWaterPoolObjects();

	if( list.IsEmpty() == True )
	{
		//ウォータープールが配置されていない場合は、視点は常に水中ではないことにする
		m_RefractClassTable[Mix::Scene::WCR_FRONT] = Mix::Scene::Common::RRC_FRONT;
		m_RefractClassTable[Mix::Scene::WCR_BACK] = Mix::Scene::Common::RRC_BACK;
		m_RefractClassTable[Mix::Scene::WCR_OVERLAP] = Mix::Scene::Common::RRC_OVERLAP;
		return;
	}

	const Mix::Geometry::Frustum& frustum = m_pCamera->GetFrustum();
	const Mix::Vector3& eyePos = m_pCamera->GetEye();

	Mix::Scene::Common::WaterPoolObject** ppObj = list.GetBeginPtr();
	Mix::Scene::Common::WaterPoolObject** ppObjEnd = list.GetEndPtr();
	Mix::Scene::Common::WaterPoolObject* pObj;

	Mix::Scene::Common::WaterPool* pContent;
	Mix::Scene::IWaterPoolContext* pContentContext;

	Float32 visualDepth = 1.0f;
	Mix::Scene::Common::WaterPool* pVisualContent = NULL;

	Renderer::WATER_POOL* wp;

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// デバッグ : 計測開始
	////////////////////////////////////////////////////////////////////////////////////////////////////

	SCENE_DEB( m_DebTimer.Reset() );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 視点が水中かどうかの判定
	// 視界に入っているウォータープールの収集
	////////////////////////////////////////////////////////////////////////////////////////////////////

	while( ppObj != ppObjEnd )
	{
		pObj = *ppObj;

		const Mix::Geometry::AABB& bounds = pObj->GetBounds();

		if( frustum.Contains( bounds ) == True )
		{
			pContent = pObj->GetContentPtr();
			pContentContext = pObj->GetContentContextPtr();

			if( ( visualDepth > 0.0f ) &&
				( Mix::Geometry::IntersectPointAABB( eyePos, bounds ) == True ) )
			{
				//視点が水中にある
				visualDepth = pContentContext->Contains( eyePos );
				pVisualContent = pObj->GetContentPtr();
			}

			if( pContent->IsRefraction() == True )
			{
				//屈折対象とする
				wp = m_VisibleWaterPoolList.Add();

				MIX_ASSERT( wp != NULL );

				wp->pBounds = &bounds;
				wp->pContext = pContentContext;
			}

#ifdef _DEBUG
			m_DebWaterPoolList.Add( pObj->GetContentPtr() );
#endif //_DEBUG
		}

		ppObj++;
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 状態を設定
	////////////////////////////////////////////////////////////////////////////////////////////////////

	m_pCamera->SetUnderWater( visualDepth <= 0.0f );

	if( m_pCamera->IsUnderWater() == True )
	{
		MIX_ASSERT( pVisualContent != NULL );

		const Mix::Scene::IWaterPool::VISUAL_PARAM& param = pVisualContent->GetVisualParam();
		Float32 ratio = MIX_FLOAT_SATURATE( 1.0f + MIX_FLOAT_DIV( visualDepth, param.depth ) );

		//ビジュアル
		m_WaterVisual.color = param.color;
		m_WaterVisual.density = param.density;
		m_WaterVisual.intensity = param.intensity;
		m_WaterVisual.threshold = 1.0f - ratio;
		m_WaterVisual.offset = MIX_FLOAT_RECIPROCAL( 1.0f - m_WaterVisual.threshold );

		//屈折効果
		m_RefractClassTable[Mix::Scene::WCR_FRONT] = Mix::Scene::Common::RRC_BACK;
		m_RefractClassTable[Mix::Scene::WCR_BACK] = Mix::Scene::Common::RRC_FRONT;
		m_RefractClassTable[Mix::Scene::WCR_OVERLAP] = Mix::Scene::Common::RRC_OVERLAP;
	}
	else
	{
		//屈折効果
		m_RefractClassTable[Mix::Scene::WCR_FRONT] = Mix::Scene::Common::RRC_FRONT;
		m_RefractClassTable[Mix::Scene::WCR_BACK] = Mix::Scene::Common::RRC_BACK;
		m_RefractClassTable[Mix::Scene::WCR_OVERLAP] = Mix::Scene::Common::RRC_OVERLAP;
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// デバッグ : 計測終了
	////////////////////////////////////////////////////////////////////////////////////////////////////

	SCENE_DEB( m_pDebCProfWaterPool->vElapsedTime = m_DebTimer.GetF32() );
	SCENE_DEB( m_pDebCProfWaterPool->vCount = m_DebWaterPoolList.GetCount() );
	SCENE_DEB( m_pDebCProfWaterPool->vrCount = m_VisibleWaterPoolList.GetCount() );
	SCENE_DEB( m_pDebCProfWaterPool->tCount = MIX_UIT_TO_UI32( m_WaterPoolList.size() ) );
}

void Renderer::CollectDrawCommand_Widget( void )
{
	if( m_pWidgetBuffer == NULL )
	{
		//ウィジェットは無効( RCAP_WIDGET )
		return;
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// ウィジェットからサブセットを収集
	////////////////////////////////////////////////////////////////////////////////////////////////////

	// プランター
	CollectWidgetSubset_Planter();

	// リービングパーティクル
	CollectWidgetSubset_LeavingParticle();

	// スキャッターパーティクル
	CollectWidgetSubset_ScatterParticle();

	// デバッグ : サブセットの数
	SCENE_DEB( m_pDebCProfWidget->subsetCount = m_WidgetSubsetList.GetCount() );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 収集したサブセットのフィニッシュ処理
	////////////////////////////////////////////////////////////////////////////////////////////////////

	switch( m_WidgetLightingMode )
	{
	case IRenderer::WL_EVERYONE:
		FinishWidget_Everyone();
		break;
	case IRenderer::WL_DETAILED:
		FinishWidget_Detailed();
		break;

	default:
		//IRenderer::WL_DEFAULT
		FinishWidget_GenerateTransparencyObjects( 0xFFFFFFFF, 0 );
	}

	// デバッグ : クワッドの数
	SCENE_DEB( m_pDebCProfWidget->quadCount = m_WidgetQuadCount );
}

void Renderer::CollectWidgetSubset_Planter( void )
{
	MIX_ASSERT( m_pOctree != NULL );
	MIX_ASSERT( m_pCamera != NULL );

	const Mix::ContainerT<Mix::Scene::Common::PlanterObject*, Mix::Memory::SECTION_SCENE>& ptList = m_pOctree->GetValidPlanterObjects();

	if( ptList.IsEmpty() == True )
	{
		return;
	}

	Mix::Scene::Common::PlanterObject* const* ppObj = ptList.GetConstBeginPtr();
	Mix::Scene::Common::PlanterObject* const* ppObjEnd = ptList.GetConstEndPtr();

	const Mix::Geometry::Frustum& frustum = m_pCamera->GetFrustum();
	const Mix::Geometry::Plane& nearPlane = frustum.GetPlane( Mix::Geometry::Frustum::PLANE_NEAR );
	const Mix::Vector3& npNorm = nearPlane.normal;
	Float32 npD = nearPlane.d;

	const Mix::Scene::ICamera::VISIBILITY_SETTINGS& visiSettings = m_pCamera->GetVisiblitySettings();
	const Mix::Scene::Common::Camera::INTERNAL_VISIBLITY_SETTINGS& internalVisiSettings = m_pCamera->GetInternalVisiblitySettings();
	Float32 foStart = internalVisiSettings.plFalloffStart;
	Float32 foMid = internalVisiSettings.plFalloffMiddle;
	Float32 foEnd = visiSettings.plLimitDistance;
	Float32 loEnd = visiSettings.loLimitDistance;

	SCENE_DEB( UInt32 debDrawFlags = m_pCamera->Debug_GetDrawFlags() );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 視界判定を行いながわ収集
	////////////////////////////////////////////////////////////////////////////////////////////////////

	//デバッグ : 計測開始
	SCENE_DEB( m_DebTimer.Reset() );

	while( ppObj != ppObjEnd )
	{
		Mix::Scene::Common::PlanterObject* pObj = *ppObj;
		Mix::Scene::Common::Planter* pPlanter = pObj->GetContentPtr();

		const Mix::Geometry::AABB& objBounds = pPlanter->GetBounds();
		const Mix::Vector3* pObjPoint = &( objBounds.points[0] );
		const Mix::Vector3* pObjPointEnd = pObjPoint + 8;
		Float32 objMinZ = +MIX_FLOAT_MAX;
		Float32 objMaxZ = -MIX_FLOAT_MAX;

		UInt32 refractClass;

		UInt32 subsetNum;
		Mix::Scene::Common::WIDGET_SPHERE_SUBSET* pSubset;
		Mix::Scene::Common::WIDGET_SPHERE_SUBSET* pSubsetEnd;

		// 内部リフレッシュ、クリッピング用のパラメータを求める
		while( pObjPoint != pObjPointEnd )
		{
			Float32 tempZ = ( pObjPoint->x * npNorm.x ) + ( pObjPoint->y * npNorm.y ) + ( pObjPoint->z * npNorm.z ) + npD;

			if( objMinZ > tempZ ) { objMinZ = tempZ; }
			if( objMaxZ < tempZ ) { objMaxZ = tempZ; }

			pObjPoint++;
		}

		// 内部リフレッシュ
		if( pPlanter->InternalRefresh( foStart, foMid, foEnd, objMinZ ) == False )
		{
			ppObj++;
			continue;
		}

		// 視界判定
		if( ( 0.0f > objMaxZ ) || ( foEnd < objMinZ ) || ( frustum.ContainsTBLR( objBounds ) == False ) )
		{
			ppObj++;
			continue;
		}

		// 屈折クラス
		refractClass = ClassifyRefract( pPlanter->GetDefaultWaterContainsResult(), objBounds );

		// サブセット
		subsetNum = pPlanter->GetSubsetCount();
		pSubset = pPlanter->GetSubsets();
		pSubsetEnd = pSubset + subsetNum;

#ifdef _DEBUG
		if( MIX_TESTBIT( debDrawFlags, Mix::Scene::DDF_PLANTER_MESH ) == Mix::Scene::DDF_PLANTER_MESH )
		{
			// ローカルライティング用のオブジェクトをリストに追加
			if( NeedsWidgetObject( pPlanter->CanLocalLighting(), objMinZ, loEnd ) == True )
			{
				Mix::Scene::Common::WIDGET_OBJECT* pWGObj = m_WidgetObjectList.Add();

				pWGObj->minZ = objMinZ;
				pWGObj->maxZ = objMaxZ;
				pWGObj->bounds.min = objBounds.min;
				pWGObj->bounds.max = objBounds.max;
				pWGObj->subsetStart = m_WidgetSubsetList.GetCount();
				pWGObj->subsetNum = subsetNum;
			}

			// サブセットをリストに追加
			while( pSubset != pSubsetEnd )
			{
				pSubset->Update( npNorm, npD );
				pSubset->refractClass = refractClass;

				m_WidgetSubsetList.Add( pSubset );

				pSubset++;
			}
		}
#else //_DEBUG
		// ローカルライティング用のオブジェクトをリストに追加
		if( NeedsWidgetObject( pPlanter->CanLocalLighting(), objMinZ, loEnd ) == True )
		{
			Mix::Scene::Common::WIDGET_OBJECT* pWGObj = m_WidgetObjectList.Add();

			pWGObj->minZ = objMinZ;
			pWGObj->maxZ = objMaxZ;
			pWGObj->bounds.min = objBounds.min;
			pWGObj->bounds.max = objBounds.max;
			pWGObj->subsetStart = m_WidgetSubsetList.GetCount();
			pWGObj->subsetNum = subsetNum;
		}

		// サブセットをリストに追加
		while( pSubset != pSubsetEnd )
		{
			pSubset->Update( npNorm, npD );
			pSubset->refractClass = refractClass;

			m_WidgetSubsetList.Add( pSubset );

			pSubset++;
		}
#endif //_DEBUG

		// デバッグ : 視界に入っているカウント
		SCENE_DEB( m_DebVisiblePlanterList.Add( pPlanter ) );
		SCENE_DEB( m_pDebCProfWidget->pl.vCount++ );

		ppObj++;
	}

	// デバッグ : 計測終了
	SCENE_DEB( m_pDebCProfWidget->pl.vElapsedTime += m_DebTimer.GetF32() );
}

void Renderer::CollectWidgetSubset_LeavingParticle( void )
{
	MIX_ASSERT( m_pOctree != NULL );
	MIX_ASSERT( m_pCamera != NULL );

	const Mix::ContainerT<Mix::Scene::Common::LeavingParticleObject*, Mix::Memory::SECTION_SCENE>& lpList = m_pOctree->GetValidLeavingParticleObjects();

	if( lpList.IsEmpty() == True )
	{
		return;
	}

	Mix::Scene::Common::LeavingParticleObject* const* ppLPObj = lpList.GetConstBeginPtr();
	Mix::Scene::Common::LeavingParticleObject* const* ppLPObjEnd = lpList.GetConstEndPtr();

	const Mix::Matrix4x4& bbMat = m_pCamera->GetBillboardMatrix();
	const Mix::Vector3& eyePos = m_pCamera->GetEye();
	const Mix::Geometry::Frustum& frustum = m_pCamera->GetFrustum();
	const Mix::Geometry::Plane& nearPlane = frustum.GetPlane( Mix::Geometry::Frustum::PLANE_NEAR );
	const Mix::Vector3& npNorm = nearPlane.normal;
	Float32 npD = nearPlane.d;

	const Mix::Scene::ICamera::VISIBILITY_SETTINGS& visiSettings = m_pCamera->GetVisiblitySettings();
	Float32 objEnd = visiSettings.paLimitDistance;
	Float32 loEnd = visiSettings.loLimitDistance;

	SCENE_DEB( UInt32 debDrawFlags = m_pCamera->Debug_GetDrawFlags() );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 視界判定をしつつ、更新、そして収集
	////////////////////////////////////////////////////////////////////////////////////////////////////

	// デバッグ : 計測開始
	SCENE_DEB( m_DebTimer.Reset() );

	while( ppLPObj != ppLPObjEnd )
	{
		Mix::Scene::Common::LeavingParticleObject* pObj = *ppLPObj;
		Mix::Scene::Common::LeavingParticle* pParticle = pObj->GetContentPtr();
		Mix::Scene::Common::WIDGET_AABB_SUBSET* pSubset;

		MIX_ASSERT( pParticle->Debug_GetVertexStride() <= Mix::Scene::Common::WIDGET_VERTEX_STRIDE );

		if( ( pParticle->IsDraw() == False ) ||
			( pParticle->IsPlay() == False ) )
		{
			//描画しない
			//再生していない
			pObj->Invalid( Mix::Scene::Common::OCTREE_VIEW_COLOR );
			ppLPObj++;
			continue;
		}

		// サブセットの更新
		pSubset = pParticle->GetSubsetPtr();
		pSubset->Update( npNorm, npD );

		if( ( 0.0f > pSubset->maxZ ) || ( objEnd < pSubset->minZ ) || ( frustum.ContainsTBLR( pSubset->bounds ) == False ) )
		{
			//視界に入っていない
			pObj->Invalid( Mix::Scene::Common::OCTREE_VIEW_COLOR );
			ppLPObj++;
			continue;
		}

		if( pParticle->InternalRefresh( eyePos, bbMat ) == False )
		{
			//内部リフレッシュが失敗した
//			pObj->Invalid( Mix::Scene::Common::OCTREE_VIEW_COLOR );
			ppLPObj++;
			continue;
		}

		// 屈折クラスを決める
		pSubset->refractClass = ClassifyRefract( pParticle->GetDefaultWaterContainsResult(), pSubset->bounds );

#ifdef _DEBUG
		if( MIX_TESTBIT( debDrawFlags, Mix::Scene::DDF_PARTICLE_MESH ) == Mix::Scene::DDF_PARTICLE_MESH )
		{
			// ローカルライティング用のオブジェクトをリストに追加
			if( NeedsWidgetObject( pParticle->CanLocalLighting(), pSubset->minZ, loEnd ) == True )
			{
				Mix::Scene::Common::WIDGET_OBJECT* pWGObj = m_WidgetObjectList.Add();

				pWGObj->minZ = pSubset->minZ;
				pWGObj->maxZ = pSubset->maxZ;
				pWGObj->bounds.min = pSubset->bounds.min;
				pWGObj->bounds.max = pSubset->bounds.max;
				pWGObj->subsetStart = m_WidgetSubsetList.GetCount();
				pWGObj->subsetNum = 1;
			}

			// サブセットをリストに追加
			m_WidgetSubsetList.Add( pSubset );
		}
#else //_DEBUG
		// ローカルライティング用のオブジェクトをリストに追加
		if( NeedsWidgetObject( pParticle->CanLocalLighting(), pSubset->minZ, loEnd ) == True )
		{
			Mix::Scene::Common::WIDGET_OBJECT* pWGObj = m_WidgetObjectList.Add();

			pWGObj->minZ = pSubset->minZ;
			pWGObj->maxZ = pSubset->maxZ;
			pWGObj->bounds.min = pSubset->bounds.min;
			pWGObj->bounds.max = pSubset->bounds.max;
			pWGObj->subsetStart = m_WidgetSubsetList.GetCount();
			pWGObj->subsetNum = 1;
		}

		// サブセットをリストに追加
		m_WidgetSubsetList.Add( pSubset );
#endif //_DEBUG

		// デバッグ : 視界に入っているリービングパーティクルの数
		SCENE_DEB( m_DebLeavingParticleList.Add( pParticle ) );
		SCENE_DEB( m_pDebCProfWidget->lp.vCount++ );

		ppLPObj++;
	}

	// デバッグ : 計測終了
	SCENE_DEB( m_pDebCProfWidget->lp.vElapsedTime += m_DebTimer.GetF32() );
}

void Renderer::CollectWidgetSubset_ScatterParticle( void )
{
	MIX_ASSERT( m_pOctree != NULL );
	MIX_ASSERT( m_pCamera != NULL );

	const Mix::ContainerT<Mix::Scene::Common::ScatterParticleUnitObject*, Mix::Memory::SECTION_SCENE>& spuList = m_pOctree->GetValidScatterParticleUnitObjects();

	if( spuList.IsEmpty() == True )
	{
		return;
	}

	Mix::Scene::Common::ScatterParticleUnitObject* const* ppSPUObj = spuList.GetConstBeginPtr();
	Mix::Scene::Common::ScatterParticleUnitObject* const* ppSPUObjEnd = spuList.GetConstEndPtr();

	const Mix::Matrix4x4& bbMat = m_pCamera->GetBillboardMatrix();
	const Mix::Vector3& eyePos = m_pCamera->GetEye();
	const Mix::Geometry::Frustum& frustum = m_pCamera->GetFrustum();
	const Mix::Geometry::Plane& nearPlane = frustum.GetPlane( Mix::Geometry::Frustum::PLANE_NEAR );
	const Mix::Vector3& npNorm = nearPlane.normal;
	Float32 npD = nearPlane.d;

	const Mix::Scene::ICamera::VISIBILITY_SETTINGS& visiSettings = m_pCamera->GetVisiblitySettings();
	Float32 objEnd = visiSettings.paLimitDistance;
	Float32 loEnd = visiSettings.loLimitDistance;

	SCENE_DEB( UInt32 debDrawFlags = m_pCamera->Debug_GetDrawFlags() );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 視界判定をしつつ、更新、そして収集
	////////////////////////////////////////////////////////////////////////////////////////////////////

	// デバッグ : 計測開始
	SCENE_DEB( m_DebTimer.Reset() );

	while( ppSPUObj != ppSPUObjEnd )
	{
		Mix::Scene::Common::ScatterParticleUnitObject* pObj = *ppSPUObj;
		Mix::Scene::Common::ScatterParticleUnit* pParticleUnit = pObj->GetContentPtr();
		Mix::Scene::Common::WIDGET_SPHERE_SUBSET* pSubset;

		MIX_ASSERT( pParticleUnit->Debug_GetVertexStride() <= Mix::Scene::Common::WIDGET_VERTEX_STRIDE );

		if( pParticleUnit->IsDraw() == False )
		{
			//描画しない
			ppSPUObj++;
			continue;
		}

		// サブセットを更新
		pSubset = pParticleUnit->GetSubsetPtr();
		pSubset->Update( npNorm, npD );

		if( ( 0.0f > pSubset->maxZ ) || ( objEnd < pSubset->minZ ) || ( frustum.ContainsTBLR( pSubset->bounds ) == False ) )
		{
			//視界に入っていない
			ppSPUObj++;
			continue;
		}

		if( pParticleUnit->InternalRefresh( bbMat ) == False )
		{
			//内部リフレッシュが失敗した
			ppSPUObj++;
			continue;
		}

		// 屈折クラスを決める
		pSubset->refractClass = ClassifyRefract( pParticleUnit->GetDefaultWaterContainsResult(), pSubset->bounds );

#ifdef _DEBUG
		if( MIX_TESTBIT( debDrawFlags, Mix::Scene::DDF_PARTICLE_MESH ) == Mix::Scene::DDF_PARTICLE_MESH )
		{
			// ローカルライティング用のオブジェクトをリストに追加
			if( NeedsWidgetObject( pParticleUnit->CanLocalLighting(), pSubset->minZ, loEnd ) == True )
			{
				Mix::Scene::Common::WIDGET_OBJECT* pWGObj = m_WidgetObjectList.Add();

				pWGObj->minZ = pSubset->minZ;
				pWGObj->maxZ = pSubset->maxZ;
				pWGObj->bounds = pSubset->bounds;
				pWGObj->subsetStart = m_WidgetSubsetList.GetCount();
				pWGObj->subsetNum = 1;
			}

			// サブセットをリストに追加
			m_WidgetSubsetList.Add( pSubset );
		}
#else //_DEBUG
		// ローカルライティング用のオブジェクトをリストに追加
		if( NeedsWidgetObject( pParticleUnit->CanLocalLighting(), pSubset->minZ, loEnd ) == True )
		{
			Mix::Scene::Common::WIDGET_OBJECT* pWGObj = m_WidgetObjectList.Add();

			pWGObj->minZ = pSubset->minZ;
			pWGObj->maxZ = pSubset->maxZ;
			pWGObj->bounds = pSubset->bounds;
			pWGObj->subsetStart = m_WidgetSubsetList.GetCount();
			pWGObj->subsetNum = 1;
		}

		// サブセットをリストに追加
		m_WidgetSubsetList.Add( pSubset );
#endif //_DEBUG

		//デバッグ : 視界に入っているスキャッターパーティクルユニットの数
		SCENE_DEB( m_DebScatterParticleUnitList.Add( pParticleUnit ) );
		SCENE_DEB( m_pDebCProfWidget->sp.vCount++ );

		ppSPUObj++;
	}

	//デバッグ : 計測終了
	SCENE_DEB( m_pDebCProfWidget->sp.vElapsedTime += m_DebTimer.GetF32() );
}

void Renderer::FinishWidget_Everyone( void )
{
	UInt32 localLightID;
	UInt32 localLightCount;

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// ソート
	////////////////////////////////////////////////////////////////////////////////////////////////////

	if( m_WidgetObjectList.GetCount() > 1 )
	{
		SCENE_DEB( m_DebTimer.Reset() );
		Renderer::SortWidgetObjects_MinZ( m_WidgetObjectList.GetBeginPtr(), 0, m_WidgetObjectList.GetCount() - 1 );
		SCENE_DEB( m_pDebCProfWidget->slElapsedTime += m_DebTimer.GetF32() );
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// ローカルライティング
	////////////////////////////////////////////////////////////////////////////////////////////////////

	if( m_WidgetObjectList.IsEmpty() == False )
	{
		SCENE_DEB( m_DebTimer.Reset() );
		AssignLocalLight( m_WidgetObjectList.GetCount(), m_WidgetObjectList.GetBeginPtr(), localLightID, localLightCount );
		SCENE_DEB( m_pDebCProfWidget->alElapsedTime += m_DebTimer.GetF32() );

		// デバッグ : ラィティング境界
#ifdef _DEBUG
		{
			Mix::Scene::Common::WIDGET_OBJECT** ppDebObj = m_WidgetObjectList.GetBeginPtr();
			Mix::Scene::Common::WIDGET_OBJECT** ppDebObjEnd = m_WidgetObjectList.GetEndPtr();
			Mix::Scene::Common::WIDGET_OBJECT* pDebObj;

			Mix::Geometry::AABB debAabb(	Mix::Vector3( +MIX_FLOAT_MAX, +MIX_FLOAT_MAX, +MIX_FLOAT_MAX ),
											Mix::Vector3( -MIX_FLOAT_MAX, -MIX_FLOAT_MAX, -MIX_FLOAT_MAX ) );

			while( ppDebObj != ppDebObjEnd )
			{
				pDebObj = *ppDebObj;

				const Mix::Geometry::AABB debBounds = pDebObj->bounds;

				debAabb.min = Mix::Vector3::Min( debAabb.min, debBounds.min );
				debAabb.max = Mix::Vector3::Max( debAabb.max, debBounds.max );

				ppDebObj++;
			}

			SCENE_DEB( m_DebWidgetBoundsList.Add( debAabb.ComputePoints() ) );
		}
#endif //_DEBUG
	}
	else
	{
		localLightID = 0xFFFFFFFF;
		localLightCount = 0;
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 半透明オブジェクトの生成
	////////////////////////////////////////////////////////////////////////////////////////////////////

	FinishWidget_GenerateTransparencyObjects( localLightID, localLightCount );
}

void Renderer::FinishWidget_Detailed( void )
{
	////////////////////////////////////////////////////////////////////////////////////////////////////
	// ローカルライティング
	////////////////////////////////////////////////////////////////////////////////////////////////////

	if( m_WidgetObjectList.IsEmpty() == False )
	{
		Mix::Scene::Common::WIDGET_OBJECT** ppObj = m_WidgetObjectList.GetBeginPtr();
		Mix::Scene::Common::WIDGET_OBJECT** ppObjEnd = m_WidgetObjectList.GetEndPtr();
		Mix::Scene::Common::WIDGET_OBJECT* pObj;

		Mix::Scene::Common::WIDGET_SUBSET** subsets = m_WidgetSubsetList.GetBeginPtr();
		Mix::Scene::Common::WIDGET_SUBSET** ppSubset;
		Mix::Scene::Common::WIDGET_SUBSET** ppSubsetEnd;
		Mix::Scene::Common::WIDGET_SUBSET* pSubset;

		UInt32 localLightID;
		UInt32 localLightCount;

		// デバッグ : 計測開始
		SCENE_DEB( m_DebTimer.Reset() );

		while( ppObj != ppObjEnd )
		{
			pObj = *ppObj;

			ppSubset = subsets + pObj->subsetStart;
			ppSubsetEnd = ppSubset + pObj->subsetNum;

			AssignLocalLight( pObj->bounds, pObj->minZ, pObj->maxZ, localLightID, localLightCount );

			while( ppSubset != ppSubsetEnd )
			{
				pSubset = *ppSubset;

				pSubset->localLightID = localLightID;
				pSubset->localLightCount = localLightCount;

				ppSubset++;
			}

			// デバッグ : ラィティング境界
			SCENE_DEB( if( localLightID != 0xFFFFFFFF ) { m_DebWidgetBoundsList.Add( pObj->bounds.ComputePoints() ); } );

			ppObj++;
		}

		// デバッグ : 計測終了
		SCENE_DEB( m_pDebCProfWidget->alElapsedTime += m_DebTimer.GetF32() );
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 半透明オブジェクトの生成
	////////////////////////////////////////////////////////////////////////////////////////////////////

	FinishWidget_GenerateTransparencyObjects();
}

void Renderer::FinishWidget_GenerateTransparencyObjects( void )
{
	MIX_ASSERT( m_pCamera != NULL );

	const Mix::Geometry::Plane& nearPlane = m_pCamera->GetFrustum().GetPlane( Mix::Geometry::Frustum::PLANE_NEAR );
	const Mix::Vector3& npN = nearPlane.normal;
	const Float32& npD = nearPlane.d;

	Mix::Scene::Common::WIDGET_SUBSET** ppSubset = m_WidgetSubsetList.GetBeginPtr();
	Mix::Scene::Common::WIDGET_SUBSET** ppSubsetEnd = m_WidgetSubsetList.GetEndPtr();
	Mix::Scene::Common::WIDGET_SUBSET* pSubset;

	UInt32 worldMatID = AssignWorldMatrix( Mix::Matrix4x4::Identity() );

	Mix::Scene::IMaterial* pMaterial;
	UInt32 refractClass;
	Float32 minZ;
	Float32 maxZ;
	UInt32 priority;

	// デバッグ : 計測開始
	SCENE_DEB( m_DebTimer.Reset() );

	while( ppSubset != ppSubsetEnd )
	{
		pSubset = ( *ppSubset );

		pMaterial = pSubset->pMaterial;
		refractClass = pSubset->refractClass;
		minZ = pSubset->minZ;
		maxZ = pSubset->maxZ;
		priority = pSubset->priority;

		if( pMaterial->GetTransparencyMethod() == Mix::Scene::IMaterial::TM_LUMP )
		{
			// サブセット単位で描画 ( 一括 )
			Renderer::TRANSPARENCY_OBJECT* pObj = m_TransparencyObjList.Add();

			pObj->type = Renderer::TO_WIDGET;
			pObj->refractClass = refractClass;
			pObj->minZ = minZ;
			pObj->maxZ = maxZ;
			pObj->priority = priority;
			pObj->z = ( minZ + maxZ ) * 0.5f;
			pObj->worldMatID = worldMatID;
			pObj->worldMatNum = 1;
			pObj->localLightID = pSubset->localLightID;
			pObj->localLightNum = pSubset->localLightCount;
			pObj->trType = IMaterial::TR_SIMPLE;
			pObj->prType = Mix::Graphics::PRIMITIVE_TRIANGLELIST;
			pObj->pMaterial = pMaterial;
			pObj->quadNum = pSubset->quadCount;
			pObj->quads = pSubset->quads;

			SCENE_DEB( m_pDebCProfWidget->objCount += 1 );
		}
		else
		{
			// クワッド単位で描画 ( 分割 )
			UInt32 localLightID = pSubset->localLightID;
			UInt32 localLightCount = pSubset->localLightCount;

			UInt32 quadCount = pSubset->quadCount;
			Mix::Scene::Common::WIDGET_QUAD** ppQuad = &( pSubset->quads[0] );
			Mix::Scene::Common::WIDGET_QUAD** ppQuadEnd = ppQuad + quadCount;

			Renderer::TRANSPARENCY_OBJECT** ppObj = m_TransparencyObjList.Add( quadCount );
			Renderer::TRANSPARENCY_OBJECT* pObj;

			while( ppQuad != ppQuadEnd )
			{
				const Mix::Vector3& pos = ( *ppQuad )->pos;

				pObj = *ppObj;

				pObj->type = Renderer::TO_WIDGET;
				pObj->refractClass = refractClass;
				pObj->minZ = minZ;
				pObj->maxZ = maxZ;
				pObj->priority = priority;
				pObj->z = ( npN.x * pos.x ) + ( npN.y * pos.y ) + ( npN.z * pos.z ) + npD;
				pObj->worldMatID = worldMatID;
				pObj->worldMatNum = 1;
				pObj->localLightID = localLightID;
				pObj->localLightNum = localLightCount;
				pObj->trType = IMaterial::TR_SIMPLE;
				pObj->prType = Mix::Graphics::PRIMITIVE_TRIANGLELIST;
				pObj->pMaterial = pMaterial;
				pObj->quadNum = 1;
				pObj->quads = ppQuad;

				ppQuad++;
				ppObj++;
			}

			SCENE_DEB( m_pDebCProfWidget->objCount += quadCount );
		}

		m_WidgetQuadCount += pSubset->quadCount;

		ppSubset++;
	}

	// デバッグ : 計測終了
	SCENE_DEB( m_pDebCProfWidget->goElapsedTime += m_DebTimer.GetF32() );
}

void Renderer::FinishWidget_GenerateTransparencyObjects( UInt32 localLightID, UInt32 localLightCount )
{
	if( m_WidgetSubsetList.IsEmpty() == True )
	{
		return;
	}

	MIX_ASSERT( m_pCamera != NULL );

	const Mix::Geometry::Plane& nearPlane = m_pCamera->GetFrustum().GetPlane( Mix::Geometry::Frustum::PLANE_NEAR );
	const Mix::Vector3& npN = nearPlane.normal;
	const Float32& npD = nearPlane.d;

	Mix::Scene::Common::WIDGET_SUBSET** ppSubset = m_WidgetSubsetList.GetBeginPtr();
	Mix::Scene::Common::WIDGET_SUBSET** ppSubsetEnd = m_WidgetSubsetList.GetEndPtr();
	Mix::Scene::Common::WIDGET_SUBSET* pSubset;

	UInt32 worldMatID = AssignWorldMatrix( Mix::Matrix4x4::Identity() );

	Mix::Scene::IMaterial* pMaterial;
	UInt32 refractClass;
	Float32 minZ;
	Float32 maxZ;
	UInt32 priority;

	// デバッグ : 計測開始
	SCENE_DEB( m_DebTimer.Reset() );

	while( ppSubset != ppSubsetEnd )
	{
		pSubset = ( *ppSubset );

		pMaterial = pSubset->pMaterial;
		refractClass = pSubset->refractClass;
		minZ = pSubset->minZ;
		maxZ = pSubset->maxZ;
		priority = pSubset->priority;

		if( pMaterial->GetTransparencyMethod() == Mix::Scene::IMaterial::TM_LUMP )
		{
			// サブセット単位で描画 ( 一括 )
			Renderer::TRANSPARENCY_OBJECT* pObj = m_TransparencyObjList.Add();

			pObj->type = Renderer::TO_WIDGET;
			pObj->refractClass = refractClass;
			pObj->minZ = minZ;
			pObj->maxZ = maxZ;
			pObj->priority = priority;
			pObj->z = ( minZ + maxZ ) * 0.5f;
			pObj->worldMatID = worldMatID;
			pObj->worldMatNum = 1;
			pObj->localLightID = localLightID;
			pObj->localLightNum = localLightCount;
			pObj->trType = IMaterial::TR_SIMPLE;
			pObj->prType = Mix::Graphics::PRIMITIVE_TRIANGLELIST;
			pObj->pMaterial = pMaterial;
			pObj->quadNum = pSubset->quadCount;
			pObj->quads = pSubset->quads;

			SCENE_DEB( m_pDebCProfWidget->objCount += 1 );
		}
		else
		{
			// クワッド単位で描画 ( 分割 )
			UInt32 quadCount = pSubset->quadCount;
			Mix::Scene::Common::WIDGET_QUAD** ppQuad = &( pSubset->quads[0] );
			Mix::Scene::Common::WIDGET_QUAD** ppQuadEnd = ppQuad + quadCount;

			Renderer::TRANSPARENCY_OBJECT** ppObj = m_TransparencyObjList.Add( quadCount );
			Renderer::TRANSPARENCY_OBJECT* pObj;

			while( ppQuad != ppQuadEnd )
			{
				const Mix::Vector3& pos = ( *ppQuad )->pos;

				pObj = *ppObj;

				pObj->type = Renderer::TO_WIDGET;
				pObj->refractClass = refractClass;
				pObj->minZ = minZ;
				pObj->maxZ = maxZ;
				pObj->priority = priority;
				pObj->z = ( npN.x * pos.x ) + ( npN.y * pos.y ) + ( npN.z * pos.z ) + npD;
				pObj->worldMatID = worldMatID;
				pObj->worldMatNum = 1;
				pObj->localLightID = localLightID;
				pObj->localLightNum = localLightCount;
				pObj->trType = IMaterial::TR_SIMPLE;
				pObj->prType = Mix::Graphics::PRIMITIVE_TRIANGLELIST;
				pObj->pMaterial = pMaterial;
				pObj->quadNum = 1;
				pObj->quads = ppQuad;

				ppQuad++;
				ppObj++;
			}

			SCENE_DEB( m_pDebCProfWidget->objCount += quadCount );
		}

		m_WidgetQuadCount += pSubset->quadCount;

		ppSubset++;
	}

	// デバッグ : 計測終了
	SCENE_DEB( m_pDebCProfWidget->goElapsedTime += m_DebTimer.GetF32() );
}

Boolean Renderer::NeedsWidgetObject( Boolean bLightingObject, Float32 objZ, Float32 lightingZ )
{
	if( ( m_WidgetLightingMode == IRenderer::WL_DEFAULT ) ||
		( bLightingObject == False ) ||
		( lightingZ < objZ ) )
	{
		return False;
	}

	return True;
}

void Renderer::SortWidgetObjects_MinZ( Mix::Scene::Common::WIDGET_OBJECT** list, Int32 first, Int32 last )
{
	const Mix::Scene::Common::WIDGET_OBJECT* pObj  = list[( first + last ) >> 1];

	Float32 minZ = pObj->minZ;

	Int32 i = first;
	Int32 j = last;

	do
	{
		while( list[i]->minZ < minZ ) { i++; }
		while( list[j]->minZ > minZ ) { j--; }

		if( i <= j )
		{
			MIX_ASSERT( ( i <= last ) && ( j >= first ) );

			Mix::Scene::Common::WIDGET_OBJECT* pTemp = list[i];

			list[i] = list[j];
			list[j] = pTemp;

			i++;
			j--;
		}

	}while( i <= j );

	if( first < j ) { Renderer::SortWidgetObjects_MinZ( list, first, j ); }
	if( i < last ) { Renderer::SortWidgetObjects_MinZ( list, i, last ); }
}

void Renderer::CollectDrawCommand_ActorModel( void )
{
	MIX_ASSERT( m_pOctree != NULL );
	MIX_ASSERT( m_pCamera != NULL );

	const Mix::ContainerT<Mix::Scene::Common::ActorModelObject*, Mix::Memory::SECTION_SCENE>& list = m_pOctree->GetValidActorModelObjects();

	if( list.GetCount() == 0 )
	{
		return;
	}

	Mix::Scene::Common::ActorModelObject* const* ppObj = list.GetConstBeginPtr();
	Mix::Scene::Common::ActorModelObject* const* ppObjEnd = list.GetConstEndPtr();

	const Mix::Vector3& eyePos = m_pCamera->GetEye();
	const Mix::Geometry::Frustum& frustum = m_pCamera->GetFrustum();
	const Mix::Geometry::Plane& nearPlane = frustum.GetPlane( Mix::Geometry::Frustum::PLANE_NEAR );

	const Mix::Scene::ICamera::VISIBILITY_SETTINGS& visiSettings = m_pCamera->GetVisiblitySettings();
	Float32 objEnd = visiSettings.amLimitDistance;

	SCENE_DEB( UInt32 debDrawFlags = m_pCamera->Debug_GetDrawFlags() );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 視界判定を行いながら収集
	////////////////////////////////////////////////////////////////////////////////////////////////////

	//デバッグ : 計測開始
	SCENE_DEB( m_DebTimer.Reset() );

	while( ppObj != ppObjEnd )
	{
		Mix::Scene::Common::ActorModelObject* pObj = *ppObj;
		Mix::Scene::Common::ActorModel* pModel = pObj->GetContentPtr();

		if( pModel->IsDraw() == False )
		{
			//描画しない
			pObj->Invalid( Mix::Scene::Common::OCTREE_VIEW_COLOR );
			ppObj++;
			continue;
		}

		const Mix::Geometry::Sphere& objBounds = pModel->GetBounds();
		Float32 objRadius = objBounds.radius;
		Float32 objZ = Mix::Vector3::Dot( nearPlane.normal, objBounds.center ) + nearPlane.d;
		Float32 objFrontZ = objZ - objRadius;
		Float32 objBackZ = objZ + objRadius;

		if( ( 0.0f > objBackZ ) || ( objEnd < objFrontZ ) )
		{
			//有効範囲外
			pObj->Invalid( Mix::Scene::Common::OCTREE_VIEW_COLOR );
			ppObj++;
			continue;
		}

#ifdef _DEBUG
		if( MIX_TESTBIT( debDrawFlags, Mix::Scene::DDF_ACTORMODEL_MESH ) == Mix::Scene::DDF_ACTORMODEL_MESH )
		{
			if( AddDrawCommand( frustum, nearPlane, pModel ) == True )
			{
				pModel->InternalRefresh( eyePos );

				//デバッグ : 視界に入っている
				SCENE_DEB( m_DebActorModelList.Add( pModel ) );
				SCENE_DEB( m_pDebCProfActorModel->vCount++ );
			}
			else
			{
				//有効範囲外
				pObj->Invalid( Mix::Scene::Common::OCTREE_VIEW_COLOR );
			}
		}
		else
		{
			if( frustum.ContainsTBLR( pModel->GetBounds() ) == True )
			{
				pModel->InternalRefresh( eyePos );

				//デバッグ : 視界に入っている
				SCENE_DEB( m_DebActorModelList.Add( pModel ) );
				SCENE_DEB( m_pDebCProfActorModel->vCount++ );
			}
			else
			{
				//有効範囲外
				pObj->Invalid( Mix::Scene::Common::OCTREE_VIEW_COLOR );
			}
		}
#else //_DEBUG
		if( AddDrawCommand( frustum, nearPlane, pModel ) == True )
		{
			pModel->InternalRefresh( eyePos );
		}
		else
		{
			pObj->Invalid( Mix::Scene::Common::OCTREE_VIEW_COLOR );
		}
#endif //_DEBUG

		ppObj++;
	}

	//デバッグ : 計測終了
	SCENE_DEB( m_pDebCProfActorModel->vcElapsedTime += m_DebTimer.GetF32() );
}

Boolean Renderer::AddDrawCommand(	const Mix::Geometry::Frustum& frustum,
									const Mix::Geometry::Plane& nearPlane,
									Mix::Scene::Common::ActorModel* pModel )
{
	MIX_ASSERT( pModel != NULL );

	const Mix::Scene::Common::ActorModel::MeshList& meshList = pModel->GetMeshList();

	size_t meshNum = meshList.size();
	if( meshNum == 0 )
	{
		return False;
	}

	Mix::Scene::Common::ActorMesh* const* ppMesh = &( meshList[0] );
	Mix::Scene::Common::ActorMesh* const* ppMeshEnd = ppMesh + meshList.size();
	Boolean bLocalLighting = pModel->IsLocalLighting();
	UInt32 trPriority = pModel->GetTransparencyPriority();
	Mix::Scene::WATER_CONTAINS_RESULT defWCR = pModel->GetDefaultWaterContainsResult();
	UInt32 meshCount = 0;

	while( ppMesh != ppMeshEnd )
	{
		const Mix::Scene::Common::ActorMesh* pMesh = *ppMesh;

		if( pMesh->IsDraw() == False )
		{
			//描画はしない
			ppMesh++;
			continue;
		}

		const Mix::Geometry::Sphere& bounds = pMesh->GetBounds();

		//Near Far のチェックは事前に行われているので Top Bottom Left Right だけ行う
		if( frustum.ContainsTBLR( bounds ) == False )
		{
			//有効範囲外
			ppMesh++;
			continue;
		}

		UInt32 boneCount = pMesh->GetBoneCount();

		const Mix::Scene::Common::ActorMesh::WorldMatrixList& worldMatList = pMesh->GetWorldMatrixList();

		const Mix::Scene::Common::ActorMesh::DrawTable& drawTable = pMesh->GetDrawTable();
		MIX_ASSERT( drawTable.size() > 0 );

		const Mix::Scene::Common::ActorMesh::DRAW* pDraw = &( drawTable[0] );
		const Mix::Scene::Common::ActorMesh::DRAW* pDrawEnd = pDraw + drawTable.size();

		Mix::Scene::IMaterial::TRANSFORM_TYPE trType = ( boneCount == 0 )? IMaterial::TR_SIMPLE : IMaterial::TR_SKINNING;

		Mix::Graphics::IVertexBuffer* pVertexBuffer = pMesh->GetVertexBufferPtr();
		Mix::Graphics::IIndexBuffer* pIndexBuffer = pMesh->GetIndexBufferPtr();

		UInt32 worldMatID = AssignWorldMatrix( worldMatList );
		UInt32 localLightID = 0xFFFFFFFF;
		UInt32 localLightCount = 0;
		Mix::Scene::Common::RENDERER_REFRACT_CLASS refractClass = Mix::Scene::Common::RRC_UNKNOWN;

		Mix::Scene::IMaterial* pMaterial;

		UInt32 mtlLocalLightID;
		UInt32 mtlLocalLightCount;

		while( pDraw != pDrawEnd )
		{
			pMaterial = pModel->GetMaterialPtr( pDraw->materialSlotIndex );

			// ローカルライトの割当 //

			if( ( bLocalLighting == True ) && ( pMaterial->IsLighting() == True ) )
			{
				if( localLightID == 0xFFFFFFFF )
				{
					// 新規に割り当てる
					AssignLocalLight( nearPlane, bounds, localLightID, localLightCount );
				}

				mtlLocalLightID = localLightID;
				mtlLocalLightCount = localLightCount;
			}
			else
			{
				mtlLocalLightID = 0xFFFFFFFF;
				mtlLocalLightCount = 0;
			}

			// コマンドの追加 //

			if( pMaterial->IsRefractive() == True )
			{
				MIX_ASSERT( pDraw->opSubsets.size() > 0 );

				const Mix::Scene::Common::ActorMesh::OPACITY_SUBSET* pSubset = &( pDraw->opSubsets[0] );
				const Mix::Scene::Common::ActorMesh::OPACITY_SUBSET* pSubsetEnd = pSubset + pDraw->opSubsets.size();

				while( pSubset != pSubsetEnd )
				{
					Renderer::DRAW_COMMAND* pRCom = m_RefractMaskComList.Add();
					Renderer::OPACITY_COMMAND* pOCom = m_RefractComList.Add();

					pRCom->worldMatID = worldMatID + pSubset->boneOffset;
					pRCom->worldMatCount = pSubset->boneCount;
					pRCom->primitiveType = Mix::Graphics::PRIMITIVE_TRIANGLELIST;
					pRCom->vertexStart = pSubset->vertexStart;
					pRCom->vertexCount = pSubset->vertexCount;
					pRCom->indexStart = pSubset->indexStart;
					pRCom->indexCount = pSubset->indexCount;
					pRCom->pMaterial = pMaterial;
					pRCom->trType = trType;
					pRCom->pVertexBuffer = pVertexBuffer;
					pRCom->pIndexBuffer = pIndexBuffer;

					pOCom->sortKey = 0;
					pOCom->worldMatID = worldMatID + pSubset->boneOffset;
					pOCom->worldMatCount = pSubset->boneCount;
					pOCom->localLightID = mtlLocalLightID;
					pOCom->localLightCount = mtlLocalLightCount;
					pOCom->primitiveType = Mix::Graphics::PRIMITIVE_TRIANGLELIST;
					pOCom->vertexStart = pSubset->vertexStart;
					pOCom->vertexCount = pSubset->vertexCount;
					pOCom->indexStart = pSubset->indexStart;
					pOCom->indexCount = pSubset->indexCount;
					pOCom->pMaterial = pMaterial;
					pOCom->trType = trType;
					pOCom->pVertexBuffer = pVertexBuffer;
					pOCom->pIndexBuffer = pIndexBuffer;

					pSubset++;
				}
			}
			else if( pMaterial->IsTransparency() == False )
			{
				MIX_ASSERT( pDraw->opSubsets.size() > 0 );

				const Mix::Scene::Common::ActorMesh::OPACITY_SUBSET* pSubset = &( pDraw->opSubsets[0] );
				const Mix::Scene::Common::ActorMesh::OPACITY_SUBSET* pSubsetEnd = pSubset + pDraw->opSubsets.size();

				UInt64 sortKey = reinterpret_cast<UInt64>( pMaterial );

				while( pSubset != pSubsetEnd )
				{
					Renderer::OPACITY_COMMAND* pCom = m_OpacityComList.Add();

					pCom->sortKey = sortKey;
					pCom->worldMatID = worldMatID + pSubset->boneOffset;
					pCom->worldMatCount = pSubset->boneCount;
					pCom->localLightID = mtlLocalLightID;
					pCom->localLightCount = mtlLocalLightCount;
					pCom->primitiveType = Mix::Graphics::PRIMITIVE_TRIANGLELIST;
					pCom->vertexStart = pSubset->vertexStart;
					pCom->vertexCount = pSubset->vertexCount;
					pCom->indexStart = pSubset->indexStart;
					pCom->indexCount = pSubset->indexCount;
					pCom->pMaterial = pMaterial;
					pCom->trType = trType;
					pCom->pVertexBuffer = pVertexBuffer;
					pCom->pIndexBuffer = pIndexBuffer;

					pSubset++;
				}
			}
			else
			{
				MIX_ASSERT( pDraw->trSubsets[pMaterial->GetTransparencyMethod()].size() > 0 );

				const Mix::Scene::Common::ActorMesh::TransparencySubsetList& subsetList = pDraw->trSubsets[pMaterial->GetTransparencyMethod()];
				const Mix::Scene::Common::ActorMesh::TRANSPARENCY_SUBSET* pSubset = &( subsetList[0] );
				const Mix::Scene::Common::ActorMesh::TRANSPARENCY_SUBSET* pSubsetEnd = pSubset + subsetList.size();

				Float32 sortKeyZ;

				if( refractClass == Mix::Scene::Common::RRC_UNKNOWN )
				{
					//水面に対するメッシュの位置関係を取得
					refractClass = ClassifyRefract( defWCR, bounds );
				}

				if( boneCount == 0 )
				{
					const Mix::Matrix4x4& worldMat = worldMatList[0];
					
					while( pSubset != pSubsetEnd )
					{
						Renderer::TRANSPARENCY_OBJECT* pTrObj = m_TransparencyObjList.Add();

						sortKeyZ = Mix::Vector3::Dot( nearPlane.normal, worldMat * pSubset->sortKey ) + nearPlane.d;

						pTrObj->type = Renderer::TO_MODEL;
						pTrObj->refractClass = refractClass;
						pTrObj->minZ = sortKeyZ;
						pTrObj->maxZ = sortKeyZ;
						pTrObj->priority = trPriority;
						pTrObj->z = sortKeyZ;
						pTrObj->worldMatID = worldMatID + pSubset->boneOffset;
						pTrObj->worldMatNum = pSubset->boneCount;
						pTrObj->localLightID = mtlLocalLightID;
						pTrObj->localLightNum = mtlLocalLightCount;
						pTrObj->trType = trType;
						pTrObj->prType = Mix::Graphics::PRIMITIVE_TRIANGLELIST;
						pTrObj->pMaterial = pMaterial;
						pTrObj->vertexStart = pSubset->vertexStart;
						pTrObj->vertexNum = pSubset->vertexCount;
						pTrObj->indexStart = pSubset->indexStart;
						pTrObj->indexNum = pSubset->indexCount;
						pTrObj->pVertexBuffer = pVertexBuffer;
						pTrObj->pIndexBuffer = pIndexBuffer;

						pSubset++;
					}
				}
				else
				{
					while( pSubset != pSubsetEnd )
					{
						const Mix::Matrix4x4& worldMat = worldMatList[pSubset->boneOffset + pSubset->affectBoneIndex];
						Renderer::TRANSPARENCY_OBJECT* pTrObj = m_TransparencyObjList.Add();
						
						sortKeyZ = Mix::Vector3::Dot( nearPlane.normal, worldMat * pSubset->sortKey ) + nearPlane.d;

						pTrObj->type = Renderer::TO_MODEL;
						pTrObj->refractClass = refractClass;
						pTrObj->minZ = sortKeyZ;
						pTrObj->maxZ = sortKeyZ;
						pTrObj->priority = 0;
						pTrObj->z = sortKeyZ;
						pTrObj->worldMatID = worldMatID + pSubset->boneOffset;
						pTrObj->worldMatNum = pSubset->boneCount;
						pTrObj->localLightID = mtlLocalLightID;
						pTrObj->localLightNum = mtlLocalLightCount;
						pTrObj->trType = trType;
						pTrObj->prType = Mix::Graphics::PRIMITIVE_TRIANGLELIST;
						pTrObj->pMaterial = pMaterial;
						pTrObj->vertexStart = pSubset->vertexStart;
						pTrObj->vertexNum = pSubset->vertexCount;
						pTrObj->indexStart = pSubset->indexStart;
						pTrObj->indexNum = pSubset->indexCount;
						pTrObj->pVertexBuffer = pVertexBuffer;
						pTrObj->pIndexBuffer = pIndexBuffer;

						pSubset++;
					}
				}
			}

			pDraw++;
			meshCount++;
		}

		ppMesh++;

		//デバッグ : プリミティブ数
		SCENE_DEB( m_pDebCProfGeneral->drawPrimCount += Renderer::Debug_CountPrimitive( Mix::Graphics::PRIMITIVE_TRIANGLELIST, pIndexBuffer->GetCount() ) );
	}

	return ( meshCount > 0 );
}

void Renderer::CollectDrawCommand_TerrainModel( void )
{
	if( m_TerrainModelList.size() == 0 )
	{
		return;
	}

	MIX_ASSERT( m_pCamera != NULL );

	const Mix::Geometry::Frustum& frustum = m_pCamera->GetFrustum();
	const Mix::Geometry::Plane& nearPlane = frustum.GetPlane( Mix::Geometry::Frustum::PLANE_NEAR );

	Mix::Scene::Common::TerrainModel** ppModel = &( m_TerrainModelList[0] );
	Mix::Scene::Common::TerrainModel** ppModelEnd = ppModel + m_TerrainModelList.size();

	SCENE_DEB( UInt32 debDrawFlags = m_pCamera->Debug_GetDrawFlags() );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 収集
	////////////////////////////////////////////////////////////////////////////////////////////////////

	//デバッグ : 計測開始
	SCENE_DEB( m_DebTimer.Reset() );

	while( ppModel != ppModelEnd )
	{
		Mix::Scene::Common::TerrainModel* pModel = *ppModel;

		if( pModel->IsDraw() == False )
		{
			//描画しない
			ppModel++;
			continue;
		}

		Mix::Scene::Common::TerrainNode* pModelNode = pModel->GetRootNodePtr();
		UInt32 meshCount = 0;

#ifdef _DEBUG

		if( MIX_TESTBIT( debDrawFlags, Mix::Scene::DDF_TERRAINMODEL_MESH ) == Mix::Scene::DDF_TERRAINMODEL_MESH )
		{
			UInt32 worldMatID = ReserveWorldMatrix();

			if( AddDrawCommand( frustum, nearPlane, worldMatID, pModel, pModelNode, meshCount ) == True )
			{
				AssignWorldMatrix( pModel->GetWorldMatrix(), worldMatID );

				//デバッグ : 視界に入っているカウント
				SCENE_DEB( m_pDebCProfTerrainModel->vCount++ );
			}
		}
		else
		{
			if( ( m_pDebPerspectiveRenderer != NULL ) &&
				( Debug_CollectTerrainBounds( frustum, pModel, pModelNode, meshCount ) == True ) )
			{
				//デバッグ : 視界に入っているカウント
				SCENE_DEB( m_pDebCProfTerrainModel->vCount++ );
			}
		}

#else //_DEBUG

		UInt32 worldMatID = ReserveWorldMatrix();

		if( AddDrawCommand( frustum, nearPlane, worldMatID, pModel, pModelNode, meshCount ) == True )
		{
			AssignWorldMatrix( pModel->GetWorldMatrix(), worldMatID );
		}

#endif //_DEBUG

		ppModel++;
	}

	//デバッグ : 計測終了
	SCENE_DEB( m_pDebCProfTerrainModel->vcElapsedTime += m_DebTimer.GetF32() );
}

Boolean Renderer::AddDrawCommand(	const Mix::Geometry::Frustum& frustum,
									const Mix::Geometry::Plane& nearPlane,
									UInt32 worldMatID,
									Mix::Scene::Common::TerrainModel* pModel,
									Mix::Scene::Common::TerrainNode* pNode,
									UInt32& meshCount )
{
	MIX_ASSERT( pModel != NULL );
	MIX_ASSERT( pNode != NULL );

	const Mix::Geometry::AABB& bounds = pNode->GetBounds();

	UIntT childCount = pNode->GetChildCount();
	UIntT i;

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// カメラ内に入っているかチェック
	////////////////////////////////////////////////////////////////////////////////////////////////////

	if( frustum.Contains( bounds ) == False )
	{
		return False;
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// メッシュを所持している場合はコマンドを追加
	////////////////////////////////////////////////////////////////////////////////////////////////////

	Mix::Scene::Common::TerrainMesh* pMesh = pNode->GetMeshPtr();

	if( pMesh != NULL )
	{
		const Mix::Scene::Common::TerrainMesh::DrawTable& drawTable = pMesh->GetDrawTable();

		MIX_ASSERT( drawTable.size() > 0 );

		const Mix::Scene::Common::TerrainMesh::DRAW* pDraw = &( drawTable[0] );
		const Mix::Scene::Common::TerrainMesh::DRAW* pDrawEnd = pDraw + drawTable.size();

		Mix::Graphics::IVertexBuffer* pVertexBuffer = pMesh->GetVertexBufferPtr();
		Mix::Graphics::IIndexBuffer* pIndexBuffer = pMesh->GetIndexBufferPtr();

		Boolean bLocalLighting = pModel->IsLocalLighting();
		UInt32 trPriority = pModel->GetTransparencyPriority();
		UInt32 localLightID = 0xFFFFFFFF;
		UInt32 localLightCount = 0;

		Mix::Scene::IMaterial* pMaterial;

		UInt32 mtlLocalLightID;
		UInt32 mtlLocalLightCount;

		//コマンドを追加
		while( pDraw != pDrawEnd )
		{
			pMaterial = pModel->GetMaterialPtr( pDraw->materialSlotIndex );

			// ローカルライトの割当 //

			if( ( bLocalLighting == True ) && ( pMaterial->IsLighting() == True ) )
			{
				if( localLightID == 0xFFFFFFFF )
				{
					// 新規に割り当てる
					AssignLocalLight( nearPlane, bounds, localLightID, localLightCount );
				}

				mtlLocalLightID = localLightID;
				mtlLocalLightCount = localLightCount;
			}
			else
			{
				mtlLocalLightID = 0xFFFFFFFF;
				mtlLocalLightCount = 0;
			}

			// コマンドの追加 //

			if( pMaterial->IsRefractive() == True )
			{
				MIX_ASSERT( pDraw->opSubsets.size() > 0 );

				const Mix::Scene::Common::TerrainMesh::OPACITY_SUBSET* pSubset = &( pDraw->opSubsets[0] );
				const Mix::Scene::Common::TerrainMesh::OPACITY_SUBSET* pSubsetEnd = pSubset + pDraw->opSubsets.size();

				while( pSubset != pSubsetEnd )
				{
					Renderer::DRAW_COMMAND* pRCom = m_RefractMaskComList.Add();
					Renderer::OPACITY_COMMAND* pOCom = m_RefractComList.Add();

					pRCom->worldMatID = worldMatID;
					pRCom->worldMatCount = 0;
					pRCom->primitiveType = Mix::Graphics::PRIMITIVE_TRIANGLELIST;
					pRCom->vertexStart = pSubset->vertexStart;
					pRCom->vertexCount = pSubset->vertexCount;
					pRCom->indexStart = pSubset->indexStart;
					pRCom->indexCount = pSubset->indexCount;
					pRCom->pMaterial = pMaterial;
					pRCom->trType = IMaterial::TR_SIMPLE;
					pRCom->pVertexBuffer = pVertexBuffer;
					pRCom->pIndexBuffer = pIndexBuffer;

					pOCom->sortKey = 0;
					pOCom->worldMatID = worldMatID;
					pOCom->worldMatCount = 0;
					pOCom->localLightID = mtlLocalLightID;
					pOCom->localLightCount = mtlLocalLightCount;
					pOCom->primitiveType = Mix::Graphics::PRIMITIVE_TRIANGLELIST;
					pOCom->vertexStart = pSubset->vertexStart;
					pOCom->vertexCount = pSubset->vertexCount;
					pOCom->indexStart = pSubset->indexStart;
					pOCom->indexCount = pSubset->indexCount;
					pOCom->pMaterial = pMaterial;
					pOCom->trType = IMaterial::TR_SIMPLE;
					pOCom->pVertexBuffer = pVertexBuffer;
					pOCom->pIndexBuffer = pIndexBuffer;

					pSubset++;
				}
			}
			else if( pMaterial->IsTransparency() == False )
			{
				MIX_ASSERT( pDraw->opSubsets.size() > 0 );

				const Mix::Scene::Common::TerrainMesh::OPACITY_SUBSET* pSubset = &( pDraw->opSubsets[0] );
				const Mix::Scene::Common::TerrainMesh::OPACITY_SUBSET* pSubsetEnd = pSubset + pDraw->opSubsets.size();

				UInt64 sortKey = reinterpret_cast<UInt64>( pMaterial );

				while( pSubset != pSubsetEnd )
				{
					Renderer::OPACITY_COMMAND* pCom = m_OpacityComList.Add();

					pCom->sortKey = sortKey;
					pCom->worldMatID = worldMatID;
					pCom->worldMatCount = 0;
					pCom->localLightID = mtlLocalLightID;
					pCom->localLightCount = mtlLocalLightCount;
					pCom->primitiveType = Mix::Graphics::PRIMITIVE_TRIANGLELIST;
					pCom->vertexStart = pSubset->vertexStart;
					pCom->vertexCount = pSubset->vertexCount;
					pCom->indexStart = pSubset->indexStart;
					pCom->indexCount = pSubset->indexCount;
					pCom->pMaterial = pMaterial;
					pCom->trType = IMaterial::TR_SIMPLE;
					pCom->pVertexBuffer = pVertexBuffer;
					pCom->pIndexBuffer = pIndexBuffer;

					pSubset++;
				}
			}
			else
			{
				MIX_ASSERT( pDraw->trSubsets[pMaterial->GetTransparencyMethod()].size() > 0 );

				const Mix::Scene::Common::TerrainMesh::TransparencySubsetList& subsetList = pDraw->trSubsets[pMaterial->GetTransparencyMethod()];
				const Mix::Scene::Common::TerrainMesh::TRANSPARENCY_SUBSET* pSubset = &( subsetList[0] );
				const Mix::Scene::Common::TerrainMesh::TRANSPARENCY_SUBSET* pSubsetEnd = pSubset + subsetList.size();

				const Mix::Matrix4x4& worldMat = pModel->GetWorldMatrix();

				while( pSubset != pSubsetEnd )
				{
					Renderer::TRANSPARENCY_OBJECT* pTrObj = m_TransparencyObjList.Add();
					Float32 sortKeyZ = Mix::Vector3::Dot( nearPlane.normal, worldMat * pSubset->sortKey ) + nearPlane.d;

					pTrObj->type = Renderer::TO_MODEL;
					pTrObj->refractClass = Mix::Scene::Common::RRC_FRONT;
					pTrObj->minZ = sortKeyZ;
					pTrObj->maxZ = sortKeyZ;
					pTrObj->priority = trPriority;
					pTrObj->z = sortKeyZ;
					pTrObj->worldMatID = worldMatID;
					pTrObj->worldMatNum = 1;
					pTrObj->localLightID = mtlLocalLightID;
					pTrObj->localLightNum = mtlLocalLightCount;
					pTrObj->trType = IMaterial::TR_SIMPLE;
					pTrObj->prType = Mix::Graphics::PRIMITIVE_TRIANGLELIST;
					pTrObj->pMaterial = pMaterial;
					pTrObj->vertexStart = pSubset->vertexStart;
					pTrObj->vertexNum = pSubset->vertexCount;
					pTrObj->indexStart = pSubset->indexStart;
					pTrObj->indexNum = pSubset->indexCount;
					pTrObj->pVertexBuffer = pVertexBuffer;
					pTrObj->pIndexBuffer = pIndexBuffer;

					pSubset++;
				}
			}

			pDraw++;
		}

		meshCount++;

		//デバッグ : プリミティブ数
		SCENE_DEB( m_pDebCProfGeneral->drawPrimCount += Renderer::Debug_CountPrimitive( Mix::Graphics::PRIMITIVE_TRIANGLELIST, pIndexBuffer->GetCount() ) );

		//デバッグ : 境界の描画( 行列と色は事前に設定してあります )
		SCENE_DEB( m_DebTerrainBoundsList.Add( bounds ) );
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 子を処理
	////////////////////////////////////////////////////////////////////////////////////////////////////

	for( i = 0; i < childCount; i++ )
	{
		AddDrawCommand( frustum, nearPlane, worldMatID, pModel, pNode->GetChildPtr( i ), meshCount );
	}

	return ( meshCount > 0 );
}

void Renderer::CollectDrawCommand_FinishTransparency( void )
{
	MIX_ASSERT( m_TransparencyObjList.GetCount() >= 2 );
	MIX_ASSERT( m_TransparencyComList.GetCount() == 0 );

	Renderer::TRANSPARENCY_OBJECT* const* ppObj = m_TransparencyObjList.GetConstBeginPtr();
	const Renderer::TRANSPARENCY_OBJECT* pObj = NULL;

	Renderer::TRANSPARENCY_COMMAND** ppCom = m_TransparencyComList.Add( m_TransparencyObjList.GetCount() );
	Renderer::TRANSPARENCY_COMMAND* pCom = NULL;
	UInt32 comCount = 0;

	Boolean wgValid = ( m_pWidgetBuffer != NULL ) && ( m_WidgetQuadCount > 0 );
	UInt32 wgVertexStart = 0;
	UInt8* wgBuff = NULL;

	MIX_ASSERT( ppObj != NULL );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// ウィジェット : バッファをロック
	////////////////////////////////////////////////////////////////////////////////////////////////////

	if( wgValid == True )
	{
		if( m_pWidgetBuffer->Lock() == False )
		{
			return;
		}

		wgBuff = reinterpret_cast<UInt8*>( m_pWidgetBuffer->Push( Mix::Scene::Common::WIDGET_QUAD_POINT_NUM * m_WidgetQuadCount ) );
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// コマンドリストの作成
	////////////////////////////////////////////////////////////////////////////////////////////////////

	while( ( *ppObj )->type != Renderer::TO_TERM )
	{
		UInt32 wgCurRefractClass = 0xFFFFFFFF;
		UInt32 wgCurPriority = 0xFFFFFFFF;
		UInt32 wgCurLocalLightID = 0xFFFFFFFF;
		Mix::Scene::IMaterial* wgCurMaterial = NULL;

		////////////////////////////////////////////////////////////////////////////////////////////////////
		// ウィジェット
		//   バーテックスバッファの作成
		//   コマンドの追加
		////////////////////////////////////////////////////////////////////////////////////////////////////

		while( ( *ppObj )->type == Renderer::TO_WIDGET )
		{
			pObj = ( *ppObj );

			Mix::Scene::Common::WIDGET_QUAD* const* ppQuad = pObj->quads;
			Mix::Scene::Common::WIDGET_QUAD* const* ppQuadEnd = ppQuad + pObj->quadNum;

			if( ( wgCurRefractClass != pObj->refractClass ) ||
				( wgCurPriority != pObj->priority ) ||
				( wgCurLocalLightID != pObj->localLightID ) ||
				( wgCurMaterial != pObj->pMaterial ) )
			{
				const UInt32& wgLocalLightID = pObj->localLightID;
				Mix::Scene::IMaterial* wgMaterial = pObj->pMaterial;

				pCom = *ppCom;

				pCom->refractClass = pObj->refractClass;
				pCom->worldMatID = pObj->worldMatID;
				pCom->worldMatCount = 1;
				pCom->localLightID = wgLocalLightID;
				pCom->localLightCount = pObj->localLightNum;
				pCom->vertexStart = wgVertexStart;
				pCom->vertexCount = 0;
				pCom->indexStart = 0;
				pCom->indexCount = 0;
				pCom->trType = IMaterial::TR_SIMPLE;
				pCom->primitiveType = Mix::Graphics::PRIMITIVE_TRIANGLELIST;
				pCom->pMaterial = wgMaterial;
				pCom->pVertexBuffer = m_pWidgetBuffer;
				pCom->pIndexBuffer = NULL;

				wgCurRefractClass = pObj->refractClass;
				wgCurPriority = pObj->priority;
				wgCurLocalLightID = wgLocalLightID;
				wgCurMaterial = wgMaterial;

				ppCom++;
				comCount++;

				// デバッグ : 生成したコマンド数
				SCENE_DEB( m_pDebCProfWidget->comCount++ );
			}

			while( ppQuad != ppQuadEnd )
			{
				const Mix::Scene::Common::WIDGET_QUAD* pQuad = *ppQuad;

				const Mix::Vector3* point = pQuad->points;
				const UInt8* data = pQuad->data;
				const UInt32& dataSize = pQuad->dataSize;
				const UInt32& twOffset = pQuad->texWriteOffset;
				const Mix::Vector2* tex = pQuad->texCoords;

				UInt8* wgWrite;

				//座標
				wgWrite = wgBuff;
				memcpy_s( wgWrite, Mix::Scene::Common::WIDGET_POS_SIZE, &point[0], Mix::Scene::Common::WIDGET_POS_SIZE ); wgWrite += Mix::Scene::Common::WIDGET_VERTEX_STRIDE;
				memcpy_s( wgWrite, Mix::Scene::Common::WIDGET_POS_SIZE, &point[1], Mix::Scene::Common::WIDGET_POS_SIZE ); wgWrite += Mix::Scene::Common::WIDGET_VERTEX_STRIDE;
				memcpy_s( wgWrite, Mix::Scene::Common::WIDGET_POS_SIZE, &point[3], Mix::Scene::Common::WIDGET_POS_SIZE ); wgWrite += Mix::Scene::Common::WIDGET_VERTEX_STRIDE;
				memcpy_s( wgWrite, Mix::Scene::Common::WIDGET_POS_SIZE, &point[1], Mix::Scene::Common::WIDGET_POS_SIZE ); wgWrite += Mix::Scene::Common::WIDGET_VERTEX_STRIDE;
				memcpy_s( wgWrite, Mix::Scene::Common::WIDGET_POS_SIZE, &point[2], Mix::Scene::Common::WIDGET_POS_SIZE ); wgWrite += Mix::Scene::Common::WIDGET_VERTEX_STRIDE;
				memcpy_s( wgWrite, Mix::Scene::Common::WIDGET_POS_SIZE, &point[3], Mix::Scene::Common::WIDGET_POS_SIZE );

				//カラー、法線
				wgWrite = wgBuff + Mix::Scene::Common::WIDGET_DATA_OFFSET;
				memcpy_s( wgWrite, dataSize, data, dataSize ); wgWrite += Mix::Scene::Common::WIDGET_VERTEX_STRIDE;
				memcpy_s( wgWrite, dataSize, data, dataSize ); wgWrite += Mix::Scene::Common::WIDGET_VERTEX_STRIDE;
				memcpy_s( wgWrite, dataSize, data, dataSize ); wgWrite += Mix::Scene::Common::WIDGET_VERTEX_STRIDE;
				memcpy_s( wgWrite, dataSize, data, dataSize ); wgWrite += Mix::Scene::Common::WIDGET_VERTEX_STRIDE;
				memcpy_s( wgWrite, dataSize, data, dataSize ); wgWrite += Mix::Scene::Common::WIDGET_VERTEX_STRIDE;
				memcpy_s( wgWrite, dataSize, data, dataSize );

				//テクスチャ座標
				wgWrite = wgBuff + twOffset;
				memcpy_s( wgWrite, Mix::Scene::Common::WIDGET_TEXTURE_SIZE, &tex[0], Mix::Scene::Common::WIDGET_TEXTURE_SIZE ); wgWrite += Mix::Scene::Common::WIDGET_VERTEX_STRIDE;
				memcpy_s( wgWrite, Mix::Scene::Common::WIDGET_TEXTURE_SIZE, &tex[1], Mix::Scene::Common::WIDGET_TEXTURE_SIZE ); wgWrite += Mix::Scene::Common::WIDGET_VERTEX_STRIDE;
				memcpy_s( wgWrite, Mix::Scene::Common::WIDGET_TEXTURE_SIZE, &tex[3], Mix::Scene::Common::WIDGET_TEXTURE_SIZE ); wgWrite += Mix::Scene::Common::WIDGET_VERTEX_STRIDE;
				memcpy_s( wgWrite, Mix::Scene::Common::WIDGET_TEXTURE_SIZE, &tex[1], Mix::Scene::Common::WIDGET_TEXTURE_SIZE ); wgWrite += Mix::Scene::Common::WIDGET_VERTEX_STRIDE;
				memcpy_s( wgWrite, Mix::Scene::Common::WIDGET_TEXTURE_SIZE, &tex[2], Mix::Scene::Common::WIDGET_TEXTURE_SIZE ); wgWrite += Mix::Scene::Common::WIDGET_VERTEX_STRIDE;
				memcpy_s( wgWrite, Mix::Scene::Common::WIDGET_TEXTURE_SIZE, &tex[3], Mix::Scene::Common::WIDGET_TEXTURE_SIZE );

				wgBuff += Mix::Scene::Common::WIDGET_QUAD_STRIDE;

				ppQuad++;
			}

			pCom->vertexCount += pObj->quadNum * Mix::Scene::Common::WIDGET_QUAD_POINT_NUM;
			wgVertexStart = pCom->vertexStart + pCom->vertexCount;

			ppObj++;
		}

		////////////////////////////////////////////////////////////////////////////////////////////////////
		// モデル ( アクター、テライン )
		//   コマンドの追加
		////////////////////////////////////////////////////////////////////////////////////////////////////

		while( ( *ppObj )->type == Renderer::TO_MODEL )
		{
			pObj = ( *ppObj );
			pCom = ( *ppCom );

			pCom->refractClass = pObj->refractClass;
			pCom->worldMatID = pObj->worldMatID;
			pCom->worldMatCount = pObj->worldMatNum;
			pCom->localLightID = pObj->localLightID;
			pCom->localLightCount = pObj->localLightNum;
			pCom->vertexStart = pObj->vertexStart;
			pCom->vertexCount = pObj->vertexNum;
			pCom->indexStart = pObj->indexStart;
			pCom->indexCount = pObj->indexNum;
			pCom->trType = pObj->trType;
			pCom->primitiveType = pObj->prType;
			pCom->pMaterial = pObj->pMaterial;
			pCom->pVertexBuffer = pObj->pVertexBuffer;
			pCom->pIndexBuffer = pObj->pIndexBuffer;

			ppObj++;

			ppCom++;
			comCount++;
		}
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// コマンドリストの不要な部分を切り捨てる
	////////////////////////////////////////////////////////////////////////////////////////////////////

	MIX_ASSERT( comCount > 0 );

	m_TransparencyComList.Reduction( comCount );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// ウィジェット : バッファをアンロック
	////////////////////////////////////////////////////////////////////////////////////////////////////

	if( wgValid == True )
	{
		m_pWidgetBuffer->Unlock();
	}
}

UInt32 Renderer::ReserveWorldMatrix( void )
{
	return m_WorldMatrixList.GetCount();
}

UInt32 Renderer::AssignWorldMatrix( const Mix::Matrix4x4& mat )
{
	UInt32 id = m_WorldMatrixList.GetCount();

	m_WorldMatrixList.Add( mat.ToTranspose() );

	return id;
}

void Renderer::AssignWorldMatrix( const Mix::Matrix4x4& mat, UInt32 id )
{
	MIX_ASSERT( m_WorldMatrixList.GetCount() == id );

	m_WorldMatrixList.Add( mat.ToTranspose() );
}

UInt32 Renderer::AssignWorldMatrix( const Mix::STL::Vector<Mix::Memory::SECTION_SCENE, Mix::Matrix4x4>& matList )
{
	MIX_ASSERT( matList.size() > 0 );

	size_t matCount = matList.size();
	UInt32 id = m_WorldMatrixList.GetCount();

	const Mix::Matrix4x4* pMat = &( matList[0] );
	const Mix::Matrix4x4* pMatEnd = pMat + matCount;

	while( pMat != pMatEnd )
	{
		m_WorldMatrixList.Add( pMat->ToTranspose() );
		pMat++;
	}

	return id;
}

void Renderer::AssignLocalLight( const Mix::Geometry::Plane& nearPlane, const Mix::Geometry::Sphere& bounds, UInt32& id, UInt32& count )
{
	Renderer::ASSIGN_LOCAL_LIGHT_CONTEXT ctx;

	Mix::Scene::Common::LOCAL_LIGHT* const* ppLocalLight;
	Mix::Scene::Common::LOCAL_LIGHT* const* ppLocalLightEnd;
	Mix::Scene::Common::LOCAL_LIGHT* pLocalLight;

	Float32 objZ;
	Float32 objFrontZ;

	Float32 dist;

	//////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// 開始
	//////////////////////////////////////////////////////////////////////////////////////////////////////////////

	if( AssignLocalLight_Begin( ctx, id, count ) == False )
	{
		return;
	}

	//////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// 判定
	//////////////////////////////////////////////////////////////////////////////////////////////////////////////

	ppLocalLight = m_VisibleLocalLightList.GetConstBeginPtr();
	ppLocalLightEnd = m_VisibleLocalLightList.GetConstEndPtr();

	objZ = Mix::Vector3::Dot( nearPlane.normal, bounds.center ) + nearPlane.d;
	objFrontZ = objZ - bounds.radius;

	while( ppLocalLight != ppLocalLightEnd )
	{
		pLocalLight = *ppLocalLight;

		if( pLocalLight->maxZ < objFrontZ )
		{
			break;
		}

		if( Mix::Geometry::IntersectSphereSphere( pLocalLight->bounds, bounds, &dist ) == True )
		{
			pLocalLight->offsetZ = pLocalLight->z - objZ;
			pLocalLight->effect = pLocalLight->bounds.radius + bounds.radius - dist;

			m_LocalLightList.Add( pLocalLight );
		}

		ppLocalLight++;
	}

	//////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// 終了
	//////////////////////////////////////////////////////////////////////////////////////////////////////////////

	AssignLocalLight_End( ctx );
}

void Renderer::AssignLocalLight( const Mix::Geometry::Plane& nearPlane, const Mix::Geometry::AABB& bounds, UInt32& id, UInt32& count )
{
	Renderer::ASSIGN_LOCAL_LIGHT_CONTEXT ctx;

	Mix::Scene::Common::LOCAL_LIGHT* const* ppLocalLight;
	Mix::Scene::Common::LOCAL_LIGHT* const* ppLocalLightEnd;
	Mix::Scene::Common::LOCAL_LIGHT* pLocalLight;

	Float32 objRadius;
	Float32 objZ;
	Float32 objFrontZ;

	//////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// 開始
	//////////////////////////////////////////////////////////////////////////////////////////////////////////////

	if( AssignLocalLight_Begin( ctx, id, count ) == False )
	{
		return;
	}

	//////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// 判定
	//////////////////////////////////////////////////////////////////////////////////////////////////////////////

	ppLocalLight = m_VisibleLocalLightList.GetConstBeginPtr();
	ppLocalLightEnd = m_VisibleLocalLightList.GetConstEndPtr();

	objRadius = ( bounds.max - bounds.center ).GetLengthF();
	objZ = Mix::Vector3::Dot( nearPlane.normal, bounds.center ) + nearPlane.d;
	objFrontZ = objZ - objRadius;

	while( ppLocalLight != ppLocalLightEnd )
	{
		pLocalLight = *ppLocalLight;

		if( pLocalLight->maxZ < objFrontZ )
		{
			break;
		}

		if( Mix::Geometry::IntersectSphereAABB( pLocalLight->bounds, bounds ) == True )
		{
			pLocalLight->offsetZ = 0.0f;
			pLocalLight->effect = 0.0f;

			m_LocalLightList.Add( pLocalLight );
		}

		ppLocalLight++;
	}

	//////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// 終了
	//////////////////////////////////////////////////////////////////////////////////////////////////////////////

	AssignLocalLight_End( ctx );
}

void Renderer::AssignLocalLight( const Mix::Geometry::AABB& bounds, Float32 minZ, Float32 maxZ, UInt32& id, UInt32& count )
{
	Renderer::ASSIGN_LOCAL_LIGHT_CONTEXT ctx;

	Mix::Scene::Common::LOCAL_LIGHT* const* ppLocalLight;
	Mix::Scene::Common::LOCAL_LIGHT* const* ppLocalLightEnd;
	Mix::Scene::Common::LOCAL_LIGHT* pLocalLight;

	//////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// 開始
	//////////////////////////////////////////////////////////////////////////////////////////////////////////////

	if( AssignLocalLight_Begin( ctx, id, count ) == False )
	{
		return;
	}

	//////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// 判定
	//////////////////////////////////////////////////////////////////////////////////////////////////////////////

	ppLocalLight = m_VisibleLocalLightList.GetConstBeginPtr();
	ppLocalLightEnd = m_VisibleLocalLightList.GetConstEndPtr();

	while( ppLocalLight != ppLocalLightEnd )
	{
		pLocalLight = *ppLocalLight;

		if( pLocalLight->maxZ < minZ )
		{
			break;
		}

		if( ( pLocalLight->minZ < maxZ ) &&
			( Mix::Geometry::IntersectSphereAABB( pLocalLight->bounds, bounds ) == True ) )
		{
			pLocalLight->offsetZ = 0.0f;
			pLocalLight->effect = 0.0f;

			m_LocalLightList.Add( pLocalLight );
		}

		ppLocalLight++;
	}

	//////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// 終了
	//////////////////////////////////////////////////////////////////////////////////////////////////////////////

	AssignLocalLight_End( ctx );
}

void Renderer::AssignLocalLight( UInt32 objNum, Mix::Scene::Common::WIDGET_OBJECT** objs, UInt32& id, UInt32& count )
{
	MIX_ASSERT( objNum > 0 );
	MIX_ASSERT( objs != NULL );

	Renderer::ASSIGN_LOCAL_LIGHT_CONTEXT ctx;

	Mix::Scene::Common::LOCAL_LIGHT* const* ppLocalLight;
	Mix::Scene::Common::LOCAL_LIGHT* const* ppLocalLightEnd;
	Mix::Scene::Common::LOCAL_LIGHT* pLocalLight;
	Float32 llMaxZ;
	Float32 llMinZ;

	Mix::Scene::Common::WIDGET_OBJECT** ppObjBegin;
	Mix::Scene::Common::WIDGET_OBJECT** ppObjEnd;
	Mix::Scene::Common::WIDGET_OBJECT** ppObj;
	Mix::Scene::Common::WIDGET_OBJECT* pObj;

	//////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// 開始
	//////////////////////////////////////////////////////////////////////////////////////////////////////////////

	if( AssignLocalLight_Begin( ctx, id, count ) == False )
	{
		return;
	}

	//////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// 判定
	//////////////////////////////////////////////////////////////////////////////////////////////////////////////

	ppLocalLight = m_VisibleLocalLightList.GetConstBeginPtr();
	ppLocalLightEnd = m_VisibleLocalLightList.GetConstEndPtr();

	ppObjBegin = &( objs[0] );
	ppObjEnd = ppObjBegin + objNum;

	while( ppLocalLight != ppLocalLightEnd )
	{
		ppObj = ppObjBegin;

		pLocalLight = *ppLocalLight;

		llMaxZ = pLocalLight->maxZ;
		llMinZ = pLocalLight->minZ;

		const Mix::Geometry::AABB& llBounds = pLocalLight->bounds;

		while( ppObj != ppObjEnd )
		{
			pObj = *ppObj;

			if( llMaxZ < pObj->minZ )
			{
				break;
			}

			if( ( llMinZ < pObj->maxZ ) &&
				( Mix::Geometry::IntersectSphereAABB( llBounds, pObj->bounds ) == True ) )
			{
				pLocalLight->offsetZ = 0.0f;
				pLocalLight->effect = 0.0f;

				m_LocalLightList.Add( pLocalLight );

				break;
			}

			ppObj++;
		}

		ppLocalLight++;
	}

	//////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// 終了
	//////////////////////////////////////////////////////////////////////////////////////////////////////////////

	AssignLocalLight_End( ctx );
}

Boolean Renderer::AssignLocalLight_Begin( Renderer::ASSIGN_LOCAL_LIGHT_CONTEXT& ctx, UInt32& id, UInt32& count )
{
	if( m_VisibleLocalLightList.IsEmpty() == True )
	{
		id = 0xFFFFFFFF;
		count = 0;
		return False;
	}

	ctx.preCount = m_LocalLightList.GetCount();
	ctx.id = &id;
	ctx.count = &count;

	return True;
}

void Renderer::AssignLocalLight_End( Renderer::ASSIGN_LOCAL_LIGHT_CONTEXT& ctx )
{
	MIX_ASSERT( ctx.id != NULL );
	MIX_ASSERT( ctx.count != NULL );

	const UInt32& preCount = ctx.preCount;
	UInt32 curCount = m_LocalLightList.GetCount();
	UInt32 count = curCount - preCount;

	if( count > 0 )
	{
		if( count > Renderer::LOCAL_LIGHT_MAX )
		{
			//ソート
			Renderer::AssignLocalLight_Sort( m_LocalLightList.GetBeginPtr(), preCount, preCount + count - 1 );

			//切り詰める
			m_LocalLightList.Reduction( curCount - ( count - Renderer::LOCAL_LIGHT_MAX ) );
			count = Renderer::LOCAL_LIGHT_MAX;
		}

		*( ctx.id ) = preCount;
		*( ctx.count ) = count;
	}
	else
	{
		*( ctx.id ) = 0xFFFFFFFF;
		*( ctx.count ) = 0;
	}
}

void Renderer::AssignLocalLight_Sort( const Mix::Scene::Common::LOCAL_LIGHT** list, Int32 first, Int32 last )
{
	const Mix::Scene::Common::LOCAL_LIGHT* pLL  = list[( first + last ) >> 1];

	Float32 offsetZ = pLL->offsetZ;
	Float32 effect = pLL->effect;

	Int32 i = first;
	Int32 j = last;

	do
	{
		while( ( list[i]->offsetZ < offsetZ ) || ( list[i]->effect > effect ) ) { i++; }
		while( ( list[j]->offsetZ > offsetZ ) || ( list[j]->effect < effect ) ) { j--; }

		if( i <= j )
		{
			MIX_ASSERT( ( i <= last ) && ( j >= first ) );

			const Mix::Scene::Common::LOCAL_LIGHT* pTemp = list[i];

			list[i] = list[j];
			list[j] = pTemp;

			i++;
			j--;
		}

	}while( i <= j );

	if( first < j ) { Renderer::AssignLocalLight_Sort( list, first, j ); }
	if( i < last ) { Renderer::AssignLocalLight_Sort( list, i, last ); }
}

Mix::Scene::Common::RENDERER_REFRACT_CLASS Renderer::ClassifyRefract( Mix::Scene::WATER_CONTAINS_RESULT wcr, const Mix::Geometry::Sphere& bounds ) const
{
	if( wcr != Mix::Scene::WCR_UNKNOWN )
	{
		return m_RefractClassTable[wcr];
	}

	if( m_VisibleWaterPoolList.IsEmpty() == True )
	{
		return Mix::Scene::Common::RRC_FRONT;
	}

	Renderer::WATER_POOL* pWP = m_VisibleWaterPoolList.GetBeginPtr();
	Renderer::WATER_POOL* pWPEnd = m_VisibleWaterPoolList.GetEndPtr();

	Mix::Scene::Common::RENDERER_REFRACT_CLASS rc;

#ifdef _DEBUG
	UInt32 debWCR;
#endif //_DEBUG

	while( pWP != pWPEnd )
	{
		if( Mix::Geometry::IntersectSphereAABB( bounds, *( pWP->pBounds ) ) == True )
		{
#ifdef _DEBUG
			debWCR = pWP->pContext->Contains( bounds );
			MIX_ASSERT( debWCR < Mix::Scene::WCR_MAX );
			rc = m_RefractClassTable[debWCR];
#else //_DEBUG
			rc = m_RefractClassTable[pWP->pContext->Contains( bounds )];
#endif //_DEBUG

			if( rc != Mix::Scene::Common::RRC_FRONT )
			{
				return rc;
			}
		}

		pWP++;
	}

	return m_RefractClassTable[Mix::Scene::WCR_FRONT];
}

Mix::Scene::Common::RENDERER_REFRACT_CLASS Renderer::ClassifyRefract( Mix::Scene::WATER_CONTAINS_RESULT wcr, const Mix::Geometry::AABB& bounds ) const
{
	if( wcr != Mix::Scene::WCR_UNKNOWN )
	{
		return m_RefractClassTable[wcr];
	}

	if( m_VisibleWaterPoolList.IsEmpty() == True )
	{
		return Mix::Scene::Common::RRC_FRONT;
	}

	Renderer::WATER_POOL* pWP = m_VisibleWaterPoolList.GetBeginPtr();
	Renderer::WATER_POOL* pWPEnd = m_VisibleWaterPoolList.GetEndPtr();

	Mix::Scene::Common::RENDERER_REFRACT_CLASS rc;

#ifdef _DEBUG
	UInt32 debWCR;
#endif //_DEBUG

	while( pWP != pWPEnd )
	{
		if( Mix::Geometry::IntersectAABBAABB( *( pWP->pBounds ), bounds ) == True )
		{
#ifdef _DEBUG
			debWCR = pWP->pContext->Contains( bounds );
			MIX_ASSERT( debWCR < Mix::Scene::WCR_MAX );
			rc = m_RefractClassTable[debWCR];
#else //_DEBUG
			rc = m_RefractClassTable[pWP->pContext->Contains( bounds )];
#endif //_DEBUG

			if( rc != Mix::Scene::Common::RRC_FRONT )
			{
				return rc;
			}
		}

		pWP++;
	}

	return m_RefractClassTable[Mix::Scene::WCR_FRONT];
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Mix::Scene::Standard::Common::Renderer : コマンドの処理
////////////////////////////////////////////////////////////////////////////////////////////////////

void Renderer::ProcessCommand( void )
{
	MIX_ASSERT( m_pCamera != NULL );

	Float32 invFarZ = MIX_FLOAT_RECIPROCAL( m_pCamera->GetFarZ() );

#ifdef _DEBUG
	Mix::Graphics::FILL_TYPE fillType = m_pCamera->Debug_GetFillType();
#else //_DEBUG
	Mix::Graphics::FILL_TYPE fillType = Mix::Graphics::FILL_SOLID;
#endif //_DEBUG

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 準備
	////////////////////////////////////////////////////////////////////////////////////////////////////

	//シャドウコマンド
	if( m_ShadowComList.GetCount() > 1 )
	{
		//デバッグ : 計測開始
		SCENE_DEB( m_DebTimer.Reset() );

		SortShadowCommand( m_ShadowComList.GetBeginPtr(), 0, m_ShadowComList.GetCount() - 1 );

		//デバッグ : 計測終了
		SCENE_DEB( m_pDebCProfProjShadow->preElapsedTime += m_DebTimer.GetF32() );
	}

	//不透明コマンド
	if( m_OpacityComList.GetCount() > 1 )
	{
		//デバッグ : 計測開始
		SCENE_DEB( m_DebTimer.Reset() );

		Renderer::SortOpacityCommand( m_OpacityComList.GetBeginPtr(), 0, m_OpacityComList.GetCount() - 1 );

		//デバッグ : 計測終了
		SCENE_DEB( m_pDebCProfDrawOpacity->preElapsedTime += m_DebTimer.GetF32() );
	}

	//半透明コマンド
	if( m_TransparencyComList.GetCount() > 0 )
	{
		//デバッグ : 計測開始
		SCENE_DEB( m_DebTimer.Reset() );

		if( m_RefractComList.IsEmpty() == True )
		{
			m_TransparencyFrontComList.Add( m_TransparencyComList.GetConstBeginPtr(), m_TransparencyComList.GetCount() );
		}
		else
		{
			Renderer::TRANSPARENCY_COMMAND** ppCom = m_TransparencyComList.GetBeginPtr();
			Renderer::TRANSPARENCY_COMMAND** ppComEnd = m_TransparencyComList.GetEndPtr();

			while( ppCom != ppComEnd )
			{
				Renderer::TRANSPARENCY_COMMAND* pCom = *ppCom;

				switch( pCom->refractClass )
				{
				case Mix::Scene::Common::RRC_OVERLAP:
					m_TransparencyFrontComList.Add( pCom );
					SCENE_DEB( m_pDebCProfDrawTransp->ovComCount++ );

				case Mix::Scene::Common::RRC_BACK:
					m_TransparencyBackComList.Add( pCom );
					break;

				case Mix::Scene::Common::RRC_FRONT:
					m_TransparencyFrontComList.Add( pCom );
					break;
				}

				ppCom++;
			}
		}

		//デバッグ : 計測終了
		SCENE_DEB( m_pDebCProfDrawTransp->dcElapsedTime += m_DebTimer.GetF32() );
	}

	SCENE_DEB( m_pDebCProfProjShadow->comCount += m_ShadowComList.GetCount() );
	SCENE_DEB( m_pDebCProfProjShadow->comCapacity = m_ShadowComList.GetCapacity() );
	SCENE_DEB( m_pDebCProfDrawOpacity->comCount += m_OpacityComList.GetCount() );
	SCENE_DEB( m_pDebCProfDrawOpacity->comCapacity = m_OpacityComList.GetCapacity() );
	SCENE_DEB( m_pDebCProfDrawRefract->comCount += m_RefractComList.GetCount() );
	SCENE_DEB( m_pDebCProfDrawRefract->comCapacity = m_RefractComList.GetCapacity() );
	SCENE_DEB( m_pDebCProfDrawTransp->comCount += m_TransparencyComList.GetCount() );
	SCENE_DEB( m_pDebCProfDrawTransp->comCapacity = m_TransparencyComList.GetCapacity() );
	SCENE_DEB( m_pDebCProfDrawTransp->bkComCount += m_TransparencyBackComList.GetCount() );
	SCENE_DEB( m_pDebCProfDrawTransp->bkComCapacity = m_TransparencyBackComList.GetCapacity() );
	SCENE_DEB( m_pDebCProfDrawTransp->frComCount += m_TransparencyFrontComList.GetCount() );
	SCENE_DEB( m_pDebCProfDrawTransp->frComCapacity = m_TransparencyFrontComList.GetCapacity() );

	Command_PrepareRendering( invFarZ );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// シャドウマッピング : ディレクショナルライトから見た深度を書き出す
	////////////////////////////////////////////////////////////////////////////////////////////////////

	if( m_pSdwDepthTex != NULL )
	{
		m_pGraphicsDev->SetTarget( m_pSdwDepthTex, NULL, NULL, NULL, m_pSdwDepthBuff );
		m_pGraphicsDev->SetViewBounds( m_SdwViewport );
		m_pGraphicsDev->SetScissorBounds( m_SdwViewport );

		m_pGraphicsDev->Clear( True, False, Mix::Vector4( 1.0f, 1.0f, 1.0f, 0.0f ) );

		if( m_ShadowComList.GetCount() > 0 )
		{
			//デバッグ : 計測開始
			SCENE_DEB( m_DebTimer.Reset() );

			Renderer::SHADOW_COMMAND* const* ppCom = m_ShadowComList.GetConstBeginPtr();
			Renderer::SHADOW_COMMAND* const* ppComEnd = m_ShadowComList.GetConstEndPtr();
			const Renderer::SHADOW_COMMAND* pCom;

			//クリア
			m_pGraphicsDev->Clear( False, True );

			//デバイスステートを設定
			m_pGraphicsDev->SetRasterizerState( Mix::Graphics::FILL_SOLID, Mix::Graphics::CULL_FRONT, False );
			m_pGraphicsDev->SetDepthState( True, True );
			m_pGraphicsDev->SetBlendState( Mix::Graphics::BLEND_COPY );

			//リセット
			Command_Reset();

			//コマンドを処理
			while( ppCom != ppComEnd )
			{
				pCom = *ppCom;

				//マテリアル
				Command_ChangeMaterial_Shadow( pCom );

				//トランスフォーム
				Command_Transform( pCom );

				//描画
				Command_DrawPrimitives( pCom );

				ppCom++;
			}

			//デバッグ : 計測終了
			SCENE_DEB( m_pDebCProfProjShadow->drawElapsedTime += m_DebTimer.GetF32() );
		}
	}

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

	m_pGraphicsDev->SetViewBounds( m_Viewport );
	m_pGraphicsDev->SetScissorBounds( m_Viewport );

	m_pGraphicsDev->SetTarget( m_pDataTex, NULL, NULL, NULL, NULL );
	m_pGraphicsDev->Clear( True, False, Mix::Vector4( 0.0f, 0.0f, 0.0f, 0.0f ) );

	m_pGraphicsDev->SetTarget( m_pDepthTexChain->GetCurrentPtr(), m_pDepthTexChain->GetNextPtr(), m_pSdwMapTex, NULL, NULL );
	m_pGraphicsDev->Clear( True, False, Mix::Vector4( 1.0f, 1.0f, 1.0f, 1.0f ) );

	m_pGraphicsDev->SetTarget( m_pColorTexChain->GetCurrentPtr(), NULL, NULL, NULL, m_pDepthBuff );
	m_pGraphicsDev->Clear( True, True, m_BackgroundColor );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// デバッグ
	////////////////////////////////////////////////////////////////////////////////////////////////////

#ifdef _DEBUG

	if( m_pCamera->Debug_GetDrawMethod() == Mix::Scene::DDM_BEFORE )
	{
		m_pGraphicsDev->SetTarget( m_pColorTexChain->GetCurrentPtr(), NULL, NULL, NULL, m_pDepthBuff );
		m_pGraphicsDev->SetViewBounds( m_Viewport );

		m_pGraphicsDev->SetBlendState( Mix::Graphics::BLEND_NORMAL );
		m_pGraphicsDev->SetDepthState( True, True );
		m_pGraphicsDev->SetRasterizerState( Mix::Graphics::FILL_SOLID, Mix::Graphics::CULL_BACK, False );

		Debug_Draw3D();
	}

#endif //_DEBUG

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 不透明
	////////////////////////////////////////////////////////////////////////////////////////////////////

	if( m_OpacityComList.GetCount() > 0 )
	{
		//デバッグ : 計測開始
		SCENE_DEB( m_DebTimer.Reset() );

		Renderer::OPACITY_COMMAND** ppCom = m_OpacityComList.GetBeginPtr();
		Renderer::OPACITY_COMMAND** ppComEnd = m_OpacityComList.GetEndPtr();

		//ターゲットを設定
		m_pGraphicsDev->SetTarget( m_pColorTexChain->GetCurrentPtr(), m_pDepthTexChain->GetNextPtr(), m_pDataTex, m_pSdwMapTex, m_pDepthBuff );
		m_pGraphicsDev->SetViewBounds( m_Viewport );
		m_pGraphicsDev->SetScissorBounds( m_Viewport );

		//ステートを設定
		m_pGraphicsDev->SetBlendState( Mix::Graphics::BLEND_COPY );
		m_pGraphicsDev->SetDepthState( True, True );
		m_pGraphicsDev->SetRasterizerState( fillType, Mix::Graphics::CULL_BACK, False );

		//テクスチャを設定
		m_pGraphicsDev->SetTexture( Renderer::TS_DEPTH, Mix::Graphics::TEXTURE_FILTER_POINT, Mix::Graphics::TEXTURE_ADDRESS_CLAMP, m_pDepthTexChain->GetCurrentPtr() );
		m_pGraphicsDev->SetTexture( Renderer::TS_SHADOW, Mix::Graphics::TEXTURE_FILTER_POINT, Mix::Graphics::TEXTURE_ADDRESS_CLAMP, m_pSdwDepthTex );
		m_pGraphicsDev->SetTexture( Renderer::TS_REFRACT, Mix::Graphics::TEXTURE_FILTER_POINT, Mix::Graphics::TEXTURE_ADDRESS_CLAMP, NULL );
		m_pGraphicsDev->SetTexture( Renderer::TS_REFLECT, Mix::Graphics::TEXTURE_FILTER_POINT, Mix::Graphics::TEXTURE_ADDRESS_CLAMP, m_pEnvTex );

		//リセット
		Command_Reset();

		//コマンドを処置
		while( ppCom != ppComEnd )
		{
			//マテリアル
			Command_ChangeMaterial_Color( *ppCom, invFarZ );

			//トランスフォーム
			Command_Transform( *ppCom );

			//ローカルライト
			Command_PlacementLocalLight( *ppCom );

			//描画
			Command_DrawPrimitives( *ppCom );

			ppCom++;
		}

		//デプステクスチャをフリップ
		m_pGraphicsDev->SetTexture( Renderer::TS_DEPTH, Mix::Graphics::TEXTURE_FILTER_POINT, Mix::Graphics::TEXTURE_ADDRESS_CLAMP, NULL );
		RenderSampling( m_pDepthTexChain );

		//デバッグ : 計測終了
		SCENE_DEB( m_pDebCProfDrawOpacity->drawElapsedTime += m_DebTimer.GetF32() );
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// アンビエントオクルージョン
	////////////////////////////////////////////////////////////////////////////////////////////////////

	if( ( m_pCamera->IsAmbientOcclusionAvailabled() == True ) &&
		( m_pCamera->IsAmbientOcclusionEnabled() == True ) )
	{
		// デバッグ : 計測開始
		SCENE_DEB( m_DebTimer.Reset() );

		// 実行
		ProcessCommand_AmbientOcclusion();

		// デバッグ : 計測終了
		SCENE_DEB( m_pDebCProfDrawNeut->aoElapsedTime += m_DebTimer.GetF32() );
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// スカイドーム
	////////////////////////////////////////////////////////////////////////////////////////////////////

	if( ( ExistsSkyDome() == True ) && ( m_pSkyDome->IsEnabled() == True ) )
	{
		SCENE_DEB( m_DebTimer.Reset() );

		// ドーム //
		if( IsAtmosphereAvailable() == True )
		{
			// 大気散乱シミュレーション
			ProcessCommand_RenderSkyDome_AtmosphereScattering( fillType );
		}
		else
		{
			// デフォルト
			ProcessCommand_RenderSkyDome_Default( fillType );
		}

		// パノラマ //
		if( m_pSkyDome->IsPanoramaAvailabled() == True )
		{
			ProcessCommand_RenderSkyDome_Panorama( fillType );
		}

		SCENE_DEB( m_pDebCProfDrawNeut->asElapsedTime += m_DebTimer.GetF32() );
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 屈折効果
	////////////////////////////////////////////////////////////////////////////////////////////////////

	if( ( m_pRefractTex != NULL ) &&
		( m_RefractMaskComList.GetCount() > 0 ) )
	{
		//デバッグ : 計測開始
		SCENE_DEB( m_DebTimer.Reset() );

		const Renderer::DRAW_COMMAND* pComR = m_RefractMaskComList.GetConstBeginPtr();
		const Renderer::DRAW_COMMAND* pComEndR = m_RefractMaskComList.GetConstEndPtr();

		//ターゲットを設定
		m_pGraphicsDev->SetTarget( m_pRefractTex, NULL, NULL, NULL, m_pDepthBuff );
		m_pGraphicsDev->SetViewBounds( m_Viewport );
		m_pGraphicsDev->SetScissorBounds( m_Viewport );
		m_pGraphicsDev->Clear( True, False, Mix::Vector4( 1.0f, 1.0f, 1.0f, 0.0f ) );

		//ステートを設定
		m_pGraphicsDev->SetBlendState( Mix::Graphics::BLEND_COPY );
		m_pGraphicsDev->SetDepthState( True, False );
		m_pGraphicsDev->SetRasterizerState( Mix::Graphics::FILL_SOLID, Mix::Graphics::CULL_NONE, False );

		//リセット
		Command_Reset();

		//コマンドを処理
		while( pComR != pComEndR )
		{
			//マテリアル
			Command_ChangeMaterial_Mask( pComR );

			//トランスフォーム
			Command_Transform( pComR );

			//描画
			Command_DrawPrimitives( pComR );

			pComR++;
		}

		//デバッグ : 計測終了
		SCENE_DEB( m_pDebCProfDrawRefract->maskElapsedTime += m_DebTimer.GetF32() );

		////////////////////////////////////////////////////////////////////////////////////////////////////

		//半透明 : 屈折面より後ろ
		if( m_TransparencyBackComList.GetCount() > 0 )
		{
			//デバッグ : 計測開始
			SCENE_DEB( m_DebTimer.Reset() );

			ProcessCommand_RenderTransparency( m_TransparencyBackComList, fillType, invFarZ );

			//デバッグ : 計測終了
			SCENE_DEB( m_pDebCProfDrawTransp->bkElapsedTime += m_DebTimer.GetF32() );
		}

		//シャドウマッピング : 屈折領域の内側
		ProcessCommand_ShadowMapping( True );

		////////////////////////////////////////////////////////////////////////////////////////////////////

		Renderer::OPACITY_COMMAND** ppComW = m_RefractComList.GetBeginPtr();
		Renderer::OPACITY_COMMAND** ppComEndW = m_RefractComList.GetEndPtr();

		//デバッグ : 計測開始
		SCENE_DEB( m_DebTimer.Reset() );

		//屈折テクスチャに背景(RGBのみ)を書き込む
		m_pGraphicsDev->SetTexture( Renderer::TS_REFRACT, Mix::Graphics::TEXTURE_FILTER_POINT, Mix::Graphics::TEXTURE_ADDRESS_CLAMP, NULL );
		RenderSampling( Mix::Graphics::COLOR_WRITE_RGB, m_pColorTexChain->GetCurrentPtr(), m_pRefractTex );

		//ターゲットを設定
		m_pGraphicsDev->SetTarget( m_pColorTexChain->GetCurrentPtr(), m_pDepthTexChain->GetNextPtr(), m_pDataTex, m_pSdwMapTex, m_pDepthBuff );
		m_pGraphicsDev->SetViewBounds( m_Viewport );
		m_pGraphicsDev->SetScissorBounds( m_Viewport );

		//ステートを設定
		m_pGraphicsDev->SetBlendState( Mix::Graphics::BLEND_NORMAL );
		m_pGraphicsDev->SetDepthState( True, True );
		m_pGraphicsDev->SetRasterizerState( fillType, Mix::Graphics::CULL_BACK, False );

		//テクスチャを設定
		m_pGraphicsDev->SetTexture( Renderer::TS_DEPTH, Mix::Graphics::TEXTURE_FILTER_POINT, Mix::Graphics::TEXTURE_ADDRESS_CLAMP, m_pDepthTexChain->GetCurrentPtr() );
		m_pGraphicsDev->SetTexture( Renderer::TS_SHADOW, Mix::Graphics::TEXTURE_FILTER_POINT, Mix::Graphics::TEXTURE_ADDRESS_CLAMP, m_pSdwDepthTex );
		m_pGraphicsDev->SetTexture( Renderer::TS_REFRACT, Mix::Graphics::TEXTURE_FILTER_POINT, Mix::Graphics::TEXTURE_ADDRESS_CLAMP, m_pRefractTex );
		m_pGraphicsDev->SetTexture( Renderer::TS_REFLECT, Mix::Graphics::TEXTURE_FILTER_POINT, Mix::Graphics::TEXTURE_ADDRESS_CLAMP, m_pEnvTex );

		//リセット
		Command_Reset();

		//コマンドを処理
		while( ppComW != ppComEndW )
		{
			//マテリアル
			Command_ChangeMaterial_Color( *ppComW, invFarZ );

			//トランスフォーム
			Command_Transform( *ppComW );

			//ローカルライト
			Command_PlacementLocalLight( *ppComW );

			//描画
			Command_DrawPrimitives( *ppComW );

			ppComW++;
		}

		//デプステクスチャをフリップ
		m_pGraphicsDev->SetTexture( Renderer::TS_DEPTH, Mix::Graphics::TEXTURE_FILTER_POINT, Mix::Graphics::TEXTURE_ADDRESS_CLAMP, NULL );
		RenderSampling( m_pDepthTexChain );

		//デバッグ : 計測終了
		SCENE_DEB( m_pDebCProfDrawRefract->drawElapsedTime += m_DebTimer.GetF32() );
	}

	if( m_pRefractTex != NULL )
	{
		m_pGraphicsDev->SetTarget( m_pRefractTex, NULL, NULL, NULL, NULL );
		m_pGraphicsDev->SetViewBounds( m_Viewport );
		m_pGraphicsDev->Clear( True, False, Mix::Vector4( 0.0f, 0.0f, 0.0f, 0.0f ) );
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 半透明( 屈折面より前 )
	////////////////////////////////////////////////////////////////////////////////////////////////////

	if( m_TransparencyFrontComList.GetCount() > 0 )
	{
		//デバッグ : 計測開始
		SCENE_DEB( m_DebTimer.Reset() );

		//コマンドを処理
		ProcessCommand_RenderTransparency( m_TransparencyFrontComList, fillType, invFarZ );

		//デプステクスチャをフリップ
		m_pGraphicsDev->SetTexture( Renderer::TS_DEPTH, Mix::Graphics::TEXTURE_FILTER_POINT, Mix::Graphics::TEXTURE_ADDRESS_CLAMP, NULL );
		RenderSampling( m_pDepthTexChain );

		//デバッグ : 計測終了
		SCENE_DEB( m_pDebCProfDrawTransp->frElapsedTime += m_DebTimer.GetF32() );
	}

	//ターゲットを設定( ポストエフェクト用 )
	m_pGraphicsDev->SetTarget( m_pColorTexChain->GetCurrentPtr(), NULL, NULL, NULL, m_pDepthBuff );
	m_pGraphicsDev->SetViewBounds( m_Viewport );
	m_pGraphicsDev->SetScissorBounds( m_Viewport );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// シャドウマッピング( 屈折領域の外側 )
	////////////////////////////////////////////////////////////////////////////////////////////////////

	ProcessCommand_ShadowMapping( False );
}

void Renderer::SortShadowCommand( Renderer::SHADOW_COMMAND** list, Int32 first, Int32 last )
{
	const Renderer::SHADOW_COMMAND* pCom  = list[( first + last ) >> 1];

	Boolean sortKey = pCom->bTransparency;

	Int32 i = first;
	Int32 j = last;

	do
	{
		while( list[i]->bTransparency > sortKey ) { i++; }
		while( list[j]->bTransparency < sortKey ) { j--; }

		if( i <= j )
		{
			MIX_ASSERT( ( i <= last ) && ( j >= first ) );

			Renderer::SHADOW_COMMAND* pTemp = list[i];

			list[i] = list[j];
			list[j] = pTemp;

			i++;
			j--;
		}

	}while( i <= j );

	if( first < j ) { Renderer::SortShadowCommand( list, first, j ); }
	if( i < last ) { Renderer::SortShadowCommand( list, i, last ); }
}

void Renderer::SortOpacityCommand( Renderer::OPACITY_COMMAND** list, Int32 first, Int32 last )
{
	const Renderer::OPACITY_COMMAND* pCom  = list[( first + last ) >> 1];

	UInt64 sortKey = pCom->sortKey;

	Int32 i = first;
	Int32 j = last;

	do
	{
		while( list[i]->sortKey < sortKey ) { i++; }
		while( list[j]->sortKey > sortKey ) { j--; }

		if( i <= j )
		{
			MIX_ASSERT( ( i <= last ) && ( j >= first ) );

			Renderer::OPACITY_COMMAND* pTemp = list[i];

			list[i] = list[j];
			list[j] = pTemp;

			i++;
			j--;
		}

	}while( i <= j );

	if( first < j ) { Renderer::SortOpacityCommand( list, first, j ); }
	if( i < last ) { Renderer::SortOpacityCommand( list, i, last ); }
}

void Renderer::ProcessCommand_AmbientOcclusion( void )
{
	MIX_ASSERT( m_pCamera != NULL );

	const Mix::Scene::ICamera::AMBIENT_OCCLUSION_SETTINGS& camSettings = m_pCamera->GetAmbientOcclusionSettings();
	const Mix::Scene::Common::Camera::INTERNAL_AMBIENT_OCCLUSION_SETTINGS& camInternalSettings = m_pCamera->GetInternalAmbientOcclusionSettings();
	Mix::Graphics::ITexture* pNormalTex = m_pCamera->GetAmbientOcclusionTexturePtr();
	UInt32 psType = ( pNormalTex != NULL )? Renderer::SSAO_TEX : Renderer::SSAO_SIMPLE;
	Renderer::RENDER_AMBIENT_OCCLUSION_ARGS args;
	Mix::Graphics::ITexture* pSourceTex;

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 実行
	////////////////////////////////////////////////////////////////////////////////////////////////////

	// イベントを通知

	args.radius = camInternalSettings.radius;
	args.threshold = camInternalSettings.threshold;
	args.depth = camInternalSettings.depth;
	args.intensity = m_GlobalAmbientColor.a * camSettings.intensity;
	if( pNormalTex != NULL )
	{
		args.ntexAspect.x = static_cast<Float32>( m_pAOTex->GetWidth() ) / static_cast<Float32>( pNormalTex->GetWidth() );
		args.ntexAspect.y = static_cast<Float32>( m_pAOTex->GetHeight() ) / static_cast<Float32>( pNormalTex->GetHeight() );
	}
	else
	{
		args.ntexAspect = Mix::Vector2::Zero();
	}
	args.color.Set( m_GlobalAmbientColor.x, m_GlobalAmbientColor.y, m_GlobalAmbientColor.z, 1.0f );

	OnRenderAmbientOcclusion( args );

	// 遮断

	MIX_ASSERT( ( m_Viewport.width - m_Viewport.x ) == m_pAOTex->GetWidth() );
	MIX_ASSERT( ( m_Viewport.height - m_Viewport.y ) == m_pAOTex->GetHeight() );

	m_pGraphicsDev->SetTarget( m_pAOTex, NULL, NULL, NULL, NULL );
	m_pGraphicsDev->SetViewBounds( m_Viewport );
	m_pGraphicsDev->Clear( True, False );

	m_pGraphicsDev->SetBlendState( Mix::Graphics::BLEND_COPY );
	m_pGraphicsDev->SetDepthState( False, False );
	m_pGraphicsDev->SetRasterizerState( Mix::Graphics::FILL_SOLID, Mix::Graphics::CULL_NONE, False );

	m_pGraphicsDev->SetTexture( Renderer::TS_SSAO_DEPTH,  Mix::Graphics::TEXTURE_FILTER_POINT, Mix::Graphics::TEXTURE_ADDRESS_CLAMP, m_pDepthTexChain->GetCurrentPtr() );
	m_pGraphicsDev->SetTexture( Renderer::TS_SSAO_NORMAL, Mix::Graphics::TEXTURE_FILTER_POINT, Mix::Graphics::TEXTURE_ADDRESS_CLAMP, m_pDataTex );
	m_pGraphicsDev->SetTexture( Renderer::TS_SSAO_BUMP,   Mix::Graphics::TEXTURE_FILTER_POINT, Mix::Graphics::TEXTURE_ADDRESS_WRAP,  pNormalTex );

	m_pGraphicsDev->SetVertexLayout( m_pSamplingVL );
	m_pGraphicsDev->SetVertexShader( m_pSamplingVS );
	m_pGraphicsDev->SetPixelShader( m_pAmbOcclPS[psType] );

	DrawQuad();

	RenderSampling( m_AOSamplingType,
					Mix::Graphics::COLOR_WRITE_RGBA,
					Mix::Graphics::BLEND_COPY,
					Mix::Graphics::TEXTURE_FILTER_POINT,
					m_pAOTex,
					m_pAOTexChain->GetCurrentPtr() );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// スムージング
	////////////////////////////////////////////////////////////////////////////////////////////////////

	pSourceTex = NULL;

	if( m_AOSamplingType == Mix::Scene::Common::RST_COPY )
	{
		if( camSettings.blur.GetType() == Mix::Scene::BLUR::T_NONE )
		{
			pSourceTex = m_pAOTex;
		}
		else
		{
			RenderBlur( camSettings.blur, m_pAOTex, m_pAOTexChain->GetCurrentPtr(), m_pAOTexChain->GetNextPtr() );

			pSourceTex = m_pAOTexChain->GetCurrentPtr();
		}
	}
	else
	{
		RenderSampling( m_AOSamplingType, 
						Mix::Graphics::COLOR_WRITE_RGBA,
						Mix::Graphics::BLEND_NORMAL,
						Mix::Graphics::TEXTURE_FILTER_LINEAR,
						m_pAOTex,
						m_pAOTexChain->GetCurrentPtr() );

		RenderBlur( camSettings.blur, m_pAOTexChain );

		pSourceTex = m_pAOTexChain->GetCurrentPtr();
	}

	MIX_ASSERT( pSourceTex != NULL );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 合成
	////////////////////////////////////////////////////////////////////////////////////////////////////

	RenderSampling( Mix::Scene::Common::RST_COPY, 
					Mix::Graphics::COLOR_WRITE_RGBA,
					Mix::Graphics::BLEND_NORMAL,
					Mix::Graphics::TEXTURE_FILTER_LINEAR,
					pSourceTex,
					m_pColorTexChain->GetCurrentPtr() );
}

void Renderer::ProcessCommand_ShadowMapping( Boolean bRefraction )
{
	MIX_ASSERT( m_pCamera != NULL );

	if( ( m_pDirectionalLight == NULL ) ||
		( m_pDirectionalLight->IsEnabled() == False ) ||
		( m_pCamera->IsShadowMappingAvailabled() == False ) ||
		( m_pCamera->IsShadowMappingEnabled() == False ) )
	{
		return;
	}

	const Mix::Scene::ICamera::SHADOW_MAPPING_SETTINGS& smSettings = m_pCamera->GetShadowMappingSettings();
	const Mix::Scene::Common::Camera::INTERNAL_VISIBLITY_SETTINGS& internalVisiSettings = m_pCamera->GetInternalVisiblitySettings();

	UInt32 rType = ( m_pRefractTex != NULL )? 1 : 0;
	UInt32 bType = Renderer::SM_FINISH_B_SOFT;

	Renderer::RENDER_SHADOW_MAPPING_ARGS smArgs;

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// デバッグ : 計測開始
	////////////////////////////////////////////////////////////////////////////////////////////////////

	SCENE_DEB( m_DebTimer.Reset() );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// スムージング
	////////////////////////////////////////////////////////////////////////////////////////////////////

	if( m_SdwMapSamplingType == Mix::Scene::Common::RST_COPY )
	{
		if( smSettings.blur.GetType() == Mix::Scene::BLUR::T_NONE )
		{
			//サンプリングタイプがコピーでかつ、ブラーをかけない場合はハードシャドウ
			bType = Renderer::SM_FINISH_B_HARD;
		}
		else
		{
			//ブラー
			RenderBlur( smSettings.blur, m_pSdwMapTex, m_pSdwMapTexChain->GetCurrentPtr(), m_pSdwMapTexChain->GetNextPtr() );
		}
	}
	else
	{
		//ダウンサンプリング
		RenderSampling( m_SdwMapSamplingType,
						Mix::Graphics::COLOR_WRITE_RGBA,
						Mix::Graphics::BLEND_COPY,
						Mix::Graphics::TEXTURE_FILTER_LINEAR,
						m_pSdwMapTex,
						m_pSdwMapTexChain->GetCurrentPtr() );

		//ブラー
		RenderBlur( smSettings.blur, m_pSdwMapTexChain );
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// フィニッシュ
	////////////////////////////////////////////////////////////////////////////////////////////////////

	// イベントを通知

	smArgs.refractFactor = ( bRefraction == True )? 0.0f : 1.0f;
	smArgs.color.r = m_GlobalAmbientColor.r;
	smArgs.color.g = m_GlobalAmbientColor.g;
	smArgs.color.b = m_GlobalAmbientColor.b;
	smArgs.color.a = smSettings.tint;
	smArgs.falloutStart = internalVisiSettings.sdwFalloffStart;
	smArgs.invFalloutDist = internalVisiSettings.sdwInvFalloffAmount;

	OnRenderShadowMapping( smArgs );

	// 実行

	m_pGraphicsDev->SetTarget( m_pColorTexChain->GetNextPtr(), NULL, NULL, NULL, NULL );
	m_pGraphicsDev->SetViewBounds( m_Viewport );

	m_pGraphicsDev->SetBlendState( Mix::Graphics::BLEND_COPY );
	m_pGraphicsDev->SetDepthState( False, False );
	m_pGraphicsDev->SetRasterizerState( Mix::Graphics::FILL_SOLID, Mix::Graphics::CULL_NONE, False );

	m_pGraphicsDev->SetTexture( Renderer::TS_SM_SHADE0, Mix::Graphics::TEXTURE_FILTER_POINT, Mix::Graphics::TEXTURE_ADDRESS_CLAMP, m_pSdwMapTex );

	if( bType == Renderer::SM_FINISH_B_HARD )
	{
		m_pGraphicsDev->SetTexture( Renderer::TS_SM_SHADE1, Mix::Graphics::TEXTURE_FILTER_POINT,  Mix::Graphics::TEXTURE_ADDRESS_CLAMP, NULL );
	}
	else
	{
		m_pGraphicsDev->SetTexture( Renderer::TS_SM_SHADE1, Mix::Graphics::TEXTURE_FILTER_LINEAR, Mix::Graphics::TEXTURE_ADDRESS_CLAMP, m_pSdwMapTexChain->GetCurrentPtr() );
	}

	m_pGraphicsDev->SetTexture( Renderer::TS_SM_DEPTH,   Mix::Graphics::TEXTURE_FILTER_POINT, Mix::Graphics::TEXTURE_ADDRESS_CLAMP, m_pDepthTexChain->GetCurrentPtr() );
	m_pGraphicsDev->SetTexture( Renderer::TS_SM_COLOR,   Mix::Graphics::TEXTURE_FILTER_POINT, Mix::Graphics::TEXTURE_ADDRESS_CLAMP, m_pColorTexChain->GetCurrentPtr() );
	m_pGraphicsDev->SetTexture( Renderer::TS_SM_REFRACT, Mix::Graphics::TEXTURE_FILTER_POINT, Mix::Graphics::TEXTURE_ADDRESS_CLAMP, m_pRefractTex );

	m_pGraphicsDev->SetVertexLayout( m_pSamplingVL );
	m_pGraphicsDev->SetVertexShader( m_pSamplingVS );
	m_pGraphicsDev->SetPixelShader( m_pSdwMapFinishPS[rType][bType] );

	DrawQuad();

	m_pColorTexChain->Flip();

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// デバッグ : 計測終了
	////////////////////////////////////////////////////////////////////////////////////////////////////

	SCENE_DEB( m_pDebCProfPostProc->smElapsedTime += m_DebTimer.GetF32() );
}

Mix::Matrix4x4 Renderer::SkyDome_ComputeWorldMatrix( void ) const
{
	MIX_ASSERT( m_pCamera != NULL );

	const Mix::Vector3& eyePos = m_pCamera->GetEye();

	Mix::Scene::ISkyDome::CONSTRAINT_TYPE crType = m_pSkyDome->GetConstraintType();
	const Mix::Scene::ISkyDome::PLANET_INFO& planetInfo = m_pSkyDome->GetPlanetInfo();
	Float32 scale = planetInfo.outerRadius;
	Mix::Vector3 offset( 0.0f, -( planetInfo.innerRadius ), 0.0f );

	Mix::Matrix4x4 ret;

	switch( crType )
	{
	case Mix::Scene::ISkyDome::CR_XYZ:
		ret.SetScaling( scale );
		ret.SetRow( 3, offset + eyePos );
		break;
	case Mix::Scene::ISkyDome::CR_XZ:
		ret.SetScaling( scale );
		ret.SetRow( 3, offset + Mix::Vector4( eyePos.x, 0.0f, eyePos.z, 1.0f ) );
		break;

	default:
		MIX_ASSERT( ( crType == Mix::Scene::ISkyDome::CR_XYZ ) || ( crType == Mix::Scene::ISkyDome::CR_XZ ) );
	}

	return ret;
}

Mix::Graphics::IPixelShader* Renderer::SkyDome_GetPixelShader( void ) const
{
	MIX_ASSERT( m_pSkyDome != NULL );

	UInt32 baseType;
	UInt32 cloudLayerType;
	UInt32 cloudLightingType;

	baseType = ( m_pSkyDome->GetBaseTexturePtr() == NULL )? Renderer::SD_BASE_0 : Renderer::SD_BASE_1;

	if( m_pSkyDome->IsCloudAvailabled() == True )
	{
		MIX_ASSERT( m_pSkyDome->GetValidCloudLayerNum() > 0 );

		const Mix::Scene::ISkyDome::CLOUD_GLOBAL_SETTINGS& cloudGlobalSettings = m_pSkyDome->GetCloudGlobalSettings();

		switch( m_pSkyDome->GetValidCloudLayerNum() )
		{
		case 1:
			cloudLayerType = Renderer::SD_CLOUD_L1;
			break;
		case 2:
			cloudLayerType = Renderer::SD_CLOUD_L2;
			break;
		}

		if( ( IsAtmosphereAvailable() == True ) &&
			( cloudGlobalSettings.asEffect == True ) &&
			( cloudGlobalSettings.asSunLighting == True ) )
		{
			cloudLightingType = 1;
		}
		else
		{
			cloudLightingType = 0;
		}
	}
	else
	{
		cloudLayerType = Renderer::SD_CLOUD_L0;
		cloudLightingType = 0;
	}

	MIX_ASSERT( m_pSkyDomePS[baseType][cloudLayerType][cloudLightingType] != NULL );

	return m_pSkyDomePS[baseType][cloudLayerType][cloudLightingType];
}

void Renderer::ProcessCommand_RenderSkyDome_Default( Mix::Graphics::FILL_TYPE fillType )
{
	MIX_ASSERT( m_pSkyDome != NULL );
	MIX_ASSERT( m_pSkyDome->GetVertexBufferPtr() != NULL );
	MIX_ASSERT( m_pSkyDome->GetIndexBufferPtr() != NULL );
	MIX_ASSERT( m_pCamera != NULL );

	const Mix::Matrix4x4& vpMat = m_pCamera->GetViewProjectionMatrix();
	Mix::Matrix4x4 wMat = SkyDome_ComputeWorldMatrix();
	Mix::Matrix4x4 wvpMat = wMat * vpMat;

	const Mix::Scene::ISkyDome::BASE_SETTINGS& baseSettings = m_pSkyDome->GetBaseSettings();
	UInt32 cloudLayerNum = m_pSkyDome->GetValidCloudLayerNum();
	const Mix::Scene::Common::SkyDome::DRAW_SUBSET* pSubset = m_pSkyDome->GetDomeSubsetPtr();

	Renderer::SKYDOME_DEFAULT_EVENT_ARGS eventArgs;

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// イベントを発生
	////////////////////////////////////////////////////////////////////////////////////////////////////

	eventArgs.wvpMat = wvpMat.ToTranspose();

	eventArgs.baseColor = baseSettings.color;
	eventArgs.baseParam.texScale = baseSettings.texScale;
	eventArgs.baseParam.texOpacity = baseSettings.texOpacity;

	if( cloudLayerNum > 0 )
	{
		const Mix::Scene::ISkyDome::CLOUD_LAYER_SETTINGS* cloudLayerSettings = m_pSkyDome->GetCloudLayerSettings();
		const Mix::Scene::Common::SkyDome::INTERNAL_CLOUD_LAYER_SETTINGS* internalCloudLayerSettings = m_pSkyDome->GetInternalCloudLayerSettings();
		const Mix::Scene::ISkyDome::CLOUD_GLOBAL_SETTINGS& cloudGlobalSettings = m_pSkyDome->GetCloudGlobalSettings();

		for( UInt32 i = 0; i < cloudLayerNum; i++ )
		{
			const Mix::Scene::ISkyDome::CLOUD_LAYER_SETTINGS& srcLayer = cloudLayerSettings[i];
			const Mix::Scene::Common::SkyDome::INTERNAL_CLOUD_LAYER_SETTINGS& srcInternalLayer = internalCloudLayerSettings[i];

			Renderer::SKYDOME_CLOUD_LAYER* dstLayer = &( eventArgs.cloudLayers[i] );

			dstLayer->texOffset = srcInternalLayer.texOffset;
			dstLayer->texScale = srcLayer.scale;
			dstLayer->texOpacity = srcLayer.opacity;
		}

		eventArgs.cloudColor = cloudGlobalSettings.color;
	}
	else
	{
		for( UInt32 i = 0; i < Mix::Scene::Common::SkyDome::CL_MAX; i++ )
		{
			Renderer::SKYDOME_CLOUD_LAYER* dstLayer = &( eventArgs.cloudLayers[i] );

			dstLayer->texOffset.Set( 0.0f, 0.0f );
			dstLayer->texScale = 0.0f;
			dstLayer->texOpacity = 0.0f;
		}

		eventArgs.cloudColor.Set( 0.0f, 0.0f, 0.0f, 0.0f );
	}

	OnRenderSkyDome( eventArgs );

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

	m_pGraphicsDev->SetTarget( m_pColorTexChain->GetCurrentPtr(), NULL, NULL, NULL, m_pDepthBuff );
	m_pGraphicsDev->SetViewBounds( m_Viewport );
	m_pGraphicsDev->SetScissorBounds( m_Viewport );

	m_pGraphicsDev->SetBlendState( Mix::Graphics::BLEND_NORMAL );
	m_pGraphicsDev->SetDepthState( True, False );
	m_pGraphicsDev->SetRasterizerState( fillType, Mix::Graphics::CULL_BACK, False );

	m_pGraphicsDev->SetVertexLayout( m_pSkyDomeVL );
	m_pGraphicsDev->SetVertexShader( m_pSkyDomeVS );
	m_pGraphicsDev->SetPixelShader( SkyDome_GetPixelShader() );
	m_pGraphicsDev->SetVertexBuffer( m_pSkyDome->GetVertexBufferPtr() );
	m_pGraphicsDev->SetIndexBuffer( m_pSkyDome->GetIndexBufferPtr() );
	m_pGraphicsDev->SetTexture( TS_SD_BASE,   Mix::Graphics::TEXTURE_FILTER_LINEAR, Mix::Graphics::TEXTURE_ADDRESS_WRAP, m_pSkyDome->GetBaseTexturePtr() );
	m_pGraphicsDev->SetTexture( TS_SD_CLOUD1, Mix::Graphics::TEXTURE_FILTER_LINEAR, Mix::Graphics::TEXTURE_ADDRESS_WRAP, m_pSkyDome->GetCloudTexturePtr1() );
	m_pGraphicsDev->SetTexture( TS_SD_CLOUD2, Mix::Graphics::TEXTURE_FILTER_LINEAR, Mix::Graphics::TEXTURE_ADDRESS_WRAP, m_pSkyDome->GetCloudTexturePtr2() );

	m_pGraphicsDev->DrawIndexed( Mix::Graphics::PRIMITIVE_TRIANGLELIST,
		pSubset->vertexStart,
		pSubset->vertexNum,
		pSubset->indexStart,
		pSubset->indexNum );

	//デバッグ : プリミティブ数
	SCENE_DEB( m_pDebCProfGeneral->drawPrimCount += Debug_CountPrimitive( Mix::Graphics::PRIMITIVE_TRIANGLELIST, pSubset->indexNum ) );
}

void Renderer::ProcessCommand_RenderSkyDome_AtmosphereScattering( Mix::Graphics::FILL_TYPE fillType )
{
	MIX_ASSERT( m_pSkyDome != NULL );
	MIX_ASSERT( m_pSkyDome->GetVertexBufferPtr() != NULL );
	MIX_ASSERT( m_pSkyDome->GetIndexBufferPtr() != NULL );
	MIX_ASSERT( m_pCamera != NULL );

	const Mix::Matrix4x4& vpMat = m_pCamera->GetViewProjectionMatrix();
	Mix::Matrix4x4 wMat = SkyDome_ComputeWorldMatrix();
	Mix::Matrix4x4 wvpMat = wMat * vpMat;

	const Mix::Scene::ISkyDome::BASE_SETTINGS& baseSettings = m_pSkyDome->GetBaseSettings();
	UInt32 cloudLayerNum = m_pSkyDome->GetValidCloudLayerNum();
	const Mix::Scene::Common::SkyDome::DRAW_SUBSET* pSubset = m_pSkyDome->GetDomeSubsetPtr();

	Mix::Scene::Common::AtmosphereScatter::INTERNAL_SETTINGS asInternalSettings = m_pAtmosphereScatter->GetInternalSettings();

	Renderer::SKYDOME_ATMOSPHERE_EVENT_ARGS eventArgs;

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// イベントを発生
	////////////////////////////////////////////////////////////////////////////////////////////////////

	eventArgs.worldMat = wMat.ToTranspose();
	eventArgs.worldViewProjMat = wvpMat.ToTranspose();
	eventArgs.sunColor = asInternalSettings.sunColor;
	eventArgs.nightColor = asInternalSettings.nightColor;
	eventArgs.baseParam.texScale = baseSettings.texScale;
	eventArgs.baseParam.texOpacity = baseSettings.texOpacity;

	if( cloudLayerNum > 0 )
	{
		const Mix::Scene::ISkyDome::CLOUD_LAYER_SETTINGS* cloudLayerSettings = m_pSkyDome->GetCloudLayerSettings();
		const Mix::Scene::Common::SkyDome::INTERNAL_CLOUD_LAYER_SETTINGS* internalCloudLayerSettings = m_pSkyDome->GetInternalCloudLayerSettings();
		const Mix::Scene::ISkyDome::CLOUD_GLOBAL_SETTINGS& cloudGlobalSettings = m_pSkyDome->GetCloudGlobalSettings();
		const Mix::Scene::Common::SkyDome::INTERNAL_CLOUD_GLOBAL_SETTINGS& internalCloudGlobalSettings = m_pSkyDome->GetInternalCloudGlobalSettings();

		// カラー

		eventArgs.cloudColor = ( cloudGlobalSettings.asEffect == True )? m_pSkyDome->ComputeCloudColorAS() : cloudGlobalSettings.color;

		// レイヤー

		for( UInt32 i = 0; i < cloudLayerNum; i++ )
		{
			const Mix::Scene::ISkyDome::CLOUD_LAYER_SETTINGS& srcLayer = cloudLayerSettings[i];
			const Mix::Scene::Common::SkyDome::INTERNAL_CLOUD_LAYER_SETTINGS& srcInternalLayer = internalCloudLayerSettings[i];

			Renderer::SKYDOME_CLOUD_LAYER* dstLayer = &( eventArgs.cloudLayers[i] );

			dstLayer->texOffset = srcInternalLayer.texOffset;
			dstLayer->texScale = srcLayer.scale;
			dstLayer->texOpacity = srcLayer.opacity;
		}

		// ライィテング

		eventArgs.cloudLighting.cornerThreshold = cloudGlobalSettings.asCornerThreshold;
		eventArgs.cloudLighting.cornerMul = internalCloudGlobalSettings.asCornerMul;
		eventArgs.cloudLighting.darkness = internalCloudGlobalSettings.asDarkness;
	}
	else
	{
		// カラー

		eventArgs.cloudColor.Set( 0.0f, 0.0f, 0.0f, 0.0f );

		// レイヤー

		for( UInt32 i = 0; i < Mix::Scene::Common::SkyDome::CL_MAX; i++ )
		{
			Renderer::SKYDOME_CLOUD_LAYER* dstLayer = &( eventArgs.cloudLayers[i] );

			dstLayer->texOffset.Set( 0.0f, 0.0f );
			dstLayer->texScale = 0.0f;
			dstLayer->texOpacity = 0.0f;
		}

		// ライティング

		eventArgs.cloudLighting.cornerThreshold = 0.0f;
		eventArgs.cloudLighting.cornerMul = 0.0f;
		eventArgs.cloudLighting.darkness = 0.0f;
	}

	OnRenderSkyDome( eventArgs );

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

	m_pGraphicsDev->SetTarget( m_pColorTexChain->GetCurrentPtr(), NULL, NULL, NULL, m_pDepthBuff );
	m_pGraphicsDev->SetViewBounds( m_Viewport );
	m_pGraphicsDev->SetScissorBounds( m_Viewport );

	m_pGraphicsDev->SetBlendState( Mix::Graphics::BLEND_NORMAL );
	m_pGraphicsDev->SetDepthState( True, False );
	m_pGraphicsDev->SetRasterizerState( fillType, Mix::Graphics::CULL_NONE, False );

	m_pGraphicsDev->SetVertexBuffer( m_pSkyDome->GetVertexBufferPtr() );
	m_pGraphicsDev->SetIndexBuffer( m_pSkyDome->GetIndexBufferPtr() );

	m_pGraphicsDev->SetVertexLayout( m_pSkyDomeVL );
	m_pGraphicsDev->SetVertexShader( m_pSkyDomeVS );
	m_pGraphicsDev->SetPixelShader( SkyDome_GetPixelShader() );
	m_pGraphicsDev->SetTexture( TS_SD_BASE,   Mix::Graphics::TEXTURE_FILTER_LINEAR, Mix::Graphics::TEXTURE_ADDRESS_WRAP, m_pSkyDome->GetBaseTexturePtr() );
	m_pGraphicsDev->SetTexture( TS_SD_CLOUD1, Mix::Graphics::TEXTURE_FILTER_LINEAR, Mix::Graphics::TEXTURE_ADDRESS_WRAP, m_pSkyDome->GetCloudTexturePtr1() );
	m_pGraphicsDev->SetTexture( TS_SD_CLOUD2, Mix::Graphics::TEXTURE_FILTER_LINEAR, Mix::Graphics::TEXTURE_ADDRESS_WRAP, m_pSkyDome->GetCloudTexturePtr2() );

	m_pGraphicsDev->DrawIndexed( Mix::Graphics::PRIMITIVE_TRIANGLELIST,
		pSubset->vertexStart,
		pSubset->vertexNum,
		pSubset->indexStart,
		pSubset->indexNum );

	//デバッグ : プリミティブ数
	SCENE_DEB( m_pDebCProfGeneral->drawPrimCount += Debug_CountPrimitive( Mix::Graphics::PRIMITIVE_TRIANGLELIST, pSubset->indexNum ) );
}

void Renderer::ProcessCommand_RenderSkyDome_Panorama( Mix::Graphics::FILL_TYPE fillType )
{
	MIX_ASSERT( m_pSkyDome != NULL );
	MIX_ASSERT( m_pSkyDome->IsPanoramaEnabled() == True );
	MIX_ASSERT( m_pSkyDome->GetPanoramaTexturePtr() != NULL );
	MIX_ASSERT( m_pSkyDome->GetVertexBufferPtr() != NULL );
	MIX_ASSERT( m_pSkyDome->GetIndexBufferPtr() != NULL );
	MIX_ASSERT( m_pCamera != NULL );

	const Mix::Vector3& eyePos = m_pCamera->GetEye();
	const Mix::Matrix4x4& vpMat = m_pCamera->GetViewProjectionMatrix();

	const Mix::Scene::ISkyDome::PANORAMA_SETTINGS& settings = m_pSkyDome->GetPanoramaSettings();
	const Mix::Scene::Common::SkyDome::DRAW_SUBSET* pSubset = m_pSkyDome->GetPanoramaSubsetPtr();

	Mix::Matrix4x4 wMat;
	Mix::Matrix4x4 wvpMat;

	Renderer::SKYDOME_PANORAMA_EVENT_ARGS eventArgs;

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// イベントを通知
	////////////////////////////////////////////////////////////////////////////////////////////////////

	wMat.SetScaling( settings.scale.x, settings.scale.y, settings.scale.x );
	wMat.m30 = eyePos.x;
	wMat.m31 = ( m_pSkyDome->GetConstraintType() == ISkyDome::CR_XYZ )? ( eyePos.y + settings.offsetY ) : settings.offsetY;
	wMat.m32 = eyePos.z;
	wMat.m33 = 1.0f;

	wvpMat = wMat * vpMat;

	eventArgs.wvpMat = wvpMat.ToTranspose();
	eventArgs.wMat = wMat.ToTranspose();
	eventArgs.baseColor = settings.color;
	eventArgs.dist = settings.dist;
	eventArgs.fogRatio = MIX_FLOAT_SATURATE( 1.0f - settings.dist * MIX_FLOAT_RECIPROCAL( m_pCamera->GetFarZ() ) );
	eventArgs.texRepeat = static_cast<Float32>( settings.texRepeatNum + 1 );

	OnRenderPanorama( eventArgs );

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

	m_pGraphicsDev->SetTarget( m_pColorTexChain->GetCurrentPtr(), NULL, NULL, NULL, m_pDepthBuff );
	m_pGraphicsDev->SetViewBounds( m_Viewport );
	m_pGraphicsDev->SetScissorBounds( m_Viewport );

	m_pGraphicsDev->SetBlendState( Mix::Graphics::BLEND_NORMAL );
	m_pGraphicsDev->SetDepthState( True, False );
	m_pGraphicsDev->SetRasterizerState( fillType, Mix::Graphics::CULL_NONE, False );

	m_pGraphicsDev->SetVertexBuffer( m_pSkyDome->GetVertexBufferPtr() );
	m_pGraphicsDev->SetIndexBuffer( m_pSkyDome->GetIndexBufferPtr() );

	m_pGraphicsDev->SetVertexLayout( m_pPanoramaVL );

	if( ( IsFogAvailable() == False ) || ( IsFogEnabled() == False ) )
	{
		m_pGraphicsDev->SetVertexShader( m_pPanoramaVS[Renderer::SD_PR] );
		m_pGraphicsDev->SetPixelShader( m_pPanoramaPS[Renderer::SD_PR] );
	}
	else
	{
		m_pGraphicsDev->SetVertexShader( m_pPanoramaVS[Renderer::SD_PR_FOG] );
		m_pGraphicsDev->SetPixelShader( m_pPanoramaPS[Renderer::SD_PR_FOG] );
	}

	m_pGraphicsDev->SetTexture( TS_SD_BASE,
								Mix::Graphics::TEXTURE_FILTER_LINEAR,
								( settings.texRepeatNum == 0 )? Mix::Graphics::TEXTURE_ADDRESS_CLAMP : Mix::Graphics::TEXTURE_ADDRESS_WRAP,
								m_pSkyDome->GetPanoramaTexturePtr() );

	m_pGraphicsDev->DrawIndexed(Mix::Graphics::PRIMITIVE_TRIANGLELIST,
		pSubset->vertexStart,
		pSubset->vertexNum,
		pSubset->indexStart,
		pSubset->indexNum );

	//デバッグ : プリミティブ数
	SCENE_DEB( m_pDebCProfGeneral->drawPrimCount += Debug_CountPrimitive( Mix::Graphics::PRIMITIVE_TRIANGLELIST, pSubset->indexNum ) );
}

void Renderer::ProcessCommand_RenderTransparency( Mix::ContainerT<Renderer::TRANSPARENCY_COMMAND*, Mix::Memory::SECTION_SCENE>& comList, Mix::Graphics::FILL_TYPE fillType, Float32 invFarZ )
{
	Renderer::TRANSPARENCY_COMMAND** ppCom = comList.GetBeginPtr();
	Renderer::TRANSPARENCY_COMMAND** ppComEnd = comList.GetEndPtr();

	//ターゲットを設定
	m_pGraphicsDev->SetTarget( m_pColorTexChain->GetCurrentPtr(), m_pDepthTexChain->GetNextPtr(), m_pDataTex, m_pSdwMapTex, m_pDepthBuff );
	m_pGraphicsDev->SetViewBounds( m_Viewport );
	m_pGraphicsDev->SetScissorBounds( m_Viewport );

	//ステートを設定
	m_pGraphicsDev->SetBlendState( Mix::Graphics::BLEND_NORMAL );
	m_pGraphicsDev->SetDepthState( True, False );
	m_pGraphicsDev->SetRasterizerState( fillType, Mix::Graphics::CULL_BACK, False );

	//テクスチャを設定
	m_pGraphicsDev->SetTexture( Renderer::TS_DEPTH, Mix::Graphics::TEXTURE_FILTER_POINT, Mix::Graphics::TEXTURE_ADDRESS_CLAMP, m_pDepthTexChain->GetCurrentPtr() );
	m_pGraphicsDev->SetTexture( Renderer::TS_SHADOW, Mix::Graphics::TEXTURE_FILTER_POINT, Mix::Graphics::TEXTURE_ADDRESS_CLAMP, m_pSdwDepthTex );
	m_pGraphicsDev->SetTexture( Renderer::TS_REFRACT, Mix::Graphics::TEXTURE_FILTER_POINT, Mix::Graphics::TEXTURE_ADDRESS_CLAMP, m_pRefractTex );
	m_pGraphicsDev->SetTexture( Renderer::TS_REFLECT, Mix::Graphics::TEXTURE_FILTER_POINT, Mix::Graphics::TEXTURE_ADDRESS_CLAMP, m_pEnvTex );

	//リセット
	Command_Reset();

	//コマンドを処理
	while( ppCom != ppComEnd )
	{
		//マテリアル
		Command_ChangeMaterial_Color( *ppCom, invFarZ );

		//トランスフォーム
		Command_Transform( *ppCom );

		//ローカルライト
		Command_PlacementLocalLight( *ppCom );

		//描画
		Command_DrawPrimitives( *ppCom );

		ppCom++;
	}
}

void Renderer::Command_PrepareRendering( Float32 invFarZ )
{
	////////////////////////////////////////////////////////////////////////////////////////////////////
	// イベントデータの作成
	////////////////////////////////////////////////////////////////////////////////////////////////////

	MIX_ASSERT( m_pCamera != NULL );

	const Mix::Scene::ICamera::SHADOW_MAPPING_SETTINGS& smSettings = m_pCamera->GetShadowMappingSettings();
	const Mix::Scene::Common::Camera::INTERNAL_SHADOW_MAPPING_SETTINGS& smInternalParam = m_pCamera->GetInternalShadowMappingSettings();
	Mix::Scene::Common::AtmosphereScatter::INTERNAL_SETTINGS asInternalSettings = m_pAtmosphereScatter->GetInternalSettings();

	Float32 smTexW;
	Float32 smTexH;

	Renderer::PREPARE_REDNERING_EVENT_ARGS prEventArgs;

	if( m_pSdwDepthTex != NULL )
	{
		smTexW = static_cast<Float32>( m_pSdwDepthTex->GetWidth() );
		smTexH = static_cast<Float32>( m_pSdwDepthTex->GetHeight() );
	}
	else
	{
		smTexW = 1.0f;
		smTexH = 1.0f;
	}

	prEventArgs.eyePos = m_pCamera->GetEye();
	prEventArgs.viewMat = m_pCamera->GetViewMatrix().ToTranspose();
	prEventArgs.viewProjMat = m_pCamera->GetViewProjectionMatrix().ToTranspose();
	prEventArgs.lightMat = m_SdwLightMat.ToTranspose();
	prEventArgs.lightBiasMat = m_SdwLightBiasMat.ToTranspose();
	prEventArgs.invFarZ = invFarZ;

	prEventArgs.globalAmbientColor = m_GlobalAmbientColor;

	if( m_pHemisphereLight != NULL )
	{
		prEventArgs.hsEnabled = m_pHemisphereLight->IsEnabled();
		prEventArgs.hsAxis = m_pHemisphereLight->GetAxis();
		prEventArgs.hsGroundColor = m_pHemisphereLight->GetGroundColor();
		prEventArgs.hsSkyColor = m_pHemisphereLight->GetSkyColor();
	}
	else
	{
		prEventArgs.hsEnabled = False;
		prEventArgs.hsAxis.Set( 0.0f, 1.0f, 0.0f, 1.0f );
		prEventArgs.hsGroundColor.Set( 0.0f, 0.0f, 0.0f, 0.0f );
		prEventArgs.hsSkyColor.Set( 0.0f, 0.0f, 0.0f, 0.0f );
	}

	if( m_pDirectionalLight != NULL )
	{
		prEventArgs.sunEnabled = m_pDirectionalLight->IsEnabled();
		prEventArgs.sunDir = m_pDirectionalLight->GetDirection();
		prEventArgs.sunColor = m_pDirectionalLight->GetColor();
	}
	else
	{
		prEventArgs.sunEnabled = False;
		prEventArgs.sunDir.Set( 0.0f, -1.0f, 0.0f, 1.0f );
		prEventArgs.sunColor.Set( 1.0f, 1.0f, 1.0f, 1.0f );
	}

	prEventArgs.fogEnabled = ( ( IsFogAvailable() == True ) && ( IsFogEnabled() == True ) );
	prEventArgs.fogParam0 = m_InternalFogSettings.p0;
	prEventArgs.fogParam1 = m_InternalFogSettings.p1;
	prEventArgs.fogColor = m_FogSettings.color;

	prEventArgs.shadowEnabled = ( ( m_pDirectionalLight != NULL ) && ( m_pDirectionalLight->IsEnabled() == True ) && ( m_pCamera->IsShadowMappingAvailabled() == True ) && ( m_pCamera->IsShadowMappingEnabled() == True ) );
	prEventArgs.shadowDepthBias = smInternalParam.depthBias;
	prEventArgs.shadowDepthSlopeScale = smSettings.depthSlopeScale;
	prEventArgs.shadowDepthBiasClamp = smSettings.depthBiasClamp;
	prEventArgs.shadowPCFRange = smInternalParam.pcfRange;
	prEventArgs.shadowPCFMul = smInternalParam.pcfMul;
	prEventArgs.shadowTexelSize.Set( MIX_FLOAT_RECIPROCAL( smTexW ), MIX_FLOAT_RECIPROCAL( smTexH ) );

	prEventArgs.asEnabled = ( IsAtmosphereAvailable() == True );
	prEventArgs.asColor = asInternalSettings.sunColor;
	prEventArgs.asSunDir = m_pAtmosphereScatter->GetSunDir();
	prEventArgs.asMultipliers = asInternalSettings.mulitpliers;
	prEventArgs.asHG = asInternalSettings.hg;
	prEventArgs.asBetaDashR = asInternalSettings.betaDashR;
	prEventArgs.asBetaDashM = asInternalSettings.betaDashM;
	prEventArgs.asBetaRM = asInternalSettings.betaRM;
	prEventArgs.asOneOverBetaRM = asInternalSettings.oneOverBetaRM;

	OnPrepareRendering( prEventArgs );
}

void Renderer::Command_Reset( void )
{
	Renderer::LOCALLIGHT_EVENT_ARGS eventArgs;

	m_CurWorldMatID = 0xFFFFFFFF;
	m_CurLocalLightID = 0xFFFFFFFF;
	m_pCurMaterial = NULL;

	eventArgs.list = NULL;
	eventArgs.count = 0;

	OnPlacementLocalLight( eventArgs );
}

void Renderer::Command_Transform( const Renderer::DRAW_COMMAND* pCom )
{
	if( m_CurWorldMatID == pCom->worldMatID )
	{
		return;
	}

	Renderer::TRANSFORM_EVENT_ARGS eventArgs;

	m_CurWorldMatID = pCom->worldMatID;

	eventArgs.list = &( m_WorldMatrixList[m_CurWorldMatID] );
	eventArgs.count = ( pCom->worldMatCount == 0 )? 1 : pCom->worldMatCount;

	OnTransform( eventArgs );
}

void Renderer::Command_ChangeMaterial_Shadow( const Renderer::SHADOW_COMMAND* pCom )
{
	if( m_pCurMaterial != pCom->pMaterial )
	{
		m_pCurMaterial = pCom->pMaterial;
		m_pCurMaterial->RenderShadow( m_pGraphicsDev, pCom->trType );
	}
}

void Renderer::Command_ChangeMaterial_Mask( const Renderer::DRAW_COMMAND* pCom )
{
	if( m_pCurMaterial != pCom->pMaterial )
	{
		m_pCurMaterial = pCom->pMaterial;
		m_pCurMaterial->RenderMask( m_pGraphicsDev, pCom->trType );
	}
}

void Renderer::Command_ChangeMaterial_Color( const Renderer::COLOR_COMMAND* pCom, Float32 invFarZ )
{
	if( m_pCurMaterial != pCom->pMaterial )
	{
		m_pCurMaterial = pCom->pMaterial;
		m_pCurMaterial->RenderColor( m_pGraphicsDev, pCom->trType );
	}
}

void Renderer::Command_PlacementLocalLight( const Renderer::COLOR_COMMAND* pCom )
{
	if( m_CurLocalLightID == pCom->localLightID )
	{
		return;
	}

	Renderer::LOCALLIGHT_EVENT_ARGS eventArgs;

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// カレントローカルライトを更新
	////////////////////////////////////////////////////////////////////////////////////////////////////

	m_CurLocalLightID = pCom->localLightID;

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// イベントを通知
	////////////////////////////////////////////////////////////////////////////////////////////////////

	if( m_CurLocalLightID != 0xFFFFFFFF )
	{
		MIX_ASSERT( pCom->localLightCount > 0 );

		eventArgs.list = &( m_LocalLightList[m_CurLocalLightID] );
		eventArgs.count = pCom->localLightCount;
	}
	else
	{
		eventArgs.list = NULL;
		eventArgs.count = 0;
	}

	OnPlacementLocalLight( eventArgs );
}

void Renderer::Command_DrawPrimitives( const Renderer::DRAW_COMMAND* pCom )
{
	m_pGraphicsDev->SetVertexBuffer( pCom->pVertexBuffer );
	m_pGraphicsDev->SetIndexBuffer( pCom->pIndexBuffer );

	if( pCom->pIndexBuffer != NULL )
	{
		m_pGraphicsDev->DrawIndexed( pCom->primitiveType, pCom->vertexStart, pCom->vertexCount, pCom->indexStart, pCom->indexCount );
	}
	else
	{
		m_pGraphicsDev->Draw( pCom->primitiveType, pCom->vertexStart, pCom->vertexCount );
	}
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Mix::Scene::Standard::Common::Renderer : ポストプロセス
////////////////////////////////////////////////////////////////////////////////////////////////////

void Renderer::PostProcess( void )
{
	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// 輝度を求める前に処理するもの
	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	// シャドウマッピング
//	PostProcess_ShadowMapping();

	// アンダーウォーター
	PostProcess_UnderWater();

	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// 階調補正の準備
	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	// ルミノシティ : 輝度の算出 and 順応
	PostProcess_LumTransform();

	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// ブライトパスを行う
	// カラーテクスチャに対しての合成( カラーテクスチャを直接変更してはならない )
	// 輝度による階調補正の影響を受ける
	//
	// ※この区間はカラーテクスチャをフリップしてはいけない
	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	// 開始 : 合成用に次のターゲットにコピー
	RenderSampling( Mix::Scene::Common::RST_COPY,
					Mix::Graphics::COLOR_WRITE_RGBA,
					Mix::Graphics::BLEND_COPY,
					Mix::Graphics::TEXTURE_FILTER_POINT,
					m_pColorTexChain->GetCurrentPtr(),
					m_pColorTexChain->GetNextPtr() );

	// ブルーム
	PostProcess_Bloom();

	// ライトシャフト
	PostProcess_LightShafts();

	// レンズフレア
	PostProcess_LensFlare();

	// 終了 : フリップ
	m_pColorTexChain->Flip();

	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// 階調補正( 16Bit or 32Bit )
	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	// ルミノシティ : 輝度による階調補正
	PostProcess_LumOperation();

	// フィルミック
	PostProcess_Filmic();

	// ガンマ補正
	PostProcess_GammaCorrection();

	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// 階調補正が行われた後に処理するもの( 8Bit )
	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	// カメラモーションブラー
	PostProcess_CameraMotionBlur();

	// 色収差
	PostProcess_Chromatism();

	// 被写界深度
	PostProcess_Dof();

	// レンズディストーション
	PostProcess_LensDistortion();

	// ビネット
	PostProcess_Vignette();

	// アンチエイリアス
	PostProcess_AntiAliasing();

	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// 最終処理
	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	PostProcess_Final();
}

void Renderer::PostProcess_UnderWater( void )
{
	MIX_ASSERT( m_pCamera != NULL );

	if( m_pCamera->IsUnderWater() == False )
	{
		return;
	}

	Renderer::UNDERWATER_EVENT_ARGS eventArgs;

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// デバッグ : 計測開始
	////////////////////////////////////////////////////////////////////////////////////////////////////

	SCENE_DEB( m_DebTimer.Reset() );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// イベントを通知
	////////////////////////////////////////////////////////////////////////////////////////////////////

	eventArgs.color = m_WaterVisual.color;
	eventArgs.density = m_WaterVisual.density;
	eventArgs.intensity = m_WaterVisual.intensity;
	eventArgs.threshold = m_WaterVisual.threshold;
	eventArgs.offset = m_WaterVisual.offset;

	OnRenderUnderWater( eventArgs );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 実行
	////////////////////////////////////////////////////////////////////////////////////////////////////

	m_pGraphicsDev->SetTarget( m_pColorTexChain->GetNextPtr(), NULL, NULL, NULL, NULL );
	m_pGraphicsDev->SetViewBounds( m_Viewport );

	m_pGraphicsDev->SetBlendState( Mix::Graphics::BLEND_COPY );
	m_pGraphicsDev->SetDepthState( False, False );
	m_pGraphicsDev->SetRasterizerState( Mix::Graphics::FILL_SOLID, Mix::Graphics::CULL_NONE, False );

	m_pGraphicsDev->SetTexture( 0, Mix::Graphics::TEXTURE_FILTER_POINT, Mix::Graphics::TEXTURE_ADDRESS_CLAMP, m_pColorTexChain->GetCurrentPtr() );
	m_pGraphicsDev->SetTexture( 1, Mix::Graphics::TEXTURE_FILTER_POINT, Mix::Graphics::TEXTURE_ADDRESS_CLAMP, m_pDepthTexChain->GetCurrentPtr() );

	m_pGraphicsDev->SetVertexLayout( m_pSamplingVL );
	m_pGraphicsDev->SetVertexShader( m_pSamplingVS );
	m_pGraphicsDev->SetPixelShader( m_pUnderWaterPS );

	DrawQuad();

	m_pColorTexChain->Flip();

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// デバッグ : 計測終了
	////////////////////////////////////////////////////////////////////////////////////////////////////

	SCENE_DEB( m_pDebCProfPostProc->uwElapsedTime += m_DebTimer.GetF32() );
}

void Renderer::PostProcess_LumTransform( void )
{
	MIX_ASSERT( m_pCamera != NULL );

	if( m_pCamera->IsLuminosityAvailabled() == False )
	{
		return;
	}

	MIX_ASSERT( m_pColorTexChain != NULL );
	MIX_ASSERT( m_pLumInitalTex != NULL );
	MIX_ASSERT( m_pLumIterateTexList != NULL );
	MIX_ASSERT( m_pLumIterateTexList->size() > 0 );
	MIX_ASSERT( m_pLumFinalTex != NULL );
	MIX_ASSERT( m_pLumAdaptedTexChain != NULL );
	MIX_ASSERT( m_pLumTransformPS[Renderer::LUM_INITAL] != NULL );
	MIX_ASSERT( m_pLumTransformPS[Renderer::LUM_ITERATE] != NULL );
	MIX_ASSERT( m_pLumTransformPS[Renderer::LUM_FINAL] != NULL );

	const Mix::Scene::ICamera::LUMINOSITY_SETTINGS camSettings = m_pCamera->GetLuminositySettings();
	Mix::Graphics::ITexture* pColorTex = m_pColorTexChain->GetCurrentPtr();

	Renderer::RENDER_LUM_TRANSFORM_ARGS tfArgs;
	Renderer::RENDER_LUM_ADAPTED_ARGS adArgs;

	Mix::Graphics::ITexture* pPreTransformTex;

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// デバッグ : 計測開始
	////////////////////////////////////////////////////////////////////////////////////////////////////

	SCENE_DEB( m_DebTimer.Reset() );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 平均輝度を求める際の共通の設定
	////////////////////////////////////////////////////////////////////////////////////////////////////

	m_pGraphicsDev->SetVertexLayout( m_pSamplingVL );
	m_pGraphicsDev->SetVertexShader( m_pSamplingVS );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 平均輝度(対数)の合計
	////////////////////////////////////////////////////////////////////////////////////////////////////

	tfArgs.texelSize.x = MIX_FLOAT_RECIPROCAL( static_cast<Float32>( pColorTex->GetWidth() ) );
	tfArgs.texelSize.y = MIX_FLOAT_RECIPROCAL( static_cast<Float32>( pColorTex->GetHeight() ) );
	tfArgs.lumRange.x = 0.0f;
	tfArgs.lumRange.y = 0.0f;

	OnRenderLumTransform( tfArgs );

	m_pGraphicsDev->SetTarget( m_pLumInitalTex, NULL, NULL, NULL, NULL );
	m_pGraphicsDev->SetViewBounds( 0, 0, m_pLumInitalTex->GetWidth(), m_pLumInitalTex->GetHeight() );

	m_pGraphicsDev->SetBlendState( Mix::Graphics::BLEND_COPY );
	m_pGraphicsDev->SetDepthState( False, False );
	m_pGraphicsDev->SetRasterizerState( Mix::Graphics::FILL_SOLID, Mix::Graphics::CULL_NONE, False );

	m_pGraphicsDev->SetTexture( Renderer::TS_LUM_TRANSFORM, Mix::Graphics::TEXTURE_FILTER_POINT, Mix::Graphics::TEXTURE_ADDRESS_CLAMP, pColorTex );

	m_pGraphicsDev->SetPixelShader( m_pLumTransformPS[Renderer::LUM_INITAL] );

	DrawQuad();

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 平均輝度の合計
	////////////////////////////////////////////////////////////////////////////////////////////////////

	pPreTransformTex = m_pLumInitalTex;

	m_pGraphicsDev->SetPixelShader( m_pLumTransformPS[Renderer::LUM_ITERATE] );

	for( UInt32 i = 0; i < m_pLumIterateTexList->size(); i++ )
	{
		Mix::Graphics::ITexture* pCurTransformTex = m_pLumIterateTexList->at( i );

		tfArgs.texelSize.x = MIX_FLOAT_RECIPROCAL( static_cast<Float32>( pPreTransformTex->GetWidth() ) );
		tfArgs.texelSize.y = MIX_FLOAT_RECIPROCAL( static_cast<Float32>( pPreTransformTex->GetHeight() ) );
		tfArgs.lumRange.x = 0.0f;
		tfArgs.lumRange.y = 0.0f;

		OnRenderLumTransform( tfArgs );

		m_pGraphicsDev->SetTarget( pCurTransformTex, NULL, NULL, NULL, NULL );
		m_pGraphicsDev->SetViewBounds( 0, 0, pCurTransformTex->GetWidth(), pCurTransformTex->GetHeight() );

		m_pGraphicsDev->SetBlendState( Mix::Graphics::BLEND_COPY );
		m_pGraphicsDev->SetDepthState( False, False );
		m_pGraphicsDev->SetRasterizerState( Mix::Graphics::FILL_SOLID, Mix::Graphics::CULL_NONE, False );

		m_pGraphicsDev->SetTexture( Renderer::TS_LUM_TRANSFORM, Mix::Graphics::TEXTURE_FILTER_POINT, Mix::Graphics::TEXTURE_ADDRESS_CLAMP, pPreTransformTex );

		DrawQuad();

		pPreTransformTex = pCurTransformTex;
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 平均輝度の合計(指数)
	////////////////////////////////////////////////////////////////////////////////////////////////////
	
	tfArgs.texelSize.x = MIX_FLOAT_RECIPROCAL( static_cast<Float32>( pPreTransformTex->GetWidth() ) );
	tfArgs.texelSize.y = MIX_FLOAT_RECIPROCAL( static_cast<Float32>( pPreTransformTex->GetHeight() ) );
	tfArgs.lumRange.x = camSettings.minLum;
	tfArgs.lumRange.y = camSettings.maxLum;

	OnRenderLumTransform( tfArgs );

	m_pGraphicsDev->SetTarget( m_pLumFinalTex, NULL, NULL, NULL, NULL );
	m_pGraphicsDev->SetViewBounds( 0, 0, m_pLumFinalTex->GetWidth(), m_pLumFinalTex->GetHeight() );

	m_pGraphicsDev->SetBlendState( Mix::Graphics::BLEND_COPY );
	m_pGraphicsDev->SetDepthState( False, False );
	m_pGraphicsDev->SetRasterizerState( Mix::Graphics::FILL_SOLID, Mix::Graphics::CULL_NONE, False );

	m_pGraphicsDev->SetTexture( Renderer::TS_LUM_TRANSFORM, Mix::Graphics::TEXTURE_FILTER_POINT, Mix::Graphics::TEXTURE_ADDRESS_CLAMP, pPreTransformTex );

	m_pGraphicsDev->SetPixelShader( m_pLumTransformPS[Renderer::LUM_FINAL] );

	DrawQuad();

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// アダプテーション
	////////////////////////////////////////////////////////////////////////////////////////////////////

	Mix::Scene::Common::Camera::LUMINOSITY_ADAPTATION_TYPE adType = m_pCamera->GetLuminosityAdaptationType();
	Boolean bAdEnabled = m_pCamera->IsLuminosityAdaptationEnabled();

	if( adType == Mix::Scene::Common::Camera::LUM_AD_SPECIFY )
	{
		Float32 adaptValue = m_pCamera->GetLuminosityAdaptationValue();

		m_pGraphicsDev->SetTarget( m_pLumAdaptedTexChain->GetCurrentPtr(), NULL, NULL, NULL, NULL );
		m_pGraphicsDev->SetViewBounds( 0, 0, m_pLumAdaptedTexChain->GetWidth(), m_pLumAdaptedTexChain->GetHeight() );
		m_pGraphicsDev->Clear( True, False, Mix::Vector4( adaptValue, adaptValue, adaptValue, 1.0f ) );
	}
	else if( adType == Mix::Scene::Common::Camera::LUM_AD_FORCE )
	{
		Renderer::RenderSampling(	Mix::Scene::Common::RST_COPY,
									Mix::Graphics::COLOR_WRITE_RGBA,
									Mix::Graphics::BLEND_COPY,
									Mix::Graphics::TEXTURE_FILTER_POINT,
									m_pLumFinalTex,
									m_pLumAdaptedTexChain->GetCurrentPtr() );
	}
	else if(	( adType == Mix::Scene::Common::Camera::LUM_AD_SLOWLY ) &&
				( bAdEnabled == True ) )
	{
		Mix::Graphics::ITexture* pPreTex = m_pLumAdaptedTexChain->GetCurrentPtr();
		Mix::Graphics::ITexture* pNextTex = m_pLumAdaptedTexChain->GetNextPtr();

		adArgs.rods = camSettings.rods;
		adArgs.cones = camSettings.cones;
		adArgs.deltaTime = m_pEngine->GetDT();

		OnRenderLumAdapted( adArgs );

		m_pGraphicsDev->SetTarget( pNextTex, NULL, NULL, NULL, NULL );
		m_pGraphicsDev->SetViewBounds( 0, 0, m_pLumAdaptedTexChain->GetWidth(), m_pLumAdaptedTexChain->GetHeight() );

		m_pGraphicsDev->SetBlendState( Mix::Graphics::BLEND_COPY );
		m_pGraphicsDev->SetDepthState( False, False );
		m_pGraphicsDev->SetRasterizerState( Mix::Graphics::FILL_SOLID, Mix::Graphics::CULL_NONE, False );

		m_pGraphicsDev->SetTexture( Renderer::TS_LUM_ADAPTED_PRE, Mix::Graphics::TEXTURE_FILTER_POINT, Mix::Graphics::TEXTURE_ADDRESS_CLAMP, pPreTex );
		m_pGraphicsDev->SetTexture( Renderer::TS_LUM_ADAPTED_CUR, Mix::Graphics::TEXTURE_FILTER_POINT, Mix::Graphics::TEXTURE_ADDRESS_CLAMP, m_pLumFinalTex );

		m_pGraphicsDev->SetPixelShader( m_pLumAdaptedPS );

		DrawQuad();

		m_pLumAdaptedTexChain->Flip();
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// デバッグ : 計測終了
	////////////////////////////////////////////////////////////////////////////////////////////////////

	SCENE_DEB( m_pDebCProfPostProc->lumTrElapsedTime += m_DebTimer.GetF32() );
}

void Renderer::PostProcess_Bloom( void )
{
	MIX_ASSERT( m_pCamera != NULL );

	if( ( m_pCamera->IsBloomAvailabled() == False ) || ( m_pCamera->IsBloomEnabled() == False ) )
	{
		return;
	}

	MIX_ASSERT( m_pColorTexChain != NULL );
	MIX_ASSERT( m_pBloomTexChainList != NULL );
	MIX_ASSERT( m_pBloomTexChainList->size() > 0 );
	MIX_ASSERT( m_pDebBloomBrightPassTex != NULL );

	Mix::Graphics::Utility::ITargetTextureChain* pBPTexChain = m_pBloomTexChainList->front();
	Mix::Graphics::ITexture* pTargetTex = m_pColorTexChain->GetNextPtr();
	Mix::Graphics::ITexture* pPreTex = NULL;

	Renderer::TextureChainList::iterator it_begin = m_pBloomTexChainList->begin();
	Renderer::TextureChainList::iterator it_end = m_pBloomTexChainList->end();
	Renderer::TextureChainList::iterator it;

	const Mix::Scene::ICamera::BLOOM_SETTINGS& camSettings = m_pCamera->GetBloomSettings();
	UInt32 index = 0;

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// デバッグ : 計測開始
	////////////////////////////////////////////////////////////////////////////////////////////////////

	SCENE_DEB( m_DebTimer.Reset() );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// ダウンサンプリング
	////////////////////////////////////////////////////////////////////////////////////////////////////

	RenderSampling( m_BloomSamplingType,
					Mix::Graphics::COLOR_WRITE_RGBA,
					Mix::Graphics::BLEND_COPY,
					Mix::Graphics::TEXTURE_FILTER_LINEAR,
					m_pColorTexChain->GetCurrentPtr(),
					pBPTexChain->GetCurrentPtr() );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// ブライトパス
	////////////////////////////////////////////////////////////////////////////////////////////////////

	RenderBrightPass( camSettings.brightPass, pBPTexChain->GetCurrentPtr(), pBPTexChain->GetNextPtr() );

	pBPTexChain->Flip();

#ifdef _DEBUG
	RenderSampling( Mix::Scene::Common::RST_COPY,
					Mix::Graphics::COLOR_WRITE_RGBA,
					Mix::Graphics::BLEND_COPY,
					Mix::Graphics::TEXTURE_FILTER_POINT,
					pBPTexChain->GetCurrentPtr(),
					m_pDebBloomBrightPassTex );
#endif //_DEBUG

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// ぼかしながらターゲットに加算合成
	////////////////////////////////////////////////////////////////////////////////////////////////////

	for( it = it_begin; it != it_end; ++it, index++ )
	{
		const Mix::Scene::ICamera::BLOOM_OVERFLOW& overflow = m_pCamera->GetBloomOverflow( index );
		const Mix::Scene::BLUR& blur = overflow.blur;
		Mix::Graphics::Utility::ITargetTextureChain* pTexChain = ( *it );

		//ダウンサンプリング
		if( pPreTex != NULL )
		{
			RenderSampling( m_BloomSamplingType,
							Mix::Graphics::COLOR_WRITE_RGBA,
							Mix::Graphics::BLEND_COPY,
							Mix::Graphics::TEXTURE_FILTER_LINEAR,
							pPreTex,
							pTexChain->GetCurrentPtr() );
		}

		//ブラー
		if( blur.IsValid() == True )
		{
			RenderBlur( blur, pTexChain );
		}

		//ターゲットに合成
		RenderSampling( Mix::Scene::Common::RST_COPY,
						overflow.intensity * camSettings.intensity,
						camSettings.blendType,
						Mix::Graphics::TEXTURE_FILTER_LINEAR,
						pTexChain->GetCurrentPtr(),
						pTargetTex );

		//次のソースになるテクスチャ
		pPreTex = pTexChain->GetCurrentPtr();
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// デバッグ : 計測開始
	////////////////////////////////////////////////////////////////////////////////////////////////////

	SCENE_DEB( m_pDebCProfPostProc->lbElapsedTime += m_DebTimer.GetF32() );
}

void Renderer::PostProcess_LightShafts( void )
{
	MIX_ASSERT( m_pCamera != NULL );

	if( ( m_pLightShaftsCaster == NULL ) ||
		( m_pLightShaftsCaster->IsEnabled() == False ) ||
		( m_pCamera->IsLightShaftsAvailabled() == False ) ||
		( m_pCamera->IsLightShaftsEnabled() == False ) )
	{
		return;
	}

	MIX_ASSERT( m_pLSTexChain != NULL );
	MIX_ASSERT( m_pDebLSBrightPassTex != NULL );

	Mix::Scene::Common::LightShaftsCaster::PARAM objParam;

	if( m_pLightShaftsCaster->GetParam( m_pCamera, objParam ) == False )
	{
		// ライトが後ろ(背中側)にある
		return;
	}

	const Mix::Scene::ICamera::LIGHT_SHAFTS_SETTINGS& camSettings = m_pCamera->GetLightShaftsSettings();
	const Mix::Scene::Common::Camera::INTERNAL_LIGHT_SHAFTS_SETTINGS& camInternalSettings = m_pCamera->GetInternalLightShaftsSettings();

	Mix::Graphics::ITexture* pNoiseTex = m_pCamera->GetLightShaftsTexturePtr();

	Renderer::RENDER_LIGHT_SHAFTS_INIT_ARGS initArgs;
	Renderer::RENDER_LIGHT_SHAFTS_BLUR_ARGS blurArgs;

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// デバッグ : 計測開始
	////////////////////////////////////////////////////////////////////////////////////////////////////

	SCENE_DEB( m_DebTimer.Reset() );

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

	initArgs.whiteness = camSettings.whiteness;

	if( pNoiseTex != NULL )
	{
		initArgs.ntexAspect.x = static_cast<Float32>( m_pColorTexChain->GetWidth() ) / static_cast<Float32>( pNoiseTex->GetWidth() );
		initArgs.ntexAspect.y = static_cast<Float32>( m_pColorTexChain->GetHeight() ) / static_cast<Float32>( pNoiseTex->GetHeight() );
	}
	else
	{
		initArgs.ntexAspect = Mix::Vector2::Zero();
	}

	OnRenderLightShaftsInit( initArgs );

	m_pGraphicsDev->SetTarget( m_pLSTexChain->GetCurrentPtr(), NULL, NULL, NULL, NULL );
	m_pGraphicsDev->SetViewBounds( m_LSViewport );

	m_pGraphicsDev->SetBlendState( Mix::Graphics::BLEND_COPY );
	m_pGraphicsDev->SetDepthState( False, False );
	m_pGraphicsDev->SetRasterizerState( Mix::Graphics::FILL_SOLID, Mix::Graphics::CULL_NONE, False );

	m_pGraphicsDev->SetVertexLayout( m_pSamplingVL );
	m_pGraphicsDev->SetVertexShader( m_pSamplingVS );
	m_pGraphicsDev->SetPixelShader( m_pLSInitPS[( pNoiseTex != NULL )? 1 : 0] );

	m_pGraphicsDev->SetTexture( Renderer::TS_LS_INIT_COLOR, Mix::Graphics::TEXTURE_FILTER_POINT, Mix::Graphics::TEXTURE_ADDRESS_CLAMP, m_pColorTexChain->GetCurrentPtr() );
	m_pGraphicsDev->SetTexture( Renderer::TS_LS_INIT_MASK,  Mix::Graphics::TEXTURE_FILTER_POINT, Mix::Graphics::TEXTURE_ADDRESS_CLAMP, m_pDataTex );
	m_pGraphicsDev->SetTexture( Renderer::TS_LS_INIT_NOISE, Mix::Graphics::TEXTURE_FILTER_POINT, Mix::Graphics::TEXTURE_ADDRESS_WRAP,  pNoiseTex );

	DrawQuad();

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// ブライトパス
	////////////////////////////////////////////////////////////////////////////////////////////////////

	RenderBrightPass(	camSettings.brightPass,
						m_pLSTexChain->GetCurrentPtr(),
						m_pLSTexChain->GetNextPtr() );

	m_pLSTexChain->Flip();

#ifdef _DEBUG
	RenderSampling( Mix::Scene::Common::RST_COPY,
					Mix::Graphics::COLOR_WRITE_RGBA,
					Mix::Graphics::BLEND_COPY,
					Mix::Graphics::TEXTURE_FILTER_POINT,
					m_pLSTexChain->GetCurrentPtr(),
					m_pDebLSBrightPassTex );
#endif //_DEBUG

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// ブラー
	////////////////////////////////////////////////////////////////////////////////////////////////////

	blurArgs.lightPos = objParam.pos;
	blurArgs.EdotL = objParam.EdotL;
	blurArgs.density = camSettings.density;
	blurArgs.decay = camSettings.decay;
	blurArgs.exposure = camSettings.exposure;
	blurArgs.fiStart = camInternalSettings.start;
	blurArgs.fiEnd = camInternalSettings.end;
	blurArgs.fiInvDist = camInternalSettings.invDist;

	OnRenderLightShaftsBlur( blurArgs );

	m_pGraphicsDev->SetTarget( m_pLSTexChain->GetNextPtr(), NULL, NULL, NULL, NULL );
	m_pGraphicsDev->SetViewBounds( m_LSViewport );
	m_pGraphicsDev->Clear( True, False, Mix::Vector4( 0.0f, 0.0f, 0.0f, 0.0f ) );

	m_pGraphicsDev->SetBlendState( Mix::Graphics::BLEND_COPY );
	m_pGraphicsDev->SetDepthState( False, False );
	m_pGraphicsDev->SetRasterizerState( Mix::Graphics::FILL_SOLID, Mix::Graphics::CULL_NONE, False );

	m_pGraphicsDev->SetTexture( Renderer::TS_LS_BLUR_COLOR, Mix::Graphics::TEXTURE_FILTER_POINT, Mix::Graphics::TEXTURE_ADDRESS_CLAMP, m_pLSTexChain->GetCurrentPtr() );
	m_pGraphicsDev->SetTexture( Renderer::TS_LS_BLUR_DEPTH, Mix::Graphics::TEXTURE_FILTER_POINT, Mix::Graphics::TEXTURE_ADDRESS_CLAMP, m_pDepthTexChain->GetCurrentPtr() );
	m_pGraphicsDev->SetTexture( Renderer::TS_LS_BLUR_DATA,  Mix::Graphics::TEXTURE_FILTER_POINT, Mix::Graphics::TEXTURE_ADDRESS_CLAMP, m_pDataTex );

	m_pGraphicsDev->SetVertexLayout( m_pSamplingVL );
	m_pGraphicsDev->SetVertexShader( m_pSamplingVS );

	switch( camSettings.samples )
	{
	case Mix::Scene::ICamera::LS_64:
		m_pGraphicsDev->SetPixelShader( m_pLSBlurPS[Renderer::LS_BLUR_M] );
		break;
	case Mix::Scene::ICamera::LS_128:
		m_pGraphicsDev->SetPixelShader( m_pLSBlurPS[Renderer::LS_BLUR_H] );
		break;
	default:
		// LS_32
		m_pGraphicsDev->SetPixelShader( m_pLSBlurPS[Renderer::LS_BLUR_L] );
		break;
	}

	DrawQuad();

	m_pLSTexChain->Flip();

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 合成
	////////////////////////////////////////////////////////////////////////////////////////////////////

	RenderSampling( Mix::Scene::Common::RST_COPY,
					Mix::Graphics::COLOR_WRITE_RGBA,
					Mix::Graphics::BLEND_ADD,
					Mix::Graphics::TEXTURE_FILTER_LINEAR,
					m_pLSTexChain->GetCurrentPtr(),
					m_pColorTexChain->GetNextPtr() );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// デバッグ : 計測終了
	////////////////////////////////////////////////////////////////////////////////////////////////////

	SCENE_DEB( m_pDebCProfPostProc->lsElapsedTime = m_DebTimer.GetF32() );
}

void Renderer::PostProcess_LensFlare( void )
{
	MIX_ASSERT( m_pCamera != NULL );

	if( ( m_pCamera->IsLensFlareAvailabled() == False ) || ( m_pCamera->IsLensFlareEnabled() == False ) )
	{
		return;
	}

	MIX_ASSERT( m_pColorTexChain != NULL );
	MIX_ASSERT( m_pLFTexChain != NULL );
	MIX_ASSERT( m_pDebLFBrightPassTex != NULL );

	const Mix::Point& screenSize = m_pGraphicsDev->GetScreenSize();

	const Mix::Scene::ICamera::LENS_FLARE_SETTINGS& camSettings = m_pCamera->GetLensFlareSettings();
	const Mix::Scene::Common::Camera::INTERNAL_LENS_FLARE_SETTINGS& camInternalSettings = m_pCamera->GetInternalLensFlareSettings();

	Mix::Graphics::ITexture* pGhostColorTex = m_pCamera->GetLensFlareTexturePtr( ICamera::LFT_COLOR );
	Mix::Graphics::ITexture* pBrustTex = m_pCamera->GetLensFlareTexturePtr( ICamera::LFT_BRUST );
	Mix::Graphics::ITexture* pDirtTex = m_pCamera->GetLensFlareTexturePtr( ICamera::LFT_DIRT );

	UInt32 i_gi = ( pGhostColorTex != NULL )? 1 : 0;
	UInt32 i_hi = ( camSettings.haloWidth > MIX_FLOAT_EPSILON )? 1 : 0;

	UInt32 m_di = ( pDirtTex != NULL )? 1 : 0;
	UInt32 m_bi = ( pBrustTex != NULL )? 1 : 0;

	Renderer::RENDER_LENSFLARE_IMAGE_ARGS imageArgs;

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// デバッグ : 計測開始
	////////////////////////////////////////////////////////////////////////////////////////////////////

	SCENE_DEB( m_DebTimer.Reset() );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// ダウンサンプリング
	////////////////////////////////////////////////////////////////////////////////////////////////////

	RenderSampling( m_LFSamplingType,
					Mix::Graphics::COLOR_WRITE_RGBA,
					Mix::Graphics::BLEND_COPY,
					Mix::Graphics::TEXTURE_FILTER_LINEAR,
					m_pColorTexChain->GetCurrentPtr(),
					m_pLFTexChain->GetCurrentPtr() );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// ブライトパス
	////////////////////////////////////////////////////////////////////////////////////////////////////

	RenderBrightPass( camSettings.brightPass, m_pLFTexChain->GetCurrentPtr(), m_pLFTexChain->GetNextPtr() );

	m_pLFTexChain->Flip();

#ifdef _DEBUG
	RenderSampling( m_LFSamplingType,
					Mix::Graphics::COLOR_WRITE_RGBA,
					Mix::Graphics::BLEND_COPY,
					Mix::Graphics::TEXTURE_FILTER_POINT,
					m_pLFTexChain->GetCurrentPtr(),
					m_pDebLFBrightPassTex );
#endif //_DEBUG

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// イメージ
	////////////////////////////////////////////////////////////////////////////////////////////////////

	MIX_ASSERT( m_pLFImagePS[i_gi][i_hi] != NULL );

	imageArgs.distortion = camInternalSettings.distoVec;
	imageArgs.numGhost = camSettings.ghostNum;
	imageArgs.ghostWeight = camSettings.ghostWeight;
	imageArgs.ghostDispersion = camSettings.ghostDispersal;
	imageArgs.haloWeight = camSettings.haloWeight;
	imageArgs.haloWidth = camSettings.haloWidth;

	OnRenderLensFlareImage( imageArgs );

	m_pGraphicsDev->SetTarget( m_pLFTexChain->GetNextPtr(), NULL, NULL, NULL, NULL );
	m_pGraphicsDev->SetViewBounds( m_LFViewport );

	m_pGraphicsDev->SetBlendState( Mix::Graphics::BLEND_COPY );
	m_pGraphicsDev->SetDepthState( False, False );
	m_pGraphicsDev->SetRasterizerState( Mix::Graphics::FILL_SOLID, Mix::Graphics::CULL_NONE, False );

	m_pGraphicsDev->SetTexture( Renderer::TS_LF_IMAGE_COLOR,       Mix::Graphics::TEXTURE_FILTER_POINT, Mix::Graphics::TEXTURE_ADDRESS_WRAP,  m_pLFTexChain->GetCurrentPtr() );
	m_pGraphicsDev->SetTexture( Renderer::TS_LF_IMAGE_GHOST_COLOR, Mix::Graphics::TEXTURE_FILTER_POINT, Mix::Graphics::TEXTURE_ADDRESS_CLAMP, pGhostColorTex );

	m_pGraphicsDev->SetVertexLayout( m_pSamplingVL );
	m_pGraphicsDev->SetVertexShader( m_pSamplingVS );
	m_pGraphicsDev->SetPixelShader( m_pLFImagePS[i_gi][i_hi] );

	DrawQuad();

	m_pLFTexChain->Flip();

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// ブラー
	////////////////////////////////////////////////////////////////////////////////////////////////////

	RenderBlur( camSettings.blur, m_pLFTexChain );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// モディファイ
	////////////////////////////////////////////////////////////////////////////////////////////////////

	if( ( m_di > 0 ) || ( m_bi > 0 ) )
	{
		MIX_ASSERT( m_pLFModifyPS[m_di][m_bi] != NULL );

		Renderer::RENDER_LENSFLARE_MODIFY_ARGS modifyArgs;

		modifyArgs.dirtIntensity = camSettings.dirtSharpness;
		modifyArgs.dirtExposure = camSettings.dirtIntensity;
		modifyArgs.brustIntensity = camSettings.brustSharpness;
		modifyArgs.brustExposure = camSettings.brustIntensity;
		modifyArgs.camMat = camInternalSettings.camMat;

		OnRenderLensFlareModify( modifyArgs );

		m_pGraphicsDev->SetTarget( m_pLFTexChain->GetNextPtr(), NULL, NULL, NULL, NULL );
		m_pGraphicsDev->SetViewBounds( m_LFViewport );

		m_pGraphicsDev->SetBlendState( Mix::Graphics::BLEND_COPY );
		m_pGraphicsDev->SetDepthState( False, False );
		m_pGraphicsDev->SetRasterizerState( Mix::Graphics::FILL_SOLID, Mix::Graphics::CULL_NONE, False );

		m_pGraphicsDev->SetTexture( Renderer::TS_LF_MODIFY_IMAGE, Mix::Graphics::TEXTURE_FILTER_LINEAR, Mix::Graphics::TEXTURE_ADDRESS_CLAMP, m_pLFTexChain->GetCurrentPtr() );
		m_pGraphicsDev->SetTexture( Renderer::TS_LF_MODIFY_DIRT,  Mix::Graphics::TEXTURE_FILTER_LINEAR, Mix::Graphics::TEXTURE_ADDRESS_CLAMP, pDirtTex );
		m_pGraphicsDev->SetTexture( Renderer::TS_LF_MODIFY_BRUST, Mix::Graphics::TEXTURE_FILTER_LINEAR, Mix::Graphics::TEXTURE_ADDRESS_CLAMP, pBrustTex );

		m_pGraphicsDev->SetVertexLayout( m_pSamplingVL );
		m_pGraphicsDev->SetVertexShader( m_pSamplingVS );
		m_pGraphicsDev->SetPixelShader( m_pLFModifyPS[m_di][m_bi] );

		DrawQuad();

		m_pLFTexChain->Flip();
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 合成
	////////////////////////////////////////////////////////////////////////////////////////////////////

	RenderSampling( Mix::Scene::Common::RST_COPY,
					camSettings.intensity,
					Mix::Graphics::BLEND_ADD,
					Mix::Graphics::TEXTURE_FILTER_LINEAR,
					m_pLFTexChain->GetCurrentPtr(),
					m_pColorTexChain->GetNextPtr() );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// デバッグ : 計測終了
	////////////////////////////////////////////////////////////////////////////////////////////////////

	SCENE_DEB( m_pDebCProfPostProc->lfElapsedTime += m_DebTimer.GetF32() );
}

void Renderer::PostProcess_LumOperation( void )
{
	MIX_ASSERT( m_pCamera != NULL );

	if( m_pCamera->IsLuminosityAvailabled() == False )
	{
		return;
	}

	MIX_ASSERT( m_pCamera != NULL );

	const Mix::Scene::ICamera::LUMINOSITY_SETTINGS& camSettings = m_pCamera->GetLuminositySettings();
	Boolean tmEnabled = ( MIX_TESTBIT( camSettings.flags, ICamera::LUM_TONE_MAPPING ) == ICamera::LUM_TONE_MAPPING );
	Boolean bsEnabled = ( MIX_TESTBIT( camSettings.flags, ICamera::LUM_BLUE_SHIFT ) == ICamera::LUM_BLUE_SHIFT );

	if( ( tmEnabled == False ) && ( bsEnabled == False ) )
	{
		return;
	}

	Boolean smEnabled = ( MIX_TESTBIT( camSettings.flags, ICamera::LUM_STATIC_MIDDLE_GRAY ) == ICamera::LUM_STATIC_MIDDLE_GRAY );

	Renderer::RENDER_LUM_OPERATOR_ARGS opArgs;

	UInt32 ta_i;
	UInt32 bs_i;

	//トーンマッピングの有無
	if( tmEnabled == True )
	{
		//中間色は指定か自動か？
		ta_i = ( smEnabled == True )? 1 : 2;
	}
	else
	{
		ta_i = 0;
	}

	// ブルシーフトの有無
	bs_i = ( bsEnabled == True )? 1 : 0;

	MIX_ASSERT( ta_i < Renderer::LUM_OP_TA_MAX );
	MIX_ASSERT( bs_i < Renderer::LUM_OP_B_MAX );
	MIX_ASSERT( m_pLumOperatorPS[ta_i][bs_i] != NULL );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// デバッグ : 計測開始
	////////////////////////////////////////////////////////////////////////////////////////////////////

	SCENE_DEB( m_DebTimer.Reset() );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 実行
	////////////////////////////////////////////////////////////////////////////////////////////////////

	opArgs.middleGray = camSettings.middleGray;
	opArgs.invWhite2 = MIX_FLOAT_RECIPROCAL( camSettings.white * camSettings.white );
	OnRenderLumOperator( opArgs );

	m_pGraphicsDev->SetTarget( m_pColorTexChain->GetNextPtr(), NULL, NULL, NULL, NULL );
	m_pGraphicsDev->SetViewBounds( m_Viewport );
	m_pGraphicsDev->SetBlendState( Mix::Graphics::BLEND_COPY );
	m_pGraphicsDev->SetDepthState( False, False );
	m_pGraphicsDev->SetRasterizerState( Mix::Graphics::FILL_SOLID, Mix::Graphics::CULL_NONE, False );
	m_pGraphicsDev->SetTexture( Renderer::TS_LUM_TM_COLOR,   Mix::Graphics::TEXTURE_FILTER_POINT, Mix::Graphics::TEXTURE_ADDRESS_CLAMP, m_pColorTexChain->GetCurrentPtr() );
	m_pGraphicsDev->SetTexture( Renderer::TS_LUM_TM_ADAPTED, Mix::Graphics::TEXTURE_FILTER_POINT, Mix::Graphics::TEXTURE_ADDRESS_CLAMP, m_pLumAdaptedTexChain->GetCurrentPtr() );
	m_pGraphicsDev->SetPixelShader( m_pLumOperatorPS[ta_i][bs_i] );

	DrawQuad();

	m_pColorTexChain->Flip();

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// デバッグ : 計測終了
	////////////////////////////////////////////////////////////////////////////////////////////////////

	SCENE_DEB( m_pDebCProfPostProc->lumOpElapsedTime += m_DebTimer.GetF32() );
}

void Renderer::PostProcess_Filmic( void )
{
	MIX_ASSERT( m_pCamera != NULL );

	if( ( m_pCamera->IsFilmicEnabled() == False ) ||
		( m_pCamera->GetFilmicType() == Mix::Scene::ICamera::FI_NONE ) )
	{
		return ;
	}

	Mix::Scene::ICamera::FILMIC_TYPE type = m_pCamera->GetFilmicType();

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// デバッグ : 計測開始
	////////////////////////////////////////////////////////////////////////////////////////////////////

	SCENE_DEB( m_DebTimer.Reset() );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// イベントの通知
	////////////////////////////////////////////////////////////////////////////////////////////////////

	if( type == Mix::Scene::ICamera::FI_HABLE )
	{
		// Hable

		const ICamera::FILMIC_HABLE_SETTINGS* camSettings = reinterpret_cast<const ICamera::FILMIC_HABLE_SETTINGS*>( m_pCamera->GetFilmicSettingsBuff( sizeof( Mix::Scene::ICamera::FILMIC_HABLE_SETTINGS ) ) );

		Renderer::RENDER_FILMIC_HABLE_ARGS args;

		args.exposureBias = camSettings->exposureBias;
		args.shoulderStrength = camSettings->shoulderStrength;
		args.linearStrength = camSettings->linearStrength;
		args.linearAngle = camSettings->linearAngle;
		args.toeStrength = camSettings->toeStrength;
		args.toeNumerator = camSettings->toeNumerator;
		args.toeDenominator = camSettings->toeDenominator;
		args.linearWhitePointValue = camSettings->linearWhitePointValue;

		OnRenderFilmicHable( args );
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 実行
	////////////////////////////////////////////////////////////////////////////////////////////////////

	MIX_ASSERT( m_pFilmicPS[type] != NULL );

	m_pGraphicsDev->SetTarget( m_pColorTexChain->GetNextPtr(), NULL, NULL, NULL, NULL );
	m_pGraphicsDev->SetViewBounds( m_Viewport );
	m_pGraphicsDev->SetBlendState( Mix::Graphics::BLEND_COPY );
	m_pGraphicsDev->SetDepthState( False, False );
	m_pGraphicsDev->SetRasterizerState( Mix::Graphics::FILL_SOLID, Mix::Graphics::CULL_NONE, False );
	m_pGraphicsDev->SetTexture( Renderer::TS_FI_COLOR, Mix::Graphics::TEXTURE_FILTER_POINT, Mix::Graphics::TEXTURE_ADDRESS_CLAMP, m_pColorTexChain->GetCurrentPtr() );
	m_pGraphicsDev->SetVertexLayout( m_pSamplingVL );
	m_pGraphicsDev->SetVertexShader( m_pSamplingVS );
	m_pGraphicsDev->SetPixelShader( m_pFilmicPS[type] );

	DrawQuad();

	m_pColorTexChain->Flip();

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// デバッグ : 計測終了
	////////////////////////////////////////////////////////////////////////////////////////////////////

	SCENE_DEB( m_pDebCProfPostProc->fmElapsedTime += m_DebTimer.GetF32() );
}

void Renderer::PostProcess_GammaCorrection( void )
{
	MIX_ASSERT( m_pCamera != NULL );

	if( m_pCamera->IsGammaEnabled() == False )
	{
		return;
	}

	Mix::Graphics::ITexture* pSource = m_pColorTexChain->GetCurrentPtr();
	Mix::Graphics::ITexture* pTarget = m_pColorTexChain->GetNextPtr();
	Renderer::RENDER_GAMMA_ARGS args;

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// デバッグ計測開始
	////////////////////////////////////////////////////////////////////////////////////////////////////

	SCENE_DEB( m_DebTimer.Reset() );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// イベントを通知
	////////////////////////////////////////////////////////////////////////////////////////////////////

	args.invValue = m_pCamera->GetInternalGammaValue();

	OnRenderGammaCorrect( args );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 実行
	////////////////////////////////////////////////////////////////////////////////////////////////////

	m_pGraphicsDev->SetTarget( pTarget, NULL, NULL, NULL, NULL );
	m_pGraphicsDev->SetViewBounds( m_Viewport );

	m_pGraphicsDev->SetBlendState( Mix::Graphics::BLEND_COPY );
	m_pGraphicsDev->SetDepthState( False, False );
	m_pGraphicsDev->SetRasterizerState( Mix::Graphics::FILL_SOLID, Mix::Graphics::CULL_NONE, False );

	m_pGraphicsDev->SetTexture( Renderer::TS_SAMPLING_SOURCE, Mix::Graphics::TEXTURE_FILTER_POINT, Mix::Graphics::TEXTURE_ADDRESS_CLAMP, pSource );

	m_pGraphicsDev->SetVertexLayout( m_pSamplingVL );
	m_pGraphicsDev->SetVertexShader( m_pSamplingVS );
	m_pGraphicsDev->SetPixelShader( m_pGammaPS );

	DrawQuad();

	m_pColorTexChain->Flip();

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// デバッグ計測終了
	////////////////////////////////////////////////////////////////////////////////////////////////////

	SCENE_DEB( m_pDebCProfPostProc->gcElapsedTime += m_DebTimer.GetF32() );
}

void Renderer::PostProcess_CameraMotionBlur( void )
{
	MIX_ASSERT( m_pCamera != NULL );

	if( m_pCamera->IsMotionBlurActivated() == False )
	{
		//動きがない
		return;
	}

	const Mix::Scene::ICamera::MOTION_BLUR_SETTINGS& settings = m_pCamera->GetMotionBlurSettings();
	const Mix::Scene::Common::Camera::INTERNAL_MOTION_BLUR_SETTINGS& internalSettings = m_pCamera->GetInternalMotionBlurSettings();

	Renderer::RENDER_CAMERA_MOTION_BLUR_ARGS args;

	MIX_ASSERT( settings.quality < Renderer::CMB_Q_MAX );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// デバッグ : 計測開始
	////////////////////////////////////////////////////////////////////////////////////////////////////

	SCENE_DEB( m_DebTimer.Reset() );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 実行
	////////////////////////////////////////////////////////////////////////////////////////////////////

	args.invViewProjMat = m_pCamera->GetInvViewProjectionMatrix().ToTranspose();
	args.preViewProjMat = m_pCamera->GetMotionBlurPreVPMat().ToTranspose();
	args.cp0 = internalSettings.cp0;
	args.cp1 = internalSettings.cp1;
	args.cp2 = internalSettings.cp2;
	args.scale = internalSettings.scale;
	args.intensity = internalSettings.intensity;
	args.invVolume = internalSettings.invVolume;
	args.dist = internalSettings.dist;

	OnRenderCameraMotionBlur( args );

	m_pGraphicsDev->SetTarget( m_pColorTexChain->GetNextPtr(), NULL, NULL, NULL, NULL );
	m_pGraphicsDev->SetViewBounds( m_Viewport );

	m_pGraphicsDev->SetBlendState( Mix::Graphics::BLEND_COPY );
	m_pGraphicsDev->SetDepthState( False, False );
	m_pGraphicsDev->SetRasterizerState( Mix::Graphics::FILL_SOLID, Mix::Graphics::CULL_NONE, False );

	m_pGraphicsDev->SetTexture( Renderer::TS_CMB_COLOR, Mix::Graphics::TEXTURE_FILTER_POINT, Mix::Graphics::TEXTURE_ADDRESS_CLAMP, m_pColorTexChain->GetCurrentPtr() );
	m_pGraphicsDev->SetTexture( Renderer::TS_CMB_DEPTH, Mix::Graphics::TEXTURE_FILTER_POINT, Mix::Graphics::TEXTURE_ADDRESS_CLAMP, m_pDepthTexChain->GetCurrentPtr() );

	m_pGraphicsDev->SetVertexLayout( m_pSamplingVL );
	m_pGraphicsDev->SetVertexShader( m_pSamplingVS );
	m_pGraphicsDev->SetPixelShader( m_pCamMotionBlurPS[settings.quality] );

	DrawQuad();

	m_pColorTexChain->Flip();

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// デバッグ : 計測終了
	////////////////////////////////////////////////////////////////////////////////////////////////////

	SCENE_DEB( m_pDebCProfPostProc->mbElapsedTime = m_DebTimer.GetF32() );
}

void Renderer::PostProcess_Chromatism( void )
{
	MIX_ASSERT( m_pCamera != NULL );

	if( ( m_pCamera->IsChromatismAvailabled() == False ) || ( m_pCamera->IsChromatismEnabled() == False ) )
	{
		return;
	}

	MIX_ASSERT( m_pCATexChain != NULL );

	const Mix::Scene::ICamera::CHROMATISM_SETTINGS& camSettings = m_pCamera->GetChromatismSettings();
	const Mix::Scene::Common::Camera::INTERNAL_CHROMATISM_SETTINGS& camInternalSettings = m_pCamera->GetInternalChromatismSettings();

	UInt32 finish_d = ( ( MIX_FLOAT_IS_ZERO( camInternalSettings.invDist ) == True ) && ( MIX_FLOAT_IS_ZERO( camInternalSettings.fiStartZ ) == True ) )? 0 : 1;

	Renderer::RENDER_CHROMATISM_FINISH_ARGS args;

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// デバッグ計測開始
	////////////////////////////////////////////////////////////////////////////////////////////////////

	SCENE_DEB( m_DebTimer.Reset() );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 歪曲収差( Rのみ )
	////////////////////////////////////////////////////////////////////////////////////////////////////

	if( m_CASamplingType == Mix::Scene::Common::RST_COPY )
	{
		// 色収差の差分をレンダリング
		RenderChromatismImage(	camSettings.distortion.k, camSettings.distortion.kCube, camSettings.distortion.scale, camSettings.colorFactor,
								m_pColorTexChain->GetCurrentPtr(),
								m_pCATexChain->GetCurrentPtr() );
	}
	else
	{
		MIX_ASSERT( ( m_CASamplingType == Mix::Scene::Common::RST_DOWN2x ) || ( m_CASamplingType == Mix::Scene::Common::RST_DOWN4x ) );

		// ダウンサンプリング
		RenderSampling( m_CASamplingType,
						Mix::Graphics::COLOR_WRITE_RGBA,
						Mix::Graphics::BLEND_COPY,
						Mix::Graphics::TEXTURE_FILTER_LINEAR,
						m_pColorTexChain->GetCurrentPtr(),
						m_pCATexChain->GetCurrentPtr() );

		// 色収差の差分をレンダリング
		RenderChromatismImage(	camSettings.distortion.k, camSettings.distortion.kCube, camSettings.distortion.scale, camSettings.colorFactor,
								m_pCATexChain->GetCurrentPtr(),
								m_pCATexChain->GetNextPtr() );


		m_pCATexChain->Flip();
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// ブラー
	////////////////////////////////////////////////////////////////////////////////////////////////////

	RenderBlur( camSettings.blur, m_pCATexChain );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// フィニッシュ
	////////////////////////////////////////////////////////////////////////////////////////////////////

	args.weight = camSettings.weight;
	args.fiStartZ = camInternalSettings.fiStartZ;
	args.fiInvDist = camInternalSettings.invDist;

	OnRenderChromatismFinish( args );

	m_pGraphicsDev->SetTarget( m_pColorTexChain->GetNextPtr(), NULL, NULL, NULL, NULL );
	m_pGraphicsDev->SetViewBounds( m_Viewport );

	m_pGraphicsDev->SetBlendState( Mix::Graphics::BLEND_COPY );
	m_pGraphicsDev->SetDepthState( False, False );
	m_pGraphicsDev->SetRasterizerState( Mix::Graphics::FILL_SOLID, Mix::Graphics::CULL_NONE, False );

	m_pGraphicsDev->SetTexture( Renderer::TS_CA_FINISH_COLOR, Mix::Graphics::TEXTURE_FILTER_POINT,  Mix::Graphics::TEXTURE_ADDRESS_CLAMP, m_pColorTexChain->GetCurrentPtr() );
	m_pGraphicsDev->SetTexture( Renderer::TS_CA_FINISH_IMAGE, Mix::Graphics::TEXTURE_FILTER_LINEAR, Mix::Graphics::TEXTURE_ADDRESS_CLAMP, m_pCATexChain->GetCurrentPtr() );
	m_pGraphicsDev->SetTexture( Renderer::TS_CA_FINISH_DEPTH, Mix::Graphics::TEXTURE_FILTER_POINT,  Mix::Graphics::TEXTURE_ADDRESS_CLAMP, m_pDepthTexChain->GetCurrentPtr() );

	m_pGraphicsDev->SetVertexLayout( m_pSamplingVL );
	m_pGraphicsDev->SetVertexShader( m_pSamplingVS );
	m_pGraphicsDev->SetPixelShader( m_pCAFinishPS[finish_d] );

	DrawQuad();

	m_pColorTexChain->Flip();

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// デバッグ計測終了
	////////////////////////////////////////////////////////////////////////////////////////////////////

	SCENE_DEB( m_pDebCProfPostProc->caElapsedTime = m_DebTimer.GetF32() );
}

void Renderer::PostProcess_Dof( void )
{
	MIX_ASSERT( m_pCamera != NULL );

	if( ( m_pCamera->IsDofAvailabled() == False ) || ( m_pCamera->IsDofEnabled() == False ) )
	{
		return;
	}

	MIX_ASSERT( m_pDofPS != NULL );
	MIX_ASSERT( m_pDofSamplingTable != NULL );
	MIX_ASSERT( m_pDofBokehTex0 != NULL );
	MIX_ASSERT( m_pDofBokehTex1 != NULL );
	MIX_ASSERT( m_pDofTempTex != NULL );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// デバッグ計測開始
	////////////////////////////////////////////////////////////////////////////////////////////////////

	SCENE_DEB( m_DebTimer.Reset() );

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

	Mix::Graphics::ITexture* pSource = m_pColorTexChain->GetCurrentPtr();
	Mix::Graphics::ITexture* pTarget = m_pColorTexChain->GetNextPtr();

	const Mix::Scene::ICamera::DOF_SETTINGS& camSettings = m_pCamera->GetDofSettings();
	const Mix::Scene::Common::Camera::INTERNAL_DOF_SETTINGS& camInternalSettings = m_pCamera->GetInternalDofSettings();

	Renderer::RENDER_DOF_ARGS args;

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// ぼかしテクスチャを作成
	////////////////////////////////////////////////////////////////////////////////////////////////////

	// Blur 1

	RenderSampling( m_DofSamplingType,
					Mix::Graphics::COLOR_WRITE_RGBA,
					Mix::Graphics::BLEND_COPY,
					Mix::Graphics::TEXTURE_FILTER_LINEAR,
					pSource,
					m_pDofBokehTex0 );

	if( camSettings.blur1.IsValid() == True )
	{
		RenderBlur( camSettings.blur1, m_pDofBokehTex0, m_pDofBokehTex0, m_pDofTempTex );
	}

	// Blur 2

	RenderSampling( m_DofSamplingType,
					Mix::Graphics::COLOR_WRITE_RGBA,
					Mix::Graphics::BLEND_COPY,
					Mix::Graphics::TEXTURE_FILTER_LINEAR,
					pSource,
					m_pDofBokehTex1 );

	if( camSettings.blur2.IsValid() == True )
	{
		RenderBlur( camSettings.blur2, m_pDofBokehTex1, m_pDofBokehTex1, m_pDofTempTex );
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// コミット( 被写界深度 )
	////////////////////////////////////////////////////////////////////////////////////////////////////

	args.nearZ = camInternalSettings.nearZ;
	args.farZ = camInternalSettings.farZ;
	args.invNearDist = camInternalSettings.invNearDist;
	args.invFarDist = camInternalSettings.invFarDist;
	args.blurThreshold = camSettings.blurThreshold;
	args.invBlurThreaholdN = camInternalSettings.invBlurThresholdN;
	args.invBlurThreaholdF = camInternalSettings.invBlurThresholdF;
	args.samplingTable = m_pDofSamplingTable;

	OnRenderDof( args );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 実行( 被写界深度 )
	////////////////////////////////////////////////////////////////////////////////////////////////////

	m_pGraphicsDev->SetTarget( pTarget, NULL, NULL, NULL, NULL );
	m_pGraphicsDev->SetViewBounds( 0, 0, pTarget->GetWidth(), pTarget->GetHeight() );
	m_pGraphicsDev->Clear( True, False );

	m_pGraphicsDev->SetBlendState( Mix::Graphics::BLEND_COPY );
	m_pGraphicsDev->SetDepthState( False, False );
	m_pGraphicsDev->SetRasterizerState( Mix::Graphics::FILL_SOLID, Mix::Graphics::CULL_NONE, False );

	m_pGraphicsDev->SetTexture( Renderer::TS_DOF_DEPTH,  Mix::Graphics::TEXTURE_FILTER_POINT,  Mix::Graphics::TEXTURE_ADDRESS_CLAMP, m_pDepthTexChain->GetCurrentPtr() );
	m_pGraphicsDev->SetTexture( Renderer::TS_DOF_DATA,   Mix::Graphics::TEXTURE_FILTER_POINT,  Mix::Graphics::TEXTURE_ADDRESS_CLAMP, m_pDataTex );
	m_pGraphicsDev->SetTexture( Renderer::TS_DOF_COLOR0, Mix::Graphics::TEXTURE_FILTER_POINT,  Mix::Graphics::TEXTURE_ADDRESS_CLAMP, pSource );
	m_pGraphicsDev->SetTexture( Renderer::TS_DOF_COLOR1, Mix::Graphics::TEXTURE_FILTER_LINEAR, Mix::Graphics::TEXTURE_ADDRESS_CLAMP, m_pDofBokehTex0 );
	m_pGraphicsDev->SetTexture( Renderer::TS_DOF_COLOR2, Mix::Graphics::TEXTURE_FILTER_LINEAR, Mix::Graphics::TEXTURE_ADDRESS_CLAMP, m_pDofBokehTex1 );

	m_pGraphicsDev->SetVertexLayout( m_pSamplingVL );
	m_pGraphicsDev->SetVertexShader( m_pSamplingVS );
	m_pGraphicsDev->SetPixelShader( m_pDofPS );

	DrawQuad();

	m_pColorTexChain->Flip();

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// デバッグ計測終了
	////////////////////////////////////////////////////////////////////////////////////////////////////

	SCENE_DEB( m_pDebCProfPostProc->dofElapsedTime += m_DebTimer.GetF32() );
}

void Renderer::PostProcess_LensDistortion( void )
{
	MIX_ASSERT( m_pCamera != NULL );

	if( m_pCamera->IsLensDistortionEnabled() == False )
	{
		return;
	}

	const Mix::Scene::ICamera::DISTORTION_SETTINGS& camSettings = m_pCamera->GetLendDistortionSettings();
	UInt32 ki = ( MIX_FLOAT_IS_ZERO( camSettings.kCube ) == False )? 1 : 0;

	Renderer::RENDER_LENS_DISTORTION_ARGS args;

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// デバッグ : 計測開始
	////////////////////////////////////////////////////////////////////////////////////////////////////

	SCENE_DEB( m_DebTimer.Reset() );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 実行
	////////////////////////////////////////////////////////////////////////////////////////////////////

	args.k = camSettings.k;
	args.kCube = camSettings.kCube;
	args.scale = camSettings.scale;

	OnRenderLensDistortion( args );

	m_pGraphicsDev->SetTarget( m_pColorTexChain->GetNextPtr(), NULL, NULL, NULL, NULL );
	m_pGraphicsDev->SetViewBounds( 0, 0, m_pColorTexChain->GetWidth(), m_pColorTexChain->GetHeight() );

	m_pGraphicsDev->SetBlendState( Mix::Graphics::BLEND_COPY );
	m_pGraphicsDev->SetDepthState( False, False );
	m_pGraphicsDev->SetRasterizerState( Mix::Graphics::FILL_SOLID, Mix::Graphics::CULL_NONE, False );

	m_pGraphicsDev->SetTexture( Renderer::TS_LD_COLOR,
								Mix::Graphics::TEXTURE_FILTER_POINT,
								Mix::Graphics::TEXTURE_ADDRESS_CLAMP,
								m_pColorTexChain->GetCurrentPtr() );

	m_pGraphicsDev->SetVertexLayout( m_pSamplingVL );
	m_pGraphicsDev->SetVertexShader( m_pSamplingVS );
	m_pGraphicsDev->SetPixelShader( m_pLensDistortionPS[ki] );

	DrawQuad();

	m_pColorTexChain->Flip();

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// デバッグ : 計測終了
	////////////////////////////////////////////////////////////////////////////////////////////////////

	SCENE_DEB( m_pDebCProfPostProc->ldElapsedTime += m_DebTimer.GetF32() );
}

void Renderer::PostProcess_Vignette( void )
{
	MIX_ASSERT( m_pCamera != NULL );

	if( m_pCamera->IsVignetteEnabled() == False )
	{
		return;
	}

	const Mix::Scene::ICamera::VIGNETTE_SETTINGS& settings = m_pCamera->GetVignetteSettings();
	const Mix::Scene::Common::Camera::INTERNAL_VIGNETTE_SETTINGS& internalSettings = m_pCamera->GetInternalVignetteSettings();

	Renderer::RENDER_VIGNETTE_ARGS args;

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// デバッグ : 計測開始
	////////////////////////////////////////////////////////////////////////////////////////////////////

	SCENE_DEB( m_DebTimer.Reset() );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 実行
	////////////////////////////////////////////////////////////////////////////////////////////////////

	args.start = internalSettings.start;
	args.invDist = internalSettings.invDist;
	args.color = settings.color;

	OnRenderVignette( args );

	m_pGraphicsDev->SetTarget( m_pColorTexChain->GetNextPtr(), NULL, NULL, NULL, NULL );
	m_pGraphicsDev->SetViewBounds( m_Viewport );

	m_pGraphicsDev->SetBlendState( Mix::Graphics::BLEND_COPY );
	m_pGraphicsDev->SetDepthState( False, False );
	m_pGraphicsDev->SetRasterizerState( Mix::Graphics::FILL_SOLID, Mix::Graphics::CULL_NONE, False );

	m_pGraphicsDev->SetTexture( Renderer::TS_VI_COLOR,
								Mix::Graphics::TEXTURE_FILTER_POINT,
								Mix::Graphics::TEXTURE_ADDRESS_CLAMP,
								m_pColorTexChain->GetCurrentPtr() );

	m_pGraphicsDev->SetVertexLayout( m_pSamplingVL );
	m_pGraphicsDev->SetVertexShader( m_pSamplingVS );
	m_pGraphicsDev->SetPixelShader( m_pVignettePS );

	DrawQuad();

	m_pColorTexChain->Flip();

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// デバッグ : 計測終了
	////////////////////////////////////////////////////////////////////////////////////////////////////

	SCENE_DEB( m_pDebCProfPostProc->viElapsedTime += m_DebTimer.GetF32() );
}

void Renderer::PostProcess_AntiAliasing( void )
{
	MIX_ASSERT( m_pCamera != NULL );

	Mix::Scene::ICamera::ANTIALIASING_TYPE aaType = m_pCamera->GetAntiAliasingType();

	if( aaType == Mix::Scene::ICamera::AA_NONE )
	{
		return;
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// デバッグ計測開始
	////////////////////////////////////////////////////////////////////////////////////////////////////

	SCENE_DEB( m_DebTimer.Reset() );

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

	Mix::Graphics::ITexture* pTarget = m_pColorTexChain->GetNextPtr();
	Mix::Graphics::ITexture* pSource = m_pColorTexChain->GetCurrentPtr();

	Float32 widthF = static_cast<Float32>( pSource->GetWidth() );
	Float32 heightF = static_cast<Float32>( pSource->GetHeight() );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// イベントを通知
	////////////////////////////////////////////////////////////////////////////////////////////////////

	Renderer::RENDER_FXAA_ARGS args;

	args.texCoords[0].x = MIX_FLOAT_DIV( -1.0f, widthF );
	args.texCoords[0].y = MIX_FLOAT_DIV( -1.0f, heightF );
	args.texCoords[0].z = MIX_FLOAT_DIV(  1.0f, widthF );
	args.texCoords[0].w = MIX_FLOAT_DIV( -1.0f, heightF );
	args.texCoords[1].x = MIX_FLOAT_DIV( -1.0f, widthF );
	args.texCoords[1].y = MIX_FLOAT_DIV(  1.0f, heightF );
	args.texCoords[1].z = MIX_FLOAT_DIV(  1.0f, widthF );
	args.texCoords[1].w = MIX_FLOAT_DIV(  1.0f, heightF );
	args.invScreenSize.x = MIX_FLOAT_RECIPROCAL( widthF );
	args.invScreenSize.y = MIX_FLOAT_RECIPROCAL( heightF );

	OnRenderFXAA( args );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 実行
	////////////////////////////////////////////////////////////////////////////////////////////////////

	m_pGraphicsDev->SetTarget( pTarget, NULL, NULL, NULL, NULL );
	m_pGraphicsDev->SetViewBounds( 0, 0, pTarget->GetWidth(), pTarget->GetHeight() );

	m_pGraphicsDev->SetBlendState( Mix::Graphics::BLEND_COPY );
	m_pGraphicsDev->SetDepthState( False, False );
	m_pGraphicsDev->SetRasterizerState( Mix::Graphics::FILL_SOLID, Mix::Graphics::CULL_NONE, False );

	m_pGraphicsDev->SetTexture( 0, Mix::Graphics::TEXTURE_FILTER_POINT, Mix::Graphics::TEXTURE_ADDRESS_CLAMP, pSource );

	m_pGraphicsDev->SetVertexLayout( m_pSamplingVL );
	m_pGraphicsDev->SetVertexShader( m_pSamplingVS );
	m_pGraphicsDev->SetPixelShader( m_pAntiAliasingPS );

	DrawQuad();

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 後処理
	////////////////////////////////////////////////////////////////////////////////////////////////////

	m_pColorTexChain->Flip();

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// デバッグ計測終了
	////////////////////////////////////////////////////////////////////////////////////////////////////

	SCENE_DEB( m_pDebCProfPostProc->aaElapsedTime += m_DebTimer.GetF32() );
}

void Renderer::PostProcess_Final( void )
{
	MIX_ASSERT( m_pCamera != NULL );

	Mix::Graphics::ITexture* pSource = m_pColorTexChain->GetCurrentPtr();
	Mix::Graphics::ITexture* pTarget = m_DeviceState.pTargetTexture[0];
	Renderer::RENDER_SAMPLING_ARGS args;

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// デバッグ描画
	////////////////////////////////////////////////////////////////////////////////////////////////////

#ifdef _DEBUG

	Mix::Scene::DEBUG_DRAW_METHOD debDrawMethod = m_pCamera->Debug_GetDrawMethod();

	m_pGraphicsDev->SetTarget( pSource, NULL, NULL, NULL, m_pDepthBuff );
	m_pGraphicsDev->SetViewBounds( m_Viewport );
	m_pGraphicsDev->SetScissorBounds( m_Viewport );

	if( debDrawMethod != Mix::Scene::DDM_BEFORE )
	{
		m_pGraphicsDev->SetBlendState( Mix::Graphics::BLEND_NORMAL );
		m_pGraphicsDev->SetDepthState( ( debDrawMethod == Mix::Scene::DDM_AFTER ), False );
		m_pGraphicsDev->SetRasterizerState( Mix::Graphics::FILL_SOLID, Mix::Graphics::CULL_NONE, FALSE );

		Debug_Draw3D();
	}

	// ブレンド、デプス、ラスタライザの設定はキャンバスレンダラーで行われる
	// また、行列、クリップのスタックは強制排出され、初期化される
	Debug_Draw2D();

#endif //_DEBUG

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// デバッグ計測開始
	////////////////////////////////////////////////////////////////////////////////////////////////////

	SCENE_DEB( m_DebTimer.Reset() );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// バックバッファへ転送
	////////////////////////////////////////////////////////////////////////////////////////////////////

	args.texelSize.x = MIX_FLOAT_RECIPROCAL( static_cast<Float32>( pSource->GetWidth() ) );
	args.texelSize.y = MIX_FLOAT_RECIPROCAL( static_cast<Float32>( pSource->GetHeight() ) );
	args.colorScale = 1.0f;

	OnRenderSampling( args );

	m_pGraphicsDev->SetTarget( pTarget, NULL, NULL, NULL, NULL );
	m_pGraphicsDev->SetViewBounds( m_DeviceState.viewport );
	m_pGraphicsDev->SetScissorBounds( m_DeviceState.scissor );

	m_pGraphicsDev->SetBlendState( m_DeviceState.blend );
	m_pGraphicsDev->SetDepthState( False, False );
	m_pGraphicsDev->SetRasterizerState( Mix::Graphics::FILL_SOLID, Mix::Graphics::CULL_NONE, m_DeviceState.rasterizer.bScissoring );

	m_pGraphicsDev->SetTexture( Renderer::TS_SAMPLING_SOURCE, m_pCamera->GetFilterType(), Mix::Graphics::TEXTURE_ADDRESS_CLAMP, pSource );

	m_pGraphicsDev->SetVertexLayout( m_pSamplingVL );
	m_pGraphicsDev->SetVertexShader( m_pSamplingVS );
	m_pGraphicsDev->SetPixelShader( m_pSamplingPS[Mix::Scene::Common::RST_COPY] );

	DrawQuad();

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// デバッグ計測終了
	////////////////////////////////////////////////////////////////////////////////////////////////////

	SCENE_DEB( m_pDebCProfPostProc->finalElapsedTime += m_DebTimer.GetF32() );
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Mix::Scene::Standard::Common::Renderer : クリーンアップ
////////////////////////////////////////////////////////////////////////////////////////////////////

void Renderer::CleanupWork( void )
{
	m_WidgetQuadCount = 0;
	m_WidgetSubsetList.Clear();
	m_WidgetObjectList.Clear();
	m_VisibleLocalLightList.Clear();
	m_LocalLightList.Clear();
	m_VisibleWaterPoolList.Clear();
	m_WorldMatrixList.Clear();
	m_TransparencyObjList.Clear();
	m_ShadowComList.Clear();
	m_OpacityComList.Clear();
	m_TransparencyComList.Clear();
	m_TransparencyBackComList.Clear();
	m_TransparencyFrontComList.Clear();
	m_RefractMaskComList.Clear();
	m_RefractComList.Clear();
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Mix::Scene::Standard::Common::Renderer : その他
////////////////////////////////////////////////////////////////////////////////////////////////////

Mix::Vector2 Renderer::GetTexelSize( Mix::Graphics::ITexture* pTex )
{
	MIX_ASSERT( pTex != NULL );

	return Mix::Vector2( 1.0f / static_cast<Float32>( pTex->GetWidth() ), 1.0f / static_cast<Float32>( pTex->GetHeight() ) );
}

Mix::Vector2 Renderer::GetTexelSize( Mix::Graphics::Utility::ITargetTextureChain* pTexChain )
{
	MIX_ASSERT( pTexChain != NULL );

	return Mix::Vector2( 1.0f / static_cast<Float32>( pTexChain->GetWidth() ), 1.0f / static_cast<Float32>( pTexChain->GetHeight() ) );
}

void Renderer::RenderSampling( Mix::Graphics::Utility::ITargetTextureChain* pTexChain )
{
	MIX_ASSERT( pTexChain != NULL );

	Renderer::RENDER_SAMPLING_ARGS args;

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// コミット
	////////////////////////////////////////////////////////////////////////////////////////////////////

	args.texelSize.x = MIX_FLOAT_RECIPROCAL( static_cast<Float32>( pTexChain->GetWidth() ) );
	args.texelSize.y = MIX_FLOAT_RECIPROCAL( static_cast<Float32>( pTexChain->GetHeight() ) );
	args.colorScale = 1.0f;

	OnRenderSampling( args );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 実行
	////////////////////////////////////////////////////////////////////////////////////////////////////

	m_pGraphicsDev->SetTarget( pTexChain->GetCurrentPtr(), NULL, NULL, NULL, NULL );
	m_pGraphicsDev->SetViewBounds( 0, 0, pTexChain->GetWidth(), pTexChain->GetHeight() );

	m_pGraphicsDev->SetBlendState( Mix::Graphics::BLEND_COPY );
	m_pGraphicsDev->SetDepthState( False, False );
	m_pGraphicsDev->SetRasterizerState( Mix::Graphics::FILL_SOLID, Mix::Graphics::CULL_NONE, False );

	m_pGraphicsDev->SetTexture( Renderer::TS_SAMPLING_SOURCE, Mix::Graphics::TEXTURE_FILTER_POINT, Mix::Graphics::TEXTURE_ADDRESS_CLAMP, pTexChain->GetNextPtr() );

	m_pGraphicsDev->SetVertexLayout( m_pSamplingVL );
	m_pGraphicsDev->SetVertexShader( m_pSamplingVS );
	m_pGraphicsDev->SetPixelShader( m_pSamplingPS[Mix::Scene::Common::RST_COPY] );

	DrawQuad();

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// フリップ
	////////////////////////////////////////////////////////////////////////////////////////////////////

	pTexChain->Flip();
}

void Renderer::RenderSampling( Mix::Graphics::COLOR_WRITE_MASK mask, Mix::Graphics::ITexture* pSource, Mix::Graphics::ITexture* pTarget )
{
	MIX_ASSERT( pSource != NULL );
	MIX_ASSERT( pTarget != NULL );

	Renderer::RENDER_SAMPLING_ARGS args;

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// コミット
	////////////////////////////////////////////////////////////////////////////////////////////////////

	args.texelSize.x = MIX_FLOAT_RECIPROCAL( static_cast<Float32>( pSource->GetWidth() ) );
	args.texelSize.y = MIX_FLOAT_RECIPROCAL( static_cast<Float32>( pSource->GetHeight() ) );
	args.colorScale = 1.0f;

	OnRenderSampling( args );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 実行
	////////////////////////////////////////////////////////////////////////////////////////////////////

	m_pGraphicsDev->SetTarget( pTarget, NULL, NULL, NULL, NULL );
	m_pGraphicsDev->SetViewBounds( 0, 0, pSource->GetWidth(), pSource->GetHeight() );

	m_pGraphicsDev->SetBlendState( Mix::Graphics::BLEND_COPY, mask );
	m_pGraphicsDev->SetDepthState( False, False );
	m_pGraphicsDev->SetRasterizerState( Mix::Graphics::FILL_SOLID, Mix::Graphics::CULL_NONE, False );

	m_pGraphicsDev->SetTexture( Renderer::TS_SAMPLING_SOURCE, Mix::Graphics::TEXTURE_FILTER_POINT, Mix::Graphics::TEXTURE_ADDRESS_CLAMP, pSource );

	m_pGraphicsDev->SetVertexLayout( m_pSamplingVL );
	m_pGraphicsDev->SetVertexShader( m_pSamplingVS );
	m_pGraphicsDev->SetPixelShader( m_pSamplingPS[Mix::Scene::Common::RST_COPY] );

	DrawQuad();
}

void Renderer::RenderSampling(	Mix::Scene::Common::RENDERER_SAMPLING_TYPE type,
								Float32 colorScale,
								Mix::Graphics::BLEND_TYPE blendMode,
								Mix::Graphics::TEXTURE_FILTER_TYPE filter,
								Mix::Graphics::ITexture* pSoruce,
								Mix::Graphics::ITexture* pTarget )
{
	MIX_ASSERT( pSoruce != NULL );

	Mix::Point targetSize;
	Renderer::RENDER_SAMPLING_ARGS args;

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// ターゲットのサイズを取得
	////////////////////////////////////////////////////////////////////////////////////////////////////

	if( pTarget != NULL )
	{
		targetSize.x = static_cast<Int32>( pTarget->GetWidth() );
		targetSize.y = static_cast<Int32>( pTarget->GetHeight() );
	}
	else
	{
		targetSize = m_pGraphicsDev->GetScreenSize();
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// コミット
	////////////////////////////////////////////////////////////////////////////////////////////////////

	args.texelSize.x = MIX_FLOAT_RECIPROCAL( static_cast<Float32>( pSoruce->GetWidth() ) );
	args.texelSize.y = MIX_FLOAT_RECIPROCAL( static_cast<Float32>( pSoruce->GetHeight() ) );
	args.colorScale = colorScale;

	OnRenderSampling( args );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 実行
	////////////////////////////////////////////////////////////////////////////////////////////////////

	m_pGraphicsDev->SetTarget( pTarget, NULL, NULL, NULL, NULL );
	m_pGraphicsDev->SetViewBounds( 0, 0, targetSize.x, targetSize.y );

	m_pGraphicsDev->SetBlendState( blendMode );
	m_pGraphicsDev->SetDepthState( False, False );
	m_pGraphicsDev->SetRasterizerState( Mix::Graphics::FILL_SOLID, Mix::Graphics::CULL_NONE, False );

	m_pGraphicsDev->SetTexture( Renderer::TS_SAMPLING_SOURCE, filter, Mix::Graphics::TEXTURE_ADDRESS_CLAMP, pSoruce );

	m_pGraphicsDev->SetVertexLayout( m_pSamplingVL );
	m_pGraphicsDev->SetVertexShader( m_pSamplingVS );
	m_pGraphicsDev->SetPixelShader( m_pSamplingPS[type] );

	DrawQuad();
}

void Renderer::RenderSampling(	Mix::Scene::Common::RENDERER_SAMPLING_TYPE type,
								Mix::Graphics::COLOR_WRITE_MASK mask,
								Mix::Graphics::BLEND_TYPE blendMode,
								Mix::Graphics::TEXTURE_FILTER_TYPE filter,
								Mix::Graphics::ITexture* pSoruce,
								Mix::Graphics::ITexture* pTarget )
{
	MIX_ASSERT( pSoruce != NULL );

	Mix::Point targetSize;
	Renderer::RENDER_SAMPLING_ARGS args;

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// ターゲットのサイズを取得
	////////////////////////////////////////////////////////////////////////////////////////////////////

	if( pTarget != NULL )
	{
		targetSize.x = static_cast<Int32>( pTarget->GetWidth() );
		targetSize.y = static_cast<Int32>( pTarget->GetHeight() );
	}
	else
	{
		targetSize = m_pGraphicsDev->GetScreenSize();
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// コミット
	////////////////////////////////////////////////////////////////////////////////////////////////////

	args.texelSize.x = MIX_FLOAT_RECIPROCAL( static_cast<Float32>( pSoruce->GetWidth() ) );
	args.texelSize.y = MIX_FLOAT_RECIPROCAL( static_cast<Float32>( pSoruce->GetHeight() ) );
	args.colorScale = 1.0f;

	OnRenderSampling( args );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 実行
	////////////////////////////////////////////////////////////////////////////////////////////////////

	m_pGraphicsDev->SetTarget( pTarget, NULL, NULL, NULL, NULL );
	m_pGraphicsDev->SetViewBounds( 0, 0, targetSize.x, targetSize.y );

	m_pGraphicsDev->SetBlendState( blendMode, mask );
	m_pGraphicsDev->SetDepthState( False, False );
	m_pGraphicsDev->SetRasterizerState( Mix::Graphics::FILL_SOLID, Mix::Graphics::CULL_NONE, False );

	m_pGraphicsDev->SetTexture( Renderer::TS_SAMPLING_SOURCE, filter, Mix::Graphics::TEXTURE_ADDRESS_CLAMP, pSoruce );

	m_pGraphicsDev->SetVertexLayout( m_pSamplingVL );
	m_pGraphicsDev->SetVertexShader( m_pSamplingVS );
	m_pGraphicsDev->SetPixelShader( m_pSamplingPS[type] );

	DrawQuad();
}

void Renderer::RenderBlur( const Mix::Scene::BLUR& param, Mix::Graphics::Utility::ITargetTextureChain* pTexChain )
{
	MIX_ASSERT( pTexChain != NULL );

	switch( param.GetType() )
	{
	case Mix::Scene::BLUR::T_KS_3x3:
		if( param.GetIntValue() > 0 ) { RenderBlur( Renderer::BLUR_3x3, param.GetIntValue(), pTexChain ); }
		break;
	case Mix::Scene::BLUR::T_KS_5x5:
		if( param.GetIntValue() > 0 ) { RenderBlur( Renderer::BLUR_5x5, param.GetIntValue(), pTexChain ); }
		break;
	case Mix::Scene::BLUR::T_GAUSSIAN:
		if( param.GetFloatValue() > MIX_FLOAT_EPSILON ) { RenderGaussianBlur( param.GetFloatValue(), pTexChain ); }
		break;
	case Mix::Scene::BLUR::T_GAUSSIAN_EX:
		if( param.GetIntValue() > 0 ) { RenderGaussianBlurEx( MIX_CLAMP( param.GetIntValue(), 4, 64 ), pTexChain ); }
		break;
	}
}

void Renderer::RenderBlur( const Mix::Scene::BLUR& param, Mix::Graphics::ITexture* pSourceTex, Mix::Graphics::ITexture* pTargetTex, Mix::Graphics::ITexture* pTempTex )
{
	MIX_ASSERT( pSourceTex != NULL );
	MIX_ASSERT( pTargetTex != NULL );
	MIX_ASSERT( pTempTex != NULL );

	if( ( param.GetType() == Mix::Scene::BLUR::T_KS_3x3 ) && ( param.GetIntValue() > 0 ) )
	{
		RenderBlur( Renderer::BLUR_3x3, param.GetIntValue(), pSourceTex, pTargetTex, pTempTex );
	}
	else if( ( param.GetType() == Mix::Scene::BLUR::T_KS_5x5 ) && ( param.GetIntValue() > 0 ) )
	{
		RenderBlur( Renderer::BLUR_5x5, param.GetIntValue(), pSourceTex, pTargetTex, pTempTex );
	}
	else if( ( param.GetType() == Mix::Scene::BLUR::T_GAUSSIAN ) && ( param.GetFloatValue() > MIX_FLOAT_EPSILON ) )
	{
		RenderGaussianBlur( param.GetFloatValue(), pSourceTex, pTargetTex, pTempTex );
	}
	else if( ( param.GetType() == Mix::Scene::BLUR::T_GAUSSIAN_EX ) && ( param.GetIntValue() > 0 ) )
	{
		RenderGaussianBlurEx( MIX_CLAMP( param.GetIntValue(), 2, 64 ), pSourceTex, pTargetTex, pTempTex );
	}
}

void Renderer::RenderBlur( Renderer::BLUR_TYPE type, Int32 iteration, Mix::Graphics::Utility::ITargetTextureChain* pTextureChain )
{
	MIX_ASSERT( type < Renderer::BLUR_TYPE_MAX );
	MIX_ASSERT( iteration >= Mix::Scene::KS_BLUR_MIN_ITERATION );
	MIX_ASSERT( iteration <= Mix::Scene::KS_BLUR_MAX_ITERATION );
	MIX_ASSERT( pTextureChain != NULL );

	Mix::Graphics::IPixelShader* pBlurPS_X = m_pBlurPS[type][Renderer::BLUR_X];
	Mix::Graphics::IPixelShader* pBlurPS_Y = m_pBlurPS[type][Renderer::BLUR_Y];

	MIX_ASSERT( pBlurPS_X != NULL );
	MIX_ASSERT( pBlurPS_Y != NULL );

	Mix::Rectangle viewport( 0, 0, pTextureChain->GetWidth(), pTextureChain->GetHeight() );
	Float32 tx = MIX_FLOAT_RECIPROCAL( static_cast<Float32>( viewport.width ) );
	Float32 ty = MIX_FLOAT_RECIPROCAL( static_cast<Float32>( viewport.height ) );
	Renderer::RENDER_BLUR_ARGS args;

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// イベント
	////////////////////////////////////////////////////////////////////////////////////////////////////

	switch( type )
	{
	case Renderer::BLUR_3x3:
		args.params[0] = Mix::Vector4( 0.0f, 0.0f, 0.0f, 0.4f );
		args.params[1] = Mix::Vector4( tx, ty, 0.0f, 0.3f );
		args.params[2] = Mix::Vector4( 0.0f, 0.0f, 0.0f, 0.0f );
		break;

	case Renderer::BLUR_5x5:
		args.params[0] = Mix::Vector4( 0.0f, 0.0f, 0.0f, 0.4f );
		args.params[1] = Mix::Vector4( tx, ty, 0.0f, 0.2f );
		args.params[2] = Mix::Vector4( tx + tx, ty + ty, 0.0f, 0.1f );
		break;
	}

	OnRenderBlur( args );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 実行
	////////////////////////////////////////////////////////////////////////////////////////////////////

	m_pGraphicsDev->SetVertexLayout( m_pSamplingVL );
	m_pGraphicsDev->SetVertexShader( m_pSamplingVS );

	for( Int32 i = 0; i < iteration; i++ )
	{
		// X方向

		m_pGraphicsDev->SetTarget( pTextureChain->GetNextPtr(), NULL, NULL, NULL, NULL );
		m_pGraphicsDev->SetViewBounds( viewport );

		m_pGraphicsDev->SetBlendState( Mix::Graphics::BLEND_COPY );
		m_pGraphicsDev->SetDepthState( False, False );
		m_pGraphicsDev->SetRasterizerState( Mix::Graphics::FILL_SOLID, Mix::Graphics::CULL_NONE, False );

		m_pGraphicsDev->SetTexture( Renderer::TS_BLUR, Mix::Graphics::TEXTURE_FILTER_LINEAR, Mix::Graphics::TEXTURE_ADDRESS_CLAMP, pTextureChain->GetCurrentPtr() );

		m_pGraphicsDev->SetPixelShader( pBlurPS_X );

		DrawQuad();

		pTextureChain->Flip();

		// Y方向

		m_pGraphicsDev->SetTarget( pTextureChain->GetNextPtr(), NULL, NULL, NULL, NULL );
		m_pGraphicsDev->SetViewBounds( viewport );

		m_pGraphicsDev->SetBlendState( Mix::Graphics::BLEND_COPY );
		m_pGraphicsDev->SetDepthState( False, False );
		m_pGraphicsDev->SetRasterizerState( Mix::Graphics::FILL_SOLID, Mix::Graphics::CULL_NONE, False );

		m_pGraphicsDev->SetTexture( Renderer::TS_BLUR, Mix::Graphics::TEXTURE_FILTER_LINEAR, Mix::Graphics::TEXTURE_ADDRESS_CLAMP, pTextureChain->GetCurrentPtr() );

		m_pGraphicsDev->SetPixelShader( pBlurPS_Y );

		DrawQuad();

		pTextureChain->Flip();
	}
}

void Renderer::RenderBlur( Renderer::BLUR_TYPE type, Int32 iteration, Mix::Graphics::ITexture* pSourceTex, Mix::Graphics::ITexture* pTargetTex, Mix::Graphics::ITexture* pTempTex )
{
	MIX_ASSERT( type < Renderer::BLUR_TYPE_MAX );
	MIX_ASSERT( iteration >= Mix::Scene::KS_BLUR_MIN_ITERATION );
	MIX_ASSERT( iteration <= Mix::Scene::KS_BLUR_MAX_ITERATION );
	MIX_ASSERT( pSourceTex != NULL );
	MIX_ASSERT( pTargetTex != NULL );
	MIX_ASSERT( pTempTex != NULL );
	MIX_ASSERT( pTargetTex != pTempTex );
	MIX_ASSERT( pSourceTex != pTempTex );

	Mix::Graphics::IPixelShader* pBlurPS_X = m_pBlurPS[type][Renderer::BLUR_X];
	Mix::Graphics::IPixelShader* pBlurPS_Y = m_pBlurPS[type][Renderer::BLUR_Y];

	MIX_ASSERT( pBlurPS_X != NULL );
	MIX_ASSERT( pBlurPS_Y != NULL );

	Mix::Rectangle viewport( 0, 0, pTargetTex->GetWidth(), pTargetTex->GetHeight() );

	Float32 tx = MIX_FLOAT_RECIPROCAL( static_cast<Float32>( viewport.width ) );
	Float32 ty = MIX_FLOAT_RECIPROCAL( static_cast<Float32>( viewport.height ) );

	Renderer::RENDER_BLUR_ARGS args;

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// イベント
	////////////////////////////////////////////////////////////////////////////////////////////////////

	switch( type )
	{
	case Renderer::BLUR_3x3:
		args.params[0] = Mix::Vector4( 0.0f, 0.0f, 0.0f, 0.4f );
		args.params[1] = Mix::Vector4( tx, ty, 0.0f, 0.3f );
		args.params[2] = Mix::Vector4( 0.0f, 0.0f, 0.0f, 0.0f );
		break;

	case Renderer::BLUR_5x5:
		args.params[0] = Mix::Vector4( 0.0f, 0.0f, 0.0f, 0.2f );
		args.params[1] = Mix::Vector4( tx, ty, 0.0f, 0.2f );
		args.params[2] = Mix::Vector4( tx + tx, ty + ty, 0.0f, 0.2f );
		break;
	}

	OnRenderBlur( args );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 実行
	////////////////////////////////////////////////////////////////////////////////////////////////////

	m_pGraphicsDev->SetVertexLayout( m_pSamplingVL );
	m_pGraphicsDev->SetVertexShader( m_pSamplingVS );

	for( Int32 i = 0; i < iteration; i++ )
	{
		// X方向

		m_pGraphicsDev->SetTarget( pTempTex, NULL, NULL, NULL, NULL );
		m_pGraphicsDev->SetViewBounds( viewport );

		m_pGraphicsDev->SetBlendState( Mix::Graphics::BLEND_COPY );
		m_pGraphicsDev->SetDepthState( False, False );
		m_pGraphicsDev->SetRasterizerState( Mix::Graphics::FILL_SOLID, Mix::Graphics::CULL_NONE, False );

		m_pGraphicsDev->SetTexture( Renderer::TS_BLUR, Mix::Graphics::TEXTURE_FILTER_LINEAR, Mix::Graphics::TEXTURE_ADDRESS_CLAMP, pSourceTex );

		m_pGraphicsDev->SetPixelShader( pBlurPS_X );

		DrawQuad();

		// Y方向

		m_pGraphicsDev->SetTarget( pTargetTex, NULL, NULL, NULL, NULL );
		m_pGraphicsDev->SetViewBounds( viewport );

		m_pGraphicsDev->SetBlendState( Mix::Graphics::BLEND_COPY );
		m_pGraphicsDev->SetDepthState( False, False );
		m_pGraphicsDev->SetRasterizerState( Mix::Graphics::FILL_SOLID, Mix::Graphics::CULL_NONE, False );

		m_pGraphicsDev->SetTexture( Renderer::TS_BLUR, Mix::Graphics::TEXTURE_FILTER_LINEAR, Mix::Graphics::TEXTURE_ADDRESS_CLAMP, pTempTex );

		m_pGraphicsDev->SetPixelShader( pBlurPS_Y );

		DrawQuad();

		// ソースになるテクスチャを切り替える

		pSourceTex = pTargetTex;
	}
}

void Renderer::RenderGaussianBlur( Float32 dispersion, Mix::Graphics::Utility::ITargetTextureChain* pTextureChain )
{
	MIX_ASSERT( dispersion >= ( Mix::Scene::GAUSSIAN_BLUR_MIN_DISPERSION - MIX_FLOAT_EPSILON ) );
	MIX_ASSERT( dispersion <= ( Mix::Scene::GAUSSIAN_BLUR_MAX_DISPERSION + MIX_FLOAT_EPSILON ) );
	MIX_ASSERT( pTextureChain != NULL );

	Mix::Rectangle viewport( 0, 0, pTextureChain->GetWidth(), pTextureChain->GetHeight() );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// イベント
	////////////////////////////////////////////////////////////////////////////////////////////////////

	OnRenderGaussianBlur( ComputeGauusianBlurArgs( viewport.width, viewport.height, dispersion ) );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 実行
	////////////////////////////////////////////////////////////////////////////////////////////////////

	m_pGraphicsDev->SetVertexLayout( m_pSamplingVL );

	// X方向

	m_pGraphicsDev->SetTarget( pTextureChain->GetNextPtr(), NULL, NULL, NULL, NULL );
	m_pGraphicsDev->SetViewBounds( viewport );

	m_pGraphicsDev->SetBlendState( Mix::Graphics::BLEND_COPY );
	m_pGraphicsDev->SetDepthState( False, False );
	m_pGraphicsDev->SetRasterizerState( Mix::Graphics::FILL_SOLID, Mix::Graphics::CULL_NONE, False );

	m_pGraphicsDev->SetTexture( Renderer::TS_GAUSSIAN_BLUR, Mix::Graphics::TEXTURE_FILTER_LINEAR, Mix::Graphics::TEXTURE_ADDRESS_CLAMP, pTextureChain->GetCurrentPtr() );

	m_pGraphicsDev->SetVertexShader( m_pGaussianBlurVS[Renderer::BLUR_X] );
	m_pGraphicsDev->SetPixelShader( m_pGaussianBlurPS[Renderer::BLUR_X] );

	DrawQuad();

	pTextureChain->Flip();

	// Y方向

	m_pGraphicsDev->SetTarget( pTextureChain->GetNextPtr(), NULL, NULL, NULL, NULL );
	m_pGraphicsDev->SetViewBounds( viewport );

	m_pGraphicsDev->SetBlendState( Mix::Graphics::BLEND_COPY );
	m_pGraphicsDev->SetDepthState( False, False );
	m_pGraphicsDev->SetRasterizerState( Mix::Graphics::FILL_SOLID, Mix::Graphics::CULL_NONE, False );

	m_pGraphicsDev->SetTexture( Renderer::TS_GAUSSIAN_BLUR, Mix::Graphics::TEXTURE_FILTER_LINEAR, Mix::Graphics::TEXTURE_ADDRESS_CLAMP, pTextureChain->GetCurrentPtr() );

	m_pGraphicsDev->SetVertexShader( m_pGaussianBlurVS[Renderer::BLUR_Y] );
	m_pGraphicsDev->SetPixelShader( m_pGaussianBlurPS[Renderer::BLUR_Y] );

	DrawQuad();

	pTextureChain->Flip();
}

void Renderer::RenderGaussianBlur( Float32 dispersion, Mix::Graphics::ITexture* pSourceTex, Mix::Graphics::ITexture* pTargetTex, Mix::Graphics::ITexture* pTempTex )
{
	MIX_ASSERT( dispersion >= ( Mix::Scene::GAUSSIAN_BLUR_MIN_DISPERSION - MIX_FLOAT_EPSILON ) );
	MIX_ASSERT( dispersion <= ( Mix::Scene::GAUSSIAN_BLUR_MAX_DISPERSION + MIX_FLOAT_EPSILON ) );
	MIX_ASSERT( pSourceTex != NULL );
	MIX_ASSERT( pTargetTex != NULL );
	MIX_ASSERT( pTempTex != NULL );
	MIX_ASSERT( pTargetTex != pTempTex );
	MIX_ASSERT( pSourceTex != pTempTex );

	Mix::Rectangle viewport( 0, 0, pTargetTex->GetWidth(), pTargetTex->GetHeight() );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// イベント
	////////////////////////////////////////////////////////////////////////////////////////////////////

	OnRenderGaussianBlur( ComputeGauusianBlurArgs( viewport.width, viewport.height, dispersion ) );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 実行
	////////////////////////////////////////////////////////////////////////////////////////////////////

	m_pGraphicsDev->SetVertexLayout( m_pSamplingVL );

	// X方向

	m_pGraphicsDev->SetTarget( pTempTex, NULL, NULL, NULL, NULL );
	m_pGraphicsDev->SetViewBounds( viewport );

	m_pGraphicsDev->SetBlendState( Mix::Graphics::BLEND_COPY );
	m_pGraphicsDev->SetDepthState( False, False );
	m_pGraphicsDev->SetRasterizerState( Mix::Graphics::FILL_SOLID, Mix::Graphics::CULL_NONE, False );

	m_pGraphicsDev->SetTexture( Renderer::TS_GAUSSIAN_BLUR, Mix::Graphics::TEXTURE_FILTER_LINEAR, Mix::Graphics::TEXTURE_ADDRESS_CLAMP, pSourceTex );

	m_pGraphicsDev->SetVertexShader( m_pGaussianBlurVS[Renderer::BLUR_X] );
	m_pGraphicsDev->SetPixelShader( m_pGaussianBlurPS[Renderer::BLUR_X] );

	DrawQuad();

	// Y方向

	m_pGraphicsDev->SetTarget( pTargetTex, NULL, NULL, NULL, NULL );
	m_pGraphicsDev->SetViewBounds( viewport );

	m_pGraphicsDev->SetBlendState( Mix::Graphics::BLEND_COPY );
	m_pGraphicsDev->SetDepthState( False, False );
	m_pGraphicsDev->SetRasterizerState( Mix::Graphics::FILL_SOLID, Mix::Graphics::CULL_NONE, False );

	m_pGraphicsDev->SetTexture( Renderer::TS_GAUSSIAN_BLUR, Mix::Graphics::TEXTURE_FILTER_LINEAR, Mix::Graphics::TEXTURE_ADDRESS_CLAMP, pTempTex );

	m_pGraphicsDev->SetVertexShader( m_pGaussianBlurVS[Renderer::BLUR_Y] );
	m_pGraphicsDev->SetPixelShader( m_pGaussianBlurPS[Renderer::BLUR_Y] );

	DrawQuad();
}

const Renderer::RENDER_GAUSSIAN_BLUR_ARGS& Renderer::ComputeGauusianBlurArgs( UInt32 width, UInt32 height, Float32 dispersion )
{
	////////////////////////////////////////////////////////////////////////////////////////////////////
	// テクスチャ座標のオフセット
	////////////////////////////////////////////////////////////////////////////////////////////////////

	if( ( MIX_FLOAT_EQUAL( m_GaussianBlurCache.width, width ) == False ) ||
		( MIX_FLOAT_EQUAL( m_GaussianBlurCache.height, height ) == False ) )
	{
		Renderer::RENDER_GAUSSIAN_BLUR_ARGS* pArgs = &( m_GaussianBlurCache.args );

		Mix::Vector4* inOffsets = pArgs->inOffsets;
		Mix::Vector4* outOffset = &( pArgs->outOffset );

		Float32 widthF = static_cast<Float32>( width );
		Float32 heightF = static_cast<Float32>( height );

		UInt32 i;
		Float32 pos;
		Mix::Vector4* offset;

		for( i = 0; i < 8; i++ )
		{
			pos = -( 1.0f + 2.0f * static_cast<Float32>( i ) );

			offset = &( inOffsets[i] );

			offset->x = MIX_FLOAT_DIV( pos, widthF );
			offset->y = 0.0f;
			offset->z = 0.0f;
			offset->w = MIX_FLOAT_DIV( pos, heightF );
		}

		outOffset->x = MIX_FLOAT_DIV( 16.0f, widthF );
		outOffset->y = MIX_FLOAT_DIV( 16.0f, heightF );
		outOffset->z = 0.0f;
		outOffset->w = 0.0f;

		m_GaussianBlurCache.width = width;
		m_GaussianBlurCache.height = height;
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// テクスチャカラーのウェイト
	////////////////////////////////////////////////////////////////////////////////////////////////////

	if( MIX_FLOAT_EQUAL( m_GaussianBlurCache.dispersion, dispersion ) == False )
	{
		Float32* weights = m_GaussianBlurCache.args.weights;

		Float32 invDispersion = MIX_FLOAT_RECIPROCAL( dispersion );
		Float32 invTotalWeight = 0.0f;

		UInt32 i;
		Float32 pos;

		for( i = 0; i < 8; i++ )
		{
			pos = 1.0f + 2.0f * static_cast<Float32>( i );
			weights[i] = ::expf( -0.5f * ( pos * pos ) * invDispersion );
			invTotalWeight += 2.0f * weights[i];
		}

		invTotalWeight = MIX_FLOAT_RECIPROCAL( invTotalWeight );

		for( i = 0; i < 8; i++ )
		{
			weights[i] *= invTotalWeight;
		}

		m_GaussianBlurCache.dispersion = dispersion;
	}

	return m_GaussianBlurCache.args;
}

void Renderer::RenderGaussianBlurEx( Int32 radius, Mix::Graphics::Utility::ITargetTextureChain* pTextureChain )
{
	MIX_ASSERT( radius >= Mix::Scene::GAUSSIAN_BLUR_EX_MIN_RADIUS );
	MIX_ASSERT( radius <= Mix::Scene::GAUSSIAN_BLUR_EX_MAX_RADIUS );
	MIX_ASSERT( pTextureChain != NULL );

	Int32 tw = pTextureChain->GetWidth();
	Int32 th = pTextureChain->GetHeight();
	Float32 tsx = MIX_FLOAT_RECIPROCAL( static_cast<Float32>( tw ) );
	Float32 tsy = MIX_FLOAT_RECIPROCAL( static_cast<Float32>( th ) );

	Renderer::RENDER_GAUSSIAN_BLUR_EX_ARGS args = ComputeGaussianExArgs( radius );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 実行
	////////////////////////////////////////////////////////////////////////////////////////////////////

	// 共通の設定

	m_pGraphicsDev->SetViewBounds( 0, 0, tw, th );

	m_pGraphicsDev->SetBlendState( Mix::Graphics::BLEND_COPY );
	m_pGraphicsDev->SetDepthState( False, False );
	m_pGraphicsDev->SetRasterizerState( Mix::Graphics::FILL_SOLID, Mix::Graphics::CULL_NONE, False );

	m_pGraphicsDev->SetVertexLayout( m_pSamplingVL );
	m_pGraphicsDev->SetVertexShader( m_pSamplingVS );
	m_pGraphicsDev->SetPixelShader( m_pGaussianBlurExPS );

	// X方向 ( 1.0f, 0.0f )

	args.step.Set( tsx, 0.0f );
	OnRenderGaussianBlurEx( args );

	m_pGraphicsDev->SetTarget( pTextureChain->GetNextPtr(), NULL, NULL, NULL, NULL );
	m_pGraphicsDev->SetTexture( TS_GAUSSIAN_BLUR, Mix::Graphics::TEXTURE_FILTER_LINEAR, Mix::Graphics::TEXTURE_ADDRESS_CLAMP, pTextureChain->GetCurrentPtr() );

	DrawQuad();

	pTextureChain->Flip();

	// Y方向 ( 0.0f, 1.0f )

	args.step.Set( 0.0f, tsy );
	OnRenderGaussianBlurEx( args );

	m_pGraphicsDev->SetTarget( pTextureChain->GetNextPtr(), NULL, NULL, NULL, NULL );
	m_pGraphicsDev->SetTexture( TS_GAUSSIAN_BLUR, Mix::Graphics::TEXTURE_FILTER_LINEAR, Mix::Graphics::TEXTURE_ADDRESS_CLAMP, pTextureChain->GetCurrentPtr() );

	DrawQuad();

	pTextureChain->Flip();
}

void Renderer::RenderGaussianBlurEx( Int32 radius, Mix::Graphics::ITexture* pSourceTex, Mix::Graphics::ITexture* pTargetTex, Mix::Graphics::ITexture* pTempTex )
{
	MIX_ASSERT( radius >= Mix::Scene::GAUSSIAN_BLUR_EX_MIN_RADIUS );
	MIX_ASSERT( radius <= Mix::Scene::GAUSSIAN_BLUR_EX_MAX_RADIUS );
	MIX_ASSERT( pSourceTex != NULL );
	MIX_ASSERT( pTargetTex != NULL );
	MIX_ASSERT( pTempTex != NULL );
	MIX_ASSERT( pTargetTex != pTempTex );
	MIX_ASSERT( pSourceTex != pTempTex );

	Float32 fRadius = static_cast<Float32>( radius );

	Int32 tw = pSourceTex->GetWidth();
	Int32 th = pSourceTex->GetHeight();
	Float32 tsx = MIX_FLOAT_RECIPROCAL( static_cast<Float32>( tw ) );
	Float32 tsy = MIX_FLOAT_RECIPROCAL( static_cast<Float32>( th ) );

	Renderer::RENDER_GAUSSIAN_BLUR_EX_ARGS args = ComputeGaussianExArgs( radius );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 実行
	////////////////////////////////////////////////////////////////////////////////////////////////////

	// 共通の設定

	m_pGraphicsDev->SetViewBounds( 0, 0, tw, th );

	m_pGraphicsDev->SetBlendState( Mix::Graphics::BLEND_COPY );
	m_pGraphicsDev->SetDepthState( False, False );
	m_pGraphicsDev->SetRasterizerState( Mix::Graphics::FILL_SOLID, Mix::Graphics::CULL_NONE, False );

	m_pGraphicsDev->SetVertexLayout( m_pSamplingVL );
	m_pGraphicsDev->SetVertexShader( m_pSamplingVS );
	m_pGraphicsDev->SetPixelShader( m_pGaussianBlurExPS );

	// X方向 ( 1.0f, 0.0f )

	args.step.Set( tsx, 0.0f );
	OnRenderGaussianBlurEx( args );

	m_pGraphicsDev->SetTarget( pTempTex, NULL, NULL, NULL, NULL );
	m_pGraphicsDev->SetTexture( TS_GAUSSIAN_BLUR, Mix::Graphics::TEXTURE_FILTER_LINEAR, Mix::Graphics::TEXTURE_ADDRESS_CLAMP, pSourceTex );

	DrawQuad();

	// Y方向 ( 0.0f, 1.0f )

	args.step.Set( 0.0f, tsy );
	OnRenderGaussianBlurEx( args );

	m_pGraphicsDev->SetTarget( pTargetTex, NULL, NULL, NULL, NULL );
	m_pGraphicsDev->SetTexture( TS_GAUSSIAN_BLUR, Mix::Graphics::TEXTURE_FILTER_LINEAR, Mix::Graphics::TEXTURE_ADDRESS_CLAMP, pTempTex );

	DrawQuad();
}

Renderer::RENDER_GAUSSIAN_BLUR_EX_ARGS Renderer::ComputeGaussianExArgs( Int32 radius )
{
	Float32 radiusF = static_cast<Float32>( radius );
	Float32 sigma = radiusF * 0.125f; //radius / 8.0f
	Float32 e = expf( -0.5f / ( sigma * sigma ) );
	Float32 e2 = e * e;

	Renderer::RENDER_GAUSSIAN_BLUR_EX_ARGS ret;

	ret.halfRadius = radiusF * 0.5f;
	ret.inc.Set( MIX_FLOAT_RECIPROCAL( ::sqrtf( MIX_2PI ) * sigma ), e, e2 );
	ret.step = Mix::Vector2::Zero();

	return ret;
}

void Renderer::RenderBrightPass( const Mix::Scene::BRIGHT_PASS& bp, Mix::Graphics::ITexture* pSourceTex, Mix::Graphics::ITexture* pTargetTex )
{
	MIX_ASSERT( m_pCamera != NULL );

	const Mix::Scene::ICamera::LUMINOSITY_SETTINGS& lum = m_pCamera->GetLuminositySettings();

	UInt32 li;
	UInt32 ai;

	Renderer::RENDER_BRIGHTPASS_ARGS args;

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// シェーダーを決定
	////////////////////////////////////////////////////////////////////////////////////////////////////

	if( ( m_pCamera->IsLuminosityAvailabled() == True ) && ( bp.bLumInf == True ) )
	{
		li = 1;
		ai = ( MIX_TESTBIT( lum.flags, ICamera::LUM_STATIC_MIDDLE_GRAY ) == ICamera::LUM_STATIC_MIDDLE_GRAY )? 0 : 1;
	}
	else
	{
		li = 0;
		ai = 0;
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// イベントを通知
	////////////////////////////////////////////////////////////////////////////////////////////////////

	args.middleGray = lum.middleGray;
	args.invWhite2 = MIX_FLOAT_RECIPROCAL( bp.white * bp.white );
	args.threshold = bp.threshold;
	args.offset = ( li == 0 )? max( Mix::Scene::BRIGHT_PASS_MIN_OFFSET, bp.offset ) : bp.offset; //シェーダーの除算対策

	OnRenderBrightPass( args );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 実行
	////////////////////////////////////////////////////////////////////////////////////////////////////

	m_pGraphicsDev->SetTarget( pTargetTex, NULL, NULL, NULL, NULL );
	m_pGraphicsDev->SetViewBounds( 0, 0, static_cast<Int32>( pTargetTex->GetWidth() ), static_cast<Int32>( pTargetTex->GetHeight() ) );

	m_pGraphicsDev->SetBlendState( Mix::Graphics::BLEND_COPY );
	m_pGraphicsDev->SetDepthState( False, False );
	m_pGraphicsDev->SetRasterizerState( Mix::Graphics::FILL_SOLID, Mix::Graphics::CULL_NONE, False );

	m_pGraphicsDev->SetTexture( Renderer::TS_BP_COLOR, Mix::Graphics::TEXTURE_FILTER_POINT, Mix::Graphics::TEXTURE_ADDRESS_CLAMP, pSourceTex );
	m_pGraphicsDev->SetTexture( Renderer::TS_BP_LUM,   Mix::Graphics::TEXTURE_FILTER_POINT, Mix::Graphics::TEXTURE_ADDRESS_CLAMP, ( m_pLumAdaptedTexChain != NULL )? m_pLumAdaptedTexChain->GetCurrentPtr() : NULL );
	m_pGraphicsDev->SetTexture( Renderer::TS_BP_MASK,  Mix::Graphics::TEXTURE_FILTER_POINT, Mix::Graphics::TEXTURE_ADDRESS_CLAMP, NULL );

	m_pGraphicsDev->SetVertexLayout( m_pSamplingVL );
	m_pGraphicsDev->SetVertexShader( m_pSamplingVS );
	m_pGraphicsDev->SetPixelShader( m_pBrightPassPS[li][ai] );

	DrawQuad();
}

void Renderer::RenderChromatismImage(	Float32 k, Float32 kCube, Float32 scale,
										const Mix::Vector4& colorFactor,
										Mix::Graphics::ITexture* pSourceTex,
										Mix::Graphics::ITexture* pTargetTex )
{
	MIX_ASSERT( pSourceTex != NULL );
	MIX_ASSERT( pTargetTex != NULL );

	UInt32 ki = ( MIX_FLOAT_IS_ZERO( kCube ) == False )? 1 : 0;

	Renderer::RENDER_CHROMATISM_IMAGE_ARGS args;

	args.k = k;
	args.kCube = kCube;
	args.scale = scale;
	args.colorFactor = colorFactor;

	OnRenderChromatismImage( args );

	m_pGraphicsDev->SetTarget( pTargetTex, NULL, NULL, NULL, NULL );
	m_pGraphicsDev->SetViewBounds( 0, 0, pTargetTex->GetWidth(), pTargetTex->GetHeight() );

	m_pGraphicsDev->SetBlendState( Mix::Graphics::BLEND_COPY );
	m_pGraphicsDev->SetDepthState( False, False );
	m_pGraphicsDev->SetRasterizerState( Mix::Graphics::FILL_SOLID, Mix::Graphics::CULL_NONE, False );

	m_pGraphicsDev->SetTexture( Renderer::TS_CA_IMAGE_COLOR,
								Mix::Graphics::TEXTURE_FILTER_POINT,
								Mix::Graphics::TEXTURE_ADDRESS_CLAMP,
								pSourceTex );

	m_pGraphicsDev->SetVertexLayout( m_pSamplingVL );
	m_pGraphicsDev->SetVertexShader( m_pSamplingVS );
	m_pGraphicsDev->SetPixelShader( m_pCAImagePS[ki] );

	DrawQuad();
}

void Renderer::DrawQuad( void )
{
	if( m_pQuadBuffer->Lock() == False )
	{
		return;
	}

	Renderer::QUAD_VERTEX* pv = static_cast<Renderer::QUAD_VERTEX*>( m_pQuadBuffer->Push( 4 ) );
	if( pv == NULL )
	{
		m_pQuadBuffer->Unlock();
		return;
	}

	const Mix::Rectangle& rect = m_pGraphicsDev->GetViewBounds();

	Float32 ox = m_QuadOffset / static_cast<Float32>( rect.width );
	Float32 oy = m_QuadOffset / static_cast<Float32>( rect.height );

	Float32 x  = -1.0f;
	Float32 y  = +1.0f;
	Float32 xx = +1.0f;
	Float32 yy = -1.0f;

	Float32 tx = 0.0f + ox;
	Float32 ty = 0.0f + oy;
	Float32 txx = 1.0f + ox;
	Float32 tyy = 1.0f + oy;

	//左上
	pv[0].pos.Set( x, y, 0.0f, 1.0f );
	pv[0].tex.Set( tx, ty );

	//右上
	pv[1].pos.Set( xx, y, 0.0f, 1.0f );
	pv[1].tex.Set( txx, ty );

	//左下
	pv[2].pos.Set( x, yy, 0.0f, 1.0f );
	pv[2].tex.Set( tx, tyy );

	//右下
	pv[3].pos.Set( xx, yy, 0.0f, 1.0f );
	pv[3].tex.Set( txx, tyy );

	m_pQuadBuffer->Unlock();

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

	m_pGraphicsDev->SetVertexBuffer( m_pQuadBuffer );
	m_pGraphicsDev->Draw( Mix::Graphics::PRIMITIVE_TRIANGLESTRIP, 0, Renderer::QUAD_VERTEX_NUM );
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Mix::Scene::Standard::Common::Renderer : デバッグ
////////////////////////////////////////////////////////////////////////////////////////////////////

#ifdef _DEBUG

void Renderer::Debug_Draw3D( void )
{
	MIX_ASSERT( m_pCamera != NULL );

	if( m_pDebPerspectiveRenderer == NULL )
	{
		return;
	}

	UInt32 debDrawFlags = m_pCamera->Debug_GetDrawFlags();
	Mix::Matrix4x4 oldMat = m_pDebPerspectiveRenderer->GetMatrix();
	Mix::Vector4 oldColor = m_pDebPerspectiveRenderer->GetColor();

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// テライン
	////////////////////////////////////////////////////////////////////////////////////////////////////

	if( MIX_TESTBIT( debDrawFlags, Mix::Scene::DDF_TERRAINMODEL_BOUNDS ) == Mix::Scene::DDF_TERRAINMODEL_BOUNDS )
	{
		if( m_DebTerrainBoundsList.IsEmpty() == False )
		{
			Mix::Geometry::AABB* pBounds = m_DebTerrainBoundsList.GetBeginPtr();
			Mix::Geometry::AABB* pBoundsEnd = m_DebTerrainBoundsList.GetEndPtr();

			m_pDebPerspectiveRenderer->SetMatrix( Mix::Matrix4x4::Identity() );
			m_pDebPerspectiveRenderer->SetColor( Mix::Scene::Common::Debug::GetDrawColor( Mix::Scene::DDC_BOUNDS ) );

			while( pBounds != pBoundsEnd )
			{
				m_pDebPerspectiveRenderer->AddBox( *pBounds );
				pBounds++;
			}
		}
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// フロア
	////////////////////////////////////////////////////////////////////////////////////////////////////

	if( MIX_TESTBIT( debDrawFlags, Mix::Scene::DDF_FLOOR_COLLIDER ) == Mix::Scene::DDF_FLOOR_COLLIDER )
	{
		if( m_pFloor != NULL )
		{
			MIX_ASSERT( m_pFloor->GetInternalObjectPtr() != NULL );
			m_pFloor->GetInternalObjectPtr()->Debug_Draw( m_pDebPerspectiveRenderer );
		}
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// ゴースト
	////////////////////////////////////////////////////////////////////////////////////////////////////

	if( MIX_TESTBIT( debDrawFlags, Mix::Scene::DDF_GHOST_COLLIDER ) == Mix::Scene::DDF_GHOST_COLLIDER )
	{
		size_t ghostNum = m_GhostList.size();

		if( ghostNum > 0 )
		{
			const Mix::Geometry::Frustum& frustum = m_pCamera->GetFrustum();

			Mix::Scene::Common::Ghost** ppGhost = &( m_GhostList[0] );
			Mix::Scene::Common::Ghost** ppGhostEnd = ppGhost + ghostNum;
			Mix::Scene::Common::Ghost* pGhost;

			Mix::Dynamics::IObject* pInternalObject;
			Mix::Geometry::AABB bounds;

			while( ppGhost != ppGhostEnd )
			{
				pGhost = *ppGhost;
				pInternalObject = ( *ppGhost )->GetInternalObjectPtr();

				bounds = pInternalObject->GetBounds();
				bounds.ComputePoints();

				if( frustum.Contains( bounds ) == True )
				{
					pInternalObject->Debug_Draw( m_pDebPerspectiveRenderer );
				}

				ppGhost++;
			}
		}
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// ウォータープール
	////////////////////////////////////////////////////////////////////////////////////////////////////

	if( MIX_TESTBIT( debDrawFlags, Mix::Scene::DDF_WATERPOOL ) != 0 )
	{
		if( MIX_TESTBIT( debDrawFlags, Mix::Scene::DDF_WATERPOOL_BOUNDS ) == Mix::Scene::DDF_WATERPOOL_BOUNDS )
		{
			if( m_DebWaterPoolList.GetCount() > 0 )
			{
				Mix::Scene::Common::WaterPool** ppWaterPool = m_DebWaterPoolList.GetBeginPtr();
				Mix::Scene::Common::WaterPool** ppWaterPoolEnd = m_DebWaterPoolList.GetEndPtr();

				m_pDebPerspectiveRenderer->SetMatrix( Mix::Matrix4x4::Identity() );
				m_pDebPerspectiveRenderer->SetColor( Mix::Scene::Common::Debug::GetDrawColor( Mix::Scene::DDC_BOUNDS ) );

				while( ppWaterPool != ppWaterPoolEnd )
				{
					m_pDebPerspectiveRenderer->AddBox( ( *ppWaterPool )->GetBounds() );
					ppWaterPool++;
				}
			}
		}
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// プランター
	////////////////////////////////////////////////////////////////////////////////////////////////////

	if( MIX_TESTBIT( debDrawFlags, Mix::Scene::DDF_PLANTER ) != 0 )
	{
		if( MIX_TESTBIT( debDrawFlags, Mix::Scene::DDF_PLANTER_BOUNDS ) == Mix::Scene::DDF_PLANTER_BOUNDS )
		{
			if( m_DebVisiblePlanterList.GetCount() > 0 )
			{
				Mix::Scene::Common::Planter** ppPlanter = m_DebVisiblePlanterList.GetBeginPtr();
				Mix::Scene::Common::Planter** ppPlanterEnd = m_DebVisiblePlanterList.GetEndPtr();

				m_pDebPerspectiveRenderer->SetMatrix( Mix::Matrix4x4::Identity() );
				m_pDebPerspectiveRenderer->SetColor( Mix::Scene::Common::Debug::GetDrawColor( Mix::Scene::DDC_BOUNDS ) );

				while( ppPlanter != ppPlanterEnd )
				{
					m_pDebPerspectiveRenderer->AddBox( ( *ppPlanter )->GetBounds() );
					ppPlanter++;
				}
			}
		}
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// パーティクル
	////////////////////////////////////////////////////////////////////////////////////////////////////

	if( MIX_TESTBIT( debDrawFlags, Mix::Scene::DDF_PARTICLE ) != 0 )
	{
		/*
			リービング
		*/

		if( m_DebLeavingParticleList.IsEmpty() == False )
		{
			Mix::Scene::Common::LeavingParticle** ppParticle = m_DebLeavingParticleList.GetBeginPtr();
			Mix::Scene::Common::LeavingParticle** ppParticleEnd = m_DebLeavingParticleList.GetEndPtr();

			while( ppParticle != ppParticleEnd )
			{
				( *ppParticle )->Debug_Draw( m_pDebPerspectiveRenderer, debDrawFlags );
				ppParticle++;
			}
		}

		/*
			スキャッター
		*/

		if( m_DebScatterParticleUnitList.IsEmpty() == False )
		{
			Mix::Scene::Common::ScatterParticleUnit** ppParticleUnit = m_DebScatterParticleUnitList.GetBeginPtr();
			Mix::Scene::Common::ScatterParticleUnit** ppParticleUnitEnd = m_DebScatterParticleUnitList.GetEndPtr();

			while( ppParticleUnit != ppParticleUnitEnd )
			{
				Mix::Scene::Common::ScatterParticle::Debug_Draw( m_pDebPerspectiveRenderer, debDrawFlags, *ppParticleUnit );
				ppParticleUnit++;
			}
		}
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// ウィジェット
	////////////////////////////////////////////////////////////////////////////////////////////////////

	if( MIX_TESTBIT( debDrawFlags, Mix::Scene::DDF_WIDGET ) != 0 )
	{
		if( MIX_TESTBIT( debDrawFlags, Mix::Scene::DDF_WIDGET_GROUP_BOUNDS ) == Mix::Scene::DDF_WIDGET_GROUP_BOUNDS )
		{
			if( m_DebWidgetBoundsList.GetCount() > 0 )
			{
				Mix::Geometry::AABB* pBounds = m_DebWidgetBoundsList.GetBeginPtr();
				Mix::Geometry::AABB* pBoundsEnd = m_DebWidgetBoundsList.GetEndPtr();

				m_pDebPerspectiveRenderer->SetMatrix( Mix::Matrix4x4::Identity() );
				m_pDebPerspectiveRenderer->SetColor( Mix::Scene::Common::Debug::GetDrawColor( Mix::Scene::DDC_BOUNDS ) );

				while( pBounds != pBoundsEnd )
				{
					m_pDebPerspectiveRenderer->AddBox( *pBounds );
					pBounds++;
				}
			}
		}
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// アクター
	////////////////////////////////////////////////////////////////////////////////////////////////////

	if( MIX_TESTBIT( debDrawFlags, Mix::Scene::DDF_ACTORMODEL ) != 0 )
	{
		if( m_DebActorModelList.IsEmpty() == False )
		{
			Mix::Scene::Common::ActorModel** ppActorModel = m_DebActorModelList.GetBeginPtr();
			Mix::Scene::Common::ActorModel** ppActorModelEnd = m_DebActorModelList.GetEndPtr();

			while( ppActorModel != ppActorModelEnd )
			{
				( *ppActorModel )->Debug_Draw( m_pDebPerspectiveRenderer, debDrawFlags );
				ppActorModel++;
			}
		}
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// ライト
	////////////////////////////////////////////////////////////////////////////////////////////////////

	/*
		ディレクショナルライト
	*/

	if( MIX_TESTBIT( debDrawFlags, Mix::Scene::DDF_DIRLIGHT ) != 0 )
	{
		if( ( m_pDirectionalLight != NULL ) && ( m_pDirectionalLight->IsEnabled() == True ) )
		{
			m_pDirectionalLight->Debug_Draw( m_pDebPerspectiveRenderer, debDrawFlags );
		}
	}

	/*
		スポットライト
	*/

	if( MIX_TESTBIT( debDrawFlags, Mix::Scene::DDF_SPOTLIGHT ) != 0 )
	{
		if( m_DebSpotLightList.IsEmpty() == False )
		{
			Mix::Scene::Common::SpotLight** ppSpotLight = m_DebSpotLightList.GetBeginPtr();
			Mix::Scene::Common::SpotLight** ppSpotLightEnd = m_DebSpotLightList.GetEndPtr();

			while( ppSpotLight != ppSpotLightEnd )
			{
				( *ppSpotLight )->Debug_Draw( m_pDebPerspectiveRenderer, debDrawFlags );
				ppSpotLight++;
			}
		}
	}

	/*
		ポイントライト
	*/

	if( MIX_TESTBIT( debDrawFlags, Mix::Scene::DDF_POINTLIGHT ) != 0 )
	{
		if( m_DebPointLightList.IsEmpty() == False )
		{
			Mix::Scene::Common::PointLight** ppPointLight = m_DebPointLightList.GetBeginPtr();
			Mix::Scene::Common::PointLight** ppPointLightEnd = m_DebPointLightList.GetEndPtr();

			while( ppPointLight != ppPointLightEnd )
			{
				( *ppPointLight )->Debug_Draw( m_pDebPerspectiveRenderer, debDrawFlags );
				ppPointLight++;
			}
		}
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// シャドウ
	////////////////////////////////////////////////////////////////////////////////////////////////////

	m_pDebPerspectiveRenderer->SetMatrix( Mix::Matrix4x4::Identity() );

	if( ( m_pDirectionalLight != NULL ) &&
		( m_pDirectionalLight->IsEnabled() == True ) &&
		( MIX_TESTBIT( debDrawFlags, Mix::Scene::DDF_SHADOW ) != 0 ) )
	{
		m_pDebPerspectiveRenderer->SetColor( Mix::Scene::Common::Debug::GetDrawColor( Mix::Scene::DDC_SM_CLIP_BOOUNDS ) );
		m_pDebPerspectiveRenderer->AddSphere( m_pDirectionalLight->Projection_GetClipBounds() );

		if( m_pDirectionalLight->Projection_IsCast() )
		{
			m_pDebPerspectiveRenderer->SetColor( Mix::Scene::Common::Debug::GetDrawColor( Mix::Scene::DDC_SM_CAST_BOOUNDS ) );
			m_pDebPerspectiveRenderer->AddBox( m_pDirectionalLight->Projection_GetCastBounds() );
		}
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// オクトリー
	////////////////////////////////////////////////////////////////////////////////////////////////////

	if( MIX_TESTBIT( debDrawFlags, Mix::Scene::DDF_OCTREE ) != 0 )
	{
		m_pOctree->Debug_Draw( m_pDebPerspectiveRenderer, debDrawFlags );
	}

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

	m_pGraphicsDev->SetBlendState( Mix::Graphics::BLEND_NORMAL );

	m_pDebPerspectiveRenderer->Update();
	m_pDebPerspectiveRenderer->Draw( m_pCamera->GetViewProjectionMatrix() );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 終了
	////////////////////////////////////////////////////////////////////////////////////////////////////

	m_pDebPerspectiveRenderer->SetMatrix( Mix::Matrix4x4::Identity() );
	m_pDebPerspectiveRenderer->SetColor( oldColor );
}

void Renderer::Debug_Draw2D( void )
{
	MIX_ASSERT( m_pCamera != NULL );

	if( m_pDebCanvasRenderer == NULL )
	{
		return;
	}

	UInt32 debDrawFlags = m_pCamera->Debug_GetDrawFlags();

	////////////////////////////////////////////////////////////////////////////////////////////////////

	m_pDebCanvasRenderer->DrainMatrix();
	m_pDebCanvasRenderer->SetMatrix( Mix::Matrix3x3::Identity() );
	m_pDebCanvasRenderer->DrainClip();
	m_pDebCanvasRenderer->SetClip( m_Viewport );
	m_pDebCanvasRenderer->SetBlendType( Mix::Graphics::BLEND_NORMAL );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// フィルミック
	////////////////////////////////////////////////////////////////////////////////////////////////////

	if( ( MIX_TESTBIT( debDrawFlags, Mix::Scene::DDF_PP_FILMIC ) == Mix::Scene::DDF_PP_FILMIC ) &&
		( m_pCamera->IsFilmicEnabled() == True ) )
	{
		Debug_DrawFilmic();
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 色収差
	////////////////////////////////////////////////////////////////////////////////////////////////////

	if( ( MIX_TESTBIT( debDrawFlags, Mix::Scene::DDF_PP_CHROMATISM ) == Mix::Scene::DDF_PP_CHROMATISM ) &&
		( m_pCamera->IsChromatismAvailabled() == True ) &&
		( m_pCamera->IsChromatismEnabled() == True ) )
	{
		const Mix::Scene::ICamera::DISTORTION_SETTINGS& distSetting = m_pCamera->GetChromatismSettings().distortion;

		m_pDebCanvasRenderer->SetColor( Mix::Scene::Common::Debug::GetDrawColor( Mix::Scene::DDC_ABERRATION ) );
		Debug_DrawDistortion2D( distSetting.k, distSetting.kCube, distSetting.scale );
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 歪曲収差
	////////////////////////////////////////////////////////////////////////////////////////////////////

	if( ( MIX_TESTBIT( debDrawFlags, Mix::Scene::DDF_PP_LENS_DISTORTION ) == Mix::Scene::DDF_PP_LENS_DISTORTION ) &&
		( m_pCamera->IsLensDistortionEnabled() == True ) )
	{
		const Mix::Scene::ICamera::DISTORTION_SETTINGS& distSetting = m_pCamera->GetLendDistortionSettings();

		m_pDebCanvasRenderer->SetColor( Mix::Scene::Common::Debug::GetDrawColor( Mix::Scene::DDC_ABERRATION ) );
		Debug_DrawDistortion2D( distSetting.k, distSetting.kCube, distSetting.scale );
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////

	m_pDebCanvasRenderer->Update();
	m_pDebCanvasRenderer->Draw();
}

void Renderer::Debug_DrawDistortion2D( Float32 k, Float32 kCube, Float32 scale )
{
	MIX_ASSERT( m_pCamera != NULL );

	static const Mix::Vector2 DISTO_CENTER( 0.5f, 0.5f );
	static const Int32 DISTO_POINT_STEP = 128;
	static const Float32 DISTO_POINT_STEP_F = static_cast<Float32>( DISTO_POINT_STEP );

	const Mix::Point& targetSize = m_pCamera->GetConfig().targetSize;

	Int32 numX = targetSize.x / DISTO_POINT_STEP;
	Int32 numY = targetSize.y / DISTO_POINT_STEP;

	if( ( targetSize.x % DISTO_POINT_STEP ) != 0 ) { numX += 1; }
	if( ( targetSize.y % DISTO_POINT_STEP ) != 0 ) { numY += 1; }

	MIX_ASSERT( ( numX > 0 ) && ( numY > 0 ) );

	Int32 lastX = numX - 1;
	Int32 lastY = numY - 1;

	Mix::Vector2 targetSizeF = targetSize;

	Mix::Vector2 step;
	Mix::Vector2 offset;

	Mix::Vector2 base;
	Mix::Vector2 p0;
	Mix::Vector2 p1;
	Mix::Vector2 p2;

	step.x = MIX_FLOAT_DIV( 1.0f, static_cast<Float32>( numX ) );
	step.y = MIX_FLOAT_DIV( 1.0f, static_cast<Float32>( numY ) );

	offset.x = ( step.x * static_cast<Float32>( numX ) - 1.0f ) * 0.5f;
	offset.y = ( step.y * static_cast<Float32>( numY ) - 1.0f ) * 0.5f;

	for( Int32 x = 0; x < numX; x++ )
	{
		for( Int32 y = 0; y < numY; y++ )
		{
			base.x = step.x * static_cast<Float32>( x ) - offset.x;
			base.y = step.y * static_cast<Float32>( y ) - offset.y;

			p0 = base;
			p1.Set( p0.x + step.x, p0.y );
			p2.Set( p0.x, p0.y + step.y );

			p0 = Debug_Distortion( p0, k, kCube, scale ) * targetSizeF;
			p1 = Debug_Distortion( p1, k, kCube, scale ) * targetSizeF;
			p2 = Debug_Distortion( p2, k, kCube, scale ) * targetSizeF;

			m_pDebCanvasRenderer->AddLine( p0, p1 );
			m_pDebCanvasRenderer->AddLine( p0, p2 );

			if( x == lastX )
			{
				p0 = base + step;
				p1.Set( p0.x, p0.y - step.y );

				p0 = Debug_Distortion( p0, k, kCube, scale ) * targetSizeF;
				p1 = Debug_Distortion( p1, k, kCube, scale ) * targetSizeF;

				m_pDebCanvasRenderer->AddLine( p0, p1 );
			}

			if( y == lastY )
			{
				p0 = base + step;
				p1.Set( p0.x - step.x, p0.y );

				p0 = Debug_Distortion( p0, k, kCube, scale ) * targetSizeF;
				p1 = Debug_Distortion( p1, k, kCube, scale ) * targetSizeF;

				m_pDebCanvasRenderer->AddLine( p0, p1 );
			}
		}
	}
}

Mix::Vector2 Renderer::Debug_Distortion( const Mix::Vector2& p, Float32 k, Float32 kCube, Float32 scale )
{
	static const Mix::Vector2 TEX_CENTER( 0.5f, 0.5f );

	Mix::Vector2 vec = p - TEX_CENTER;
	Float32 r2 = Mix::Vector2::Dot( vec, vec );
	Float32 f;
	Mix::Vector2 ret;

	if( MIX_FLOAT_IS_ZERO( kCube ) == False )
	{
		f = 1.0f - r2 * ( k + kCube * sqrtf( r2 ) );
	}
	else
	{
		f = 1.0f - r2 * k;
	}

	ret = vec * f * MIX_FLOAT_RECIPROCAL( scale ) + TEX_CENTER;

	return ret;
}

void Renderer::Debug_DrawFilmic( void )
{
	const Mix::Scene::ICamera::DEBUG_DRAW_FILIMIC_SETTINGS& settings = m_pCamera->Debug_GetDrawFilmicSettings();

	const Mix::Rectangle& rect = settings.rect;
	const Int32& padding = settings.padding;
	const Float32& valueMax = settings.valueMax;
	const Float32& valueStep = settings.valueStep;
	const Int32& memNum = settings.memNum;
	const Float32& errValue = settings.errValue;

	Mix::Scene::ICamera::FILMIC_TYPE type = m_pCamera->GetFilmicType();
	Mix::Graphics::Utility::IFont* pFont = NULL;
	Mix::Vector2 fontSize;
	Mix::Vector2 halfFontSize;
	Float32 margin;
	Mix::Vector2 offset;
	Mix::RectangleF frameRect;
	Float32 memStep;
	Float32 modValueMax;
	Float32 curve;
	Float32 cx;
	Float32 cy;
	Float32 sx;
	Float32 sy;
	Mix::Vector2 p1;
	Mix::Vector2 p2;
	Mix::StringW tempStr;

	if( m_pDebCanvasRenderer->GetFont( &pFont ) == True )
	{
		tempStr.Sprintf( L"%.1f", valueMax );

		fontSize = Mix::Graphics::Utility::MeasureString( pFont, tempStr.GetConstPtr() );

		margin = fontSize.y * 0.5f;

		offset.x = fontSize.x /*フォント*/ + margin /*マージン*/ + margin /*メモリ*/;
		offset.y = fontSize.y /*フォント*/ + margin /*マージン*/ + margin /*メモリ*/;
	}
	else
	{
		fontSize.Set( 0.0f, 0.0f );

		margin = 8.0f;

		offset.x = margin;
		offset.y = margin;
	}

	halfFontSize = fontSize * 0.5f;

	frameRect.x = static_cast<Float32>( rect.x + padding ) + offset.x;
	frameRect.y = static_cast<Float32>( rect.y + padding ) + halfFontSize.y;
	frameRect.width = static_cast<Float32>( rect.width - padding * 2 ) - offset.x - halfFontSize.x;
	frameRect.height = static_cast<Float32>( rect.height - padding * 2 ) - offset.y - halfFontSize.y;

	sx = MIX_FLOAT_DIV( frameRect.width, valueMax );
	sy = MIX_FLOAT_DIV( frameRect.height, valueMax );

	cx = frameRect.x;
	cy = frameRect.y + frameRect.height;

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 背景
	////////////////////////////////////////////////////////////////////////////////////////////////////

	m_pDebCanvasRenderer->SetColor( Mix::Scene::Common::Debug::GetDrawColor( Mix::Scene::DDC_FILMIC_BG ) );
	m_pDebCanvasRenderer->AddFillRectangle( rect );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// メモリ
	////////////////////////////////////////////////////////////////////////////////////////////////////

	memStep = MIX_FLOAT_DIV( valueMax, static_cast<Float32>( memNum ) );
	modValueMax = valueMax + memStep * errValue;

	m_pDebCanvasRenderer->SetColor( Mix::Scene::Common::Debug::GetDrawColor( Mix::Scene::DDC_FILMIC_MEMORY ) );

	for( Float32 value = 0.0f; value < modValueMax; value += memStep )
	{
		//X(列)
		p1.Set( frameRect.x + value * sx, frameRect.y + frameRect.height + margin );
		p2.Set( p1.x                    , frameRect.y );
		m_pDebCanvasRenderer->AddLine( p1, p2 );

		//Y(行)
		p1.Set( frameRect.x - margin         , frameRect.y + frameRect.height - value * sy );
		p2.Set( frameRect.x + frameRect.width, p1.y );
		m_pDebCanvasRenderer->AddLine( p1, p2 );
	}

	if( pFont != NULL )
	{
		for( Float32 value = 0.0f; value < modValueMax; value += memStep )
		{
			tempStr.Sprintf( L"%.1f", value );
			fontSize = Mix::Graphics::Utility::MeasureString( pFont, tempStr.GetConstPtr() );

			//X(列)
			m_pDebCanvasRenderer->AddString(	frameRect.x + value * sx - fontSize.x * 0.5f,
										frameRect.y + frameRect.height + ( margin + margin ), tempStr.GetConstPtr() );

			//Y(行)
			m_pDebCanvasRenderer->AddString(	frameRect.x - ( margin + margin ) - fontSize.x,
										frameRect.y + frameRect.height - value * sy - fontSize.y * 0.5f, tempStr.GetConstPtr() );
		}
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// カーブ
	////////////////////////////////////////////////////////////////////////////////////////////////////

	modValueMax = valueMax + valueStep * errValue;
	
	m_pDebCanvasRenderer->SetColor( Mix::Scene::Common::Debug::GetDrawColor( Mix::Scene::DDC_FILMIC_CURVE ) );

	if( type == Mix::Scene::ICamera::FI_HEJL )
	{
		curve = Debug_TonemapHejl( 0.0f );

		p1.x = cx;
		p1.y = cy - ( curve * sx );

		for( Float32 value = valueStep; value < modValueMax; value += valueStep )
		{
			curve = Debug_TonemapHejl( value );

			p2.x = cx + ( value * sx );
			p2.y = cy - ( curve * sy );

			m_pDebCanvasRenderer->AddLine( p1, p2 );

			p1 = p2;
		}
	}
	else if( type == Mix::Scene::ICamera::FI_HABLE )
	{
		Mix::Scene::ICamera::FILMIC_HABLE_SETTINGS setting;

		if( m_pCamera->GetFilmicSettings( &setting, sizeof( Mix::Scene::ICamera::FILMIC_HABLE_SETTINGS ) ) == True )
		{
			Float32 expBias = setting.exposureBias;
			Float32 A = setting.shoulderStrength;
			Float32 B = setting.linearStrength;
			Float32 C = setting.linearAngle;
			Float32 D = setting.toeStrength;
			Float32 E = setting.toeNumerator;
			Float32 F = setting.toeDenominator;
			Float32 W = setting.linearWhitePointValue;

			Float32 whiteScale = MIX_FLOAT_RECIPROCAL( Debug_TonemapHable( A, B, C, D, E, F, W ) );

			curve = Debug_TonemapHable( A, B, C, D, E, F, 0.0f ) * whiteScale;
			p1.x = cx;
			p1.y = cy - ( curve * sy );

			for( Float32 value = valueStep; value < modValueMax; value += valueStep )
			{
				curve = Debug_TonemapHable( A, B, C, D, E, F, expBias * value ) * whiteScale;

				p2.x = cx + ( value * sx );
				p2.y = cy - ( curve * sy );

				m_pDebCanvasRenderer->AddLine( p1, p2 );

				p1 = p2;
			}
		}
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 後処理
	////////////////////////////////////////////////////////////////////////////////////////////////////

	MIX_RELEASE( pFont );
}

Float32 Renderer::Debug_TonemapHejl( Float32 x )
{
	Float32 ret;

	ret = max( 0.0f, x - 0.004f );

	ret = MIX_FLOAT_DIV( ( ret * ( 6.2f * ret + 0.5f ) ), ( ret * ( 6.2f * ret + 1.7f ) + 0.06f ) );
	ret = powf( ret, 2.2f );

	return ret;
}

Float32 Renderer::Debug_TonemapHable( Float32 A, Float32 B, Float32 C, Float32 D, Float32 E, Float32 F, Float32 x )
{
	return MIX_FLOAT_DIV( ( x * ( A * x + C * B ) + D * E ), ( x * ( A * x + B ) + D * F ) ) - MIX_FLOAT_DIV( E, F );
}

Boolean Renderer::Debug_CollectTerrainBounds(	const Mix::Geometry::Frustum& frustum,
												Mix::Scene::Common::TerrainModel* pModel,
												Mix::Scene::Common::TerrainNode* pNode,
												UInt32& meshCount )
{
	MIX_ASSERT( m_pDebPerspectiveRenderer  != NULL );

	const Mix::Geometry::AABB& bounds = pNode->GetBounds();

	UIntT childCount = pNode->GetChildCount();
	UIntT i;

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// カメラ内に入っているかチェック
	////////////////////////////////////////////////////////////////////////////////////////////////////

	if( frustum.Contains( bounds ) == False )
	{
		return False;
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// メッシュを所持している場合は境界を追加
	////////////////////////////////////////////////////////////////////////////////////////////////////

	if( pNode->GetMeshPtr() != NULL )
	{
		//デバッグ : 境界の描画( 行列と色は事前に設定してあります )
		m_DebTerrainBoundsList.Add( bounds );

		meshCount++;
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 子を処理
	////////////////////////////////////////////////////////////////////////////////////////////////////

	for( i = 0; i < childCount; i++ )
	{
		Debug_CollectTerrainBounds( frustum, pModel, pNode->GetChildPtr( i ), meshCount );
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////

	return ( meshCount > 0 );
}

UInt32 Renderer::Debug_CountPrimitive( Mix::Graphics::PRIMITIVE_TYPE type, UInt32 indexCount )
{
	UInt32 count = 0;

	switch( type )
	{
	case Mix::Graphics::PRIMITIVE_POINTLIST:
		count = indexCount;
		break;
	case Mix::Graphics::PRIMITIVE_LINELIST:
		count = ( indexCount >> 1 );
		break;
	case Mix::Graphics::PRIMITIVE_LINESTRIP:
		if( indexCount >= 2 )
		{
			count = ( indexCount - 1 );
		}
		break;
	case Mix::Graphics::PRIMITIVE_TRIANGLELIST:
		count = ( indexCount / 3 );
		break;
	case Mix::Graphics::PRIMITIVE_TRIANGLESTRIP:
		if( indexCount >= 3 )
		{
			count = ( indexCount - 2 );
		}
		break;
	}

	return count;
}

#endif //_DEBUG

}}}}
