//-----------------------------------------------------------------------------
// File: Z-buffer.cpp
//
// Desc: Simple tutorial code to show how to enable z-buffering. The z-buffer
//       itself is created in the winmain.cpp file. This file controls
//       rendering and the setting of renderstates (some of which affect
//       z-buffering).
//
// Copyright (c) 1998 Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------

#define STRICT
#define D3D_OVERLOADS
#include <math.h>
#include <d3d.h>
#include <stdio.h>
#include "blobs.h"
#include "texture.h"
#include "gemmath.h"
#include "syncinfo.h"
//#include "cube.h"
#include "object3d.h"
#include "volumetric.h"
#include "extrastuff.h"


//-----------------------------------------------------------------------------
// Defines, constants, and global variables
//-----------------------------------------------------------------------------
#define NUM_OBJECTS 4

D3DMATRIX           g_matBox[20];
D3DMATRIX			g_matLocal;
D3DMATRIX			g_matMorph;
D3DMATRIX			g_matObject1;
D3DMATRIX			g_matObject2;
D3DMATRIX			matObjProj;
D3DMATRIX			matBackLocal[10];
D3DMATRIX			matBannerLocal[10];
D3DMATRIX			matStrip[12];

gem_Vector			vecExplode[5];

D3DLVERTEX			MirrorVerts[4][4];
D3DLVERTEX			ClipVerts[4][4];

D3DLVERTEX			Banner[4];

D3DLVERTEX			MirrorPlain[4][4];
D3DLVERTEX			ClipPlain[4][4];

D3DTLVERTEX			Background[4];           // Vertices used to render the backdrop
D3DTLVERTEX			Overground[4];
D3DTLVERTEX			LightBarVer[4];
D3DTLVERTEX			LightBarHrz[4];

D3DLVERTEX			Flare[4];

D3DLVERTEX			shiluette[1000];
DWORD				vNumber;


D3DLVERTEX			FxPlain[12000];
WORD				FxPlainInd[70000];

gem_Vector			flarePos[8];
gem_Matrix			mtxFlare[20];

gem_Matrix			mtxFlareRot;

gem_Vector			FlarezCube[8];

FLOAT				fVolumeColor[6];
FLOAT				fVolumeEmiterPos[6];


D3DLVERTEX			FxPlain2[200];
WORD				FxPlainInd2[1000];

D3DMATERIAL7		mtrlAlpha;


OBJECT3D			sphere;

OBJECT3D			torus[5];

OBJECT3D			morphed;

OBJECT3D			blob[2];
OBJECT3D			morph2;
OBJECT3D			morph3;

OBJECT3D			lett;

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

DWORD				added[28];

DWORD				lightOff[6];

DWORD				lineOn1;
DWORD				lineOn2;

DWORD				bNbr;


LPDIRECTDRAWSURFACE7 back;
LPDIRECTDRAWSURFACE7 _01;
LPDIRECTDRAWSURFACE7 mask;
LPDIRECTDRAWSURFACE7 volumeMap;
LPDIRECTDRAWSURFACE7 logo;
LPDIRECTDRAWSURFACE7 mirrortext;
LPDIRECTDRAWSURFACE7 mirrorback;
LPDIRECTDRAWSURFACE7 text1, text2;
LPDIRECTDRAWSURFACE7 light;
LPDIRECTDRAWSURFACE7 lightstrip;

BLOBGRID			g_Grid;
BLOB3D				boob[10];


D3DVERTEX			vertab1[20000];
D3DVERTEX			vertab2[20000];

LPWORD				pLineBlobInd;
DWORD				pLineBlobIndNbr;

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

D3DVERTEX			cube[36];

D3DLVERTEX			strip[23*6];

DWORD				nbr;

gem_Vector			pos[5];

FLOAT				alpha1, alpha2, alpha;

FLOAT				lbVerPos[10];
FLOAT				lbHrzPos[10];

gem_Matrix			vertTrans;

D3DLVERTEX			Flarez[10000];

/*
FLOAT* CreatePlane( FLOAT* plane, gem_Vector& a, gem_Vector& b, gem_Vector& c )
{
    gem_Vector	n = Normalize( Cross( b-c, a-c ) );

    plane[0] = n.x; 
	plane[1] = n.y; 
	plane[2] = n.z; 
    plane[3] = -( n.x*c.x + n.y*c.y + n.z*c.z );

    return plane;
}

VOID MirrorMtx( D3DMATRIX& matMirror, gem_Vector& n, FLOAT D )
{
	matMirror = (D3DMATRIX)IdentMtx();

    matMirror._11 -= 2*n.x*n.x; matMirror._12 -= 2*n.x*n.y; matMirror._13 -= 2*n.x*n.z;
    matMirror._21 -= 2*n.y*n.x; matMirror._22 -= 2*n.y*n.y; matMirror._23 -= 2*n.y*n.z;
    matMirror._31 -= 2*n.z*n.x; matMirror._32 -= 2*n.z*n.y; matMirror._33 -= 2*n.z*n.z;
    matMirror._41 -= 2*D*n.x;   matMirror._42 -= 2*D*n.y;   matMirror._43 -= 2*D*n.z;	
}*/


VOID ComputeNormals( LPD3DVERTEX v, LPWORD ind, DWORD vCount, DWORD fCount )
{
	gem_Vector	n;
	gem_Vector  v1;
	gem_Vector  v2;


	for( DWORD i = 0 ;  i<vCount ; i++ )
	{
		n = gem_Vector( 0, 0, 0 );

		for( DWORD j = 0 ; j<fCount ; j++ )
		{
			if( ind[3*j] == i || ind[3*j+1] == i || ind[3*j+2] == i )
			{
				v1.x = v[ind[3*j+1]].x - v[ind[3*j]].x;
				v1.y = v[ind[3*j+1]].y - v[ind[3*j]].y;
				v1.z = v[ind[3*j+1]].z - v[ind[3*j]].z;

				v2.x = v[ind[3*j+2]].x - v[ind[3*j]].x;
				v2.y = v[ind[3*j+2]].y - v[ind[3*j]].y;
				v2.z = v[ind[3*j+2]].z - v[ind[3*j]].z;

				n = n + Cross( v1, v2 );
			}
		}

		n = Normalize( n );

		v[i].nx = n.x;
		v[i].ny = n.y;
		v[i].nz = n.z;
	}
}


//--------------------------------------------------------------------------------------------
//	volume control function
//--------------------------------------------------------------------------------------------


/*
HRESULT App_InitDeviceObjects( LPDIRECT3DDEVICE7 pd3dDevice )
{

	//LoadTexture( "efxtex.jpg", &back, pd3dDevice );
	//LoadTexture( "efxback.jpg", &back, pd3dDevice );
	LoadTexture( "boxback.jpg", &back, pd3dDevice );	
	LoadTexture( "board.jpg", &text1, pd3dDevice );
	//LoadTexture( "efxtex.jpg", &text2, pd3dDevice );
	//LoadTexture( "efxback.jpg", &text1, pd3dDevice );
	LoadTexture( "light2.jpg", &light, pd3dDevice );
	//LoadTexture( "volume.jpg", &volumeMap, pd3dDevice );

	LoadTexture( "texturka.bmp", &_01, pd3dDevice );

	//LoadAlphaChannel( "alpha.bmp", &text1, pd3dDevice, 0 );
	LoadAlphaChannel( "alpha.bmp", &back, pd3dDevice, 0 );
    
	vInfo.chull = new gem_Vector[50];
	vInfo.vNbr  = 10;
	vInfo.emiterPos = gem_Vector( 0, 0, -10 );

	LONG		i;

	for( i = 0 ; i<10 ; i++ )
	{
		FLOAT	ang = 3.14159f*(FLOAT)i/5.0f;

		vInfo.chull[i].x = 0.6f*(FLOAT)cos( ang );
		vInfo.chull[i].y = 0.6f*(FLOAT)sin( ang );
		vInfo.chull[i].z = 2.02f;
	}
	

	//CreateVolume( &vInfo, &volume, 0x00cfcfcf );		
	//CreateVolume( &vInfo, &volume, 0x00ffffff );		


	D3DLIGHT7			light;
	ZeroMemory( &light, sizeof(light) );
	light.dltType		= D3DLIGHT_POINT;
	light.dcvDiffuse.r	= 1.0f;
	light.dcvDiffuse.g	= 1.0f;
	light.dcvDiffuse.b	= 1.0f;
	light.dvPosition.x	= 10.0f;
	light.dvPosition.y	= 0.0f;
	light.dvPosition.z	= 40.0f;
	light.dvAttenuation0= 1.0f;
	light.dvAttenuation1= 0.02f;
	light.dvAttenuation2= 0.0002f;
	light.dvRange		= 40.0f;

	if( FAILED( pd3dDevice->SetLight( 0, &light ) ) )
		return E_FAIL; 

	pd3dDevice->LightEnable( 0, TRUE );

	

	LoadObject3D( "kulka.o3d", &sphere );
	ApplySphereMap( sphere.vert, sphere.vertNbr, pd3dDevice );

	//LoadObject3D( "tor01.o3d", &morphed );	
	
	//LoadObject3D( "tor01.o3d", &torus[1] );
	//LoadObject3D( "tor02.o3d", &torus[2] );
	//LoadObject3D( "tor03.o3d", &torus[3] );	
	//LoadObject3D( "tor04.o3d", &torus[4] );
	
	//LoadObject3D( "blob01.o3d", &blob[0] );	
	//LoadObject3D( "blob02.o3d", &blob[1] );
	//LoadObject3D( "blob02.o3d", &morph2 );
	//LoadObject3D( "blob01.o3d", &morph3 );

	//CreateLineList( &blob[0], pLineBLOB3DIndNbr, pLineBLOB3DInd );
	

	DDCOLORKEY ckey;

	ckey.dwColorSpaceLowValue = 0x00000000;
	ckey.dwColorSpaceHighValue = 0x00000000;

	_01->SetColorKey( DDCKEY_SRCBLT, &ckey );	

	InitCubeFx();

	pd3dDevice->LightEnable( 0, TRUE );

	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.25f;
    pd3dDevice->SetMaterial( &mtrl );

	ZeroMemory( &mtrlAlpha, sizeof(mtrlAlpha) );
    mtrlAlpha.dcvAmbient.r = 1.0f;
    mtrlAlpha.dcvAmbient.g = 1.0f;
    mtrlAlpha.dcvAmbient.b = 1.0f;
	mtrlAlpha.dcvDiffuse.r = 0.0f;
    mtrlAlpha.dcvDiffuse.g = 0.0f;
    mtrlAlpha.dcvDiffuse.b = 0.0f;
	mtrlAlpha.dcvDiffuse.a = 0.2f;

	D3DLVERTEX			Plain[4];

	Plain[0] = D3DLVERTEX( D3DVECTOR(-20, 20, 1 ), 0x30FFFFFF, 0, 0, 0 );
	Plain[1] = D3DLVERTEX( D3DVECTOR( 20, 20, 1 ), 0x30FFFFFF, 0, 1, 0 );
	Plain[2] = D3DLVERTEX( D3DVECTOR(-20,-20, 1 ), 0x30FFFFFF, 0, 0, 1 );
	Plain[3] = D3DLVERTEX( D3DVECTOR( 20,-20, 1 ), 0x30FFFFFF, 0, 1, 1 );

	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 );

	CreatePlain( 50, 50, FxPlain, FxPlainInd, Plain );

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



	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;

	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 = 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.
	
	//pd3dDevice->SetRenderState( D3DRENDERSTATE_ALPHABLENDENABLE, TRUE );
	pd3dDevice->SetRenderState( D3DRENDERSTATE_AMBIENT, 0xFFFFFFFF );
	

	return S_OK;
}

HRESULT App_FrameMove( LPDIRECT3DDEVICE7 pd3dDevice, LPSYNCINFO sync )
{
	
	FLOAT	x1, y1;
	FLOAT	x2, y2;
	LONG	ind, i, j;
	FLOAT	coeff1, coeff2, coeff;
	FLOAT	a, b;
	FLOAT	_sin, _cos;
	FLOAT	fTimeKey = sync->fTimeKey;

	static  FLOAT sync0Key;
	static	DWORD dwSync0;
	static  FLOAT sync1Key;
	static	DWORD dwSync1;
	
	static  FLOAT lightOffTime[6];

	static  D3DMATRIX matProj;

	static  FLOAT lineOn1Key;
	static  FLOAT lineOn2Key;	

	if( sync->dwSync00 )
	{
		sync0Key = fTimeKey;
		dwSync0 = 1;
		sync->dwSync00 = 0;
	}

	if( dwSync0 )
	{		
		
		if( fTimeKey - sync0Key < 0.1f )
		{
			coeff = (fTimeKey - sync0Key)*10.0f;
			matProj = (D3DMATRIX)ProjectionMtx( 50.0f + 100*coeff, 1.0f, 1000.0f, 0.70f );			
		}
		else
		{
			dwSync0 = 0;
			sync0Key = fTimeKey;
			matProj = (D3DMATRIX)ProjectionMtx( 150.0f, 1.0f, 1000.0f, 0.70f );			
		}

	}
	else
	{
		if( fTimeKey - sync0Key < 0.25f )
		{
			coeff = (fTimeKey - sync0Key)*4.0f;
			matProj = (D3DMATRIX)ProjectionMtx( 150.0f - 100*coeff, 1.0f, 1000.0f, 0.70f );			
		}
		else
		{
			matProj = (D3DMATRIX)ProjectionMtx( 50.0f, 1.0f, 1000.0f, 0.70f );
		}
	}

	matObjProj = (D3DMATRIX)ProjectionMtx( 50.0f, 1.0f, 1000.0f, 0.70f );			
	
    pd3dDevice->SetTransform( D3DTRANSFORMSTATE_PROJECTION, &matProj );

	for( i = 2 ; i<8 ; i++ )
	{
		if( sync->tableSync[i] )
		{
			lightOff[i-2] = 1;
			sync->tableSync[i] = 0;
			lightOffTime[i-2] = fTimeKey;
		}
	}

	for( i = 0 ; i<6 ; i++ )
	{
		if( lightOff[i] )
		{
			if( fTimeKey - lightOffTime[i] > 0.05f )
			{			
				lightOff[i] = 0;								
			}		
		}
	}

	if( sync->dwSync08 )
	{
		lineOn1 = 1;
		sync->dwSync08 = 0;
		lineOn1Key = fTimeKey;
	}

	if( lineOn1 )
	{
		if( fTimeKey - lineOn1Key <= 0.25f )
		{
			alpha1 = 0.25f - ( fTimeKey - lineOn1Key );
		}
		else
		{
			lineOn1 = 0;
		}		
	}

	if( sync->dwSync09 )
	{
		lineOn2 = 1;
		sync->dwSync09 = 0;
		lineOn2Key = fTimeKey;
	}

	if( lineOn2 )
	{
		if( fTimeKey - lineOn2Key <= 0.25f )
		{
			alpha2 = 0.25f - ( fTimeKey - lineOn2Key );
		}
		else
		{
			lineOn2 = 0;
		}		
	}

	if( sync->dwSync01 )
	{
		sync1Key = fTimeKey;
		dwSync1 = 1;
		sync->dwSync01 = 0;
	}

	
	if( dwSync1 )
	{
		if( fTimeKey - sync1Key < 0.25f )
		{
			coeff = (fTimeKey - sync1Key)*4.0f;
			g_matLocal = (D3DMATRIX)(RotationMtx( 1.8f*fTimeKey, 2.0f*fTimeKey, -1.2f*fTimeKey )*
									 TranslationMtx( 10.0f - coeff*5.0f, 0.0f, 40.0f - coeff*30.0f ));
		}
		else
		{
			dwSync1 = 0;
			sync1Key = fTimeKey;
			g_matLocal = (D3DMATRIX)(RotationMtx( 1.8f*fTimeKey, 2.0f*fTimeKey, -1.2f*fTimeKey )*
								     TranslationMtx( 5.0f, 0.0f, 10.0f ));
		}
	}
	else
	{
		if( fTimeKey - sync1Key < 0.1f )
		{
			coeff = (fTimeKey - sync1Key)*10.0f;
			g_matLocal = (D3DMATRIX)(RotationMtx( 1.8f*fTimeKey, 2.0f*fTimeKey, -1.2f*fTimeKey )*
									 TranslationMtx( 5.0f + coeff*5.0f, 0.0f, 10.0f + coeff*30.0f ));
		}
		else
		{
			g_matLocal = (D3DMATRIX)(RotationMtx( 1.8f*fTimeKey, 2.0f*fTimeKey, -1.2f*fTimeKey )*
								     TranslationMtx( 10.0f, 0.0f, 40.0f ));
		}
	}	

	g_matMorph = (D3DMATRIX)(RotationMtx( -2*fTimeKey, 0, 0 )*
							 TranslationMtx( 80, 0, 50 ));

	vertTrans = ScaleMtx( 0.8f )*(RotationMtx( -fTimeKey, 0, 0 )*TranslationMtx( 64, 0, 40 ));


	if( fTimeKey<1.0f )
	{
		g_matObject1= (D3DMATRIX)(RotationMtx( -3*fTimeKey, 3*fTimeKey, -2*fTimeKey )*
							      TranslationMtx( -80, -2, 20 ));
		
		g_matObject2= (D3DMATRIX)(RotationMtx( 2*fTimeKey, -3*fTimeKey, 3*fTimeKey )*
							      TranslationMtx( -80, -2, 20 ));
	}
	else
	{
		if( fTimeKey<2.0f )
		{
			coeff = fTimeKey - 1.0f;
			g_matObject1= (D3DMATRIX)(RotationMtx( -3*fTimeKey, 3*fTimeKey, -2*fTimeKey )*
							          TranslationMtx( -30 + 22*coeff, -2, 20 ));

			g_matObject2= (D3DMATRIX)(RotationMtx( 2*fTimeKey, -3*fTimeKey, 3*fTimeKey )*
							          TranslationMtx( -30 + 22*coeff, -2, 20 ));
		}
		else
		{
			g_matObject1= (D3DMATRIX)(RotationMtx( -3*fTimeKey, 3*fTimeKey, -2*fTimeKey )*
							          TranslationMtx( -8, -2, 20 ));

			g_matObject2= (D3DMATRIX)(RotationMtx( 2*fTimeKey, -3*fTimeKey, 3*fTimeKey )*
						 			  TranslationMtx( -8, -2, 20 ));
		}
	}



	LONG		frame = (LONG)(fTimeKey*300.0f);
	LONG		srcInd;
	LONG		destInd;
	FLOAT		mFactor;
	
	frame = frame%800;

	if( frame>=0 && frame<200 )
	{
		mFactor = (FLOAT)frame*0.005f;
		srcInd = 4;
		destInd = 3;	
	}

	if( frame>=200 && frame<400 )
	{
		mFactor = (FLOAT)(frame-200)*0.005f;
		srcInd = 3;
		destInd = 1;	
	}

	if( frame>=400 && frame<600 )
	{
		mFactor = (FLOAT)(frame-400)*0.005f;
		srcInd = 1;
		destInd = 2;	
	}

	if( frame>=600 && frame<800 )
	{
		mFactor = (FLOAT)(frame-600)*0.005f;
		srcInd = 2;
		destInd = 4;	
	}	

	
	MorphObject( &torus[srcInd], &torus[destInd], mFactor, &morphed );
	
	for( i = 0; i<20 ; i++ )
	{
		g_matBox[i] = (D3DMATRIX)(ScaleMtx( (1.5f+sin(2*(1+cos((FLOAT)i*3.1415/20))*fTimeKey+0.05f*(FLOAT)i)) )*								  
								  RotationMtx( -1.5f*(fTimeKey-0.01f*(FLOAT)i), 2.0f*(fTimeKey-0.01f*(FLOAT)i), -1.0f*(fTimeKey-0.01f*(FLOAT)i) )*
							      TranslationMtx( 0, 0, 4 ));	

		
		mtxFlare[i] = RotationMtx( -1.5f*(fTimeKey-0.05f*(FLOAT)i), 2.0f*(fTimeKey-0.05f*(FLOAT)i), -1.0f*(fTimeKey-0.05f*(FLOAT)i) )*
		 						TranslationMtx( 0, 0, 4 );
			
	}

	g_matBox[0] = (D3DMATRIX)(RotationMtx( -1.5f*(fTimeKey), 2.0f*(fTimeKey), -1.0f*(fTimeKey) )*
							      TranslationMtx( 0, 0, 4 ));	

		
	coeff = (1.0f + (FLOAT)sin( fTimeKey*2.0f ))*0.5f;

	MorphObject( &blob[0], &blob[1], coeff, &morph2 );	
	MorphObject( &blob[1], &blob[0], coeff, &morph3 );	


	_sin = (FLOAT)sin( fTimeKey );
	_cos = (FLOAT)cos( fTimeKey );
	a = 6*_sin;
	b = 6*_cos;
	coeff = 30*(2+_sin);
	coeff1 = 1+_sin;
	coeff2 = 1+_cos;
	

	FLOAT	angle1, angle2;	

	for( angle1 = 1, i = 2 ; i<50 ; i++, angle1 += 3.1415f/48.0f )
		for( angle2 = 1, j = 2 ; j<50 ; j++, angle2 += 3.1415f/48.0f )
		{
			ind = i*51 + j;
			x1 = FxPlain[ind].x;
			y1 = FxPlain[ind].y;
			x2 = FxPlain[ind].x - a;
			y2 = FxPlain[ind].y - b;

			

			
			if( x1*x1 + y1*y1 < 250 )
			{
				FxPlain[ind].z = 200 - 18*sqrt( 1 - x1*x1/250.0f - y1*y1/250.0f );
			}
			else
				FxPlain[ind].z = 1;

			

			
			if( x2*x2 + y2*y2 < 200 )
			{
				FxPlain[ind].z = coeff*(FLOAT)sqrt( 1 - x2*x2*0.005 - y2*y2*0.005 );
			}
			else
				FxPlain[ind].z = 1;			
			
			FxPlain[ind].z -= 6.0f*(FLOAT)cos( sqrt( coeff1*x1*x1 + coeff2*y1*y1 ) );
			


			//FxPlain[ind].z = 20 - 2*cos( sqrt( coeff1*x1*x1 + coeff2*y1*y1 ) );

			
		}

	

	for( i = 0 ; i<=50 ; i++ )
		for( j = 0 ; j<=50 ; j++ )
		{
			ind = i*51 + j;
			FxPlain[ind].tu = (FLOAT)j*0.05f - _cos*0.25f;
			FxPlain[ind].tv = (FLOAT)i*0.05f - _sin*0.25f;
		}

	for( i = 0 ; i<6*23 ; i+=6 )
	{
		strip[i+0].tu = 2*fTimeKey;
		strip[i+1].tu = 2*fTimeKey + 1.0f;
		strip[i+2].tu = 2*fTimeKey + 1.0f;
		strip[i+3].tu = 2*fTimeKey + 1.0f;
		strip[i+4].tu = 2*fTimeKey;
		strip[i+5].tu = 2*fTimeKey;
	}

	
	return S_OK;
}

/*
HRESULT App_Render( LPDIRECT3DDEVICE7 pd3dDevice, D3DRECT* prcViewportRect )
{
	DWORD					time1, time2;
	FLOAT					fps;
	LPDIRECTDRAWSURFACE7	pdds;
	HDC						hdc;
	D3DMATRIX				mat = (D3DMATRIX)IdentMtx();	
	FLOAT					density = 0.015f;
	FLOAT					start = 75.0f;
	FLOAT					end = 150.0f;

	time1 = timeGetTime();

	pd3dDevice->Clear( 1UL, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0L );		
	
	pd3dDevice->BeginScene();	
	pd3dDevice->SetTransform( D3DTRANSFORMSTATE_WORLD, &mat );
	pd3dDevice->SetRenderState( D3DRENDERSTATE_LIGHTING, FALSE );
	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_ZENABLE, D3DZB_USEW );
	pd3dDevice->SetRenderState( D3DRENDERSTATE_ZWRITEENABLE, TRUE );
	pd3dDevice->SetRenderState( D3DRENDERSTATE_ALPHABLENDENABLE, FALSE );
	pd3dDevice->SetRenderState( D3DRENDERSTATE_FOGENABLE, TRUE );
	pd3dDevice->SetRenderState( D3DRENDERSTATE_FOGCOLOR, 0x007080b0 );
	pd3dDevice->SetRenderState( D3DRENDERSTATE_FOGTABLEMODE, D3DFOG_LINEAR );
	pd3dDevice->SetRenderState( D3DRENDERSTATE_FOGSTART, *(DWORD*)(&start) ); 
	pd3dDevice->SetRenderState( D3DRENDERSTATE_FOGEND, *(DWORD*)(&end) ); 
	pd3dDevice->SetRenderState( D3DRENDERSTATE_WRAP0, D3DWRAPCOORD_0 | D3DWRAPCOORD_1 ); 	
		

	pd3dDevice->SetTexture( 0, text2 );	
	pd3dDevice->SetTransform( D3DTRANSFORMSTATE_WORLD, &g_matLocal );	
	RenderObject3D( &sphere, pd3dDevice );		


	pd3dDevice->SetTexture( 0, back );		
	pd3dDevice->SetRenderState( D3DRENDERSTATE_LIGHTING, TRUE );
	pd3dDevice->SetRenderState( D3DRENDERSTATE_CULLMODE, D3DCULL_NONE );
	pd3dDevice->SetRenderState( D3DRENDERSTATE_ZWRITEENABLE, TRUE );
	pd3dDevice->SetRenderState( D3DRENDERSTATE_ZENABLE, D3DZB_USEW );	
	pd3dDevice->SetTransform( D3DTRANSFORMSTATE_WORLD, &g_matMorph );	
	RenderObject3D( &morphed, pd3dDevice );	

	gem_Vector a;
	D3DMATRIX  flareMat;	

	pd3dDevice->SetTexture( 0, light );
	pd3dDevice->SetRenderState( D3DRENDERSTATE_WRAP0, FALSE ); 	
	pd3dDevice->SetRenderState( D3DRENDERSTATE_LIGHTING, FALSE );		
	pd3dDevice->SetRenderState( D3DRENDERSTATE_ALPHABLENDENABLE, TRUE );
	pd3dDevice->SetRenderState( D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE);
	pd3dDevice->SetRenderState( D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE );
	pd3dDevice->SetRenderState( D3DRENDERSTATE_CULLMODE, D3DCULL_NONE );
	pd3dDevice->SetRenderState( D3DRENDERSTATE_ZWRITEENABLE, FALSE );
	pd3dDevice->SetRenderState( D3DRENDERSTATE_FOGENABLE, FALSE );		

	for( LONG z = 0 ;  z<24 ; z+=5 )
	{
		for( LONG k = z*48 ; k<48*(z+1) ; k++ )
		{
			a.x = morphed.vert[k].x;
			a.y = morphed.vert[k].y;
			a.z = morphed.vert[k].z;

			flareMat = (D3DMATRIX)TranslationMtx( a*vertTrans );
			pd3dDevice->SetTransform( D3DTRANSFORMSTATE_WORLD, &flareMat );	

			pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, D3DFVF_LVERTEX, Flare, 4, NULL );
		}		
	}
	

	pd3dDevice->SetRenderState( D3DRENDERSTATE_FOGENABLE, TRUE );

	pd3dDevice->SetRenderState( D3DRENDERSTATE_WRAP0, D3DWRAPCOORD_0 | D3DWRAPCOORD_1 ); 	

	pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2 );
			
	pd3dDevice->SetTexture( 0, volumeMap );

	pd3dDevice->SetRenderState( D3DRENDERSTATE_ANTIALIAS, D3DANTIALIAS_SORTINDEPENDENT  );
	
	
	pd3dDevice->SetRenderState( D3DRENDERSTATE_ALPHABLENDENABLE, TRUE );
	pd3dDevice->SetRenderState( D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA );
	pd3dDevice->SetRenderState( D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE );	
	

	for( LONG i = 0 ; i<4; i++ )
	{		
		
		
		if( !lightOff[i] )
		{
			//vInfo.emiterPos.z = fVolumeEmiterPos[i];
			//CreateVolume( &vInfo, &volume, color[i] );		
		
			mat = (D3DMATRIX)RotationMtx( (FLOAT)i*0.5f*3.14159f, 0, 0 )*g_matLocal;
			pd3dDevice->SetTransform( D3DTRANSFORMSTATE_WORLD, &mat );
			RenderVolume( &volume, pd3dDevice );

			//DeleteVolume( &volume );	
		}
	}

		
	if( !lightOff[4] )
	{
		//vInfo.emiterPos.z = fVolumeEmiterPos[4];


		mat = GetD3DMATRIX( RotationMtx( 0, 0.5f*3.14159f, 0 ) )*g_matLocal;
		pd3dDevice->SetTransform( D3DTRANSFORMSTATE_WORLD, &mat );
		RenderVolume( &volume, pd3dDevice );

		//DeleteVolume( &volume );
	}



	if( !lightOff[5] )
	{
		//vInfo.emiterPos.z = fVolumeEmiterPos[5];
		//CreateVolume( &vInfo, &volume, color[5] );
	
		mat = GetD3DMATRIX( RotationMtx( 0, -0.5f*3.14159f, 0 ) )*g_matLocal;
		pd3dDevice->SetTransform( D3DTRANSFORMSTATE_WORLD, &mat );
		RenderVolume( &volume, pd3dDevice );
		
	}

	pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );

	pd3dDevice->SetTexture( 0, text1 );	
	pd3dDevice->SetTransform( D3DTRANSFORMSTATE_PROJECTION, &matObjProj );
	//D3DMATRIX	tmpMat = GetD3DMATRIX( ScaleMtx( gem_Vector( 1.0f, 1.0f, 1.0f ) ) )*g_matObject;	
	pd3dDevice->SetRenderState( D3DRENDERSTATE_ZENABLE, FALSE );
	pd3dDevice->SetRenderState( D3DRENDERSTATE_ALPHABLENDENABLE, TRUE );
	pd3dDevice->SetRenderState( D3DRENDERSTATE_CULLMODE, D3DCULL_NONE );
	pd3dDevice->SetTransform( D3DTRANSFORMSTATE_WORLD, &g_matObject1 );
	pd3dDevice->SetRenderState( D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA );
	pd3dDevice->SetRenderState( D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE );	
	ApplySphereMap( morph2.vert, morph2.vertNbr, pd3dDevice );
	RenderObject3D( &morph2, pd3dDevice );

	if( lineOn1 )
	{
		D3DMATERIAL7		mtrl;		
		D3DMATRIX			matLine = (D3DMATRIX)ScaleMtx( alpha1*2.0f + 1.0f)*g_matObject1;

		pd3dDevice->SetTransform( D3DTRANSFORMSTATE_WORLD, &matLine );

		mtrlAlpha.dcvDiffuse.a = alpha1;

		pd3dDevice->GetMaterial( &mtrl );
		pd3dDevice->SetMaterial( &mtrlAlpha );

		pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2 );
		pd3dDevice->SetRenderState( D3DRENDERSTATE_LIGHTING, TRUE );		

		pd3dDevice->DrawIndexedPrimitive( D3DPT_LINELIST, D3DFVF_VERTEX, 
										  morph2.vert, morph2.vertNbr, 
										  pLineBLOB3DInd, pLineBLOB3DIndNbr, NULL );

		pd3dDevice->SetRenderState( D3DRENDERSTATE_LIGHTING, FALSE );		
		pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );
		pd3dDevice->SetMaterial( &mtrl );
	}
	
	pd3dDevice->SetTransform( D3DTRANSFORMSTATE_WORLD, &g_matObject2 );
	ApplySphereMap( morph3.vert, morph3.vertNbr, pd3dDevice );
	RenderObject3D( &morph3, pd3dDevice );	

	if( lineOn2 )
	{
		D3DMATERIAL7		mtrl;		
		D3DMATRIX			matLine = (D3DMATRIX)ScaleMtx( alpha2*2.0f + 1.0f)*g_matObject2;

		pd3dDevice->SetTransform( D3DTRANSFORMSTATE_WORLD, &matLine );

		mtrlAlpha.dcvDiffuse.a = alpha2;

		pd3dDevice->GetMaterial( &mtrl );
		pd3dDevice->SetMaterial( &mtrlAlpha );

		pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2 );
		pd3dDevice->SetRenderState( D3DRENDERSTATE_LIGHTING, TRUE );				

		pd3dDevice->DrawIndexedPrimitive( D3DPT_LINELIST, D3DFVF_VERTEX, 
										  morph3.vert, morph3.vertNbr, 
										  pLineBlobInd, pLineBlobIndNbr, NULL );

		pd3dDevice->SetRenderState( D3DRENDERSTATE_LIGHTING, FALSE );		
		pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );
		pd3dDevice->SetMaterial( &mtrl );
	}
	
	
	pd3dDevice->SetRenderState( D3DRENDERSTATE_ALPHABLENDENABLE, TRUE );
	pd3dDevice->SetRenderState( D3DRENDERSTATE_ZENABLE, D3DZB_USEW );	
	

	pd3dDevice->SetTexture( 0, NULL );
	
	pd3dDevice->EndScene();

	time2 = timeGetTime() - time1;
	fps = 1000.0f/(FLOAT)time2;

	pd3dDevice->GetRenderTarget( &pdds );

	CHAR buffer[80];
	sprintf( buffer, "%10.02f fps ", fps );	

	if( SUCCEEDED( pdds->GetDC( &hdc ) ) )
	{				    
		SetTextColor( hdc, RGB(255,255,0) );
		SetBkMode( hdc, TRANSPARENT );
		ExtTextOut( hdc, 10, 10, 0, NULL, buffer, strlen(buffer), NULL );
    
		pdds->ReleaseDC(hdc);
	}

	

	return S_OK;
}
*/


HRESULT App_Render( LPDIRECT3DDEVICE7 pd3dDevice )
{
	DWORD					time1, time2;
	FLOAT					fps;
	LPDIRECTDRAWSURFACE7	pdds;
	HDC						hdc;
	D3DMATRIX				mat = GetD3DMATRIX( IdentMtx() );

	time1 = timeGetTime();


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

	pd3dDevice->BeginScene();
	pd3dDevice->SetTransform( D3DTRANSFORMSTATE_WORLD, &mat );
	pd3dDevice->SetRenderState( D3DRENDERSTATE_LIGHTING, FALSE );
	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_ZENABLE, D3DZB_USEW );
	pd3dDevice->SetRenderState( D3DRENDERSTATE_ZWRITEENABLE, TRUE );

	pd3dDevice->SetTexture( 0, back );	
	pd3dDevice->SetRenderState( D3DRENDERSTATE_ALPHABLENDENABLE, TRUE );
	pd3dDevice->SetRenderState( D3DRENDERSTATE_SRCBLEND, D3DBLEND_INVSRCALPHA );
	pd3dDevice->SetRenderState( D3DRENDERSTATE_DESTBLEND, D3DBLEND_SRCALPHA );
	pd3dDevice->SetRenderState( D3DRENDERSTATE_CULLMODE, D3DCULL_NONE );
	pd3dDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, D3DFVF_LVERTEX, FxPlain, 2601, FxPlainInd, 15000, NULL );		

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

	pd3dDevice->SetRenderState( D3DRENDERSTATE_ZENABLE, D3DZB_FALSE );	
	pd3dDevice->SetRenderState( D3DRENDERSTATE_ZWRITEENABLE, FALSE );
	
	pd3dDevice->SetTexture( 0, text1 );	
	pd3dDevice->SetRenderState( D3DRENDERSTATE_LIGHTING, TRUE );		
	pd3dDevice->SetRenderState( D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA );
	pd3dDevice->SetRenderState( D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE );
	pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2 );
	pd3dDevice->SetRenderState( D3DRENDERSTATE_CULLMODE, D3DCULL_NONE );

	for( LONG j = 0 ; j<15 ; j+=3 )
	{
		pd3dDevice->SetTransform( D3DTRANSFORMSTATE_WORLD, &g_matBox[j] );
		D3DMATERIAL7       mtrl;
		ZeroMemory( &mtrl, sizeof(mtrl) );
		mtrl.dcvAmbient.r = 1.0f;
		mtrl.dcvAmbient.g = 1.0f;
		mtrl.dcvAmbient.b = 1.0f;
		mtrl.dcvDiffuse.r = 1.0f;
		mtrl.dcvDiffuse.g = 1.0f;
		mtrl.dcvDiffuse.b = 1.0f;
		mtrl.dcvDiffuse.a = 0.25f;
		pd3dDevice->SetMaterial( &mtrl );		
		
		pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, D3DFVF_VERTEX, cube, 36, NULL );	
	}	

	pd3dDevice->SetTexture( 0, _01 );

	pd3dDevice->SetRenderState( D3DRENDERSTATE_COLORKEYENABLE, TRUE );

	pd3dDevice->SetRenderState( D3DRENDERSTATE_ALPHABLENDENABLE, TRUE );
	pd3dDevice->SetRenderState( D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA );
	pd3dDevice->SetRenderState( D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE );	
	
	/*SetAlphaValue( strip, 23*6, 0x40 );
	for( j = 1 ; j<4 ; j++ )
	{
		for( LONG i = 0 ; i<12 ; i++ )
		{
			D3DMATRIX	_mat = matStrip[i]*g_matBox[j];

			pd3dDevice->SetTransform( D3DTRANSFORMSTATE_WORLD, &_mat );		
			pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, D3DFVF_LVERTEX, strip, 23*6, NULL );	
		}
	}*/

	SetAlphaValue( strip, 23*6, 0x7f );
	for( LONG i = 0 ; i<12 ; i++ )
	{
		D3DMATRIX	_mat = matStrip[i]*g_matBox[0];

		pd3dDevice->SetTransform( D3DTRANSFORMSTATE_WORLD, &_mat );		
		pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, D3DFVF_LVERTEX, strip, 23*6, NULL );	
	}

	//pd3dDevice->SetRenderState( D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA);
	//pd3dDevice->SetRenderState( D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE );
	//pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2 );
	pd3dDevice->SetTexture( 0, light );

	for( j = 0 ; j<20 ; j++ )
		for( LONG i = 0 ; i<8; i++ )
		{
			D3DMATRIX	_mat = (D3DMATRIX)(ScaleMtx( 0.3f - (FLOAT)j*0.0125f )*
										   TranslationMtx( flarePos[i]*mtxFlare[j] ) );
			
			pd3dDevice->SetTransform( D3DTRANSFORMSTATE_WORLD, &_mat );		
			pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, D3DFVF_LVERTEX, Flare, 4, NULL );
		}
			

	pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );
	
	pd3dDevice->SetRenderState( D3DRENDERSTATE_COLORKEYENABLE, FALSE );	

	mat = (D3DMATRIX)IdentMtx();
	pd3dDevice->SetTransform( D3DTRANSFORMSTATE_WORLD, &mat );
	pd3dDevice->SetRenderState( D3DRENDERSTATE_LIGHTING, FALSE );
	pd3dDevice->SetTexture( 0, back );		
	pd3dDevice->SetRenderState( D3DRENDERSTATE_ALPHABLENDENABLE, TRUE );
	pd3dDevice->SetRenderState( D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA );
	pd3dDevice->SetRenderState( D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA );
	pd3dDevice->SetRenderState( D3DRENDERSTATE_ZENABLE, D3DZB_USEW );		
	pd3dDevice->SetRenderState( D3DRENDERSTATE_ZWRITEENABLE, TRUE );
	pd3dDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, D3DFVF_LVERTEX, FxPlain, 2601, FxPlainInd, 15000, NULL );		

	//pd3dDevice->Clear( 1UL, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0L );		

	pd3dDevice->EndScene();

	time2 = timeGetTime() - time1;
	fps = 1000.0f/(FLOAT)time2;

	pd3dDevice->GetRenderTarget( &pdds );

	CHAR buffer[80];
	sprintf( buffer, "%10.02f fps ", fps );	

	if( SUCCEEDED( pdds->GetDC( &hdc ) ) )
	{				    
		SetTextColor( hdc, RGB(255,255,0) );
		SetBkMode( hdc, TRANSPARENT );
		ExtTextOut( hdc, 10, 10, 0, NULL, buffer, strlen(buffer), NULL );
    
		pdds->ReleaseDC(hdc);
	}

	return S_OK;
}


DWORD		tblSeg[28][2] =
{ 
	{ 0, 3 }, { 4, 9 }, { 10, 15 }, { 16, 19 }, { 20, 24 }, { 25, 28 },
	{ 29, 32 }, { 33, 36 }, { 37, 41 }, { 42, 45 }, { 46, 48 }, { 49, 52 },
	{ 53, 56 }, { 57, 60 }, { 61, 66 }, { 67, 69 }, { 70, 72 }, { 73, 76 },
	{ 77, 79 }, { 80, 84 }, { 85, 88 }, { 89, 91 }, { 92, 95 }, { 96, 101 },
	{ 102, 107 }, { 108, 113 }, { 114, 119 }, { 120, 125 }
};

DWORD		tblNbr[28] =
{
	10, 0, 27, 6, 13, 7, 21, 25, 9, 14, 17, 3, 8, 22, 19, 2, 15, 1, 4, 11, 23, 5, 16, 20, 12, 24, 18, 26 
};

//-----------------------------------------------------------------------------
// Name: App_InitDeviceObjects()
// Desc: Initialize scene objects. This function is called after all the
//       DirectDraw and Direct3D objects have been initialized. It makes sense
//       to structure code this way, separating the DDraw/D3D initialization
//       code from the app-specific intialization code.
//-----------------------------------------------------------------------------
/*
HRESULT App_InitDeviceObjects( LPDIRECT3DDEVICE7 pd3dDevice )
{
	// Data for the geometry of the triangle. Note that this tutorial only
	// uses ambient lighting, so the vertices' normals are not actually used.

	//gem_Scene a;	

	LoadTexture( "nopee1.jpg", &back, pd3dDevice );
	LoadTexture( "env.jpg", &text1, pd3dDevice );	
	//LoadTexture( "blobo.jpg", &text2, pd3dDevice );	
	LoadTexture( "letttex.jpg", &text2, pd3dDevice );	
	LoadTexture( "ramka.bmp", &mirrortext, pd3dDevice );	
	LoadTexture( "tyl.bmp", &mirrorback, pd3dDevice );	
	LoadTexture( "efxx.jpg", &lightstrip, pd3dDevice );	
	LoadTexture( "light2.jpg", &light, pd3dDevice );

	LoadAlphaChannel( "baran1.bmp", &mask, pd3dDevice );	

	LoadObject3D( "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 );

	DDSURFACEDESC2			ddsd;
	ZeroMemory( &ddsd, sizeof( ddsd ) );
	ddsd.dwSize = sizeof( ddsd );
	mask->GetSurfaceDesc( &ddsd );

	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 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].r = 3.5;
	boob[0].R = 4;
	boob[0].negative = FALSE;
	
	boob[1].pos =  GetD3DVECTOR( pos[1] );	
	//boob[1].negative = TRUE;
	boob[1].negative = FALSE;

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

	boob[3].pos =  GetD3DVECTOR( pos[3] );	
	//boob[3].negative = TRUE;
	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 );
	
	// Get a ptr to the ID3D object to create materials and/or lights. Note:
	// the Release() call just serves to decrease the ref count.
    LPDIRECT3D7 pD3D;
    if( FAILED( pd3dDevice->GetDirect3D( &pD3D ) ) )
        return E_FAIL;
    pD3D->Release();

	// 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.)
    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 );

	D3DLIGHT7			light;
	ZeroMemory( &light, sizeof(light) );
	light.dltType		= D3DLIGHT_POINT;
	light.dcvDiffuse.r	= 1.0f;
	light.dcvDiffuse.g	= 1.0f;
	light.dcvDiffuse.b	= 1.0f;
	light.dvPosition.x	= 0.0f;
	light.dvPosition.y	= 0.0f;
	light.dvPosition.z	= -10.0f;
	light.dvAttenuation0= 1.0f;
	light.dvRange		= D3DLIGHT_RANGE_MAX;

	//if( FAILED( pd3dDevice->SetLight( 0, &light ) ) )
	//	return E_FAIL; 

	pd3dDevice->LightEnable( 0, TRUE );

	// init backgroud "mesh"
	D3DVECTOR vFar = D3DVECTOR( 0.0f, 0.0f, 0.5f );
    Background[0] = D3DTLVERTEX( vFar, 0.5f, 0xFFFFFFFF, 0, 0.0f, 1.0f );
    Background[1] = D3DTLVERTEX( vFar, 0.5f, 0xFFFFFFFF, 0, 0.0f, 0.0f );
    Background[2] = D3DTLVERTEX( vFar, 0.5f, 0xFFFFFFFF, 0, 1.0f, 1.0f );
    Background[3] = D3DTLVERTEX( vFar, 0.5f, 0xFFFFFFFF, 0, 1.0f, 0.0f );

	LightBarVer[0] = D3DTLVERTEX( D3DVECTOR( 10, 470, 0.5f ), 0.5f, 0x70ffffff, 0, 0, 1 );
	LightBarVer[1] = D3DTLVERTEX( D3DVECTOR( 10,  10, 0.5f ), 0.5f, 0x70ffffff, 0, 0, 0 );
	LightBarVer[2] = D3DTLVERTEX( D3DVECTOR( 15, 470, 0.5f ), 0.5f, 0x70ffffff, 0, 1, 1 );
	LightBarVer[3] = D3DTLVERTEX( D3DVECTOR( 15,  10, 0.5f ), 0.5f, 0x70ffffff, 0, 1, 0 );

	LightBarHrz[0] = D3DTLVERTEX( D3DVECTOR( 10, 470, 0.5f ), 0.5f, 0x70ffffff, 0, 0, 1 );
	LightBarHrz[1] = D3DTLVERTEX( D3DVECTOR( 10,  10, 0.5f ), 0.5f, 0x70ffffff, 0, 0, 0 );
	LightBarHrz[2] = D3DTLVERTEX( D3DVECTOR( 15, 470, 0.5f ), 0.5f, 0x70ffffff, 0, 1, 1 );
	LightBarHrz[3] = D3DTLVERTEX( D3DVECTOR( 15,  10, 0.5f ), 0.5f, 0x70ffffff, 0, 1, 0 );

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

	Overground[0] = Background[0];
	Overground[1] = Background[1];
	Overground[2] = Background[2];
	Overground[3] = Background[3];			

	D3DLVERTEX			Plain[4];

	Plain[0] = D3DLVERTEX( D3DVECTOR(-8,10, 1.5 ), 0x30FFFFFF, 0, 0, 0 );
	Plain[1] = D3DLVERTEX( D3DVECTOR( 8,10, 1.5 ), 0x30FFFFFF, 0, 1, 0 );
	Plain[2] = D3DLVERTEX( D3DVECTOR(-8,-6, 3 ),   0x30FFFFFF, 0, 0, 1 );
	Plain[3] = D3DLVERTEX( D3DVECTOR( 8,-6, 3 ),   0x30FFFFFF, 0, 1, 1 );

	CreatePlain( 5, 5, FxPlain, FxPlainInd, Plain );
	
	MirrorVerts[0][0] = D3DLVERTEX( D3DVECTOR( -3.5f,  3.5f, 7.0f ), 0xFFFFFF, 0, 0, 0 );
	MirrorVerts[0][1] = D3DLVERTEX( D3DVECTOR(  3.5f,  3.5f, 7.0f ), 0xFFFFFF, 0, 1, 0 );
	MirrorVerts[0][2] = D3DLVERTEX( D3DVECTOR( -3.5f, -3.5f, 7.0f ), 0xFFFFFF, 0, 0, 1 );
	MirrorVerts[0][3] = D3DLVERTEX( D3DVECTOR(  3.5f, -3.5f, 7.0f ), 0xFFFFFF, 0, 1, 1 );

	ClipVerts[0][0] = D3DLVERTEX( D3DVECTOR( -2.8f,  2.8f, 6.97f ), 0x80000000, 0, 0, 0 );
	ClipVerts[0][1] = D3DLVERTEX( D3DVECTOR(  2.8f,  2.8f, 6.97f ), 0x80000000, 0, 1, 0 );
	ClipVerts[0][2] = D3DLVERTEX( D3DVECTOR( -2.8f, -2.8f, 6.97f ), 0x80000000, 0, 0, 1 );
	ClipVerts[0][3] = D3DLVERTEX( D3DVECTOR(  2.8f, -2.8f, 6.97f ), 0x80000000, 0, 1, 1 );

	FLOAT		alpha = 0.5f*3.1415f;
	gem_Matrix	a;
	gem_Vector	vec;	

	for( int i = 1 ; i<4 ; i++, alpha+=0.5f*3.1415f )
	{
		a = RotationMtx( alpha, 0, 0 );			

		for( int j = 0 ; j<4 ; j++ )
		{
			vec.x = MirrorVerts[0][j].x;
			vec.y = MirrorVerts[0][j].y;
			vec.z = MirrorVerts[0][j].z;

			vec   = vec*a;

			MirrorVerts[i][j].x = vec.x;
			MirrorVerts[i][j].y = vec.y;
			MirrorVerts[i][j].z = vec.z;			

			MirrorVerts[i][j].tu =    MirrorVerts[0][j].tu;
			MirrorVerts[i][j].tv =    MirrorVerts[0][j].tv;
			MirrorVerts[i][j].color = MirrorVerts[0][j].color;

			vec.x = ClipVerts[0][j].x;
			vec.y = ClipVerts[0][j].y;
			vec.z = ClipVerts[0][j].z;

			vec   = vec*a;

			ClipVerts[i][j].x = vec.x;
			ClipVerts[i][j].y = vec.y;
			ClipVerts[i][j].z = vec.z;			

			ClipVerts[i][j].tu =    ClipVerts[0][j].tu;
			ClipVerts[i][j].tv =    ClipVerts[0][j].tv;
			ClipVerts[i][j].color = ClipVerts[0][j].color;
		}
	}

	
	Banner[0] = D3DLVERTEX( D3DVECTOR( 0, 2, 105 ), 0x80FFFFFF, 0, 0, 1 ); 
	Banner[1] = D3DLVERTEX( D3DVECTOR( 0, 2,  95 ), 0x80FFFFFF, 0, 1, 1 );
	Banner[2] = D3DLVERTEX( D3DVECTOR( 0,-2, 105 ), 0x80FFFFFF, 0, 0, 0 );
    Banner[3] = D3DLVERTEX( D3DVECTOR( 0,-2,  95 ), 0x80FFFFFF, 0, 1, 0 );
	
    // 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 );
			
	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 App_FrameMove( 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.	

	gem_Matrix		a = IdentMtx();
	FLOAT			rot[4], d = -1;	
	FLOAT			texCoord[4][2];
	FLOAT			fTimeKey = sync->fTimeKey;
	LONG			i, j;

	static FLOAT			sync0Coeff;
	static FLOAT			sync0Key;
	static DWORD			sync0;
	static FLOAT			sync1Key;
	static DWORD			sync1;
		
	DWORD	frame = ((DWORD)(fTimeKey*100.0f));
	FLOAT   len;
	DWORD	nbr;	

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

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

	if( frame>=400 && frame<430 )
	{
		full.vNbrSpot = 0;
		full.vNbrHull = 0;

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

		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>=500 && frame<1000 )
	{
		full.vNbrSpot = 0;
		full.vNbrHull = 0;

		len = 25.1f - (FLOAT)( frame - 500 )*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>=900 && frame<1000 )
	{
		len = 255.0f - (FLOAT)(frame - 900)*255.0f/100.0f;
		DWORD	ddd = (DWORD)len;
		ddd = ((DWORD)(((FLOAT)ddd*0.7f))<<16) | ((DWORD)(((FLOAT)ddd*0.8f))<<8) | ddd;

		SetExtrudedColor( &full, ddd );
	}


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


	if( sync->dwSync00 )
	{
		sync0 = 1;
		sync0Key = fTimeKey;
		sync->dwSync00 = 0;
	}

	if( sync->dwSync01 )
	{
		sync1 = 1;
		sync1Key = fTimeKey;
		sync->dwSync01 = 0;
	}

	if( fTimeKey < 4.0f )
	{
		FLOAT		value = 2.0f*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;
	}

	if( sync0 )
	{
		FLOAT		time = fTimeKey - sync0Key ;

		if( time < 0.2f )
		{
			sync0Coeff = 5.0f*( fTimeKey - sync0Key );
		}
		
		if( time >= 0.2f && time < 0.4f )
		{
			sync0Coeff = 2 - 5.0f*( fTimeKey - sync0Key );
		}		
		
		if( time > 0.4f )
		{
			sync0 = 0;
			sync0Coeff = 0;
		}		
	}
	else
	{
		sync0Coeff = 0;
	}

	if( fTimeKey < 2.0f )
	{
		sync0Coeff = 5.0f*( 2.0f - fTimeKey );
	}

	if( fTimeKey < 1.0f )
	{
		LightBarVer[0].sy = 480*fTimeKey;
		LightBarVer[1].sy = 480*fTimeKey - 460;
		LightBarVer[2].sy = 480*fTimeKey;
		LightBarVer[3].sy = 480*fTimeKey - 460;

		LightBarHrz[0].sx = -640*fTimeKey + 640;
		LightBarHrz[1].sx = -640*fTimeKey + 640;
		LightBarHrz[2].sx = 1280 - 640*fTimeKey;		
		LightBarHrz[3].sx = 1280 - 640*fTimeKey;
	}

	texCoord[0][0] = 0.0f;
	texCoord[0][1] = 1.0f;

	texCoord[1][0] = 0.0f;
	texCoord[1][1] = 0.0f;

	texCoord[2][0] = 1.0f;
	texCoord[2][1] = 1.0f;

	texCoord[3][0] = 1.0f;
	texCoord[3][1] = 0.0f;

	rot[0] = fTimeKey*2.5f;
	rot[1] = -fTimeKey*4.0f;
	rot[2] = -fTimeKey*2.0f;
	rot[3] = fTimeKey*3.0f;
	rot[4] = -fTimeKey*1.5f;

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

	if( sync1 )
	{
		FLOAT		time = fTimeKey - sync1Key ;

		if( time < 0.1f )
		{
			g_matLocal = (D3DMATRIX)( ScaleMtx( 1.0f + 3.0f*time)*RotationMtx( fTimeKey*2.0f, -fTimeKey*3.0f, fTimeKey ) );
		}

		if( time >= 0.1f && time < 0.2f )
		{
			g_matLocal = (D3DMATRIX)( ScaleMtx( 1.6f - 3.0f*time)*RotationMtx( fTimeKey*2.0f, -fTimeKey*3.0f, fTimeKey ) );
		}

		if( time >= 0.2f )
		{
			sync1 = 0;
			sync1Key = 0;
			g_matLocal = (D3DMATRIX)RotationMtx( fTimeKey*2.0f, -fTimeKey*3.0f, fTimeKey );
		}
	}
	else
	{
		g_matLocal = (D3DMATRIX)RotationMtx( fTimeKey*2.0f, -fTimeKey*3.0f, fTimeKey );
	}

	for( i = 0 ; i<5 ; i++ )
	{
		lbVerPos[2*i]	= 40.0f + ( 1.0f + (FLOAT)sin( fTimeKey*0.31f*(FLOAT)(i+1) + i ) )*20.0f;
		lbVerPos[2*i+1] = 40.0f + ( 1.0f + (FLOAT)cos( fTimeKey*0.15f*(FLOAT)(i+1) - (FLOAT)i*0.5f ) )*20.0f;
		lbHrzPos[2*i]	= 400.0f + ( 1.0f + (FLOAT)cos( fTimeKey + i ) )*20.0f;
		lbHrzPos[2*i+1] = 400.0f +( 1.0f + (FLOAT)sin( fTimeKey*0.25f*(FLOAT)(i+1) - i ) )*20.0f;
	}

	gem_Vector		vec;

	gem_Vector	syncVec[4];

	syncVec[0] = gem_Vector(  0,  0,  8 );
	syncVec[1] = gem_Vector(  8,  0,  0 );
	syncVec[2] = gem_Vector(  0,  0, -8 );
	syncVec[3] = gem_Vector( -8,  0,  0 );
	
	for( i = 0 ; i<4 ; i++ )
	{
		if( fTimeKey < 2 )
		{
			a = RotationMtx( 0, 3.14159f*0.5f, 0 );
		}
		else
		{
			a = RotationMtx( -(fTimeKey - 2)*0.5f, (fTimeKey-2)*1.2f + 3.14159f*0.5f, (fTimeKey-2)*2.1f );
		}

		for( j = 0 ; j<4 ; j++ )
		{
			vec.x = MirrorVerts[i][j].x + syncVec[i].x*sync0Coeff;
			vec.y = MirrorVerts[i][j].y + syncVec[i].y*sync0Coeff;
			vec.z = MirrorVerts[i][j].z + syncVec[i].z*sync0Coeff;

			vec   = vec*a;

			MirrorPlain[i][j].x = vec.x;
			MirrorPlain[i][j].y = vec.y;
			MirrorPlain[i][j].z = vec.z;

			MirrorPlain[i][j].tu = MirrorVerts[i][j].tu;
			MirrorPlain[i][j].tv = MirrorVerts[i][j].tv;
			MirrorPlain[i][j].color = MirrorVerts[i][j].color;

			vec.x = ClipVerts[i][j].x + syncVec[i].x*sync0Coeff;
			vec.y = ClipVerts[i][j].y + syncVec[i].y*sync0Coeff;
			vec.z = ClipVerts[i][j].z + syncVec[i].z*sync0Coeff;

			vec   = vec*a;

			ClipPlain[i][j].x = vec.x;
			ClipPlain[i][j].y = vec.y;
			ClipPlain[i][j].z = vec.z;

			ClipPlain[i][j].tu = ClipVerts[i][j].tu;
			ClipPlain[i][j].tv = ClipVerts[i][j].tv;
			ClipPlain[i][j].color = ClipVerts[i][j].color;

			
			
		}

		Background[i].tu = texCoord[i][0] + (FLOAT)sin( fTimeKey*0.1f );
		Background[i].tv = texCoord[i][1] + (FLOAT)cos( fTimeKey*0.1f );
	}

	FLOAT aaa	  = ((FLOAT)sin( fTimeKey ) + 1.0f)*0.2f + 0.1f;

	alpha = fTimeKey*0.5f>1.0f ? 1.0f : fTimeKey*0.5f;	

	for( i = 0 ; i<10 ; i++ )
	{
		matBackLocal[i] = GetD3DMATRIX( RotationMtx( 0.0f, 0.0f, d*(1.0f+(FLOAT)i/10.0f)*fTimeKey*0.55f )*
										TranslationMtx( gem_Vector( 0.0f, 0.0f, 3.0f*i+3 ) ) );
	}


	FLOAT		val;		
	FLOAT		ang[10][2];

	ang[0][0] = 5.9f; ang[0][1] = -3.0f; ang[1][0] = 2.3f; ang[1][1] = -1.0f;
	ang[2][0] = 7.5f; ang[2][1] = -2.0f; ang[3][0] = 5.1f; ang[3][1] =  0.0f;
	ang[4][0] = 6.9f; ang[4][1] =  1.0f; ang[5][0] = 3.9f; ang[5][1] =  2.0f; 
	ang[6][0] = 3.5f; ang[6][1] = -5.0f; ang[7][0] = 3.0f; ang[7][1] =  4.0f;
	ang[8][0] = 4.5f; ang[8][1] =  3.0f; ang[9][0] = 8.1f; ang[9][1] =  5.0f;
	


	for( i = 0 ; i<8 ; i++ )
	{		
		val = (FLOAT)fmod( 40*fTimeKey+i*20.0f, 160.0f );

		matBannerLocal[i] = GetD3DMATRIX( TranslationMtx( gem_Vector( 0, 0, -100.0f ) )*
				  						  TranslationMtx( gem_Vector( 0, 0, -val ) )*
										  RotationMtx( -3.1415f*3.0f/180.0f, 0.0f, 0.0f )*
										  TranslationMtx( gem_Vector( 0, 0, 100.0f ) ) );
	}

	if( fTimeKey<8.0f )
	{
		mtxFlareRot = RotationMtx( fTimeKey*0.5, -fTimeKey*0.4, -fTimeKey*0.7 )*
					  TranslationMtx( 0, 0, 20 );
	}
	else
	{
		if( fTimeKey<14.0f )
		{
			mtxFlareRot = RotationMtx( fTimeKey*0.5, -fTimeKey*0.4, -fTimeKey*0.7 )*
						  TranslationMtx( 0, 0, 20.0f - (fTimeKey-8.0f)*6.666f );
		}
		else
		{
			mtxFlareRot = RotationMtx( fTimeKey*0.5, -fTimeKey*0.4, -fTimeKey*0.7 )*
					  TranslationMtx( 0, 0, -20 );
		}
	}

	/*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 App_Render( 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).
	LPDIRECTDRAWSURFACE7	pdds;
	HRESULT					hr;
	D3DMATERIAL7			mtrl;	
	DWORD					nbr1, nbr2;

	DWORD					time1, time2;
	FLOAT					fps;

	LONG					i, j;

    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	

	time1 = timeGetTime();
	
	//Calculate( g_Grid, boob, 5 );
	//nbr1 = CalculateVertex( g_Grid, boob, 5, vertab1, TRUE );	
	//nbr2 = CalculateVertex( g_Grid, boob, 5, vertab2, FALSE );	
	//ApplySphereMap( vertab1, nbr1, pd3dDevice );
	//ApplySphereMap( vertab2, nbr2, pd3dDevice );
	
	HDC			hdc;
   

	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 );

	pd3dDevice->SetTexture( 0, back );
/*		
	for( i = 0 ; i<7 ; i++ )
	{
		pd3dDevice->SetTransform( D3DTRANSFORMSTATE_WORLD, &matBackLocal[i] );				
		pd3dDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, D3DFVF_LVERTEX, FxPlain, 36, FxPlainInd, 150, NULL );
	}

	pd3dDevice->SetRenderState( D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA );
	pd3dDevice->SetRenderState( D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA );
			

	pd3dDevice->SetTexture( 0, mask );	

	pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );	
	pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, D3DFVF_TLVERTEX, Background, 4, 0 );
	
	pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2 );	

	pd3dDevice->SetTexture( 0, lightstrip );


	pd3dDevice->SetRenderState( D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA );
	pd3dDevice->SetRenderState( D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE );
	

	for( i = 0 ; i<10 ; i++ )
	{
		LightBarVer[0].sx = lbVerPos[i];
		LightBarVer[1].sx = lbVerPos[i];
		LightBarVer[2].sx = lbVerPos[i] + 12;
		LightBarVer[3].sx = lbVerPos[i] + 12;

		pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, D3DFVF_TLVERTEX, LightBarVer, 4, 0 );

		LightBarHrz[0].sy = lbHrzPos[i] + 12;
		LightBarHrz[1].sy = lbHrzPos[i];
		LightBarHrz[2].sy = lbHrzPos[i] + 12;		
		LightBarHrz[3].sy = lbHrzPos[i];

		pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, D3DFVF_TLVERTEX, LightBarHrz, 4, 0 );
	}
		
	pd3dDevice->SetTexture( 0, mask );
	
	pd3dDevice->SetRenderState( D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA );
	pd3dDevice->SetRenderState( D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA );
	
	/*
	for( i = 0 ; i<8 ; i++ )
	{
		pd3dDevice->SetTransform( D3DTRANSFORMSTATE_WORLD, &matBannerLocal[i] );		
		pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, D3DFVF_LVERTEX, Banner, 4, 0 );
	}

	
	pd3dDevice->SetRenderState( D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE );
	pd3dDevice->SetRenderState( D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE );

	pd3dDevice->GetMaterial( &mtrl );
	mtrl.dcvDiffuse.a = alpha*0.35f;
	pd3dDevice->SetMaterial( &mtrl );
/*	
	for( i = 0 ; i<4; i++ )
	{		
		pd3dDevice->SetRenderState( D3DRENDERSTATE_ZWRITEENABLE, TRUE );		
		pd3dDevice->SetRenderState( D3DRENDERSTATE_ALPHABLENDENABLE, FALSE );		
		pd3dDevice->SetRenderState( D3DRENDERSTATE_LIGHTING, FALSE );
		pd3dDevice->SetRenderState( D3DRENDERSTATE_CLIPPLANEENABLE, 0x00 );		

		pd3dDevice->SetTransform( D3DTRANSFORMSTATE_WORLD, &matTrn );

		pd3dDevice->SetTexture( 0, mirrortext );

		pd3dDevice->SetRenderState( D3DRENDERSTATE_ZWRITEENABLE, FALSE );
		pd3dDevice->SetRenderState( D3DRENDERSTATE_CULLMODE, D3DCULL_CCW );

		pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, D3DFVF_LVERTEX, MirrorPlain[i], 4, NULL );

		pd3dDevice->SetTexture( 0, mirrorback );
		
		pd3dDevice->SetRenderState( D3DRENDERSTATE_ZWRITEENABLE, TRUE );
		pd3dDevice->SetRenderState( D3DRENDERSTATE_CULLMODE, D3DCULL_CW );

		pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, D3DFVF_LVERTEX, MirrorPlain[i], 4, NULL );				

		D3DMATRIX  matMirror;
		
		gem_Vector a = gem_Vector( ClipPlain[i][0].x, ClipPlain[i][0].y, ClipPlain[i][0].z );
		gem_Vector b = gem_Vector( ClipPlain[i][1].x, ClipPlain[i][1].y, ClipPlain[i][1].z );
		gem_Vector c = gem_Vector( ClipPlain[i][3].x, ClipPlain[i][3].y, ClipPlain[i][3].z );
		gem_Vector d = gem_Vector( ClipPlain[i][2].x, ClipPlain[i][2].y, ClipPlain[i][2].z );		

		gem_Vector n = Normalize( Cross( b-a, c-a ) );
		gem_Vector o = ( a + b + c + d )*0.25;

		MirrorMtx( matMirror, n, Length( o ) );

		matMirror = matWorld*matMirror*matTrn;

		gem_Matrix mtxTrn = TranslationMtx( -7, 0, 20 );
		a = a*mtxTrn;
		b = b*mtxTrn;
		c = c*mtxTrn;
		d = d*mtxTrn;

		FLOAT plane[4];
		pd3dDevice->SetClipPlane( 0, CreatePlane( plane, a, b, gem_Vector( 0, 0, -10 ) ) );
		pd3dDevice->SetClipPlane( 1, CreatePlane( plane, b, c, gem_Vector( 0, 0, -10 ) ) );
		pd3dDevice->SetClipPlane( 2, CreatePlane( plane, c, d, gem_Vector( 0, 0, -10 ) ) );
		pd3dDevice->SetClipPlane( 3, CreatePlane( plane, d, a, gem_Vector( 0, 0, -10 ) ) );
	

		

		pd3dDevice->SetRenderState( D3DRENDERSTATE_CLIPPLANEENABLE, 0x0f );				

		pd3dDevice->SetTransform( D3DTRANSFORMSTATE_WORLD, &matMirror );

		pd3dDevice->SetTexture( 0, text1 );

		pd3dDevice->SetRenderState( D3DRENDERSTATE_ALPHABLENDENABLE, FALSE );
		pd3dDevice->SetRenderState( D3DRENDERSTATE_ZWRITEENABLE, TRUE );			
		pd3dDevice->SetRenderState( D3DRENDERSTATE_CULLMODE, D3DCULL_NONE );

		pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, D3DFVF_VERTEX, vertab1, nbr1, NULL );
				
		pd3dDevice->SetTexture( 0, text2 );
	
		pd3dDevice->SetRenderState( D3DRENDERSTATE_ALPHABLENDENABLE, TRUE );	
		pd3dDevice->SetRenderState( D3DRENDERSTATE_ZWRITEENABLE, FALSE );				
		pd3dDevice->SetRenderState( D3DRENDERSTATE_CULLMODE, D3DCULL_NONE );

		pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, D3DFVF_VERTEX, vertab2, nbr2, NULL );

		pd3dDevice->SetRenderState( D3DRENDERSTATE_CLIPPLANEENABLE, 0x00 );	

		pd3dDevice->SetRenderState( D3DRENDERSTATE_LIGHTING, FALSE );
		pd3dDevice->SetRenderState( D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA );
		pd3dDevice->SetRenderState( D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA );
		pd3dDevice->SetTransform( D3DTRANSFORMSTATE_WORLD, &matTrn );

		pd3dDevice->SetTexture( 0, NULL );

		pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, D3DFVF_LVERTEX, ClipPlain[i], 4, NULL );

		pd3dDevice->SetRenderState( D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE );
		pd3dDevice->SetRenderState( D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE );
				
	}

	mtrl.dcvDiffuse.a = alpha;
	pd3dDevice->SetMaterial( &mtrl );
	pd3dDevice->SetTexture( 0, text1 );	
	
	pd3dDevice->SetRenderState( D3DRENDERSTATE_CLIPPLANEENABLE, 0x00 );	

	matWorld = matWorld*matTrn;

	pd3dDevice->SetTransform( D3DTRANSFORMSTATE_WORLD, &matWorld );
	
	pd3dDevice->SetRenderState( D3DRENDERSTATE_ALPHABLENDENABLE, FALSE );
	pd3dDevice->SetRenderState( D3DRENDERSTATE_ZWRITEENABLE, TRUE );		
	pd3dDevice->SetRenderState( D3DRENDERSTATE_LIGHTING, TRUE );

	pd3dDevice->SetRenderState( D3DRENDERSTATE_CULLMODE, D3DCULL_NONE );
//	pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, D3DFVF_VERTEX, vertab1, nbr1, NULL );		

	pd3dDevice->SetTexture( 0, text2 );			
	
	pd3dDevice->SetRenderState( D3DRENDERSTATE_ALPHABLENDENABLE, TRUE );
	pd3dDevice->SetRenderState( D3DRENDERSTATE_ZWRITEENABLE, FALSE );
	pd3dDevice->SetRenderState( D3DRENDERSTATE_LIGHTING, TRUE );

	pd3dDevice->SetRenderState( D3DRENDERSTATE_CULLMODE, D3DCULL_NONE );
//	pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, D3DFVF_VERTEX, vertab2, nbr2, NULL );		

	pd3dDevice->SetRenderState( D3DRENDERSTATE_ALPHABLENDENABLE, FALSE );	
	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, text2 );			
	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, light );

	RenderFlareSystem( FlarezCube, g_Grid, boob, 5, pd3dDevice );
	pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );


	pd3dDevice->EndScene();

	time2 = timeGetTime() - time1;
	fps = 1000.0f/(FLOAT)time2;

	pd3dDevice->GetRenderTarget( &pdds );

	CHAR buffer[80];
	sprintf( buffer, "%10.02f fps ", fps );

	if( SUCCEEDED( pdds->GetDC( &hdc ) ) )
	{				    
		SetTextColor( hdc, RGB(255,255,0) );
		SetBkMode( hdc, TRANSPARENT );
		ExtTextOut( hdc, 10, 10, 0, NULL, buffer, strlen(buffer), NULL );
    
		pdds->ReleaseDC(hdc);
	}

	//pdds->Release;

	

    // 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 App_DeleteDeviceObjects( LPDIRECT3DDEVICE7 pd3dDevice )
{	
	DeleteVolume( &volume );
	DeleteVolume( &extruded );
	DeleteVolume( &full );

	SAFE_RELEASE( back );
	SAFE_RELEASE( _01 );
	SAFE_RELEASE( mask );
	SAFE_RELEASE( volumeMap );
	SAFE_RELEASE( logo );
	SAFE_RELEASE( text1 );
	SAFE_RELEASE( text2 );
	SAFE_RELEASE( light );
	SAFE_RELEASE( mirrortext );
	SAFE_RELEASE( mirrorback );

	DeleteObject3D( &sphere );

	LONG		i;

	for(  i = 0 ; i<5 ; i++ )
		DeleteObject3D( &torus[i] );

	DeleteObject3D( &morphed );
	DeleteObject3D( &blob[0] );
	DeleteObject3D( &blob[1] );
	DeleteObject3D( &morph2 );
	DeleteObject3D( &morph3 );
}

