//----------------------------------------------------------------------------------------------
// initial sequence with nice volumetric light fx
// coded by acid/z51 (do i know this fella?)
//----------------------------------------------------------------------------------------------
// this file is part of source code from inertia³ demo (c)zone51 `2000
//----------------------------------------------------------------------------------------------

#define  D3D_OVERLOADS
#include "TitleExplode.h"
#include "volumetric.h"
#include "object3d.h"
#include "texture.h"
#include "blobs.h"
#include "extrastuff.h"
#include "texturemenager.h"

static	D3DMATRIX				g_matLocal;

static	gem_Vector				vecExplode[5];

static	D3DLVERTEX				Flare[4];

static	D3DLVERTEX				shiluette[1000];
static	DWORD					vNumber;

static	gem_Vector				FlarezCube[8];

static	gem_Matrix				mtxFlareRot;

static	OBJECT3D				lett;

static	VOLUMEINFO				vInfo;
static	VOLUME					volume;
static	VOLUME					extruded;
static	VOLUME					full;

static	DWORD					added[28];

static	DWORD					explode;
static	FLOAT					explodePow;
static	DWORD					spaw;
static	FLOAT					spawPow;
static	DWORD					spawNbr;

static	D3DTLVERTEX				FadeV[4];

static	D3DLVERTEX				Flarez[10000];
static	gem_Vector				pos[5];

static	BLOBGRID				g_Grid;
static	BLOB3D					boob[10];

static	DWORD					Fade = 0;

HRESULT fxInit_Title( LPDIRECT3DDEVICE7 pd3dDevice )
{	
	LoadTexture( "data\\textures\\letttex.jpg", pd3dDevice );	
	LoadTexture( "data\\textures\\light2.jpg", pd3dDevice );	

	LoadObject3D( "data\\objects\\letti.o3d", &lett );
	TransformObject3D( &lett, ScaleMtx( 0.4f )*TranslationMtx( 10, 2, 0 ) );
	
	vNumber = CreateShiluette( &lett, shiluette );

	Flare[0] = D3DLVERTEX( D3DVECTOR(-3, 3, 0 ), 0x80ffffff, 0, 0, 0 );
	Flare[1] = D3DLVERTEX( D3DVECTOR( 3, 3, 0 ), 0x80ffffff, 0, 1, 0 );
	Flare[2] = D3DLVERTEX( D3DVECTOR(-3,-3, 0 ), 0x80ffffff, 0, 0, 1 );
	Flare[3] = D3DLVERTEX( D3DVECTOR( 3,-3, 0 ), 0x80ffffff, 0, 1, 1 );

	full.vNbrHull = 0;
	full.vNbrSpot = 0;
	full.volumeHull = new D3DLVERTEX[126*18];
	full.volumeSpot = new D3DLVERTEX[126*120];

	ZeroMemory( added, 28*sizeof(DWORD) );

	vecExplode[0] = Normalize( gem_Vector( -0.1f,  0.1f, -1.0f ) );
	vecExplode[1] = Normalize( gem_Vector(  0.1f,  0.1f, -1.0f ) );
	vecExplode[2] = Normalize( gem_Vector(  0.0f,  0.0f, -1.0f ) );
	vecExplode[3] = Normalize( gem_Vector(  0.1f, -0.1f, -1.0f ) );
	vecExplode[4] = Normalize( gem_Vector( -0.1f, -0.1f, -1.0f ) );			

	D3DVECTOR vFar = D3DVECTOR( 0.0f, 0.0f, 0.5f );
    FadeV[0] = D3DTLVERTEX( vFar, 0.5f, 0xFFFFFFFF, 0, 0.01f, 0.99f );
    FadeV[1] = D3DTLVERTEX( vFar, 0.5f, 0xFFFFFFFF, 0, 0.01f, 0.01f );
    FadeV[2] = D3DTLVERTEX( vFar, 0.5f, 0xFFFFFFFF, 0, 0.99f, 0.99f );
    FadeV[3] = D3DTLVERTEX( vFar, 0.5f, 0xFFFFFFFF, 0, 0.99f, 0.01f );

	D3DVIEWPORT7 vp;
    pd3dDevice->GetViewport(&vp);
    FadeV[0].sy = (FLOAT)vp.dwHeight;
    FadeV[2].sy = (FLOAT)vp.dwHeight;
    FadeV[2].sx = (FLOAT)vp.dwWidth;
    FadeV[3].sx = (FLOAT)vp.dwWidth;

	D3DVECTOR GridPos(0,0,0);

	pos[0] = gem_Vector( -2.5, 0, 0);
	pos[1] = gem_Vector(  2.5, 0, 0);
	pos[2] = gem_Vector(  0, 3, 0);
    pos[3] = gem_Vector(  0,-3, 0);
	pos[4] = gem_Vector(  -0.1, 1, -2 );

	FlarezCube[0] = gem_Vector( -4,  4, -4 );
	FlarezCube[1] = gem_Vector(  4,  4, -4 );
	FlarezCube[2] = gem_Vector( -4,  4,  4 );
	FlarezCube[3] = gem_Vector(  4,  4,  4 );
	FlarezCube[4] = gem_Vector( -4, -4, -4 );
	FlarezCube[5] = gem_Vector(  4, -4, -4 );
	FlarezCube[6] = gem_Vector( -4, -4,  4 );
	FlarezCube[7] = gem_Vector(  4, -4,  4 );

	boob[0].pos =  GetD3DVECTOR( pos[0] );		
	boob[0].negative = FALSE;
	
	boob[1].pos =  GetD3DVECTOR( pos[1] );		
	boob[1].negative = FALSE;

	boob[2].pos =  GetD3DVECTOR( pos[2] );	
	boob[2].negative = FALSE;

	boob[3].pos =  GetD3DVECTOR( pos[3] );		
	boob[3].negative = FALSE;

	boob[4].pos =  GetD3DVECTOR( pos[4] );	
	boob[4].negative = FALSE;


	InitGrid( g_Grid, GridPos, 32);

	D3DVECTOR p1( 0.0f, 3.0f, 0.0f );
	D3DVECTOR p2( 3.0f,-3.0f, 0.0f );
	D3DVECTOR p3(-3.0f,-3.0f, 0.0f );
	

	// Set the object material as yellow. We're setting the ambient color here
	// since this tutorial only uses ambient lighting. For apps that use real
	// lights, the diffuse and specular values should be set. (In addition, the
	// polygons' vertices need normals for true lighting.)
    
			
	return S_OK;
}

//-----------------------------------------------------------------------------
// Name: App_FrameMove()
// Desc: Called once per frame, the call is used for animating the scene. The
//       device is used for changing various render states, and the timekey is
//       used for timing of the dynamics of the scene.
//-----------------------------------------------------------------------------
HRESULT fxFrameMove_Title( LPDIRECT3DDEVICE7 pd3dDevice, LPSYNCINFO sync )
{
    // For this tutorial, we are rotating several triangles about the y-axis.
	// (Note: the triangles are meant to intersect, to show how z-buffering
	// handles hidden-surface removal.)

	// For each object, set up a local rotation matrix to be applied right
	// before rendering the object's polygons.	

	//*********************************************************************
	D3DMATERIAL7       mtrl;
	ZeroMemory( &mtrl, sizeof(mtrl) );
    mtrl.dcvAmbient.r = 0.3f;
    mtrl.dcvAmbient.g = 0.3f;
    mtrl.dcvAmbient.b = 0.3f;
	mtrl.dcvDiffuse.r = 1.0f;
    mtrl.dcvDiffuse.g = 1.0f;
    mtrl.dcvDiffuse.b = 1.0f;
	mtrl.dcvDiffuse.a = 0.4f;
    pd3dDevice->SetMaterial( &mtrl );	

	
    // Set the transform matrices. Direct3D uses three independant matrices:
	// the world matrix, the view matrix, and the projection matrix. For
	// convienence, we are first setting up an identity matrix.
    D3DMATRIX mat;
	mat._11 = mat._22 = mat._33 = mat._44 = 1.0f;
	mat._12 = mat._13 = mat._14 = mat._41 = 0.0f;
	mat._21 = mat._23 = mat._24 = mat._42 = 0.0f;
	mat._31 = mat._32 = mat._34 = mat._43 = 0.0f;
	
	// The world matrix controls the position and orientation of the polygons
	// in world space. We'll use it later to spin the triangle.
	D3DMATRIX matWorld = mat;
    pd3dDevice->SetTransform( D3DTRANSFORMSTATE_WORLD, &matWorld );

	// The view matrix defines the position and orientation of the camera.
	// Here, we are just moving it back along the z-axis by 10 units.
	D3DMATRIX matView = CameraMtx( gem_Vector( 0, 0, -10 ), gem_Vector( 0, 0, 20 ), 0 );//mat;
	//matView._43 = 10.0f;
    pd3dDevice->SetTransform( D3DTRANSFORMSTATE_VIEW, &matView );

	// The projection matrix defines how the 3D scene is "projected" onto the
	// 2D render target (the backbuffer surface). Refer to the docs for more
	// info about projection matrices.
	D3DMATRIX matProj = GetD3DMATRIX( ProjectionMtx( 45.0f, 0.5f, 1000.0f, 0.70f ) );
	
    pd3dDevice->SetTransform( D3DTRANSFORMSTATE_PROJECTION, &matProj );
	pd3dDevice->SetRenderState( D3DRENDERSTATE_ALPHABLENDENABLE, TRUE );
	pd3dDevice->SetRenderState( D3DRENDERSTATE_AMBIENT, 0xFFFFFFFF );
	pd3dDevice->SetRenderState( D3DRENDERSTATE_ZENABLE, D3DZB_USEW );
	//********************************************************************************

	gem_Matrix			a = IdentMtx();
	FLOAT				rot[4], d = -1;	
	FLOAT				texCoord[4][2];
	FLOAT				fTimeKey = sync->fTimeKey;
	LONG				i, j;	
		
	DWORD	frame = ((DWORD)(fTimeKey*50.0f));
	FLOAT   len;
	DWORD	nbr;	

	gem_Vector		src = gem_Vector( 0, 0, 50 );
	
	if( frame>450 && frame < 500 )
	{
		explode = 1;
		explodePow = (FLOAT)(frame - 450 )*0.5f;
	}
	else
	{
		explode = 0;
	}	

	if( frame>=350 && frame < 450 )
	{
		spaw = 1;
		spawPow = (FLOAT)(frame - 350)*0.8f/100.0f;
		DWORD ddd = (DWORD)(255*spawPow);
		SetAlphaValue( shiluette, vNumber, ddd );
	}
	else
	{
		spaw = 0;
	}

	if( frame>=450 && frame<480 )
	{
		full.vNbrSpot = 0;
		full.vNbrHull = 0;

		if( frame < 455 )
		{
			len = 0.1f;
		}
		else
		{
			len = 0.1f + (FLOAT)( frame - 455 );
		}

		AddToExtruded( &lett, &full, 0, 97, len, src );

		DWORD	ccc = ((DWORD)(255.0f*0.7f)<<16) | ((DWORD)(255.0f*0.8f)<<8) | 255;
		SetExtrudedColor( &full, ccc );
	}

	/*if( frame>=400 && frame<600 )
	{
		FLOAT	locTime = frame - 400;

		src.y = 5*sin( 6.283f*locTime/100.0f )*( locTime/200.0f );
		src.x = 7.5*cos( 6.283f*locTime/100.0f )*( locTime/200.0f );
	}*/

	if( frame>=550 && frame<1050 )
	{
		full.vNbrSpot = 0;
		full.vNbrHull = 0;

		len = 25.1f - (FLOAT)( frame - 550 )*25.0f/500.0f;		

		AddToExtruded( &lett, &full, 0, 97, len, src );
		DWORD	ccc = ((DWORD)(255.0f*0.7f)<<16) | ((DWORD)(255.0f*0.8f)<<8) | 255;
		SetExtrudedColor( &full, ccc );
	}

	if( frame>=950 && frame<1050 )
	{
		FLOAT		coeff = (1050.0f - (FLOAT)frame)/100.0f;

		DWORD		r = (DWORD)(coeff*0.7f*255.0f);
		DWORD		g = (DWORD)(coeff*0.8f*255.0f);
		DWORD		b = (DWORD)(coeff*1.0f*255.0f);

		DWORD		ccc = (r<<16) | (g<<8) | b;

		SetExtrudedColor( &full, ccc );
	}


	if( frame>=1050 )
	{
		full.vNbrSpot = 0;
		full.vNbrHull = 0;
	}

	if( fTimeKey < 8.0f )
	{
		FLOAT		value = fTimeKey;

		boob[0].r = value>3.5f ? 3.5f : value;
		boob[1].r = value>3.0f ? 3.0f : value;
		boob[2].r = value>4.0f ? 4.0f : value;
		boob[3].r = value>5.5f ? 5.5f : value;
		boob[4].r = value>4.5f ? 4.5f : value;

		boob[0].R = value>4.0f ? 4.0f : value;
		boob[1].R = value>6.0f ? 6.0f : value;
		boob[2].R = value>5.0f ? 5.0f : value;
		boob[3].R = value>8.0f ? 8.0f : value;
		boob[4].R = value>8.0f ? 8.0f : value;
	}
	else
	{
		boob[0].r = 3.5;
		boob[0].R = 4;
		boob[1].r = 3;
		boob[1].R = 6;		
		boob[2].r = 4;
		boob[2].R = 5;	
		boob[3].r = 5.5;
		boob[3].R = 8;	
		boob[4].r = 4.5;
		boob[4].R = 8;
	}

	rot[0] = fTimeKey*1.75f;
	rot[1] = -fTimeKey*2.0f;
	rot[2] = -fTimeKey;
	rot[3] = fTimeKey*1.5f;
	rot[4] = -fTimeKey*0.75f;

	for( i = 0; i<5 ; i++ )
	{
		a = RotationMtx( rot[i], rot[i], 0 );
		boob[i].pos = GetD3DVECTOR( pos[i]*a );
	}
	

	if( fTimeKey<21.0f )
	{
		mtxFlareRot = RotationMtx( fTimeKey*0.25, -fTimeKey*0.4, -fTimeKey*0.35 )*
					  TranslationMtx( 0, 0, 20 );
	}
	else
	{
		if( fTimeKey<35.0f )
		{
			mtxFlareRot = RotationMtx( fTimeKey*0.25, -fTimeKey*0.4, -fTimeKey*0.35 )*
						  TranslationMtx( 0, 0, 20.0f - (fTimeKey-21.0f)*3.333f );
		}
		else
		{
			mtxFlareRot = RotationMtx( fTimeKey*0.25, -fTimeKey*0.4, -fTimeKey*0.35 )*
					  TranslationMtx( 0, 0, -20 );
		}
	}

	if( fTimeKey > 29.0f )
	{
		Fade = 1;

		DWORD alpha = (DWORD)( ( fTimeKey - 29.0f )*0.5*255.0f );

		if( alpha > 255 ) 
			alpha = 255;

		alpha <<= 24;

		FadeV[0].dcColor = alpha | 0xffffff;
		FadeV[1].dcColor = alpha | 0xffffff;
		FadeV[2].dcColor = alpha | 0xffffff;
		FadeV[3].dcColor = alpha | 0xffffff;
	}

	/*FlarezCube[0].x = -4 - 2*sin( 2*fTimeKey );
	FlarezCube[1].y =  4 + 2*cos( 2*fTimeKey );
	FlarezCube[2].z =  4 - 2*sin( 2*fTimeKey );
	FlarezCube[3].y =  4 + 2*sin( 2*fTimeKey );
	FlarezCube[4].z = -4 + 2*cos( 2*fTimeKey );
	FlarezCube[5].x =  4 - 2*sin( 2*fTimeKey );
	FlarezCube[6].y = -4 + 2*cos( 2*fTimeKey );
	FlarezCube[7].z =  4 - 2*sin( 2*fTimeKey );
*/

	return S_OK;
}

VOID RenderFlareSystem( gem_Vector* cube, BLOBGRID& grid, LPBLOB3D blob, DWORD n, LPDIRECT3DDEVICE7 pd3dDevice )
{
	D3DMATRIX		mat;

	gem_Vector		pos, fpos, a, b, c, d;
	int				i, j, k;
	FLOAT			delta = grid.delta;
	FLOAT			size, coeff;
	DWORD			index = 0;
	LPD3DLVERTEX	F = Flarez;
	WORD			nbr = 0;

	mat = (D3DMATRIX)IdentMtx();
	pd3dDevice->SetTransform( D3DTRANSFORMSTATE_WORLD, &mat );

	for( pos.x = grid.pos.x + 11*delta, i = 10 ; i<20 ; i++, pos.x+=delta )
		for( pos.y = grid.pos.y - 11*delta, j = 10; j<20 ; j++, pos.y-=delta )
			for( pos.z = grid.pos.z + 11*delta, k = 10; k<20 ; k++, pos.z+=delta, F+=6, nbr+=6 )
			{
				grid.val[i][j][k] = 0;
				for( int l=0; l<n; l++)									
					grid.val[i][j][k] += BlobFun( blob[l], GetD3DVECTOR( pos ) );

				size = fabs( grid.val[i][j][k]*0.2 );
				if( size< 0.0 ) size = 0.0;
				if( size> 1.50 ) size = 1.50;

				coeff = (FLOAT)(i - 10)*0.1111f;
				a = LERP( cube[0], cube[1], coeff );
				b = LERP( cube[2], cube[3], coeff );
				c = LERP( cube[4], cube[5], coeff );
				d = LERP( cube[6], cube[7], coeff );

				coeff = (FLOAT)(j - 10)*0.1111f;
				a = LERP( a, b, coeff );
				b = LERP( c, d, coeff );

				coeff = (FLOAT)(k - 10)*0.1111f;

				a = LERP( a, b, coeff );

				fpos = a*mtxFlareRot;

				F[0] = D3DLVERTEX( D3DVECTOR( fpos.x-size, fpos.y+size, fpos.z ), 0x80ffffff, 0, 0, 0 );
				F[1] = D3DLVERTEX( D3DVECTOR( fpos.x+size, fpos.y+size, fpos.z ), 0x80ffffff, 0, 1, 0 );
				F[2] = D3DLVERTEX( D3DVECTOR( fpos.x-size, fpos.y-size, fpos.z ), 0x80ffffff, 0, 0, 1 );

				F[3] = D3DLVERTEX( D3DVECTOR( fpos.x+size, fpos.y+size, fpos.z ), 0x80ffffff, 0, 1, 0 );
				F[4] = D3DLVERTEX( D3DVECTOR( fpos.x+size, fpos.y-size, fpos.z ), 0x80ffffff, 0, 1, 1 );
				F[5] = D3DLVERTEX( D3DVECTOR( fpos.x-size, fpos.y-size, fpos.z ), 0x80ffffff, 0, 0, 1 );
			}

	pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, D3DFVF_LVERTEX, Flarez, nbr, 0 );
}



//-----------------------------------------------------------------------------
// Name: App_Render()
// Desc: Renders the scene. This tutorial draws a bunch of intersecting
//       triangles that are rotating about the y-axis. Without z-buffering,
//       the polygons could not be drawn correctly (unless the app performed
//       complex polygon-division routines and sorted the polygons in back-to-
//       front order.)
//-----------------------------------------------------------------------------
HRESULT fxRender_Title( LPDIRECT3DDEVICE7 pd3dDevice )
{
    // Clear the viewport to a blue color. Also "clear" the z-buffer to the
	// value 1.0 (which represents the far clipping plane).	
	D3DMATERIAL7			mtrl;	
	LONG					i, j;
	HRESULT					hr;

    hr = pd3dDevice->Clear( 1UL, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0L );	

	D3DMATRIX	matTrn = GetD3DMATRIX( TranslationMtx( gem_Vector( -7, 0, 20 ) ) );
	D3DMATRIX	matWorld;
	D3DMATRIX   mat    = GetD3DMATRIX( IdentMtx() );
	
	// The world matrix controls the position and orientation of the polygons
	// in world space. We'll use it later to spin the triangle.

    matWorld = g_matLocal;

    // Begin the scene		
	
	Calculate( g_Grid, boob, 5 );	
   

	pd3dDevice->BeginScene();

	pd3dDevice->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTFN_LINEAR );	
	pd3dDevice->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTFG_LINEAR );
	pd3dDevice->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTFN_ANISOTROPIC );	
	pd3dDevice->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTFG_ANISOTROPIC );
	pd3dDevice->SetTextureStageState( 0, D3DTSS_MAXANISOTROPY, 2 );
	

	pd3dDevice->SetRenderState( D3DRENDERSTATE_ZWRITEENABLE, FALSE );
	pd3dDevice->SetRenderState( D3DRENDERSTATE_CULLMODE, D3DCULL_NONE );
	pd3dDevice->SetRenderState( D3DRENDERSTATE_ALPHABLENDENABLE, TRUE );
	pd3dDevice->SetRenderState( D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA );
	pd3dDevice->SetRenderState( D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE );			
	pd3dDevice->SetRenderState( D3DRENDERSTATE_LIGHTING, FALSE );

	mat    = (D3DMATRIX)TranslationMtx( 0, 0, 15 );
	pd3dDevice->SetTransform( D3DTRANSFORMSTATE_WORLD, &mat );
	
	//RenderObject3D( &lett, pd3dDevice );	
	pd3dDevice->SetRenderState( D3DRENDERSTATE_ALPHABLENDENABLE, TRUE );
	pd3dDevice->SetRenderState( D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA );
	pd3dDevice->SetRenderState( D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE );
	pd3dDevice->SetTexture( 0, NULL );

	if( spaw )	
		pd3dDevice->DrawPrimitive( D3DPT_LINELIST, D3DFVF_LVERTEX, shiluette, vNumber, NULL );	
	

	//RenderExtruded( &extruded, pd3dDevice );
	RenderExtruded( &full, pd3dDevice );

	pd3dDevice->SetTexture( 0, GetTexture( "data\\textures\\letttex.jpg" ) );			
	pd3dDevice->SetRenderState( D3DRENDERSTATE_ALPHABLENDENABLE, FALSE );

	FLOAT		ox, oy, oz;

	if( explode )
	{		
		for( i = 0, j = 0 ; i<98 ; i++, j = (j+1)%5 )
		{
			ox = (lett.vert[lett.ind[i*3]].x+lett.vert[lett.ind[i*3+1]].x+lett.vert[lett.ind[i*3+2]].x)*0.333f; 
			oy = (lett.vert[lett.ind[i*3]].y+lett.vert[lett.ind[i*3+1]].y+lett.vert[lett.ind[i*3+2]].y)*0.333f; 
			oz = (lett.vert[lett.ind[i*3]].z+lett.vert[lett.ind[i*3+1]].z+lett.vert[lett.ind[i*3+2]].z)*0.333f; 

			mat = (D3DMATRIX)( TranslationMtx( -ox, -oy, -oz )*							 
							   RotationMtx( -explodePow*0.25, explodePow*0.05, explodePow*0.01 )*
							   TranslationMtx( ox, oy, oz )*
							   TranslationMtx( 0, 0, 15 )*
							   TranslationMtx( explodePow*vecExplode[j] ) );
			pd3dDevice->SetTransform( D3DTRANSFORMSTATE_WORLD, &mat );
			RenderFace( &lett, i, pd3dDevice );
		}
	}	

	pd3dDevice->SetRenderState( D3DRENDERSTATE_ALPHABLENDENABLE, TRUE );
	pd3dDevice->SetRenderState( D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA );
	pd3dDevice->SetRenderState( D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE );
	pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2 );

	pd3dDevice->SetTexture( 0, GetTexture( "data\\textures\\light2.jpg" ) );

	RenderFlareSystem( FlarezCube, g_Grid, boob, 5, pd3dDevice );	

	pd3dDevice->SetTexture( 0, NULL );

	
	if( Fade )
	{
		pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, D3DFVF_TLVERTEX, FadeV, 4, 0 );				
	}
	
	pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );

	pd3dDevice->EndScene();

    // End the scene    

    return S_OK;
}

//-----------------------------------------------------------------------------
// Name: App_DeleteDeviceObjects()
// Desc: Called when the device is being deleted, this function deletes any
//       device dependant objects.
//-----------------------------------------------------------------------------

#define SAFE_RELEASE( obj ) \
	 if( obj ) obj->Release()

VOID fxDelete_Title( LPDIRECT3DDEVICE7 pd3dDevice )
{	
	DeleteVolume( &volume );
	DeleteVolume( &extruded );
	DeleteVolume( &full );	

	DeleteObject( &lett );
}

