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


#include "sphere.h" 
 
CSphere::CSphere( int Rings , int Segments , int Tex1 , int Tex2 , int Tex3 , Color color ) :  
	CCustomRenderer (  
		CVertex::PosNormalColorTex0Tex1 ,  
		( Rings + 1 ) * ( Segments + 1 ) ,  // VB Size  
		0 , // Usage normal  
		false , // static VB  
		2 * Rings * ( Segments + 1 ) , // IB Size  
		Tex1 , Tex2 , Tex3 , 0 ,  
		0 , 0 )  
{ 
	this->Rings    = Rings ;   
	this->Segments = Segments ;  
	this->color    = color ;  
	// set vertex count and index count  
	Vertices = ( Rings + 1 ) * ( Segments + 1 ) ; 
	Indices  = 2 * Rings * ( Segments + 1 ) ; 
 
	Layer = SxDL::Models ;  
} 
 
CSphere::~CSphere(void) 
{ 
} 
 
 
HRESULT CSphere::OnPopulateBuffers ( void * pVertices , void * pIndices )						 
{  
	// Cast to our vertex format  
    VertexPosNormalColorTex0Tex1 * Vertex = ( VertexPosNormalColorTex0Tex1 * ) pVertices ;  
    unsigned short * Index = ( unsigned short * ) pIndices ;  
    // Establish constants used in sphere generation 
    float DeltaRingAngle = ( D3DX_PI / Rings ); 
    float DeltaSegAngle  = ( 2.0f * D3DX_PI / Segments ); 
	// Initialize vertex index  
	unsigned short VerticeIndex = 0 ;  
    // Generate the group of rings for the sphere 
    for( int ring = 0; ring < Rings + 1 ; ++ ring ) 
    { 
        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 + 1 ; ++ seg ) 
        { 
            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  
			Vertex->n     = Vertex->p ;   
			Vertex->color = color ;  
			Vertex->tu1   = - ( float ) seg  / ( float ) Segments; 
			Vertex->tv1   =   ( float ) ring / ( float ) Rings; 
			Vertex->tu2   = Vertex->tu1 ;  
			Vertex->tv2   = Vertex->tv1 ;  
			// Next vertex  
			++ Vertex ; 
			// add two indices except for last ring  
			if ( ring != Rings )  
			{ 
				* Index = VerticeIndex ;  
				++ Index  ; 
				* Index = VerticeIndex + ( ( unsigned short ) Segments + 1 ) ;  
				++ Index ; 
				++ VerticeIndex ;  
			} ;  
        } ; // end for seg  
    } // end for ring  
 
	return S_OK ;  
} ;  
 
HRESULT CSphere::OnRender ( LPDIRECT3DDEVICE9 Device , CEntity * Entity ) 
{  
	HRESULT hr = Device->DrawIndexedPrimitive (  
		D3DPT_TRIANGLESTRIP, 0, 0, // min index  
		Vertices ,  0, // start index  
		Indices - 2 ) ; // number of primitives 
	return hr ;  
}  
 
CTexturedSphere::CTexturedSphere ( int Rings , int Segments , int Tex ) :  
	CSphere ( Rings , Segments , Tex , 0 , 0 )  
{ 
}  
 
CAlphaSphere::CAlphaSphere ( int Rings , int Segments , int Tex ) :  
	CSphere ( Rings , Segments , Tex , 0 , 0 , 0x80808080 )  
{ 
}  
 
 
HRESULT CAlphaSphere::OnSetRenderStates ( LPDIRECT3DDEVICE9 Device )	 
{  
	// enable blending  
	Device->SetRenderState ( D3DRS_ALPHABLENDENABLE, TRUE ); 
	Device->SetRenderState ( D3DRS_SRCBLEND,  D3DBLEND_ONE ); 
	Device->SetRenderState ( D3DRS_DESTBLEND, D3DBLEND_ONE ); 
    Device->SetRenderState( D3DRS_ALPHATESTENABLE, TRUE ); 
	return S_OK ;  
} ;  
 
HRESULT CAlphaSphere::OnRestoreRenderStates ( LPDIRECT3DDEVICE9 Device )  
{  
	// disable alpha blending  
	Device->SetRenderState ( D3DRS_ALPHABLENDENABLE, FALSE ); 
    Device->SetRenderState( D3DRS_ALPHATESTENABLE, FALSE ); 
	return S_OK ;  
} ;  
 
 
CBumpedSphere::CBumpedSphere ( int Rings , int Segments , int Tex1 , int Tex2 ) :  
	CSphere ( Rings , Segments , 0 , Tex2 , Tex1 )  
{ 
}  
 
HRESULT CBumpedSphere::OnRestore ( )						 
{ 
	// Create the normal map from the Bump map 
	LPDIRECT3DTEXTURE9 HeightMap = Texture3 ; 
	HRESULT hr = S_OK ;  
	if ( NULL != HeightMap )  
	{ 
		D3DSURFACE_DESC desc; 
		HeightMap->GetLevelDesc ( 0, & desc ) ; 
		hr = D3DXCreateTexture (  
			Device, desc.Width, desc.Height, 0, 0, 
			D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,  
			& Texture1 ) ;  
		{ 
			// Generate a Normal Map  
			D3DXComputeNormalMap(  
				Texture1 , HeightMap ,  
				NULL, 0, D3DX_CHANNEL_RED, 40.0f /* BumpFactor */ / 10.0f ) ;  
		} ;  
	} ;  
	return hr ;  
}  
 
HRESULT CBumpedSphere::OnInvalidate ( )  
{ 
	SAFE_RELEASE ( Texture1 ) ;  
	return S_OK ;  
}  
 
HRESULT CBumpedSphere::OnSetRenderStates ( LPDIRECT3DDEVICE9 Device )	 
{  
	D3DXVECTOR3 vLight ( 1.0f, 1.0f, 1.0f ) ;  
	D3DXVec3Normalize( & vLight , & vLight ) ;  
	DWORD dwFactor = CTools::VectortoRGBA ( & vLight , 0.0f ) ;  
    Device->SetRenderState ( D3DRS_TEXTUREFACTOR, dwFactor ) ;  
	// stage 0 : bump 
    Device->SetTextureStageState ( 0, D3DTSS_COLOROP,   D3DTOP_DOTPRODUCT3 ) ;  
    Device->SetTextureStageState ( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ) ;  
    Device->SetTextureStageState ( 0, D3DTSS_COLORARG2, D3DTA_TFACTOR ) ;  
	// stage 1 : color 
    Device->SetTextureStageState ( 1, D3DTSS_COLOROP,   D3DTOP_MODULATE ) ;  
    Device->SetTextureStageState ( 1, D3DTSS_COLORARG1, D3DTA_CURRENT ) ;  
    Device->SetTextureStageState ( 1, D3DTSS_COLORARG2, D3DTA_TEXTURE ) ;  
	return S_OK ;  
} ;  
 
HRESULT CBumpedSphere::OnRestoreRenderStates ( LPDIRECT3DDEVICE9 Device )  
{  
    Device->SetRenderState ( D3DRS_TEXTUREFACTOR, 0xFFFFFFFF ) ;  
    Device->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_MODULATE ); 
    Device->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); 
    Device->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); 
    Device->SetTextureStageState( 0, D3DTSS_ALPHAOP,   D3DTOP_MODULATE ); 
    Device->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); 
    Device->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE ); 
	Device->SetTextureStageState( 1, D3DTSS_COLOROP,   D3DTOP_DISABLE ); 
	Device->SetTextureStageState( 1, D3DTSS_ALPHAOP,   D3DTOP_DISABLE ); 
	return S_OK ;  
} ;