📄 dx9_particle_system.cpp
字号:
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = d3ddm.Format;
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, g_hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp, &g_pd3dDevice );
D3DXMATRIX matView;
D3DXMatrixLookAtLH( &matView, &D3DXVECTOR3(0.0f, 0.0f,-10.0f),
&D3DXVECTOR3(0.0f, 0.0f, 0.0f),
&D3DXVECTOR3(0.0f, 1.0f, 0.0f ) );
g_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );
D3DXMATRIX matProj;
D3DXMatrixPerspectiveFovLH( &matProj, D3DXToRadian( 45.0f ), 1.0f, 1.0f, 200.0f );
g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );
g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
//
// Create the floor geometry...
//
loadTexture();
g_pd3dDevice->CreateVertexBuffer( 4*sizeof(Vertex), D3DUSAGE_WRITEONLY,
Vertex::FVF_Flags, D3DPOOL_DEFAULT,
&g_pVertexBuffer, NULL );
void *pVertices;
g_pVertexBuffer->Lock( 0, sizeof(g_floorVertices), (void**)&pVertices, 0 );
memcpy( pVertices, g_floorVertices, sizeof(g_floorVertices) );
g_pVertexBuffer->Unlock();
}
//-----------------------------------------------------------------------------
// Name: shutDown()
// Desc:
//-----------------------------------------------------------------------------
void shutDown( void )
{
for( int i = 0; i < 6; ++i )
{
if( g_pParticleSystems[i] != NULL )
{
delete g_pParticleSystems[i];
g_pParticleSystems[i] = NULL;
}
}
if( g_pVertexBuffer != NULL )
g_pVertexBuffer->Release();
if( g_pTexture != NULL )
g_pTexture->Release();
if( g_pd3dDevice != NULL )
g_pd3dDevice->Release();
if( g_pD3D != NULL )
g_pD3D->Release();
}
//-----------------------------------------------------------------------------
// Name: initParticles()
// Desc:
//-----------------------------------------------------------------------------
HRESULT initParticles( void )
{
//
// Exploding burst
//
g_pParticleSystems[0] = new CParticleSystem();
g_pParticleSystems[0]->SetTexture( "particle.bmp" );
g_pParticleSystems[0]->SetMaxParticles( 100 );
g_pParticleSystems[0]->SetNumToRelease( 100 );
g_pParticleSystems[0]->SetReleaseInterval( 0.05f );
g_pParticleSystems[0]->SetLifeCycle( 0.5f );
g_pParticleSystems[0]->SetSize( 1.0f );
g_pParticleSystems[0]->SetColor( D3DXCOLOR( 1.0f, 0.0f, 0.0f, 1.0f ));
g_pParticleSystems[0]->SetPosition( D3DXVECTOR3( 0.0f, 5.0f, 0.0f) );
g_pParticleSystems[0]->SetVelocity( D3DXVECTOR3( 0.0f, 0.0f, 0.0f) );
g_pParticleSystems[0]->SetGravity( D3DXVECTOR3( 0.0f, 0.0f, 0.0f) );
g_pParticleSystems[0]->SetWind( D3DXVECTOR3( 0.0f, 0.0f, 0.0f) );
g_pParticleSystems[0]->SetVelocityVar( 10.0f );
g_pParticleSystems[0]->Init( g_pd3dDevice );
//
// Wind blown fountain
//
g_pParticleSystems[1] = new CParticleSystem();
g_pParticleSystems[1]->SetTexture( "particle.bmp" );
g_pParticleSystems[1]->SetMaxParticles( 500 );
g_pParticleSystems[1]->SetNumToRelease( 5 );
g_pParticleSystems[1]->SetReleaseInterval( 0.05f );
g_pParticleSystems[1]->SetLifeCycle( 4.0f );
g_pParticleSystems[1]->SetSize( 0.5f );
g_pParticleSystems[1]->SetColor( D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f ));
g_pParticleSystems[1]->SetPosition( D3DXVECTOR3( 0.0f, 0.0f, 0.0f ) );
g_pParticleSystems[1]->SetVelocity( D3DXVECTOR3( 0.0f, 5.0f, 0.0f ) );
g_pParticleSystems[1]->SetGravity( D3DXVECTOR3( 0.0f, 0.0f, 0.0f ) );
g_pParticleSystems[1]->SetWind( D3DXVECTOR3( 2.0f, 0.0f, 0.0f ) );
g_pParticleSystems[1]->SetVelocityVar( 1.5f );
g_pParticleSystems[1]->Init( g_pd3dDevice );
//
// Omni-directiional emission expanding into space with no air resistence
//
g_pParticleSystems[2] = new CParticleSystem();
g_pParticleSystems[2]->SetTexture( "particle.bmp" );
g_pParticleSystems[2]->SetMaxParticles( 2048 );
g_pParticleSystems[2]->SetNumToRelease( 10 );
g_pParticleSystems[2]->SetReleaseInterval( 0.05f );
g_pParticleSystems[2]->SetLifeCycle( 5.0f );
g_pParticleSystems[2]->SetSize( 0.5f );
g_pParticleSystems[2]->SetColor( D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f ));
g_pParticleSystems[2]->SetPosition( D3DXVECTOR3( 0.0f, 0.0f, 0.0f) );
g_pParticleSystems[2]->SetVelocity( D3DXVECTOR3( 0.0f, 0.0f, 0.0f) );
g_pParticleSystems[2]->SetGravity( D3DXVECTOR3( 0.0f, 0.0f, 0.0f) );
g_pParticleSystems[2]->SetWind( D3DXVECTOR3( 0.0f, 0.0f, 0.0f) );
g_pParticleSystems[2]->SetAirResistence( false );
g_pParticleSystems[2]->SetVelocityVar(2.0f);
g_pParticleSystems[2]->Init( g_pd3dDevice );
//
// Fountain particles behave like paint spots when striking a plane as
// the wind blowing them towards us
//
g_pParticleSystems[3] = new CParticleSystem();
g_pParticleSystems[3]->SetTexture( "particle.bmp" );
g_pParticleSystems[3]->SetMaxParticles( 100 );
g_pParticleSystems[3]->SetNumToRelease( 10 );
g_pParticleSystems[3]->SetReleaseInterval( 0.05f );
g_pParticleSystems[3]->SetLifeCycle( 3.0f );
g_pParticleSystems[3]->SetSize( 0.5f );
g_pParticleSystems[3]->SetColor( D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f ));
g_pParticleSystems[3]->SetPosition( D3DXVECTOR3( 0.0f, 0.0f, 0.0f ) );
g_pParticleSystems[3]->SetVelocity( D3DXVECTOR3( 0.0f, 5.0f, 0.0f ) );
g_pParticleSystems[3]->SetGravity( D3DXVECTOR3( 0.0f, 0.0f, 0.0f ) );
g_pParticleSystems[3]->SetWind( D3DXVECTOR3( 0.0f, 0.0f, -20.0f ) );
g_pParticleSystems[3]->SetVelocityVar( 2.5f );
g_pParticleSystems[3]->SetCollisionPlane( D3DXVECTOR3( 0.0f, 0.0f,1.0f ),
D3DXVECTOR3( 0.0f, 0.0f, -5.0f ),
1.0f, CR_STICK );
g_pParticleSystems[3]->Init( g_pd3dDevice );
//
// Fountain using a single collision plane acting as a floor
//
g_pParticleSystems[4] = new CParticleSystem();
g_pParticleSystems[4]->SetTexture( "particle.bmp" );
g_pParticleSystems[4]->SetMaxParticles( 200 );
g_pParticleSystems[4]->SetNumToRelease( 10 );
g_pParticleSystems[4]->SetReleaseInterval( 0.05f );
g_pParticleSystems[4]->SetLifeCycle( 5.0f );
g_pParticleSystems[4]->SetSize( 1.5f );
g_pParticleSystems[4]->SetColor( D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f ));
g_pParticleSystems[4]->SetPosition( D3DXVECTOR3( 0.0f, 0.0f, 0.0f ) );
g_pParticleSystems[4]->SetVelocity( D3DXVECTOR3( 0.0f, 0.0f, 0.0f ) );
g_pParticleSystems[4]->SetGravity( D3DXVECTOR3( 0.0f, -9.8f, 0.0f ) );
g_pParticleSystems[4]->SetWind( D3DXVECTOR3( 0.0f, 0.0f, 0.0f ) );
g_pParticleSystems[4]->SetVelocityVar( 20.0f );
g_pParticleSystems[4]->SetCollisionPlane( D3DXVECTOR3( 0.0f, 1.0f, 0.0f ),
D3DXVECTOR3( 0.0f, 0.0f, 0.0f ) );
g_pParticleSystems[4]->Init( g_pd3dDevice );
//
// Fountain boxed-in by 6 collision planes
//
g_pParticleSystems[5] = new CParticleSystem();
g_pParticleSystems[5]->SetTexture( "particle.bmp" );
g_pParticleSystems[5]->SetMaxParticles( 100 );
g_pParticleSystems[5]->SetNumToRelease( 5 );
g_pParticleSystems[5]->SetReleaseInterval( 0.05f );
g_pParticleSystems[5]->SetLifeCycle( 5.0f );
g_pParticleSystems[5]->SetSize( 1.5f );
g_pParticleSystems[5]->SetColor( D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f ));
g_pParticleSystems[5]->SetPosition( D3DXVECTOR3( 0.0f, 0.0f, 0.0f ) );
g_pParticleSystems[5]->SetVelocity( D3DXVECTOR3( 0.0f, 0.0f, 0.0f ) );
g_pParticleSystems[5]->SetGravity( D3DXVECTOR3( 0.0f, -9.8f, 0.0f ) );
g_pParticleSystems[5]->SetWind( D3DXVECTOR3( 0.0f, 0.0f, 0.0f ) );
g_pParticleSystems[5]->SetVelocityVar( 20.0f );
// Create a series of planes to collide with
g_pParticleSystems[5]->SetCollisionPlane( D3DXVECTOR3( 0.0f, 1.0f, 0.0f ),
D3DXVECTOR3( 0.0f, 0.0f, 0.0f ) ); // Floor
g_pParticleSystems[5]->SetCollisionPlane( D3DXVECTOR3( 1.0f, 0.0f, 0.0f ),
D3DXVECTOR3(-3.0f, 0.0f, 0.0f ) ); // Left Wall
g_pParticleSystems[5]->SetCollisionPlane( D3DXVECTOR3(-1.0f, 0.0f, 0.0f ),
D3DXVECTOR3( 3.0f, 0.0f, 0.0f ) ); // Right Wall
g_pParticleSystems[5]->SetCollisionPlane( D3DXVECTOR3( 0.0f, 0.0f, 1.0f ),
D3DXVECTOR3( 0.0f, 0.0f,-3.0f ) ); // Front Wall
g_pParticleSystems[5]->SetCollisionPlane( D3DXVECTOR3( 0.0f, 0.0f,-1.0f ),
D3DXVECTOR3( 0.0f, 0.0f, 3.0f ) ); // Back Wall
g_pParticleSystems[5]->SetCollisionPlane( D3DXVECTOR3( 0.0f,-1.0f, 0.0f ),
D3DXVECTOR3( 0.0f, 5.0f, 0.0f ) ); // Ceiling
g_pParticleSystems[5]->Init( g_pd3dDevice );
return S_OK;
}
//-----------------------------------------------------------------------------
// Name : updateViewMatrix()
// Desc : Builds a view matrix suitable for Direct3D.
//
// Here's what the final matrix should look like:
//
// | rx ux lx 0 |
// | ry uy ly 0 |
// | rz uz lz 0 |
// | -(r.e) -(u.e) -(l.e) 1 |
//
// Where r = Right vector
// u = Up vector
// l = Look vector
// e = Eye position in world space
// . = Dot-product operation
//
//-----------------------------------------------------------------------------
void updateViewMatrix( void )
{
D3DXMATRIX view;
D3DXMatrixIdentity( &view );
D3DXVec3Normalize( &g_vLook, &g_vLook );
D3DXVec3Cross( &g_vRight, &g_vUp, &g_vLook );
D3DXVec3Normalize( &g_vRight, &g_vRight );
D3DXVec3Cross( &g_vUp, &g_vLook, &g_vRight );
D3DXVec3Normalize( &g_vUp, &g_vUp );
view._11 = g_vRight.x;
view._12 = g_vUp.x;
view._13 = g_vLook.x;
view._14 = 0.0f;
view._21 = g_vRight.y;
view._22 = g_vUp.y;
view._23 = g_vLook.y;
view._24 = 0.0f;
view._31 = g_vRight.z;
view._32 = g_vUp.z;
view._33 = g_vLook.z;
view._34 = 0.0f;
view._41 = -D3DXVec3Dot( &g_vEye, &g_vRight );
view._42 = -D3DXVec3Dot( &g_vEye, &g_vUp );
view._43 = -D3DXVec3Dot( &g_vEye, &g_vLook );
view._44 = 1.0f;
g_pd3dDevice->SetTransform( D3DTS_VIEW, &view );
}
//-----------------------------------------------------------------------------
// Name: render()
// Desc:
//-----------------------------------------------------------------------------
void render( void )
{
g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
D3DCOLOR_COLORVALUE(0.0f, 0.0f, 0.0, 1.0f), 1.0f, 0 );
getRealTimeUserInput();
updateViewMatrix();
//
// The particle system will need to know how much time has passed since
// the last time it was updated, so we'll need to keep track of how much
// time has elapsed since the last frame update...
//
g_pParticleSystems[g_nActiveSystem]->Update( (float)g_fElpasedTime );
g_pd3dDevice->BeginScene();
//
// Render the floor...
//
//g_pd3dDevice->SetTexture( 0, g_pTexture );
//g_pd3dDevice->SetStreamSource( 0, g_pVertexBuffer, 0, sizeof(Vertex) );
//g_pd3dDevice->SetFVF( Vertex::FVF_Flags );
//g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2);
//
// Prepare to render particle system
//
//
// Setting D3DRS_ZWRITEENABLE to FALSE makes the Z-Buffer read-only, which
// helps remove graphical artifacts generated from rendering a list of
// particles that haven't been sorted by distance to the eye.
//
// Setting D3DRS_ALPHABLENDENABLE to TRUE allows particles, which overlap,
// to alpha blend with each other correctly.
//
g_pd3dDevice->SetRenderState( D3DRS_ZWRITEENABLE, FALSE );
g_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
g_pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE );
//
// Render particle system
//
g_pd3dDevice->SetTexture( 0, g_pParticleSystems[g_nActiveSystem]->GetTextureObject() );
g_pParticleSystems[g_nActiveSystem]->Render( g_pd3dDevice );
//
// Reset render states...
//
g_pd3dDevice->SetRenderState( D3DRS_ZWRITEENABLE, TRUE );
g_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
g_pd3dDevice->EndScene();
g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -