|
楼主 |
发表于 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;
- }
复制代码
下雪的粒子效果 |
|