www.pudn.com > sxdl.zip > blob.cpp


#include "blob.h" 
 
 
 
CBlob::CBlob ( int Rings , int Segments , int TextureId , int VertexShaderId ) :  
	CCustomRenderer  
	(  
		CVertex::PosNormal ,  
		BlobVBSize ( Rings , Segments ) ,  // VB Size  
		D3DUSAGE_POINTS , // Usage point sprites   
		false , // static VB  
		0 , // No IB  
		TextureId , 0 , 0 , 0 , // Texturing 
		VertexShaderId , 0  
	)  
{ 
	this->Rings    = Rings ;   
	this->Segments = Segments ;  
	// set vertex count  
	Vertices = BlobVBSize ( Rings , Segments ) ; 
	// effetcs live in the foreground  
	Layer = SxDL::Foreground ;  
} 
 
CBlob::~CBlob ( void ) 
{ 
} 
 
HRESULT CBlob::OnPopulateBuffers ( void * pVertices , void * )						 
{  
	// Cast to our vertex format  
    VertexPosNormal * Vertex = ( VertexPosNormal * ) pVertices ;  
    // Establish constants used in sphere generation 
    float DeltaRingAngle = ( D3DX_PI / Rings ) ; 
    float DeltaSegAngle  = ( 2.0f * D3DX_PI / Segments ) ; 
    // Generate the group of rings for the sphere 
    for( int ring = 1 ; ring < Rings ; ++ ring ) // dont do the poles  
    { 
        float r0 = sinf ( ring * DeltaRingAngle ) ; 
        float y0 = cosf ( ring * DeltaRingAngle ) ; 
        // Generate the group of segments for the current ring 
        for( int seg = 0; seg < Segments ; ++ seg ) // dont close the ring  
        { 
            float x0 =  r0 * sinf ( seg * DeltaSegAngle ) ; 
            float z0 =  r0 * cosf ( seg * DeltaSegAngle ) ; 
			// Add one vertices to the strip which makes up the sphere 
			Vertex->p = D3DXVECTOR3 ( x0, y0 , z0 ) ; // already normalized  
			// normal is a pseudo random vector  
			// we'll play with it within the vertex shader  
			float a = CTools::randf ( 1.0f , 129.0f ) ;  
			float b = CTools::randf ( 1.0f , 129.0f ) ;  
			float c = CTools::randf ( 1.0f , 129.0f ) ;  
			Vertex->n = D3DXVECTOR3 ( a, b, c ) ;   
			// Next vertex  
			++ Vertex ; 
        } ; // end for seg  
    } ; // end for ring  
	// north pole 
	Vertex->p = D3DXVECTOR3 ( 0.0f , 1.0f , 0.0f ) ; // normalized  
	float a = CTools::randf ( 1.0f , 129.0f ) ;  
	float b = CTools::randf ( 1.0f , 129.0f ) ;  
	float c = CTools::randf ( 1.0f , 129.0f ) ;  
	Vertex->n = D3DXVECTOR3 ( a, b, c ) ;   
	// Next vertex  
	++ Vertex ; 
	// south pole 
	Vertex->p = D3DXVECTOR3 ( 0.0f , -1.0f , 0.0f ) ; // normalized  
	a = CTools::randf ( 1.0f , 129.0f ) ;  
	b = CTools::randf ( 1.0f , 129.0f ) ;  
	c = CTools::randf ( 1.0f , 129.0f ) ;  
	Vertex->n = D3DXVECTOR3 ( a, b, c ) ;   
 
	return S_OK ;  
} ;  
 
HRESULT CBlob::OnRender ( LPDIRECT3DDEVICE9 Device , CEntity * Entity ) 
{  
	HRESULT hr =  
		Device->DrawPrimitive ( D3DPT_POINTLIST , 0 , Vertices ) ;  
	return hr ;  
}  
 
HRESULT CBlob::OnSetRenderStates ( LPDIRECT3DDEVICE9 Device )	 
{  
	// enable Z buffering  
    Device->SetRenderState( D3DRS_ZENABLE,   TRUE ) ; 
    Device->SetRenderState( D3DRS_ZWRITEENABLE,   TRUE ) ; 
 
	Device->SetRenderState ( D3DRS_POINTSPRITEENABLE, TRUE ); 
    Device->SetRenderState ( D3DRS_POINTSCALEENABLE,  TRUE ) ; 
	// dynamic point sizing is not always supported.  
	// So do it is here   
    Device->SetRenderState ( D3DRS_POINTSIZE,     CTools::FtoDW ( 10.0f ) ); 
    Device->SetRenderState ( D3DRS_POINTSIZE_MIN, CTools::FtoDW (  0.1f ) ); 
    Device->SetRenderState ( D3DRS_POINTSIZE_MAX, CTools::FtoDW ( 64.0f ) ); 
    Device->SetRenderState ( D3DRS_POINTSCALE_A,  CTools::FtoDW (  0.0f ) ); 
    Device->SetRenderState ( D3DRS_POINTSCALE_B,  CTools::FtoDW (  0.0f ) ); 
    Device->SetRenderState ( D3DRS_POINTSCALE_C,  CTools::FtoDW (  1.0f ) ); 
	return S_OK ;  
} ;  
 
HRESULT CBlob::OnRestoreRenderStates ( LPDIRECT3DDEVICE9 Device )  
{  
    Device->SetRenderState( D3DRS_ZENABLE,   FALSE ) ; 
    Device->SetRenderState( D3DRS_ZWRITEENABLE, FALSE ) ; 
 
	Device->SetRenderState ( D3DRS_POINTSPRITEENABLE, FALSE ); 
	return S_OK ;  
} ;  
 
HRESULT CBlob::OnSetVertexShaderConstants ( LPDIRECT3DDEVICE9 Device , CEntity * Entity )  
{  
	CBlobableEntity * e = ( CBlobableEntity * ) Entity ;  
	// Set the static vertex shader constants. 
	float ColorDiffuse [ ] =  
		{ e->RedDiffuse,  e->GrnDiffuse, e->BluDiffuse, 1.0f } ;  
	float ColorFade [ ] =  
		{ e->RedFade,  e->GrnFade, e->BluFade, 1.0f } ;  
	Device->SetVertexShaderConstantF (  2, ( const float * ) & ColorDiffuse, 1 ); 
	Device->SetVertexShaderConstantF (  3, ( const float * ) & ColorFade,    1 ); 
 
	// Set the dynamic vertex shader constants. 
	float vC11 [ ] =  
	{  
		0.01f + 5.0f * e->Alive ( ) , 
		e->Alive ( ) , // color lerp factor  
		10.0f + CTools::randf ( ) * 2.0f ,	 // particle size  
		CTools::randf ( 1.0f , 129.0f )   
	} ; 
	Device->SetVertexShaderConstantF ( 11, ( const float * ) & vC11, 1 ); 
	// D3DXVECTOR4 vC12 ( 0.0f, 0.0f, 0.8f,  0.7f ) ; 
	D3DXVECTOR4 vC12 ( 0.0f, 0.0f, 0.01f,  0.4f ) ; 
	Device->SetVertexShaderConstantF ( 12, ( const float * ) & vC12, 1 ); 
 
	D3DXMATRIX View       = Game->Camera.GetViewMatrix ( ) ; 
	D3DXMATRIX Projection = Game->Camera.GetProjectionMatrix ( ) ; 
	D3DXMATRIX ShaderMatrix ;  
	D3DXMatrixTranspose ( & ShaderMatrix, & ( e->GetWorldMatrix ( ) * View * Projection ) ); 
	Device->SetVertexShaderConstantF ( 4, ( const float * ) & ShaderMatrix , 4 ); 
 
	return S_OK ;  
} ;  
 
CBlobableEntity::CBlobableEntity  ( int ColorStyle )  
{ 
	if      ( ColorStyle == 0 ) 
	{ 
		RedDiffuse = CTools::randf ( 0.8f , 0.9f ) ;  
		GrnDiffuse = CTools::randf ( 0.5f , 0.8f ) ;  
		BluDiffuse = CTools::randf ( 0.4f , 0.6f ) ;  
	} 
	else if ( ColorStyle == 1 )     
	{ 
		RedDiffuse = CTools::randf ( 0.7f , 0.9f ) ;  
		GrnDiffuse = CTools::randf ( 0.1f , 0.5f ) ;  
		BluDiffuse = CTools::randf ( 0.1f , 0.3f ) ;  
	} 
	else if ( ColorStyle == 2 )   
	{ 
		RedDiffuse = CTools::randf ( 0.5f , 0.6f ) ;   
		GrnDiffuse = CTools::randf ( 0.2f , 0.5f ) ;  
		BluDiffuse = CTools::randf ( 0.1f , 0.3f ) ;  
	} 
	else if ( ColorStyle == 3 )  
	{ 
		RedDiffuse = CTools::randf ( 0.6f , 0.7f ) ;   
		GrnDiffuse = CTools::randf ( 0.3f , 0.6f ) ;  
		BluDiffuse = CTools::randf ( 0.2f , 0.4f ) ;  
	}  
	else if ( ColorStyle == 4 )  
	{ 
		RedDiffuse = CTools::randf ( 0.1f , 0.4f ) ;  
		BluDiffuse = CTools::randf ( 0.5f , 0.9f ) ;   
		GrnDiffuse = CTools::randf ( 0.1f , 0.4f ) ;  
	} ;  
	// fading into dark red, dark green or dark blue  
	if ( ColorStyle == 4 )  
	{ 
		RedFade = CTools::randf ( 0.0f , 0.1f ) ;  
		GrnFade = CTools::randf ( 0.0f , 0.1f ) ;  
		BluFade = CTools::randf ( 0.1f , 0.5f ) ;  
	} 
	else if ( ColorStyle == 3 )  
	{ 
		RedFade = CTools::randf ( 0.0f , 0.2f ) ;  
		GrnFade = CTools::randf ( 0.2f , 0.6f ) ;  
		BluFade = CTools::randf ( 0.0f , 0.2f ) ;  
	}  
	else 
	{ 
		RedFade = CTools::randf ( 0.2f , 0.6f ) ;  
		GrnFade = CTools::randf ( 0.0f , 0.1f ) ;  
		BluFade = CTools::randf ( 0.0f , 0.2f ) ;  
	} ;  
}