// Atmosphere.cpp: implementation of the CAtmosphere class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "Atmosphere.h"

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

VOID SetupPod( PTLVERTEX pVertices, FLOAT fScale, FLOAT fRotation, DWORD dwAlpha )
{
	he3d_CVector			vUV[4];
	he3d_CMatrix			mtx = ZRotationMtx( fRotation )*ScaleMtx( fScale );
	he3d_CVector			v;
	DWORD					dwColor = (dwAlpha<<24)|0xffffff;

	vUV[0] = he3d_CVector( -0.5f, -0.5f, 0.0f );
	vUV[1] = he3d_CVector( -0.5f,  0.5f, 0.0f );
	vUV[2] = he3d_CVector(  0.5f, -0.5f, 0.0f );
	vUV[3] = he3d_CVector(  0.5f,  0.5f, 0.0f );

	for( DWORD i = 0 ; i < 4 ; i++ )
	{
		v = vUV[i]*mtx;

		pVertices[i].m_fU = v.x;
		pVertices[i].m_fV = v.y;
		pVertices[i].m_dwColor = dwColor;
	}
}

CAtmosphere::CAtmosphere( PDIRECT3DDEVICE8 pDevice ) : CEfx( pDevice )
{
	m_pvbPod = NULL;
	m_piqFade = NULL;	

	if( FAILED( m_pDevice->CreateVertexBuffer( 4*sizeof(TLVERTEX), 0, FVF_TLVERTEX, D3DPOOL_DEFAULT, &m_pvbPod ) ) )
		throw CSystemException( DEMO_EXCEPTION_D3DERROR, "unable to creatre pod vertex buffer" );

	m_piqFade = new CImageQuad( m_pDevice );

	try
	{
		LoadTexture( "cloud1.jpg" );
	}
	catch( CTextureException )
	{
		throw CSystemException( DEMO_EXCEPTION_FILENOTFOUND, "unable to load textures" );
	}

	PTLVERTEX				pVertices;

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

	pVertices[0] = TLVERTEX( 0.0f, 480.0f, 0.0f, 0.5f, 0x00ffffff,  0.0f, 0.0f );
	pVertices[1] = TLVERTEX( 0.0f,   0.0f, 0.0f, 0.5f, 0x00ffffff,  0.0f, 0.0f );
	pVertices[2] = TLVERTEX( 640.0f, 480.0f, 0.0f, 0.5f, 0x00ffffff,  0.0f, 0.0f );
	pVertices[3] = TLVERTEX( 640.0f, 0.0f, 0.0f, 0.5f, 0x00ffffff,  0.0f, 0.0f );

	m_pvbPod->Unlock();

	m_fAlpha[0] = 0.0f;
	m_fAlpha[1] = 1.0f;
	m_fAlpha[2] = 1.0f;
	m_fAlpha[3] = 1.0f;
	m_fAlpha[4] = 1.0f;

	m_fScale[0] = 1.0f;
	m_fScale[1] = 0.8f;
	m_fScale[2] = 0.6f;
	m_fScale[3] = 0.4f;
	m_fScale[4] = 0.2f;

	for( DWORD i = 0 ; i < 5 ; i++ )
		m_fRotationSpeed[i] = 0.5f + 0.5f*RAND();

	m_dwCurrentPod = 4;
	m_fSwapTime = 0.0f;
}

CAtmosphere::~CAtmosphere()
{
	if( m_pvbPod )
		m_pvbPod->Release();
}

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

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

BOOL CAtmosphere::UpdateFrame( FLOAT fTime )
{
	FLOAT					fT = fTime - m_fSwapTime;;
	DWORD					dwIndex;

	m_fAlpha[m_dwCurrentPod] = 1.0f - fT;
	m_fAlpha[(m_dwCurrentPod+1)%5] = fT;

	if( m_fAlpha[m_dwCurrentPod] <= 0.0f )
	{
		m_fSwapTime = fTime;
		fT = 0.0f;
		m_fAlpha[m_dwCurrentPod] = 0.0f;
		m_fAlpha[(m_dwCurrentPod+1)%5] = 1.0f;		

		m_fRotationSpeed[m_dwCurrentPod] = 0.5f + 0.5f*RAND();

		if( m_dwCurrentPod == 0 )
			m_dwCurrentPod = 4;
		else
			m_dwCurrentPod = m_dwCurrentPod - 1;
	}
	
	dwIndex = (m_dwCurrentPod + 1)%5;

	for( DWORD i = 0 ; i < 5 ; i++, dwIndex = (dwIndex + 1)%5 )
	{
		m_fScale[dwIndex] = 1.0f - 0.2f*fT - 0.2f*(FLOAT)i;
		m_fRotation[dwIndex] = m_fRotationSpeed[dwIndex]*fTime;
	}

	FLOAT					fAlpha = 0.0f;

	if( fTime < 1.0f )
	{
		m_piqFade->SetColor( 0x0 );
		fAlpha = ( 1.0f - fTime )*255.0f;
	}

	if( fTime > 3.0f )
	{
		m_piqFade->SetColor( 0xaa8c57 );
		fAlpha = ( fTime - 3.0f )*60.0f;
	}

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

	m_piqFade->SetAlpha( (DWORD)fAlpha );	

	return TRUE;
}

BOOL CAtmosphere::RenderEfx()
{
	m_pDevice->Clear( 0, NULL, D3DCLEAR_TARGET, 0x00, 1.0f, 0 );

	m_pDevice->SetRenderState( D3DRS_ZENABLE, FALSE );
	m_pDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );

	m_pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
	m_pDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
	m_pDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE );
	m_pDevice->SetTexture( 0, GetTexture( "cloud1.jpg" ) );
	m_pDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2 );
	m_pDevice->SetVertexShader( FVF_TLVERTEX );
	m_pDevice->SetStreamSource( 0, m_pvbPod, sizeof(TLVERTEX) );

	PTLVERTEX				pVertices;

	for( DWORD i = 0 ; i < 5 ; i++ )
	{
		m_pvbPod->Lock( 0, 0, (LPBYTE*)&pVertices, 0 );
		SetupPod( pVertices, m_fScale[i], m_fRotation[i], (DWORD)(m_fAlpha[i]*64.0f) );
		m_pvbPod->Unlock();

		m_pDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );
	}

	m_pDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );
	
	m_pDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
	m_pDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
	m_pDevice->SetTexture( 0, NULL );

	m_piqFade->Render( m_pDevice );

	m_pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );

	return TRUE;
}


