|
|

楼主 |
发表于 2005-4-14 18:20:00
|
显示全部楼层
Re: 高手来,读下PointSprites程序
class CMyD3DApplication : public CD3DApplication
{
CD3DFont* m_pFont;
CD3DFont* m_pFontSmall;
// Ground stuff
LPDIRECT3DTEXTURE9 m_pGroundTexture;
D3DXPLANE m_planeGround;
LPDIRECT3DVERTEXBUFFER9 m_pGroundVB;
LPDIRECT3DINDEXBUFFER9 m_pGroundIB;
DWORD m_dwNumGroundIndices;
DWORD m_dwNumGroundVertices;
// Particle stuff
LPDIRECT3DTEXTURE9 m_pParticleTexture;
CParticleSystem* m_pParticleSystem;
DWORD m_dwNumParticlesToEmit;
DWORD m_dwParticleColor;
BOOL m_bAnimateEmitter;
BYTE m_bKey[256];
BOOL m_bDrawReflection;
BOOL m_bCanDoAlphaBlend;
BOOL m_bDrawHelp;
// Variables for determining view position
D3DXVECTOR3 m_vPosition;
D3DXVECTOR3 m_vVelocity;
FLOAT m_fYaw;
FLOAT m_fYawVelocity;
FLOAT m_fPitch;
FLOAT m_fPitchVelocity;
D3DXMATRIXA16 m_matView;
D3DXMATRIXA16 m_matOrientation;
HRESULT ConfirmDevice( D3DCAPS9*, DWORD, D3DFORMAT, D3DFORMAT );
protected:
HRESULT OneTimeSceneInit();
HRESULT InitDeviceObjects();
HRESULT RestoreDeviceObjects();
HRESULT InvalidateDeviceObjects();
HRESULT DeleteDeviceObjects();
HRESULT Render();
HRESULT FrameMove();
HRESULT FinalCleanup();
VOID UpdateCamera();
public:
LRESULT MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
CMyD3DApplication();
};
//-----------------------------------------------------------------------------
// Name: WinMain()
// Desc: Entry point to the program. Initializes everything, and goes into a
// message-processing loop. Idle time is used to render the scene.
//-----------------------------------------------------------------------------
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT )
{
CMyD3DApplication d3dApp;
InitCommonControls();
if( FAILED( d3dApp.Create( hInst ) ) )
return 0;
return d3dApp.Run();
}
//-----------------------------------------------------------------------------
// Name: CMyD3DApplication()
// Desc: Application constructor. Sets attributes for the app.
//-----------------------------------------------------------------------------
CMyD3DApplication::CMyD3DApplication()
{
m_strWindowTitle = _T(" ointSprites: Using particle effects");
m_d3dEnumeration.AppUsesDepthBuffer = TRUE;
m_pFont = new CD3DFont( _T("Arial"), 12, D3DFONT_BOLD );
m_pFontSmall = new CD3DFont( _T("Arial"), 9, D3DFONT_BOLD );
m_pParticleSystem = new CParticleSystem( 512, 2048, 0.03f );
m_pParticleTexture = NULL;
m_dwNumParticlesToEmit = 10;
m_bAnimateEmitter = FALSE;
m_dwParticleColor = COLOR_WHITE;
m_pGroundTexture = NULL;
m_dwNumGroundVertices = (GROUND_GRIDSIZE + 1) * (GROUND_GRIDSIZE + 1);
m_dwNumGroundIndices = (GROUND_GRIDSIZE * GROUND_GRIDSIZE) * 6;
m_pGroundVB = NULL;
m_pGroundIB = NULL;
m_planeGround = D3DXPLANE( 0.0f, 1.0f, 0.0f, 0.0f );
m_bDrawReflection = FALSE;
m_bCanDoAlphaBlend = FALSE;
m_bDrawHelp = FALSE;
ZeroMemory( m_bKey, 256 );
m_vPosition = D3DXVECTOR3( 0.0f, 3.0f,-4.0f );
m_vVelocity = D3DXVECTOR3( 0.0f, 0.0f, 0.0f );
m_fYaw = 0.03f;
m_fYawVelocity = 0.0f;
m_fPitch = 0.5f;
m_fPitchVelocity = 0.0f;
D3DXMatrixTranslation( &m_matView, 0.0f, 0.0f, 10.0f );
D3DXMatrixTranslation( &m_matOrientation, 0.0f, 0.0f, 0.0f );
}
//-----------------------------------------------------------------------------
// Name: OneTimeSceneInit()
// Desc: Called during initial app startup, this function performs all the
// permanent initialization.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::OneTimeSceneInit()
{
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: FrameMove()
// Desc: Called once per frame, the call is the entry point for animating
// the scene.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::FrameMove()
{
// Slow things down for the REF device
if( m_d3dCaps.DeviceType == D3DDEVTYPE_REF )
m_fElapsedTime = 0.05f;
// Determine emitter position
D3DXVECTOR3 vEmitterPostion( 0.0f, 0.0f, 0.f );
if( m_bAnimateEmitter )
vEmitterPostion = D3DXVECTOR3( 3*sinf(m_fTime), 0.0f, 3*cosf(m_fTime) );
// Update particle system
m_pParticleSystem->Update( m_fElapsedTime, m_dwNumParticlesToEmit,
g_clrColor[m_dwParticleColor],
g_clrColorFade[m_dwParticleColor], 8.0f,
vEmitterPostion );
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: Render()
// Desc: Called once per frame, the call is the entry point for 3d
// rendering. This function sets up render states, clears the
// viewport, and renders the scene.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::Render()
{
// Update the camera here rather than in FrameMove() so you can
// move the camera even when the scene is paused
UpdateCamera();
if( FAILED( m_pd3dDevice->BeginScene() ) )
return S_OK;
// Clear the viewport
m_pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
0x00000000, 1.0f, 0L );
// Draw reflection of particles
if( m_bDrawReflection )
{
D3DXMATRIXA16 matReflectedView;
D3DXMatrixReflect( &matReflectedView, &m_planeGround );
D3DXMatrixMultiply( &matReflectedView, &matReflectedView, &m_matView );
m_pd3dDevice->SetRenderState( D3DRS_ZWRITEENABLE, FALSE );
m_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
m_pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ONE );
m_pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE );
m_pd3dDevice->SetTransform( D3DTS_VIEW, &matReflectedView );
m_pd3dDevice->SetTexture( 0, m_pParticleTexture );
m_pParticleSystem->Render( m_pd3dDevice );
m_pd3dDevice->SetRenderState( D3DRS_ZWRITEENABLE, TRUE );
m_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
}
// Draw the ground
if( m_bDrawReflection )
{
m_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
m_pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
m_pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
}
m_pd3dDevice->SetTransform( D3DTS_VIEW, &m_matView );
m_pd3dDevice->SetTexture( 0, m_pGroundTexture );
m_pd3dDevice->SetFVF( COLORVERTEX::FVF );
m_pd3dDevice->SetStreamSource( 0, m_pGroundVB, 0, sizeof(COLORVERTEX) );
m_pd3dDevice->SetIndices( m_pGroundIB );
m_pd3dDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 0, m_dwNumGroundVertices, 0, m_dwNumGroundIndices/3 );
// Draw particles
m_pd3dDevice->SetRenderState( D3DRS_ZWRITEENABLE, FALSE );
m_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
m_pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ONE );
m_pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE );
m_pd3dDevice->SetTexture(0, m_pParticleTexture );
m_pParticleSystem->Render( m_pd3dDevice );
m_pd3dDevice->SetRenderState( D3DRS_ZWRITEENABLE, TRUE );
m_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
// Output statistics
m_pFont->DrawText( 2, 0, D3DCOLOR_ARGB(255,255,255,0), m_strFrameStats );
m_pFont->DrawText( 2, 20, D3DCOLOR_ARGB(255,255,255,0), m_strDeviceStats );
// Draw help
if( m_bDrawHelp )
{
m_pFontSmall->DrawText( 2, 40, 0xffffffff,
_T("Keyboard controls:") );
m_pFontSmall->DrawText( 20, 60, 0xffffffff,
_T("Move\nTurn\nPitch\nSlide\n\nHelp\n"
"Change device\nAnimate emitter\n"
"Change color\n\nToggle reflection\n"
"Exit") );
m_pFontSmall->DrawText( 160, 60, 0xffffffff,
_T("W,S\nE,Q\nA,Z\nArrow keys\n\n"
"F1\nF2\nF3\nF4\n\nR\nEsc") );
}
else
m_pFontSmall->DrawText( 2, 40, 0xffffffff,
_T("Press F1 for help") );
// End the scene.
m_pd3dDevice->EndScene();
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: UpdateCamera()
// Desc:
//-----------------------------------------------------------------------------
VOID CMyD3DApplication::UpdateCamera()
{
FLOAT fElapsedTime;
if( m_fElapsedTime > 0.0f )
fElapsedTime = m_fElapsedTime;
else
fElapsedTime = 0.05f;
FLOAT fSpeed = 3.0f*fElapsedTime;
FLOAT fAngularSpeed = 1.0f*fElapsedTime;
// De-accelerate the camera movement (for smooth motion)
m_vVelocity *= 0.9f;
m_fYawVelocity *= 0.9f;
m_fPitchVelocity *= 0.9f;
// Process keyboard input
if( m_bKey[VK_RIGHT] ) m_vVelocity.x += fSpeed; // Slide Right
if( m_bKey[VK_LEFT] ) m_vVelocity.x -= fSpeed; // Slide Left
if( m_bKey[VK_UP] ) m_vVelocity.y += fSpeed; // Slide Up
if( m_bKey[VK_DOWN] ) m_vVelocity.y -= fSpeed; // Slide Down
if( m_bKey['W'] ) m_vVelocity.z += fSpeed; // Move Forward
if( m_bKey['S'] ) m_vVelocity.z -= fSpeed; // Move Backward
if( m_bKey['E'] ) m_fYawVelocity += fSpeed; // Turn Right
if( m_bKey['Q'] ) m_fYawVelocity -= fSpeed; // Turn Left
if( m_bKey['Z'] ) m_fPitchVelocity += fSpeed; // Turn Down
if( m_bKey['A'] ) m_fPitchVelocity -= fSpeed; // Turn Up
if( m_bKey[VK_ADD] ) if( m_dwNumParticlesToEmit < 10 ) m_dwNumParticlesToEmit++;
if( m_bKey[VK_SUBTRACT] ) if( m_dwNumParticlesToEmit > 0 ) m_dwNumParticlesToEmit--;
// Update the position vector
D3DXVECTOR3 vT = m_vVelocity * fSpeed;
D3DXVec3TransformNormal( &vT, &vT, &m_matOrientation );
m_vPosition += vT;
if( m_vPosition.y < 1.0f )
m_vPosition.y = 1.0f;
// Update the yaw-pitch-rotation vector
m_fYaw += fAngularSpeed * m_fYawVelocity;
m_fPitch += fAngularSpeed * m_fPitchVelocity;
if( m_fPitch < 0.0f ) m_fPitch = 0.0f;
if( m_fPitch > D3DX_PI/2 ) m_fPitch = D3DX_PI/2;
// Set the view matrix
D3DXQUATERNION qR;
D3DXQuaternionRotationYawPitchRoll( &qR, m_fYaw, m_fPitch, 0.0f );
D3DXMatrixAffineTransformation( &m_matOrientation, 1.25f, NULL, &qR, &m_vPosition );
D3DXMatrixInverse( &m_matView, NULL, &m_matOrientation );
}
//-----------------------------------------------------------------------------
// Name: InitDeviceObjects()
// Desc: Initialize scene objects.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::InitDeviceObjects()
{
HRESULT hr;
// Create textures
if( FAILED( D3DUtil_CreateTexture( m_pd3dDevice, _T("Ground2.bmp"),
&m_pGroundTexture ) ) )
return D3DAPPERR_MEDIANOTFOUND;
if( FAILED( D3DUtil_CreateTexture( m_pd3dDevice, _T("Particle.bmp"),
&m_pParticleTexture ) ) )
return D3DAPPERR_MEDIANOTFOUND;
// Set up the fonts and textures
m_pFont->InitDeviceObjects( m_pd3dDevice );
m_pFontSmall->InitDeviceObjects( m_pd3dDevice );
// Check if we can do the reflection effect
m_bCanDoAlphaBlend = (m_d3dCaps.SrcBlendCaps & D3DPBLENDCAPS_SRCALPHA) &&
(m_d3dCaps.DestBlendCaps & D3DPBLENDCAPS_INVSRCALPHA);
if( m_bCanDoAlphaBlend )
m_bDrawReflection = TRUE;
// Create ground object
{
// Create vertex buffer for ground object
hr = m_pd3dDevice->CreateVertexBuffer( m_dwNumGroundVertices*sizeof(COLORVERTEX),
D3DUSAGE_WRITEONLY, COLORVERTEX::FVF,
D3DPOOL_MANAGED, &m_pGroundVB, NULL );
if( FAILED(hr) )
return E_FAIL;
// Fill vertex buffer
COLORVERTEX* pVertices;
if( FAILED( m_pGroundVB->Lock( 0, 0, (void**)&pVertices, NULL ) ) )
return hr;
// Fill in vertices
for( DWORD zz = 0; zz <= GROUND_GRIDSIZE; zz++ )
{
for( DWORD xx = 0; xx <= GROUND_GRIDSIZE; xx++ )
{
pVertices->v.x = GROUND_WIDTH * (xx/(FLOAT)GROUND_GRIDSIZE-0.5f);
pVertices->v.y = 0.0f;
pVertices->v.z = GROUND_HEIGHT * (zz/(FLOAT)GROUND_GRIDSIZE-0.5f);
pVertices->color = GROUND_COLOR;
pVertices->tu = xx*GROUND_TILE/(FLOAT)GROUND_GRIDSIZE;
pVertices->tv = zz*GROUND_TILE/(FLOAT)GROUND_GRIDSIZE;
pVertices++;
}
}
m_pGroundVB->Unlock();
// Create the index buffer
WORD* pIndices;
hr = m_pd3dDevice->CreateIndexBuffer( m_dwNumGroundIndices*sizeof(WORD),
D3DUSAGE_WRITEONLY,
D3DFMT_INDEX16, D3DPOOL_MANAGED,
&m_pGroundIB, NULL );
if( FAILED(hr) )
return E_FAIL;
// Fill the index buffer
m_pGroundIB->Lock( 0, 0, (void**)&pIndices, 0 );
if( FAILED(hr) )
return E_FAIL;
// Fill in indices
for( DWORD z = 0; z < GROUND_GRIDSIZE; z++ )
{
for( DWORD x = 0; x < GROUND_GRIDSIZE; x++ )
{
DWORD vtx = x + z * (GROUND_GRIDSIZE+1);
*pIndices++ = (WORD)( vtx + 1 );
*pIndices++ = (WORD)( vtx + 0 );
*pIndices++ = (WORD)( vtx + 0 + (GROUND_GRIDSIZE+1) );
*pIndices++ = (WORD)( vtx + 1 );
*pIndices++ = (WORD)( vtx + 0 + (GROUND_GRIDSIZE+1) );
*pIndices++ = (WORD)( vtx + 1 + (GROUND_GRIDSIZE+1) );
}
}
m_pGroundIB->Unlock();
}
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: RestoreDeviceObjects()
// Desc:
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::RestoreDeviceObjects()
{
HRESULT hr;
m_pFont->RestoreDeviceObjects();
m_pFontSmall->RestoreDeviceObjects();
// Set the world matrix
D3DXMATRIXA16 matWorld;
D3DXMatrixIdentity( &matWorld );
m_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
// Set projection matrix
D3DXMATRIXA16 matProj;
FLOAT fAspect = ((FLOAT)m_d3dsdBackBuffer.Width) / m_d3dsdBackBuffer.Height;
D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, fAspect, 0.1f, 100.0f );
m_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );
m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );
m_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_DISABLE );
m_pd3dDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
m_pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ONE );
m_pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE );
m_pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
m_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW );
m_pd3dDevice->SetRenderState( D3DRS_SHADEMODE, D3DSHADE_FLAT );
// Initialize the particle system
if( FAILED( hr = m_pParticleSystem->RestoreDeviceObjects( m_pd3dDevice ) ) )
return hr;
return S_OK;
}
|
|