// ParticleLogo.cpp: implementation of the CParticleLogo class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "ParticleLogo.h"

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

CParticleLogo::CParticleLogo( PDIRECT3DDEVICE8 pDevice ) : CEfx( pDevice )
{
	ifstream				stream;		

	stream.open( "data\\extras\\logo.tmpl", ios::in|ios::binary );	

	if( stream.fail() )	
		throw CSystemException( DEMO_EXCEPTION_FILENOTFOUND, _T("file logo.tmpl not found") );
	

	if( stream.read( m_pbTempl, 4096 ).gcount() != 4096 )
	{
		stream.close();
		throw CSystemException( DEMO_EXCEPTION_UNABLETOREAD, _T("error during reading file logo.tmpl") );
	}

	stream.close();	

	if( FAILED( m_pDevice->CreateVertexBuffer( 3*1024*sizeof(LVERTEX), D3DUSAGE_DYNAMIC, FVF_LVERTEX, D3DPOOL_SYSTEMMEM, &m_pvbParticle ) ) )
		throw CSystemException( DEMO_EXCEPTION_D3DERROR, _T("unable to create flare vertex buffer") );	

	for( int i = 0 ; i < 64 ; i++ )
		for( int j = 0 ; j < 64 ; j++ )						
			m_pvPoints[i*64+j] = he3d_CVector( -0.5f + (FLOAT)j/63.0f, -0.5f + (FLOAT)i/63.0f, -0.5f + RAND() );					

	try
	{
		LoadAlphaTexture( "flare00.bmp" );		
		LoadTexture( "backgnd.jpg" );
	}
	catch( CTextureException )
	{
		m_pvbParticle->Release();
		throw CSystemException( DEMO_EXCEPTION_FILENOTFOUND, _T("unable to load textures") );
	}			

	m_pmBackSphere = new CSimpleMesh();

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

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

	m_piqFade->SetColor( 0x0 );
	m_piqFade->SetAlpha( 0x0 );	
}

CParticleLogo::~CParticleLogo()
{
	if( m_pvbParticle )
		m_pvbParticle->Release();

	delete m_piqFade;
	delete m_pmBackSphere;
	
	CEfx::~CEfx();
}

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

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

BOOL CParticleLogo::UpdateFrame( FLOAT fTime )
{		
	if( fTime < 7.0f )
	{
		FLOAT			angle = 3.14f*sinf(fTime*3.14f/10.0f);
		m_mtxFrame = RotationMtx( angle, angle, angle )*ScaleMtx( 3.0f );
	}
	else if( fTime < 10.0f )
	{
		FLOAT			angle = 3.14f*sinf(fTime*3.14f/10.0f);
		FLOAT			coeff = -0.5f*(expf(-fTime-10.0f) - 1.0f );
		m_mtxFrame = RotationMtx( angle, angle, angle )*ScaleMtx( 3.0f - (fTime - 7.0f)*0.66f )*TranslationMtx( 0, 0, (fTime-7.0f)*coeff );
	}
	else if( fTime < 13.0f )
	{
		FLOAT			coeff = -0.5f*(expf(-fTime-10.0f) - 1.0f );
		m_mtxFrame = TranslationMtx( 0, 0, (fTime-7.0f)*coeff );
	}
	else if( fTime < 17.0f )
	{
		FLOAT			coeff = -0.5f*(expf(-fTime-10.0f) - 1.0f );
		m_mtxFrame = ScaleMtx( 1.0f, 1.0f, 1.0f - 0.25f*(fTime-13.0f) )*TranslationMtx( 0, 0, (fTime-7.0f)*coeff );
	}
	else if( fTime < 18.0f )
	{
		m_mtxFrame = ScaleMtx( 1.0f, 1.0f, 0.0f )*TranslationMtx( 0, 0, 5.0f );
	}
	else 
	{
		m_mtxFrame = ScaleMtx( 1.0f, 1.0f, (fTime-18.0f)*(fTime-17.0f)*0.5f )*TranslationMtx( 0, 0, 5.0f );
	}

	PLVERTEX			pVertices;

	FLOAT				size;
	DWORD				col;

	FLOAT				s1, s2;

	he3d_CVector		vec;

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

	for( int i = 0 ; i < 64 ; i+=2 )
		for( int j = 0 ; j < 64 ; j+= 2 )
		{
			vec = m_pvPoints[i*64 + j]*m_mtxFrame;
			col = 255 - m_pbTempl[i*64 + j];
			size = (sinf(fTime*2 + j - i*5 + col) + 1.0f)*0.1f + 0.1f;
			col = D3DCOLOR_XRGB( col, col, col );			

			s1 = 0.33f*size;
			s2 = 0.66f*size;
			
			*(pVertices++) = LVERTEX( vec.x - s1, vec.y + s2, vec.z, col, 0.0f, 0.0f );
			*(pVertices++) = LVERTEX( vec.x - s1, vec.y - s1, vec.z, col, 0.0f, 1.0f );
			*(pVertices++) = LVERTEX( vec.x + s2, vec.y - s1, vec.z, col, 1.0f, 1.0f );			
		}

	m_pvbParticle->Unlock();		

	m_mtxFrame = RotationMtx( fTime*0.10f, fTime*0.05f, -fTime*0.15f )*ScaleMtx( 0.02f );

	m_dwBackFactor = (DWORD)( fTime*50.0f );
	m_dwFadeFactor = 0x0;

	if( m_dwBackFactor > 0xff )
		m_dwBackFactor = 0xff;

	m_dwBackFactor = D3DCOLOR_XRGB( m_dwBackFactor, m_dwBackFactor, m_dwBackFactor );

	if( fTime >= 22.0f )
		m_dwFadeFactor = (DWORD)( ( fTime - 22.0f )*85.0f );

	if( m_dwFadeFactor > 0xff )
		m_dwFadeFactor = 0xff;

	return TRUE;
}

BOOL CParticleLogo::RenderEfx()
{				
	m_pDevice->SetRenderState( D3DRS_ZWRITEENABLE, FALSE );	
	m_pDevice->SetRenderState( D3DRS_LIGHTING, TRUE );	
	m_pDevice->SetRenderState( D3DRS_WRAP0, D3DWRAPCOORD_0|D3DWRAPCOORD_1 );
	m_pDevice->SetRenderState( D3DRS_AMBIENT, m_dwBackFactor );

	m_pDevice->SetTexture( 0, GetTexture( "backgnd.jpg" ) );
	
	m_pDevice->SetTransform( D3DTS_WORLD, m_mtxFrame );	
	m_pDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CW );
	m_pmBackSphere->Render( m_pDevice );

	m_pDevice->SetRenderState( D3DRS_WRAP0, FALSE );

	m_pDevice->SetTexture( 0, GetTexture( "flare00.bmp" ) );		
	m_pDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG2 );

	m_pDevice->SetRenderState( D3DRS_LIGHTING, FALSE );	
	m_pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );		
	m_pDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );	
	m_pDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );					
	m_pDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );	

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

	m_pDevice->SetVertexShader( FVF_LVERTEX );	
	m_pDevice->SetStreamSource( 0, m_pvbParticle, sizeof(LVERTEX) );	
	m_pDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, 1024 );	

	m_pDevice->SetTexture( 0, NULL );
	m_pDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );

	m_piqFade->SetAlpha( m_dwFadeFactor );
	m_piqFade->Render( m_pDevice );

	m_pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );	
	
	
	return TRUE;
}
