// Volcanic.cpp: implementation of the CVolcanic class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "Volcanic.h"
#include "object.h"

#define	XCENTER		320.0f
#define	YCENTER		250.0f

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

CVolcanic::CVolcanic( PDIRECT3DDEVICE8 pDevice ) : CEfx( pDevice ), m_bsLava( 20 )
{
	try
	{
		scene.Initialize( m_pDevice );
		scene.Load( "data\\scenes\\volcanic.scene" );
		scene.SetVieport( 0.5f, 1000.0f, 0.75f );		
	}
	catch( he3d_CException e )
	{
		if( e.code == HE3DERR_UNABLETOLOAD )
			throw CSystemException( DEMO_EXCEPTION_UNABLETOREAD, "unable to load volcanic.scene" );
		else
			throw CSystemException( DEMO_EXCEPTION_D3DERROR, "unable to initialize scene class" );
	}

	m_piqFade = NULL;
	m_pvbSky = NULL;
	m_pvbMeteorHalo = NULL;

	m_piqFade = new CImageQuad( m_pDevice );
	m_piqFade->SetColor( 0xffffff );
	m_piqExplodeFlare = new CImageQuad( m_pDevice );
	m_piqExplodeFlare->SetARGB( 0x00ffffff );

	if( FAILED( m_pDevice->CreateVertexBuffer( 4*sizeof(LVERTEX), 0, FVF_LVERTEX, D3DPOOL_DEFAULT, &m_pvbSky ) ) )
		throw CSystemException( DEMO_EXCEPTION_D3DERROR, "unable to create sky vertex buffer" );

	if( !m_mMeteor.Load( m_pDevice, "data\\objects\\meteor.smf" ) )
		throw CSystemException( DEMO_EXCEPTION_FILENOTFOUND, "unable to load meteor.smf" );	

	if( FAILED( m_pDevice->CreateVertexBuffer( 100*sizeof(PARTICLEVERTEX), 0, FVF_PARTICLEVERTEX, D3DPOOL_DEFAULT, &m_pvbMeteorHalo ) ) )
		throw CSystemException( DEMO_EXCEPTION_D3DERROR, "unable to create meteor halo vertex buffer" );

	if( !m_mSphere.Load( m_pDevice, "data\\objects\\sphere2.smf" ) )
		throw CSystemException( DEMO_EXCEPTION_FILENOTFOUND, "unable to load sphere.smf" );	

	PVERTEX					pVerts;
	LPBYTE					pbTmp;

	m_mSphere.LockMesh( (LPBYTE*)&pVerts, &pbTmp );
	for( DWORD i = 0 ; i < m_mSphere.GetVertexCount() ; i++ )
	{
		pVerts[i].m_fV = 1.0f - pVerts[i].m_vPos.y;
		pVerts[i].m_fU = (atan2f( pVerts[i].m_vPos.z, pVerts[i].m_vPos.x ) - 1.5f)/H_PI2 + 0.01f;
	}
	m_mSphere.UnlockMesh();

	m_bRenderSphere = FALSE;
	m_bRenderExplode = FALSE;
	m_bRenderFade = FALSE;

	PPARTICLEVERTEX			pV;
	FLOAT					a, b;

	m_pvbMeteorHalo->Lock( 0, 0, (LPBYTE*)&pV, 0 );

	for( i = 0 ; i < 100 ; i++ )
	{
		a = H_2PI*RAND();
		b = H_2PI*RAND();

		pV[i].color = 0xffffffff;
		pV[i].size	= 5.0f;		
		pV[i].p		= he3d_CVector( 1.3f*cosf(a)*sinf(b), 1.3f*cosf(b), 1.3f*sinf(a)*sinf(b) );
	}

	m_pvbMeteorHalo->Unlock();

	PLVERTEX				pVertices;

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

	*(pVertices++) = LVERTEX( -50.0f, 50.0f, -50.0f, 0xffffff, 0.0f, 1.0f );
	*(pVertices++) = LVERTEX( -50.0f, 50.0f,  50.0f, 0xffffff, 0.0f, 0.0f );
	*(pVertices++) = LVERTEX(  50.0f, 50.0f, -50.0f, 0xffffff, 1.0f, 1.0f );
	*(pVertices++) = LVERTEX(  50.0f, 50.0f,  50.0f, 0xffffff, 1.0f, 0.0f );

	m_pvbSky->Unlock();

	try
	{
		LoadTexture( "flare1.bmp" );		
		LoadTexture( "cloud1.jpg" );
		LoadTexture( "cloud1_a.jpg" );
		LoadAlphaTexture( "smoke.bmp" );
		LoadTexture( "rock1.jpg" );
		LoadTexture( "shockwave2.jpg" );
		LoadTexture( "meteorflare.jpg" );
	}
	catch( CTextureException )
	{
		throw CSystemException( DEMO_EXCEPTION_FILENOTFOUND, "unable to load textures" );
	}

	if( !m_psSystem.Initialize( m_pDevice ) )
		throw CSystemException( DEMO_EXCEPTION_D3DERROR, "unable to initilize volcan particle system" );

	if( !m_psSmokeSystem.Initialize( m_pDevice ) )
		throw CSystemException( DEMO_EXCEPTION_D3DERROR, "unable to initilize smoke particle system" );

	if( !m_psMeteorSystem.Initialize( m_pDevice ) )
		throw CSystemException( DEMO_EXCEPTION_D3DERROR, "unable to initilize meteor trace particle system" );

	if( !m_bsLava.Initialize( m_pDevice ) )
		throw CSystemException( DEMO_EXCEPTION_D3DERROR, "unable to initilize lava blob system" );

	m_psSystem.SetCollision( C_PLANE );	
	m_psSystem.SetPlane( he3d_CVector( 0, 1, 0 ), 0 );
	m_psSystem.SetTexture( GetTexture( "flare1.bmp" ) );
	m_psSystem.SetBlurCoeff( 0.3f );
	m_psSystem.ConfigureSparks( 5, 0.2f, 0.5f, 2.0f, 1.0f );
	m_psSystem.ConfigureGravity( G_VECTOR, he3d_CVector( 0, -1, 0 ), 0.5f );

	m_psSmokeSystem.SetTexture( GetTexture( "smoke.bmp" ) );
	m_psSmokeSystem.ConfigureGravity( G_VECTOR, he3d_CVector( 0, 0, -1 ), 0.05f );
	m_psSmokeSystem.SetRenderType( RT_SUB );

	m_psMeteorSystem.SetTexture( GetTexture( "flare1.bmp" ) );
	m_psMeteorSystem.ConfigureGravity( G_VECTOR, he3d_CVector( 0, 0, 0 ), 0.0f );

	for( i = 0 ; i < 20 ; i++ )
	{
		m_peEmiter[i].SetEmitAngle( 0.12f );
		m_peEmiter[i].SetEmitCount( 10, 0 );
		m_peEmiter[i].SetEmiterDir( he3d_CVector( 0, 1, 0 ) );
		m_peEmiter[i].SetLifeTime( 30.0f, 5.0f );
		m_peEmiter[i].SetSize( 0.75f, 0.25f );
		m_peEmiter[i].SetVelocity( 5.5f, 2.5f );
		m_peEmiter[i].SetEmitInterval( 2.0f );
		m_peEmiter[i].SetEmiterPos( he3d_CVector( 0.0f, 5.0f, 0.0f ) + 2.5f*he3d_CVector( SIGNEDRAND(), 0, SIGNEDRAND() ) );

		m_psSystem.AddEmiter( &m_peEmiter[i] );		
	}	

	for( i = 0 ; i < 5 ; i++ )
	{
		m_peSmokeEmiter[i].SetEmitAngle( 0.15f );
		m_peSmokeEmiter[i].SetEmitCount( 2, 0 );
		m_peSmokeEmiter[i].SetEmiterDir( he3d_CVector( 0, 1, 0 ) );
		m_peSmokeEmiter[i].SetSize( 10.0f, 2.0f );
		m_peSmokeEmiter[i].SetVelocity( 2.0f, 0.5f );
		m_peSmokeEmiter[i].SetLifeTime( 55.0f, 5.0f );
		m_peSmokeEmiter[i].SetEmiterPos( he3d_CVector( 0.0f, 1.0f, 0.0f ) + 1.5f*he3d_CVector( SIGNEDRAND(), 0, SIGNEDRAND() ) );
		m_peSmokeEmiter[i].SetParticleType( PT_STANDARD );

		m_psSmokeSystem.AddEmiter( &m_peSmokeEmiter[i] );
	}

	for( i = 0 ; i < 5 ; i++ )
	{
		m_peMeteorEmiter[i].SetEmitAngle( 0.2f );
		m_peMeteorEmiter[i].SetEmitCount( 5, 0 );
		m_peMeteorEmiter[i].SetSize( 5.0f, 0.5f );
		m_peMeteorEmiter[i].SetVelocity( 2.0f, 1.0f );
		m_peMeteorEmiter[i].SetLifeTime( 5.0f, 2.0f );
		m_peMeteorEmiter[i].SetParticleType( PT_STANDARD );

		m_psMeteorSystem.AddEmiter( &m_peMeteorEmiter[i] );
	}

	for( i = 0 ; i < 7 ; i++ )
	{
		m_b3dLava[i].m_dwColor = 0xffffff;
		m_b3dLava[i].m_dwSign = FALSE;
		m_b3dLava[i].m_fDensity = 1.0f;
		m_b3dLava[i].m_fRadius = 3.0f;

		m_bsLava.AddBlob( &m_b3dLava[i] );
	}

	m_vBlobs[0] = he3d_CVector( 0.0f, 0.0f, 0.0f );
	m_vBlobs[1] = he3d_CVector( 1.0f, 0.0f, 0.0f );
	m_vBlobs[2] = he3d_CVector( 0.5f, 0.0f,  0.86f );
	m_vBlobs[3] = he3d_CVector( -0.5f, 0.0f, 0.86f );
	m_vBlobs[4] = he3d_CVector( -1.0f, 0.0f, 0.0f );
	m_vBlobs[5] = he3d_CVector( -0.5f, 0.0f, -0.86f );
	m_vBlobs[6] = he3d_CVector( 0.5f, 0.0f, -0.86f );

	for( FLOAT fT = 0 ; fT < 20.0f ; fT += 0.25f )
	{
		m_psSystem.Update( fT );
		m_psSmokeSystem.Update( fT );		
	}
}

CVolcanic::~CVolcanic()
{	
	if( m_piqFade )
		delete m_piqFade;

	if( m_pvbSky )
		m_pvbSky->Release();

	if( m_pvbMeteorHalo )
		m_pvbMeteorHalo->Release();
}

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

BOOL CVolcanic::FinishEfx()
{
	scene.CloseScene();

	return TRUE;
}

BOOL CVolcanic::UpdateFrame( FLOAT fTime )
{
	scene.Transform( 25.0f*fTime );		
	
	m_psSystem.Update( fTime + 20.0f );
	m_psSmokeSystem.Update( fTime + 20.0f );

	m_fSkyMovement = fTime*0.05f;

	he3d_CKeyframer*		keyframer = scene.GetKeyframer( "NULL01" );

	m_mtxMeteor = ScaleMtx( 40.0f )*keyframer->mtxFrame;	

	he3d_CVector			vPos = he3d_CVector( keyframer->mtxFrame._41, keyframer->mtxFrame._42, keyframer->mtxFrame._43 );
	he3d_CVector			vTmp;

	for( DWORD i = 0 ; i < 5 ; i++ )
	{
		vTmp = vPos + 4.0f*he3d_CVector( SIGNEDRAND(), SIGNEDRAND(), SIGNEDRAND() );

		m_peMeteorEmiter[i].SetEmiterPos( vTmp );
		m_peMeteorEmiter[i].SetEmiterDir( Normalize( m_vPrevPos - vPos ) );
	}

	m_vPrevPos = vPos;

	m_psMeteorSystem.Update( fTime );

	PPARTICLEVERTEX			pVertices;

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

	for( i = 0 ; i < 100 ; i++ )	
		pVertices[i].color = ( ( rand()%128 + 127 ) << 24 ) | 0xffffff;	

	m_pvbMeteorHalo->Unlock();

	if( fTime > 27.0f )
	{
		m_bRenderSphere = TRUE;
		m_fSphereScale = (fTime - 27.0f)*11.0f;
	}

	FLOAT					fAlpha = 0.0f;

	m_bRenderFade = FALSE;

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

	if( fTime > 28.0f )
	{
		m_bRenderFade = TRUE;		
		fAlpha = (fTime - 28.0f)*140.0f;
		m_piqFade->SetColor( 0xffffff );
	}	

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

	m_piqFade->SetAlpha( (DWORD)fAlpha );

	m_bRenderExplode = FALSE;

	if( fTime >= 27.0f && fTime <= 28.0f )
	{
		m_bRenderExplode = TRUE;

		fAlpha = sinf( (fTime - 27.0f)*H_PI );

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

		m_piqExplodeFlare->Resize( XCENTER - 1000.0f*fAlpha, YCENTER - 800.0f*fAlpha, XCENTER + 1000.0f*fAlpha, YCENTER + 800.0f*fAlpha );
		m_piqExplodeFlare->SetAlpha( (DWORD)( 255.0f*fAlpha ) );
	}

	for( i = 0 ; i < 7 ; i++ )	
		m_b3dLava[i].m_vPos = 2.0f*m_vBlobs[i] + he3d_CVector( 0, 8.0f + 1.0f*sinf( fTime + (FLOAT)i ), 0 );	

	m_bsLava.CalculateDensity();

	return TRUE;
}

BOOL CVolcanic::RenderEfx()
{
	he3d_CCameraObject*		cam;

	cam = (he3d_CCameraObject*)scene.GetObject( "CAMERA01" );

	he3d_CMatrix			mtxTexture;
	he3d_CMatrix			mtx = IdentMtx();

	mtx._22 = 0.0f;
	mtx._23 = 1.0f;
	mtx._33 = 0.0f;
	mtx._32 = 1.0f;

	mtxTexture = InverseMtx( cam->mtxCamera )*mtx*ScaleMtx( 0.02f, 0.005f, 0.02f )*TranslationMtx( 0, m_fSkyMovement, 0 );

	m_pDevice->SetRenderState( D3DRS_FOGENABLE, TRUE );
	m_pDevice->SetRenderState( D3DRS_FOGTABLEMODE, D3DFOG_EXP2 );
	m_pDevice->SetRenderState( D3DRS_FOGCOLOR, 0xaa8c57 );
	m_pDevice->SetRenderState( D3DRS_FOGDENSITY, FLT2DWORD( 0.03f ) );

	m_pDevice->SetRenderState( D3DRS_AMBIENT, 0xffffff );
	m_pDevice->Clear( 0, 0, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, 0xaa8c57, 1.0f, 0 );
	m_pDevice->SetRenderState( D3DRS_ZENABLE, D3DZB_FALSE );
	
	m_pDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION );
	m_pDevice->SetTextureStageState( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2 );	
	m_pDevice->SetTransform( D3DTS_TEXTURE0, mtxTexture );
	m_pDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
	m_pDevice->SetRenderState( D3DRS_ZWRITEENABLE, FALSE );
	m_pDevice->SetTexture( 0, GetTexture( "cloud1.jpg" ) );
	m_pDevice->SetTransform( D3DTS_WORLD, ScaleMtx( 4.5f, 1.9f, 4.5f )*TranslationMtx( 0, -80, 0 ) );	
	m_pDevice->SetVertexShader( FVF_LVERTEX );
	m_pDevice->SetStreamSource( 0, m_pvbSky, sizeof(LVERTEX) );
	m_pDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );
	m_pDevice->SetRenderState( D3DRS_ZWRITEENABLE, TRUE );
	m_pDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU );
	m_pDevice->SetTextureStageState( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE );	

	m_pDevice->SetRenderState( D3DRS_ZENABLE, D3DZB_TRUE );
	m_pDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
	m_pDevice->SetTransform( D3DTS_WORLD, m_mtxMeteor );
	m_pDevice->SetRenderState( D3DRS_FOGENABLE, FALSE );
	m_pDevice->SetTexture( 0, GetTexture( "rock1.jpg" ) );
	m_pDevice->SetTextureStageState( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2 );
	m_pDevice->SetTransform( D3DTS_TEXTURE0, RotationMtx( 5.0f*m_fSkyMovement, -2.5f*m_fSkyMovement, 4.0f*m_fSkyMovement ) );
	m_mMeteor.Render( m_pDevice );
	m_pDevice->SetTextureStageState( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE );

	if( m_bRenderSphere )
	{		
		m_pDevice->SetRenderState( D3DRS_WRAP0, D3DWRAP_U|D3DWRAP_V );
		m_pDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ONE );
		m_pDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE );		
		m_pDevice->SetTexture( 0, GetTexture( "shockwave2.jpg" ) );								
		m_pDevice->SetTransform( D3DTS_WORLD, YRotationMtx( -0.5f )*ScaleMtx( m_fSphereScale )*TranslationMtx( 41.0f, 0.0f, -21.0f ) );		
		m_mSphere.Render( m_pDevice );
		m_pDevice->SetRenderState( D3DRS_WRAP0, FALSE );				
	}

	m_pDevice->SetTextureStageState( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE );

	m_pDevice->SetTexture( 0, GetTexture( "flare1.bmp" ) );
	m_pDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2 );
	m_pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
	m_pDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
	m_pDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE );
	m_pDevice->SetRenderState( D3DRS_POINTSPRITEENABLE, TRUE );
	m_pDevice->SetRenderState( D3DRS_POINTSCALEENABLE, TRUE );
	m_pDevice->SetRenderState( D3DRS_ZWRITEENABLE, FALSE );
	m_pDevice->SetTransform( D3DTS_WORLD, RotationMtx( 4.0f*m_fSkyMovement, -3.0f*m_fSkyMovement, 5.0f*m_fSkyMovement )*m_mtxMeteor );
	m_pDevice->SetVertexShader( FVF_PARTICLEVERTEX );
	m_pDevice->SetStreamSource( 0, m_pvbMeteorHalo, sizeof(PARTICLEVERTEX) );
	m_pDevice->DrawPrimitive( D3DPT_POINTLIST, 0, 100 );
	m_pDevice->SetRenderState( D3DRS_POINTSPRITEENABLE, FALSE );
	m_pDevice->SetRenderState( D3DRS_POINTSCALEENABLE, FALSE );
	m_pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
	m_pDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );
	m_pDevice->SetRenderState( D3DRS_ZWRITEENABLE, TRUE );

	m_pDevice->SetRenderState( D3DRS_FOGENABLE, TRUE );

	m_pDevice->SetTexture( 1, GetTexture( "cloud1_a.jpg" ) );
	m_pDevice->SetTextureStageState( 1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION );
	m_pDevice->SetTextureStageState( 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2 );
	m_pDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_MODULATE );	

	m_pDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );

	m_pDevice->SetTransform( D3DTS_TEXTURE1, mtxTexture );
	m_pDevice->SetRenderState( D3DRS_WRAP0, D3DWRAP_U|D3DWRAP_V );
	scene.Render();
	m_pDevice->SetRenderState( D3DRS_WRAP0, FALSE );
	m_pDevice->SetTexture( 1, NULL );
	m_pDevice->SetTextureStageState( 1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU );
	m_pDevice->SetTextureStageState( 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE );
	m_pDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_DISABLE );

	m_pDevice->SetRenderState( D3DRS_FOGENABLE, FALSE );		

	m_pDevice->SetTexture( 0, GetTexture( "rock1.jpg" ) );
	m_pDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACENORMAL );
	m_pDevice->SetTextureStageState( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2 );
	m_pDevice->SetTransform( D3DTS_TEXTURE0, TranslationMtx( 1.0f, 1.0f, 1.0f )*ScaleMtx( 0.5f ) );	
	m_bsLava.Render( m_pDevice, FALSE );
	m_pDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU );
	m_pDevice->SetTextureStageState( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE );

	m_pDevice->SetRenderState( D3DRS_LIGHTING, FALSE );

	m_psSmokeSystem.Render( m_pDevice );
	m_psSystem.Render( m_pDevice );		
	m_pDevice->SetTransform( D3DTS_WORLD, IdentMtx() );		
	m_psMeteorSystem.Render( m_pDevice );

	if( m_bRenderFade )
	{
		m_pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
		m_pDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
		m_pDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
		m_pDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2 );
		m_piqFade->Render( m_pDevice );
		m_pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
		m_pDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );		
	}

	if( m_bRenderExplode )
	{
		m_pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
		m_pDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
		m_pDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE );
		m_pDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2 );
		m_pDevice->SetTexture( 0, GetTexture( "meteorflare.jpg" ) );
		m_piqExplodeFlare->Render( m_pDevice );
		m_pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
		m_pDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );		
	}

	m_pDevice->SetRenderState( D3DRS_LIGHTING, TRUE );

	return TRUE;
}
