| 
 | 
 
 
 楼主 |
发表于 2006-9-27 17:53:51
|
显示全部楼层
 
 
 
【实例4-1】简单粒子——雪
  下面是CSnowParticles类的完整实现。
CSnowParticles类头文件- //=============================================================================
 - //Desc: CSnowParticles.h
 - //=============================================================================
 - #pragma once
 - #include "d3dx9.h"
 - #include "Utility.h"
 - #define  PARTICLENUM_SNOW  1000
 - //顶点结构
 - struct CUSTOMVERTEX_SNOW
 - {
 -     float x, y, z;        
 -     float u, v;
 - };
 - #define D3DFVF_CUSTOMEVERTEX_SNOW (D3DFVF_XYZ|D3DFVF_TEX1)
 - //雪花粒子结构
 - struct SnowParticle
 - {
 -     float x, y, z;        //位置
 -     float fYaw;        //绕自身Y轴旋转角度
 -     float fPitch;        //绕自身X轴旋转角度
 -     float Dspeed;       //下降速度
 -     float Rspeed;       //旋转速度
 -     int   TexIndex;    //纹理
 - };
 - class CSnowParticles
 - {
 - public:
 -     CSnowParticles(void);
 -     ~CSnowParticles(void);
 -     HRESULT Init( LPDIRECT3DDEVICE9 pd3dDevice );
 -     void Update( float fElapsedTime );
 -     void Render( LPDIRECT3DDEVICE9 pd3dDevice );
 - private:
 - protected:
 -     LPDIRECT3DVERTEXBUFFER9    m_pSnowVB;        //粒子顶点缓冲区
 -     D3DXMATRIX                   m_matSnow;        //粒子世界矩阵
 -     LPDIRECT3DTEXTURE9          m_pSnowTex[3];    //粒子纹理
 -     SnowParticle                     snow[PARTICLENUM_SNOW];  //雪花粒子数组
 - };
 
  复制代码- CSnowParticles类源文件
 - //=============================================================================
 - //Desc: CSnowParticles.cpp
 - //=============================================================================
 - #include ".\snowparticles.h"
 - CSnowParticles::CSnowParticles(void)
 - {
 - }
 - CSnowParticles::~CSnowParticles(void)
 - {
 -     SAFE_RELEASE(m_pSnowVB);
 -     for(int i=0;i<3; i++)
 -         SAFE_RELEASE(m_pSnowTex[i]);
 - }
 - //粒子数据的初始化
 - HRESULT CSnowParticles::Init( LPDIRECT3DDEVICE9 pd3dDevice )
 - {
 -     //创建雪花粒子顶点缓冲区
 -     if( FAILED(  pd3dDevice->CreateVertexBuffer( 4*sizeof(CUSTOMVERTEX_SNOW),
 -         0, D3DFVF_CUSTOMEVERTEX_SNOW,
 -         D3DPOOL_DEFAULT, &m_pSnowVB, NULL ) ) )
 -     {
 -         return E_FAIL;
 -     }
 -     //填充雪花粒子顶点缓冲区
 -     CUSTOMVERTEX_SNOW vertices2[] =
 -     {
 -         { -1, 0, 0,   0.0f, 1.0f, },
 -         { -1, 2, 0,   0.0f, 0.0f, },
 -         {  1, 0, 0,   1.0f, 1.0f, }, 
 -         {  1, 2, 0,   1.0f, 0.0f, }
 -     };
 -     VOID* pVertices2;
 -     if( FAILED( m_pSnowVB->Lock( 0, sizeof(vertices2), (void**)&pVertices2, 0 ) ) ) 
 - return E_FAIL;
 -     memcpy( pVertices2, vertices2, sizeof(vertices2) );
 -     m_pSnowVB->Unlock();
 -     //创建雪花纹理
 -     if( FAILED( D3DXCreateTextureFromFile( pd3dDevice, "snow1.png", &m_pSnowTex[0] )))
 -   return E_FAIL;
 -     if( FAILED( D3DXCreateTextureFromFile( pd3dDevice, "snow2.png", &m_pSnowTex[1] ))) 
 - return E_FAIL;
 -     if( FAILED( D3DXCreateTextureFromFile( pd3dDevice, "snow3.png", &m_pSnowTex[2] ))) 
 - return E_FAIL;
 -     //初始化雪花粒子数组
 -     srand(GetTickCount());
 -     for(int i=0; i<PARTICLENUM_SNOW; i++)
 -     {    
 -         snow[i].x        = float(rand()%200-100);
 -         snow[i].z        = float(rand()%200-100);
 -         snow[i].y        = float(rand()%250);
 -         snow[i].fYaw     = (rand()%100)/50.0f*D3DX_PI;
 -         snow[i].fPitch   = (rand()%100)/50.0f*D3DX_PI;
 -         snow[i].Dspeed   = 20.0f + rand()%10;
 -         snow[i].Rspeed   = 1.0f +  rand()%10/10.0f;
 -         snow[i].TexIndex = rand()%3;    //随即获取雪花粒子纹理
 -     }
 -     return S_OK;
 - }
 - //粒子的数据更新
 - void CSnowParticles::Update( float fElapsedTime )
 - {
 -     //更新每个雪花粒子的当前位置和角度
 -     for(int i=0; i<PARTICLENUM_SNOW; i++)
 -     {
 -         snow[i].y -= snow[i].Dspeed*fElapsedTime;
 -         if(snow[i].y<-100)
 -             snow[i].y = 150.0f;
 -         snow[i].fYaw    += snow[i].Rspeed * fElapsedTime;
 -         snow[i].fPitch  += snow[i].Rspeed * fElapsedTime;
 -     }
 - }
 - //粒子的渲染
 - void CSnowParticles::Render( LPDIRECT3DDEVICE9 pd3dDevice )
 - {
 -     //设置Alpha混合系数
 -     pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
 -     pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
 -     //禁用照明效果
 -     pd3dDevice->SetRenderState( D3DRS_LIGHTING, false );
 -     //渲染所有雪花
 -     for(int i=0; i<PARTICLENUM_SNOW; i++)
 -     {
 -         //构造并设置当前雪花粒子的世界矩阵
 -         static D3DXMATRIX matYaw, matPitch, matTrans;
 -         D3DXMatrixRotationY(&matYaw, snow[i].fYaw);
 -         D3DXMatrixRotationX(&matPitch, snow[i].fPitch);
 -         D3DXMatrixTranslation(&matTrans, snow[i].x, snow[i].y, snow[i].z);
 -         m_matSnow = matYaw * matPitch * matTrans;
 -         pd3dDevice->SetTransform( D3DTS_WORLD,  &m_matSnow);
 -         //渲染当前雪花粒子
 -         pd3dDevice->SetTexture( 0, m_pSnowTex[snow[i].TexIndex] ); 
 -         pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
 -         pd3dDevice->SetStreamSource(0, m_pSnowVB, 0, sizeof(CUSTOMVERTEX_SNOW));
 -         pd3dDevice->SetFVF(D3DFVF_CUSTOMEVERTEX_SNOW);
 -         pd3dDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
 -         pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, false);
 -     }
 - }
 
  复制代码 项目主文件
  下面是调用这个类的主文件:- //=============================================================================
 - //Desc: 雪花粒子效果主文件
 - //=============================================================================
 - #include <Windows.h>
 - #include <mmsystem.h>
 - #include <d3dx9.h>
 - #include <strsafe.h>
 - #include "SnowParticles.h"
 - //-----------------------------------------------------------------------------
 - //全局变量
 - //-----------------------------------------------------------------------------
 - LPDIRECT3D9                 g_pD3D       = NULL; //D3D接口
 - LPDIRECT3DDEVICE9          g_pd3dDevice  = NULL; //D3D设备
 - CSnowParticles*                g_pSnowParticles = NULL; //雪花类指针
 - //-----------------------------------------------------------------------------
 - //Name: InitD3D()
 - //Desc: 初始化D3D环境
 - //-----------------------------------------------------------------------------
 - HRESULT InitD3D( HWND hWnd )
 - {
 -     //创建D3D对象
 -     if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
 -         return E_FAIL;
 -     //初始化D3D设备数据结构
 -     D3DPRESENT_PARAMETERS d3dpp;
 -     ZeroMemory( &d3dpp, sizeof(d3dpp) );
 -     d3dpp.Windowed = TRUE;
 -     d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
 -     d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
 -     //创建D3D设备
 -     if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
 -         D3DCREATE_SOFTWARE_VERTEXPROCESSING,
 -         &d3dpp, &g_pd3dDevice ) ) )
 -     {
 -         return E_FAIL;
 -     }
 -     g_pSnowParticles = new CSnowParticles;
 -     g_pSnowParticles->Init(g_pd3dDevice);
 -     //渲染状态双面可见
 -     g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
 -     //渲染状态 关闭灯光
 -     g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
 -     return S_OK;
 - }
 - //-----------------------------------------------------------------------------
 - //Name: Cleanup()
 - //Desc: 释放所有申请的资源
 - //-----------------------------------------------------------------------------
 - VOID Cleanup()
 - {
 -     delete g_pSnowParticles;
 -     if( g_pd3dDevice != NULL )
 -         g_pd3dDevice->Release();
 -     if( g_pD3D != NULL )
 -         g_pD3D->Release();
 - }
 - //-----------------------------------------------------------------------------
 - //Name: SetupMatrices()
 - //Desc: 设置世界矩阵,视角变换矩阵和投影变换矩阵
 - //-----------------------------------------------------------------------------
 - VOID SetupMatrices()
 - {
 -     D3DXVECTOR3 vEyePt( 0.0f,1.0f,-5.0f );   //摄像机位置
 -     D3DXVECTOR3 vLookatPt( 1.0f, 0.0f, 0.0f ); //观察点位置,前进后退,向左向右,向上向下
 -     D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f );  //摄像机正方向(本地坐标系)
 -     D3DXMATRIXA16 matView;
 -     D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec );
 -     g_pd3dDevice->SetTransform( D3DTS_VIEW, &matView ) ;
 -     D3DXMATRIXA16 matProj; 
 - //它说明物体如何随着距离而缩小,参数定义了屏幕纵横比第四和第五个参数定义最近和最远剪切平面
 -     D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, 1.0f, 1.0f, 100.0f ); 
 -     g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );
 - }
 - //-----------------------------------------------------------------------------
 - //Name: Render()
 - //Desc: 渲染
 - //-----------------------------------------------------------------------------
 - VOID Render()
 - {
 -     //清屏
 -     g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,0), 1.0f, 0 );
 -     static float fPreTime = static_cast<float>(timeGetTime());
 -     float fCurrentTime = static_cast<float>(timeGetTime());
 -     float fElapsedTime = (fCurrentTime - fPreTime)*0.001f;
 -     g_pSnowParticles->Update(fElapsedTime);
 -     fPreTime = fCurrentTime;
 -     //开始渲染
 -     if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
 -     {
 -         //矩阵变换
 -         SetupMatrices();
 -         //渲染雪花
 -         g_pSnowParticles->Render(g_pd3dDevice);
 -         //渲染结束
 -         g_pd3dDevice->EndScene();
 -     }
 -     //翻转缓冲
 -     g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
 - }
 - //-----------------------------------------------------------------------------
 - //Name: MsgProc()
 - //Desc: 消息处理
 - //-----------------------------------------------------------------------------
 - LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
 - {
 -     switch( msg )
 -     {
 -     case WM_DESTROY:
 -         Cleanup();
 -         PostQuitMessage( 0 );
 -         return 0;
 -     }
 -     return DefWindowProc( hWnd, msg, wParam, lParam );
 - }
 - //-----------------------------------------------------------------------------
 - //Name: WinMain()
 - //Desc: Win32主程序
 - //-----------------------------------------------------------------------------
 - INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT )
 - {
 -     //注册窗口类
 -     WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L,
 -         GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
 -         "D3D Tutorial", NULL };
 -     RegisterClassEx( &wc );
 -     //创建窗口
 -     HWND hWnd = CreateWindow( "D3D Tutorial", "v5.0 粒子系统:雪花粒子效果",
 -         WS_OVERLAPPEDWINDOW, 100, 100, 400, 400,
 -         GetDesktopWindow(), NULL, wc.hInstance, NULL );
 -     //初始化 Direct3D
 -     if( SUCCEEDED( InitD3D( hWnd ) ) )
 -     {
 -     
 -             //显示窗口
 -             ShowWindow( hWnd, SW_SHOWDEFAULT );
 -             UpdateWindow( hWnd );
 -             //消息循环
 -             MSG msg;
 -             ZeroMemory( &msg, sizeof(msg) );
 -             while( msg.message!=WM_QUIT )
 -             {
 -                 if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
 -                 {
 -                     TranslateMessage( &msg );
 -                     DispatchMessage( &msg );
 -                 }
 -                 else
 -                     Render();    //渲染
 -             }
 -         
 -     }
 -     //注销窗口类
 -     UnregisterClass( "D3D Tutorial", wc.hInstance );
 -     return 0;
 - }
 
  复制代码 
 
下雪的粒子效果 |   
 
 
 
 |