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


#include "tunnel.h"

CTunnel::CTunnel ( int _Rings , int _Segments , int Tex1 , int Tex2 , int Tex3 , Color _color , int _ShaderId ) :
CCustomRenderer (
CVertex::PosNormalColorTex0 ,
( _Rings + 1 ) * ( _Segments + 1 ) , // VB Size
0 , // Usage normal
false , // static VB
2 * _Rings * ( _Segments + 1 ) , // IB Size
Tex1 , Tex2 , Tex3 , 0 ,
_ShaderId , 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 ;
Positions = new Vector4 [ _Rings ] ;
}

CTunnel::~CTunnel(void)
{
delete [ ] Positions ;
}


HRESULT CTunnel::OnPopulateBuffers ( void * pVertices , void * pIndices )
{
// The geometry of the tunnel is kind of cone based on the sphere code.
//
// Cast to our vertex format
VertexPosNormalColorTex0 * Vertex = ( VertexPosNormalColorTex0 * ) pVertices ;
unsigned short * Index = ( unsigned short * ) pIndices ;
// Establish constants used in sphere generation
float DeltaRingAngle = ( D3DX_PI / Rings );
float DeltaRingRadius = ( 1.0f / 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 = 1.0f - ring * DeltaRingRadius ; // critical change here
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
Vertex->p = D3DXVECTOR3 ( x0,z0,y0 ) ; // y and z swapped here
Vertex->n = Vertex->p ;
// push the ring index as the red color
// for future use in the vertex shader
color = color &amt; 0xFF00FFFF ;
Vertex->color = ( ring << 16 ) | color ; //
Vertex->tu = - ( float ) seg / ( float ) Segments;
Vertex->tv

= ( float ) ring / ( float ) Rings;
// 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 CTunnel::OnSetVertexShaderConstants ( LPDIRECT3DDEVICE9 Device , CEntity * Entity )
{
// compute the position offsets
const float dt = 0.005f ;
float AbsoluteTime = Game->Timing.GetAbsolute ( ) ;
float Time = AbsoluteTime / 4.0f ;
float OmegaX = 2.0f + 0.15f * cosf ( 2.0f * Time ) ;
float OmegaY = 5.0f + 0.20f * cosf ( 1.5f * Time ) ;
for ( int i = 0 ; i < 20 ; ++ i )
{
Positions [ i ].x = ( 0.0f + i * i * 0.01f ) * sinf ( OmegaX * ( Time + i * dt ) ) ;
Positions [ i ].y = ( 0.0f + i * i * 0.01f ) * sinf ( OmegaY * ( Time + i * dt ) + 5.0f ) ;
Positions [ i ].z = 0.0f ;
Positions [ i ].w = 0.0f ;
Device->SetVertexShaderConstantF ( 20 + i , (float*) &amt; Positions [ i ] , 1 ) ;
} ;
// Set the shader matrix
D3DXMATRIX View = Game->Camera.GetViewMatrix ( ) ;
D3DXMATRIX Projection = Game->Camera.GetProjectionMatrix ( ) ;
D3DXMATRIX ShaderMatrix ;
D3DXMatrixTranspose ( &amt; ShaderMatrix, &amt; ( Entity->GetWorldMatrix ( ) * View * Projection ) );
Device->SetVertexShaderConstantF ( 4, ( const float * ) &amt; ShaderMatrix , 4 );
// Lighting vector and other constants
float Light[] = { 1.00f, 0.00f, 0.00f, 0.00f };
D3DCOLORVALUE CvDiffuse = CTools::ColorValueFromRGB ( color , 2.0f ) ;
float Diffuse [] = { CvDiffuse.r , CvDiffuse.g , CvDiffuse.b , CvDiffuse.a };
float Ambient[] = { 0.50f, 0.50f, 0.50f, 0.50f };
// Set the lighting vertex shader constants
Device->SetVertexShaderConstantF ( 10, (float*) Light, 1 ) ;
Device->SetVertexShaderConstantF ( 11, (float*) Diffuse, 1 ) ;
Device->SetVertexShaderConstantF ( 12, (float*) Ambient, 1 ) ;

return S_OK ;
}

HRESULT CTunnel::OnRender ( LPDIRECT3DDEVICE9 Device , CEntity * Entity )
{
// basic constants
float AbsoluteTime = Game->Timing.GetAbsolute ( ) ;
float SpeedUp = 0.5f * sinf ( AbsoluteTime ) ;
IsSpeedingUp = SpeedUp > 0.0f ;
float Time = 1.2f * AbsoluteTime + SpeedUp ;
D3DXVECTOR4 Zero ( 0.0f, 0.0f, 1.0f, 255.0f ) ;
Device->SetVertexShaderConstantF ( 0, (float*) &amt; Zero, 1 ) ;
D3DXVECTOR4 One ( 1.0f, 0.5f, 0.0f , Time / 2.0f ) ;
Device->SetVertexShaderConstantF ( 1, (float*) &amt; One, 1 ) ;
//
HRESULT hr ;
hr = Device->DrawIndexedPrimitive (
D3DPT_TRIANGLESTRIP, 0, 0, // min index
Vertices , 0, // start index
Indices - 2 ) ; // number of primitives
Device->SetTexture ( 0 , Texture2 ) ;
// enable blending
Device->SetRenderState ( D3DRS_ALPHABLENDENABLE, TRUE );
Device->SetRenderState ( D3DRS_SRCBLEND, D3DBLEND_ONE );
Device->SetRenderState ( D3DRS_DESTBLEND, D3DBLEND_ONE );
Device->SetRenderState( D3DRS_ALPHATESTENABLE, TRUE );
// Change sliding params
One = Vector4 ( 1.0f, 0.5f, Time / 1.3f , Time / 3.0f ) ;
Device->SetVertexShaderConstantF ( 1, (float*) &amt; One, 1 ) ;
hr = Device->DrawIndexedPrimitive (
D3DPT_TRIANGLESTRIP, 0, 0, // min index
Vertices , 0, // start index
Indices - 2 ) ; // number of primitives
// disable alpha blending
Device->SetRenderState ( D3DRS_ALPHABLENDENABLE, FALSE );
Device->SetRenderState( D3DRS_ALPHATESTENABLE, FALSE );
return hr ;
}