// SolarSystem.cpp: implementation of the CSolarSystem class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "SolarSystem.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

#define	CROWNSIZE		1.2f

CSolarSystem::CSolarSystem( PDIRECT3DDEVICE8 pDevice ) : CEfx( pDevice )
{	
	if( !m_mSphere.Load( m_pDevice, "data\\objects\\planet.smf" ) )
		throw CSystemException( DEMO_EXCEPTION_FILENOTFOUND, "unable to load planet.smf" );		

	m_pvbStars = NULL;
	m_pvbRing = NULL;
	m_pvbSolarCrown = NULL;
	m_piqFade = NULL;
	m_pvbRing = NULL;

	if( !CreateRing( m_pDevice, 10.0f, 15.0f, 100, &m_pvbRing ) )
		throw CSystemException( DEMO_EXCEPTION_D3DERROR, "unable to create rings vertex buffer" );

	if( FAILED( m_pDevice->CreateVertexBuffer( 5000*sizeof(SIMPLEVERTEX), 0, FVF_SIMPLEVERTEX, D3DPOOL_DEFAULT, &m_pvbStars ) ) )
		throw CSystemException( DEMO_EXCEPTION_D3DERROR, "unable to create stars vertex buffer" );

	if( FAILED( m_pDevice->CreateVertexBuffer( 500*sizeof(SIMPLEVERTEX), 0, FVF_SIMPLEVERTEX, D3DPOOL_DEFAULT, &m_pvbRays ) ) )
		throw CSystemException( DEMO_EXCEPTION_D3DERROR, "unable to create rays vertex buffer" );

	if( FAILED( m_pDevice->CreateVertexBuffer( 2000*sizeof(SIMPLEVERTEX), 0, FVF_SIMPLEVERTEX, D3DPOOL_DEFAULT, &m_pvbSolarCrown ) ) )
		throw CSystemException( DEMO_EXCEPTION_D3DERROR, "unable to create solar crown vertex buffer" );

	if( !m_psSeedSystem.Initialize( m_pDevice ) )
		throw CSystemException( DEMO_EXCEPTION_D3DERROR, "unable to create seed particle system" );

	m_psSeedSystem.ConfigureGravity( G_VECTOR, he3d_CVector( 0.0f, 0.0f, 1.0f ), 0.0f );
	m_psSeedSystem.SetTexture( GetTexture( "flare0.bmp" ) );
	m_psSeedSystem.AddEmiter( &m_peSeedEmiter );
	
	m_peSeedEmiter.SetVelocity( 1.0f, 0.5f );
	m_peSeedEmiter.SetEmitCount( 15, 5 );
	m_peSeedEmiter.SetEmitAngle( 0.1f );
	m_peSeedEmiter.SetLifeTime( 1.0f, 0.5f );
	m_peSeedEmiter.SetParticleType( PT_STANDARD );
	m_peSeedEmiter.SetSize( 0.3f, 0.0f );
	m_peSeedEmiter.SetEmitInterval( 0.01f );	
	m_peSeedEmiter.SetEmiterDir( he3d_CVector( 0.0f, 0.0f, 1.0f ) );

	for( DWORD i = 0 ; i < 10 ; i++ )
	{
		m_vBeamDir[i] = Polar2Cartesian3d( 1.0f, H_2PI*RAND(), H_2PI*RAND() );

		m_peBeamEmiter[i].SetEmiterDir( -m_vBeamDir[i] );
		m_peBeamEmiter[i].SetEmiterPos( he3d_CVector( 0.0f, 0.0f, -30.75f )*XRotationMtx( 0.1f ) );
		m_peBeamEmiter[i].SetVelocity( 0.7f, 0.25f );
		m_peBeamEmiter[i].SetEmitCount( 5, 0 );
		m_peBeamEmiter[i].SetEmitAngle( 0.1f );
		m_peBeamEmiter[i].SetLifeTime( 1.5f, 0.5f );
		m_peBeamEmiter[i].SetParticleType( PT_STANDARD );
		m_peBeamEmiter[i].SetSize( 0.2f, 0.0f );
		m_peBeamEmiter[i].SetEmitInterval( 0.01f );	
		m_peBeamEmiter[i].SetEmiterDir( he3d_CVector( 0.0f, 0.0f, 1.0f ) );
		m_peBeamEmiter[i].SetEmitInterval( 0.01f );

		m_psSeedSystem.AddEmiter( &m_peBeamEmiter[i] );
	}

	m_vPrevPos = he3d_CVector( 0.0f, 0.0f, 0.0f );

	try
	{
		LoadTexture( "earth.jpg", MIP_ALL );
		LoadTexture( "moon.jpg", MIP_ALL );
		LoadTexture( "jupiter.jpg", MIP_ALL );
		LoadTexture( "saturn.jpg", MIP_ALL );
		LoadTexture( "mars.jpg", MIP_ALL );
		LoadTexture( "uran.jpg", MIP_ALL );
		LoadTexture( "wenus.jpg", MIP_ALL );
		LoadTexture( "saturnrings.jpg", MIP_ALL );
		LoadTexture( "uranrings.jpg", MIP_ALL );

		LoadTexture( "flare0.bmp" );		
	}
	catch( CTextureException )
	{
		throw CSystemException( DEMO_EXCEPTION_FILENOTFOUND, "unable to load textures" );
	}

	m_ptextPlanets[0] = GetTexture( "moon.jpg" );
	m_ptextPlanets[1] = GetTexture( "wenus.jpg" );
	m_ptextPlanets[2] = GetTexture( "earth.jpg" );
	m_ptextPlanets[3] = GetTexture( "mars.jpg" );
	m_ptextPlanets[4] = GetTexture( "jupiter.jpg" );
	m_ptextPlanets[5] = GetTexture( "saturn.jpg" );
	m_ptextPlanets[6] = GetTexture( "uran.jpg" );
	m_ptextPlanets[7] = GetTexture( "uran.jpg" );
	m_ptextPlanets[8] = GetTexture( "moon.jpg" );

	PSIMPLEVERTEX			pVertices;

	m_pvbStars->Lock( 0, 0, (LPBYTE*)&pVertices, 0 );

	for( i = 0 ; i < 5000 ; i++ )	
	{	
		pVertices[i].m_vPos = Polar2Cartesian3d( 500.0f, H_2PI*RAND(), H_2PI*RAND() );
		pVertices[i].m_dwColor = 0xffffff;
	}
	
	m_pvbStars->Unlock();

	m_pvbRays->Lock( 0, 0, (LPBYTE*)&pVertices, 0 );

	for( i = 0 ; i < 500 ; i += 2)
	{
		pVertices[i+0].m_vPos = he3d_CVector( 0.0f, 0.0f, 0.0f );
		pVertices[i+0].m_dwColor = 0xffffffff;

		pVertices[i+1].m_vPos = Polar2Cartesian3d( 1.0f + RAND(), H_2PI*RAND(), H_2PI*RAND() );
		pVertices[i+1].m_dwColor = 0x00ffffff;
	}

	m_pvbRays->Unlock();

	m_pvbSolarCrown->Lock( 0, 0, (LPBYTE*)&pVertices, 0 );

	for( i = 0 ; i < 2000 ; i += 2)
	{
		m_vCrown[i/2] = Polar2Cartesian3d( CROWNSIZE + CROWNSIZE*RAND(), H_2PI*RAND(), H_2PI*RAND() );

		pVertices[i+0].m_vPos = he3d_CVector( 0.0f, 0.0f, 0.0f );
		pVertices[i+0].m_dwColor = 0xffffff00;

		pVertices[i+1].m_vPos = m_vCrown[i/2];
		pVertices[i+1].m_dwColor = 0x00000000;
	}

	m_pvbSolarCrown->Unlock();

	he3d_CVector			v = he3d_CVector( 0.0f, 0.0f, 0.0f );
	he3d_CMatrix			mtx;

	m_vsCamPos[0] = VECTORKEY( 0.0f, he3d_CVector( 0.0f, 3.0f, -35.0f ) );
	mtx = TranslationMtx( 0.0f, 0.0f, -50.0f )*YRotationMtx( 0.010f*4.0f + 0.0f )*XRotationMtx( 0.01f );
	m_vsCamPos[1] = VECTORKEY( 4.0f, v*mtx );
	mtx = TranslationMtx( 0.0f, 0.0f, -80.0f )*YRotationMtx( 0.010f*8.0f + 0.5f )*XRotationMtx( 0.05f );
	m_vsCamPos[2] = VECTORKEY( 8.0f, v*mtx );
	mtx = TranslationMtx( 0.0f, 0.0f, -110.0f )*YRotationMtx( 0.005f*12.0f + 1.0f )*XRotationMtx( 0.01f );
	m_vsCamPos[3] = VECTORKEY( 12.0f, v*mtx );
	mtx = TranslationMtx( 0.0f, 0.0f, -150.0f )*YRotationMtx( 0.005f*16.0f + 1.5f )*XRotationMtx( 0.01f );
	m_vsCamPos[4] = VECTORKEY( 16.0f, v*mtx );

	mtx = TranslationMtx( 0.0f, 0.0f, -30.75f )*YRotationMtx( 0.005f*0.0f + 0.0f )*XRotationMtx( 0.1f );
	m_peSeedEmiter.SetEmiterPos( v*mtx );	
	m_vsSeedPos[0] = VECTORKEY( 0.0f, v*mtx );
	mtx = TranslationMtx( 0.0f, 0.0f, -50.0f )*YRotationMtx( 0.010f*3.0f + 0.0f )*XRotationMtx( 0.01f );
	m_vsSeedPos[1] = VECTORKEY( 3.0f, v*mtx );
	mtx = TranslationMtx( 0.0f, 0.0f, -80.0f )*YRotationMtx( 0.010f*6.0f + 0.45f )*XRotationMtx( 0.01f );
	m_vsSeedPos[2] = VECTORKEY( 6.0f, v*mtx );
	mtx = TranslationMtx( 0.0f, 0.0f, -110.0f )*YRotationMtx( 0.010f*9.0f + 0.9f )*XRotationMtx( 0.01f );
	m_vsSeedPos[3] = VECTORKEY( 9.0f, v*mtx );
	mtx = TranslationMtx( 0.0f, 0.0f, -180.0f )*YRotationMtx( 0.010f*16.0f + 1.95f )*XRotationMtx( 0.01f );
	m_vsSeedPos[4] = VECTORKEY( 16.0f, v*mtx );

	InitVectorSpline( 5, m_vsSeedPos );

	m_vsCamTrg[0] = VECTORKEY(  0.0f, he3d_CVector( 0.0f, 0.0f, 0.0f ) );
	m_vsCamTrg[1] = VECTORKEY(  3.0f, he3d_CVector( -10.0f, 0.0f, -35.0f ) );	
	m_vsCamTrg[2] = VECTORKEY(  6.0f, GetVectorSplineValue( 6.0f, 5, m_vsSeedPos ) );		
	m_vsCamTrg[3] = VECTORKEY(  8.0f, GetVectorSplineValue( 8.0f, 5, m_vsSeedPos ) );	
	m_vsCamTrg[4] = VECTORKEY( 10.0f, GetVectorSplineValue( 10.0f, 5, m_vsSeedPos ) );	
	m_vsCamTrg[5] = VECTORKEY( 14.0f, he3d_CVector( 0.0f, 0.0f, 0.0f ) );

	InitVectorSpline( 5, m_vsCamPos );	
	InitVectorSpline( 6, m_vsCamTrg );

	for( FLOAT fT = 0 ; fT < 5.0f ; fT += 0.1f )
		m_psSeedSystem.Update( fT );

	m_piqFade = new CImageQuad( m_pDevice, 0, 0, 512, 512 );
}

CSolarSystem::~CSolarSystem()
{
	if( m_pvbStars )
		m_pvbStars->Release();

	if( m_pvbRing )
		m_pvbRing->Release();

	if( m_pvbRays )
		m_pvbRays->Release();

	if( m_pvbSolarCrown )
		m_pvbSolarCrown->Release();

	if( m_piqFade )
		delete m_piqFade;
}

BOOL CSolarSystem::InitEfx()
{	
	return TRUE;
}

BOOL CSolarSystem::FinishEfx()
{
	return TRUE;
}

BOOL CSolarSystem::UpdateFrame( FLOAT fTime )
{
	he3d_CVector				vEmiter = GetVectorSplineValue( fTime, 5, m_vsSeedPos );
	he3d_CVector				vDir = m_vPrevPos - vEmiter;

	m_vPrevPos = vEmiter;

	m_peSeedEmiter.SetEmiterPos( vEmiter );
	m_peSeedEmiter.SetEmiterDir( vDir );

	for( DWORD i = 0 ; i < 10 ; i++ )	
		m_peBeamEmiter[i].SetEmiterPos( he3d_CVector( 0.0f, 0.0f, -30.75f )*XRotationMtx( 0.1f ) + m_vBeamDir[i]*fTime*1.0f );	

	m_psSeedSystem.Update( fTime + 5.0f );

	// material & light setup 

	D3DLIGHT8				d3dlit;
	D3DMATERIAL8			d3dmat;

	ZeroMemory( &d3dlit, sizeof(D3DLIGHT8) );
	ZeroMemory( &d3dmat, sizeof(D3DMATERIAL8) );

	d3dlit.Type = D3DLIGHT_POINT;
	d3dlit.Attenuation0 = 1.0f;
	d3dlit.Position.x = 0.0f;
	d3dlit.Position.y = 0.0f;
	d3dlit.Position.z = 0.0f;
	d3dlit.Diffuse.r = 1.0f;
	d3dlit.Diffuse.g = 0.8f;
	d3dlit.Diffuse.b = 0.5f;
	d3dlit.Range = 1000.0f;

	d3dmat.Ambient.r = 1.0f;
	d3dmat.Ambient.g = 1.0f;
	d3dmat.Ambient.b = 1.0f;
	d3dmat.Diffuse.a = 0.05f;
	d3dmat.Diffuse.r = 1.0f;
	d3dmat.Diffuse.g = 1.0f;
	d3dmat.Diffuse.b = 1.0f;

	m_pDevice->SetMaterial( &d3dmat );
	m_pDevice->SetLight( 0, &d3dlit );
	m_pDevice->LightEnable( 0, TRUE );	

	// camera setup

	he3d_CVector			vPos = GetVectorSplineValue( fTime, 5, m_vsCamPos );
	he3d_CVector			vTrg = GetVectorSplineValue( fTime, 6, m_vsCamTrg );

	m_pDevice->SetTransform( D3DTS_PROJECTION, ProjectionMtx( 45.0f, 0.75f, 0.5f, 1000.0f ) );
	m_pDevice->SetTransform( D3DTS_VIEW, CameraMtx( vPos, vTrg, 0.0f ) );

	// transformations

	m_mtxPlanets[0] = ScaleMtx( 0.002f )*YRotationMtx( 0.1f*fTime )*XRotationMtx( 0.2f )*
					  TranslationMtx( 0.0f, 0.0f, -15.0f )*YRotationMtx( 0.020f*fTime - 0.7f )*XRotationMtx( -0.1f );
	m_mtxPlanets[1] = ScaleMtx( 0.006f )*YRotationMtx( -0.1f*fTime )*XRotationMtx( 0.1f )*
					  TranslationMtx( 0.0f, 0.0f, -20.0f )*YRotationMtx( 0.010f*fTime + 0.6f )*XRotationMtx( -0.05f );
	m_mtxPlanets[2] = ScaleMtx( 0.006f )*YRotationMtx( 0.2f*fTime )*XRotationMtx( 0.3f )*
					  TranslationMtx( 0.0f, 0.0f, -30.0f )*YRotationMtx( 0.005f*fTime + 0.0f )*XRotationMtx( 0.1f );
	m_mtxPlanets[3] = ScaleMtx( 0.003f )*YRotationMtx( 0.15f*fTime )*XRotationMtx( 0.3f )*
					  TranslationMtx( 0.0f, 0.0f, -40.0f )*YRotationMtx( 0.015f*fTime + 1.2f )*XRotationMtx( 0.05f );

	m_mtxPlanets[4] = ScaleMtx( 0.07f )*YRotationMtx( 0.15f*fTime )*XRotationMtx( 0.1f )*
					  TranslationMtx( 0.0f, 0.0f, -50.0f )*YRotationMtx( 0.010f*fTime + 0.4f )*XRotationMtx( 0.01f );

	m_mtxPlanets[5] = ScaleMtx( 0.04f )*YRotationMtx( 0.15f*fTime )*XRotationMtx( 0.4f )*
					  TranslationMtx( 0.0f, 0.0f, -80.0f )*YRotationMtx( 0.010f*fTime + 0.8f )*XRotationMtx( 0.05f );

	m_mtxPlanets[6] = ScaleMtx( 0.025f )*YRotationMtx( 0.15f*fTime )*XRotationMtx( H_PI2 )*
					  TranslationMtx( 0.0f, 0.0f, -95.0f )*YRotationMtx( 0.005f*fTime + 1.2f )*XRotationMtx( 0.01f );

	m_mtxPlanets[7] = ScaleMtx( 0.025f )*YRotationMtx( 0.15f*fTime )*XRotationMtx( -0.2f )*
					  TranslationMtx( 0.0f, 0.0f, -110.0f )*YRotationMtx( 0.002f*fTime - 0.7f )*XRotationMtx( -0.01f );

	m_mtxPlanets[8] = ScaleMtx( 0.002f )*YRotationMtx( 0.15f*fTime )*XRotationMtx( H_PI2 )*
					  TranslationMtx( 0.0f, 0.0f, -110.0f )*YRotationMtx( 0.012f*fTime - 0.3f )*XRotationMtx( 0.05f )*TranslationMtx( 0.0f, 0.0f, -10.0f );



	m_mtxRays = YRotationMtx( 0.2f*fTime )*XRotationMtx( 0.3f )*
				TranslationMtx( 0.0f, 0.0f, -30.0f )*YRotationMtx( 0.005f*fTime + 0.0f )*XRotationMtx( 0.1f );

	m_mtxSaturnRings = ScaleMtx( 1.0f )*XRotationMtx( H_PI2 )*YRotationMtx( 0.15f*fTime )*XRotationMtx( 0.4f )*ZRotationMtx( -0.4f )*
					   TranslationMtx( 0.0f, 0.0f, -80.0f )*YRotationMtx( 0.010f*fTime + 0.8f )*XRotationMtx( 0.05f );

	m_mtxUranRings	= ScaleMtx( 0.5f )*ZRotationMtx( 0.15f*fTime )*
					  TranslationMtx( 0.0f, 0.0f, -95.0f )*YRotationMtx( 0.005f*fTime + 1.2f )*XRotationMtx( 0.01f );

	m_mtxMoon = ScaleMtx( 0.002f )*YRotationMtx( 0.005f*fTime )*TranslationMtx( 0.0f, 0.0f, -1.0f )*YRotationMtx( 0.05f*fTime )*
				TranslationMtx( 0.0f, 0.0f, -30.0f )*YRotationMtx( 0.005f*fTime + 0.0f )*XRotationMtx( 0.1f );

	m_mtxCrown = RotationMtx( 0.05f*fTime, 0.1f*fTime, -0.1f*fTime );

	PSIMPLEVERTEX			pVertices;

	m_pvbSolarCrown->Lock( 0, 0, (LPBYTE*)&pVertices, 0 );

	for( i = 0 ; i < 1000 ; i++ )			
		pVertices[2*i].m_vPos = m_vCrown[i]*( 1.0f + 0.5f*sinf( 2.0f*fTime + (FLOAT)i ) );

	m_pvbSolarCrown->Unlock();


	FLOAT					fAlpha = 0.0f;

	if( fTime < 2.0f )
	{
		m_piqFade->SetColor( 0xffffff );
		fAlpha = ( 2.0f - fTime )*128.0f;
	}

	if( fTime > 14.0f )
	{
		m_piqFade->SetColor( 0x0 );
		fAlpha = ( fTime - 14.0f )*128.0f;
	}

	if( fAlpha < 0.0f )
		fAlpha = 0.0f;
	else if( fAlpha > 255.0f )
		fAlpha = 255.0f;	

	m_piqFade->SetAlpha( (DWORD)fAlpha );

	return TRUE;
}

BOOL CSolarSystem::RenderEfx()
{	
	m_pDevice->Clear( 0, NULL, D3DCLEAR_ZBUFFER|D3DCLEAR_TARGET, 0x0, 1.0f, 0 );
	m_pDevice->SetRenderState( D3DRS_WRAP0, D3DWRAP_U|D3DWRAP_V );		
	m_pDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
	
	m_pDevice->SetRenderState( D3DRS_ZENABLE, D3DZB_FALSE );	
	m_pDevice->SetRenderState( D3DRS_LIGHTING, FALSE );

	m_pDevice->SetTexture( 0, NULL );

	m_pDevice->SetVertexShader( FVF_SIMPLEVERTEX );
	m_pDevice->SetTransform( D3DTS_WORLD, IdentMtx() );
	m_pDevice->SetStreamSource( 0, m_pvbStars, sizeof(SIMPLEVERTEX) );
	m_pDevice->DrawPrimitive( D3DPT_POINTLIST, 0, 5000 );

	m_pDevice->SetRenderState( D3DRS_ZENABLE, D3DZB_TRUE );	
	m_pDevice->SetRenderState( D3DRS_LIGHTING, TRUE );
	m_pDevice->SetRenderState( D3DRS_AMBIENT, 0xffff8f );
	
	m_pDevice->SetTransform( D3DTS_WORLD, ScaleMtx( 0.02f ) );
	m_mSphere.Render( m_pDevice );		

	m_pDevice->SetRenderState( D3DRS_AMBIENT, 0x707070 );	

	for( DWORD i = 0 ; i < 9 ; i++ )
	{
		m_pDevice->SetTexture( 0, m_ptextPlanets[i] );
		m_pDevice->SetTransform( D3DTS_WORLD, m_mtxPlanets[i] );
		m_mSphere.Render( m_pDevice );		
	}

	m_pDevice->SetTexture( 0, m_ptextPlanets[0] );
	m_pDevice->SetTransform( D3DTS_WORLD, m_mtxMoon );
	m_mSphere.Render( m_pDevice );		

	m_pDevice->SetRenderState( D3DRS_WRAP0, FALSE );
	m_pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
	m_pDevice->SetRenderState( D3DRS_ZWRITEENABLE, FALSE );
	m_pDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
	m_pDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ONE );
	m_pDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE );	

	m_pDevice->SetVertexShader( FVF_LVERTEX );
	m_pDevice->SetStreamSource( 0, m_pvbRing, sizeof(LVERTEX) );

	m_pDevice->SetTexture( 0, GetTexture( "saturnrings.jpg" ) );
	m_pDevice->SetTransform( D3DTS_WORLD, m_mtxSaturnRings );

	m_pDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 200 );

	m_pDevice->SetTexture( 0, GetTexture( "uranrings.jpg" ) );
	m_pDevice->SetTransform( D3DTS_WORLD, m_mtxUranRings );

	m_pDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 200 );

	m_pDevice->SetTexture( 0, NULL );

	m_pDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
	m_pDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE );	

	m_pDevice->SetVertexShader( FVF_SIMPLEVERTEX );

	m_pDevice->SetTransform( D3DTS_WORLD, m_mtxRays );	
	m_pDevice->SetStreamSource( 0, m_pvbRays, sizeof(SIMPLEVERTEX) );
	m_pDevice->DrawPrimitive( D3DPT_LINELIST, 0, 250 );

	m_pDevice->SetTransform( D3DTS_WORLD, m_mtxCrown );	
	m_pDevice->SetStreamSource( 0, m_pvbSolarCrown, sizeof(SIMPLEVERTEX) );
	m_pDevice->DrawPrimitive( D3DPT_LINELIST, 0, 1000 );

	m_pDevice->SetTransform( D3DTS_WORLD, IdentMtx() );	

	m_psSeedSystem.Render( m_pDevice );	

	m_pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
	m_pDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
	m_pDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );	

	m_piqFade->Render( m_pDevice );

	m_pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
	m_pDevice->SetRenderState( D3DRS_ZWRITEENABLE, TRUE );
	m_pDevice->SetRenderState( D3DRS_LIGHTING, TRUE );

	return TRUE;
}