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, &amt; desc ) ;
hr = D3DXCreateTexture (
Device, desc.Width, desc.Height, 0, 0,
D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
&amt; 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( &amt; vLight , &amt; vLight ) ;
DWORD dwFactor = CTools::VectortoRGBA ( &amt; 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 ;
} ;