粒子系统
SnowParticleClass.h
//============================================================================= // Name: SnowParticleClass.h // Des: 一个封装了雪花粒子系统系统的类的头文件 //============================================================================= #pragma once #include "D3DUtil.h" #define PARTICLE_NUMBER 15000 //雪花粒子数量,显卡不好、运行起来卡的童鞋请取小一点。 #define SNOW_SYSTEM_LENGTH_X 20000 //雪花飞扬区域的长度 #define SNOW_SYSTEM_WIDTH_Z 20000 //雪花飞扬区域的宽度 #define SNOW_SYSTEM_HEIGHT_Y 20000 //雪花飞扬区域的高度 //------------------------------------------------------------------------------------------------- //雪花粒子的FVF顶点结构和顶点格式 //------------------------------------------------------------------------------------------------- struct POINTVERTEX { float x, y, z; //顶点位置 float u,v ; //顶点纹理坐标 }; #define D3DFVF_POINTVERTEX (D3DFVF_XYZ|D3DFVF_TEX1) //------------------------------------------------------------------------------------------------- // Desc: 雪花粒子结构体的定义 //------------------------------------------------------------------------------------------------- struct SNOWPARTICLE { float x, y, z; //坐标位置 float RotationY; //雪花绕自身Y轴旋转角度 float RotationX; //雪花绕自身X轴旋转角度 float FallSpeed; //雪花下降速度 float RotationSpeed; //雪花旋转速度 int TextureIndex; //纹理索引数 }; //------------------------------------------------------------------------------------------------- // Desc: 粒子系统类的定义 //------------------------------------------------------------------------------------------------- class SnowParticleClass { private: LPDIRECT3DDEVICE9 m_pd3dDevice; //D3D设备对象 SNOWPARTICLE m_Snows[PARTICLE_NUMBER]; //雪花粒子数组 LPDIRECT3DVERTEXBUFFER9 m_pVertexBuffer; //粒子顶点缓存 LPDIRECT3DTEXTURE9 m_pTexture[6]; //雪花纹理数组 public: SnowParticleClass(LPDIRECT3DDEVICE9 pd3dDevice); //构造函数 ~SnowParticleClass(); //析构函数 HRESULT InitSnowParticle(); //粒子系统初始化函数 HRESULT UpdateSnowParticle( float fElapsedTime); //粒子系统更新函数 HRESULT RenderSnowParticle( ); //粒子系统渲染函数 };
SnowParticleClass.cpp
//============================================================================= // Name: SnowParticleClass.cpp // Des: 一个封装了雪花粒子系统系统的类的源文件 //============================================================================= #include "d3dx9.h" #include "SnowParticleClass.h" //------------------------------------------------------------------------------------------------- // Desc: 构造函数 //------------------------------------------------------------------------------------------------- SnowParticleClass::SnowParticleClass(LPDIRECT3DDEVICE9 pd3dDevice) { //给各个参数赋初值 m_pd3dDevice=pd3dDevice; m_pVertexBuffer=NULL; for(int i=0; i<5; i++) m_pTexture[i] = NULL; } //------------------------------------------------------------------------------------------------- // Name: SnowParticleClass::InitSnowParticle( ) // Desc: 粒子系统初始化函数 //------------------------------------------------------------------------------------------------- HRESULT SnowParticleClass::InitSnowParticle( ) { //初始化雪花粒子数组 srand(GetTickCount()); for(int i=0; i<PARTICLE_NUMBER; i++) { m_Snows[i].x = float(rand()%SNOW_SYSTEM_LENGTH_X-SNOW_SYSTEM_LENGTH_X/2); m_Snows[i].z = float(rand()%SNOW_SYSTEM_WIDTH_Z-SNOW_SYSTEM_WIDTH_Z/2); m_Snows[i].y = float(rand()%SNOW_SYSTEM_HEIGHT_Y); m_Snows[i].RotationY = (rand()%100)/50.0f*D3DX_PI; m_Snows[i].RotationX = (rand()%100)/50.0f*D3DX_PI; m_Snows[i].FallSpeed = 300.0f + rand()%500; m_Snows[i].RotationSpeed = 5.0f + rand()%10/10.0f; m_Snows[i].TextureIndex = rand()%6; } //创建雪花粒子顶点缓存 m_pd3dDevice->CreateVertexBuffer( 4*sizeof(POINTVERTEX), 0, D3DFVF_POINTVERTEX,D3DPOOL_MANAGED, &m_pVertexBuffer, NULL ); //填充雪花粒子顶点缓存 POINTVERTEX vertices[] = { { -30.0f, 0.0f, 0.0f, 0.0f, 1.0f, }, { -30.0f, 60.0f, 0.0f, 0.0f, 0.0f, }, { 30.0f, 0.0f, 0.0f, 1.0f, 1.0f, }, { 30.0f, 60.0f, 0.0f, 1.0f, 0.0f, } }; //加锁 VOID* pVertices; m_pVertexBuffer->Lock( 0, sizeof(vertices), (void**)&pVertices, 0 ); //访问 memcpy( pVertices, vertices, sizeof(vertices) ); //解锁 m_pVertexBuffer->Unlock(); //创建6种雪花纹理 D3DXCreateTextureFromFile( m_pd3dDevice, L"GameMedia\\snow1.jpg", &m_pTexture[0] ); D3DXCreateTextureFromFile( m_pd3dDevice, L"GameMedia\\snow2.jpg", &m_pTexture[1] ); D3DXCreateTextureFromFile( m_pd3dDevice, L"GameMedia\\snow3.jpg", &m_pTexture[2] ); D3DXCreateTextureFromFile( m_pd3dDevice, L"GameMedia\\snow4.jpg", &m_pTexture[3] ); D3DXCreateTextureFromFile( m_pd3dDevice, L"GameMedia\\snow5.jpg", &m_pTexture[4] ); D3DXCreateTextureFromFile( m_pd3dDevice, L"GameMedia\\snow6.jpg", &m_pTexture[5] ); return S_OK; } //------------------------------------------------------------------------------------------------- // Name: SnowParticleClass::UpdateSnowParticle( ) // Desc: 粒子系统更新函数 //------------------------------------------------------------------------------------------------- HRESULT SnowParticleClass::UpdateSnowParticle( float fElapsedTime) { //一个for循环,更新每个雪花粒子的当前位置和角度 for(int i=0; i<PARTICLE_NUMBER; i++) { m_Snows[i].y -= m_Snows[i].FallSpeed*fElapsedTime; //如果雪花粒子落到地面, 重新将其高度设置为最大 if(m_Snows[i].y<0) m_Snows[i].y = SNOW_SYSTEM_WIDTH_Z; //更改自旋角度 m_Snows[i].RotationY += m_Snows[i].RotationSpeed * fElapsedTime; m_Snows[i].RotationX += m_Snows[i].RotationSpeed * fElapsedTime; } return S_OK; } //------------------------------------------------------------------------------------------------- // Name: SnowParticleClass::RenderSnowParticle( ) // Desc: 粒子系统渲染函数 //------------------------------------------------------------------------------------------------- HRESULT SnowParticleClass::RenderSnowParticle( ) { //禁用照明效果 m_pd3dDevice->SetRenderState( D3DRS_LIGHTING, false ); //设置纹理状态 m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); //将纹理颜色混合的第一个参数的颜色值用于输出 m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); //纹理颜色混合的第一个参数的值就取纹理颜色值 m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR ); //缩小过滤状态采用线性纹理过滤 m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR ); //放大过滤状态采用线性纹理过滤 //设置Alpha混合系数 m_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, true); //打开Alpha混合 m_pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE); //源混合系数设为1 m_pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE); //目标混合系数设为1 //设置剔出模式为不剔除任何面 m_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE ); //渲染雪花 for(int i=0; i<PARTICLE_NUMBER; i++) { //构造并设置当前雪花粒子的世界矩阵 static D3DXMATRIX matYaw, matPitch, matTrans, matWorld; D3DXMatrixRotationY(&matYaw, m_Snows[i].RotationY); D3DXMatrixRotationX(&matPitch, m_Snows[i].RotationX); D3DXMatrixTranslation(&matTrans, m_Snows[i].x, m_Snows[i].y, m_Snows[i].z); matWorld = matYaw * matPitch * matTrans; m_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld); //渲染当前雪花粒子 m_pd3dDevice->SetTexture( 0, m_pTexture[m_Snows[i].TextureIndex] ); //设置纹理 m_pd3dDevice->SetStreamSource(0, m_pVertexBuffer, 0, sizeof(POINTVERTEX)); //把包含的几何体信息的顶点缓存和渲染流水线相关联 m_pd3dDevice->SetFVF(D3DFVF_POINTVERTEX); //设置FVF灵活顶点格式 m_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2); //绘制 } //恢复相关渲染状态:Alpha混合 、剔除状态、光照 m_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, false); m_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW ); m_pd3dDevice->SetRenderState( D3DRS_LIGHTING, true ); return S_OK; } //------------------------------------------------------------------------------------------------- // Desc: 析构函数 //------------------------------------------------------------------------------------------------- SnowParticleClass::~SnowParticleClass() { SAFE_RELEASE(m_pVertexBuffer); for(int i=0;i<3; i++) { SAFE_RELEASE(m_pTexture[i]); } }