第15讲 粒子系统.docx
《第15讲 粒子系统.docx》由会员分享,可在线阅读,更多相关《第15讲 粒子系统.docx(17页珍藏版)》请在冰豆网上搜索。
第15讲粒子系统
第15讲粒子系统
1、定义
粒子系统到底是什么?
所谓的粒子系统,就是将人们看到的物体运动和自然现象,用一系列运动的粒子来描述,再将这些粒子运动的轨迹映射到显示屏上,在显示屏上看到的就是物体运动和自然现象的模拟效果了。
利用粒子系统,可以在屏幕中表现诸多的特殊效果,如:
焰火、火苗、落叶、雪花飞舞等。
不怕做不到,就怕想不到。
只要你的想象力足够丰富,你可以创造出意想不到的奇迹来。
粒子系统的基本思想是:
采用许多形状简单的微小粒子作为基本元素,用它们来表示不规则模糊物体。
这些粒子都有各自的生命周期,在系统中都要经历“产生”、“运动和生长”及“消亡”三个阶段。
粒子系统是一个有“生命”的系统,因此不象传统方法那样只能生成瞬时静态的景物画面,而是可以产生一系列运动进化的画面,这使得模拟动态的自然景物成为可能。
利用粒子系统生成画面的基本步骤是:
1、粒子源产生新的粒子(初始化粒子);
2、赋予每一新粒子一定的属性(更新粒子),并将粒子的生命周期递减一个时间步;
3、删去那些已经超过生存期的粒子(删除后可以根据具体需要重新初始化或做其他处理);
4、根据粒子的动态属性对粒子进行移动和变换;
5、显示由有生命的粒子组成的图像。
粒子系统采用随机过程来控制粒子的产生数量,确定新产生粒子的一些初始随机属性,如初始运动方向、初始大小、初始颜色、初始透明度、初始形状以及生存期等,并在粒子的运动和生长过程中随机地改变这些属性。
粒子系统的随机性使模拟不规则模糊物体变得十分简便。
粒子系统应用的关键在于如何描述粒子的运动轨迹,也就是构造粒子的运动函数。
函数选择的恰当与否,决定效果的逼真程度。
其次,坐标系的选定(即视角)也有一定的关系,视角不同,看到的效果自然不一样了。
2、粒子系统生命周期
每颗粒子的生命周期或工作处理流程如图:
3、粒子系统数据结构
/**粒子结构*/
structParticle
{
D3DXVECTOR3position;/**<粒子的位置*/
D3DXVECTOR3velocity;/**<粒子的速度*/
D3DXVECTOR3acceleration;/**<粒子的加速度*/
floatlifetime;/**<粒子生命值*/
floatdec;/**<粒子消失的速度*/
floatsize;/**<粒子尺寸*/
D3DCOLOR/*D3DCOLORVALUE*/color;/**<粒子的颜色*/
};
4、粒子系统类
(1)Particle.h文件
#pragmaonce
#include
#include
/**粒子结构*/
structParticle
{
D3DXVECTOR3position;/**<粒子的位置*/
D3DXVECTOR3velocity;/**<粒子的速度*/
D3DXVECTOR3acceleration;/**<粒子的加速度*/
floatlifetime;/**<粒子生命值*/
floatdec;/**<粒子消失的速度*/
floatsize;/**<粒子尺寸*/
D3DCOLOR/*D3DCOLORVALUE*/color;/**<粒子的颜色*/
};
classCParticle
{
public:
CParticle();/**<构造函数*/
virtual~CParticle();/**<析构函数*/
/**粒子的初始化*/
virtualboolInit(int_num);
/**粒子的渲染*/
virtualvoidRender()=0;
/**粒子的更新*/
virtualvoidUpdate()=0;
protected:
intm_iNum;/**<粒子总数目*/
Particle*m_pList;/**<粒子指针*/
};
(1)Particle.cpp文件
#include"Particle.h"
/**构造函数*/
CParticle:
:
CParticle()
{
m_iNum=0;
m_pList=NULL;
}
/**析构函数*/
CParticle:
:
~CParticle()
{
if(m_pList!
=NULL)
{
delete[]m_pList;
m_pList=NULL;
}
}
/**粒子的初始化*/
boolCParticle:
:
Init(int_num)
{
m_iNum=_num;
m_pList=newParticle[m_iNum];
if(m_pList==NULL)
returnfalse;
returntrue;
}
/**粒子的渲染*/
voidCParticle:
:
Render()
{}
/**粒子的更新*/
voidCParticle:
:
Update()
{}
5、粒子系统实例—雨的模拟
(1)Rain.h文件
#pragmaonce
#include"particle.h"
#include
#include
structParticleVertex
{
D3DVECTORpos;
floatpsize;
D3DCOLORcolor;
};
#defineD3DFVF_PV(D3DFVF_XYZ|D3DFVF_PSIZE|D3DFVF_DIFFUSE)
classCRain:
publicCParticle
{
public:
CRain(LPDIRECT3DDEVICE9pd3dDevice);
~CRain(void);
boolInit(intnum);//初始化过程
voidRender();//渲染过程
voidUpdate();//更新过程
protected:
LPDIRECT3DDEVICE9m_pDevice;//设备对象
LPDIRECT3DVERTEXBUFFER9m_pVB;//顶点缓冲区
D3DXMATRIXm_matRain;//世界转换矩阵
floatm_ParticleSize;
D3DXVECTOR3m_fDspeed;
};
(2)Rain.cpp文件
#include"Rain.h"
CRain:
:
CRain(LPDIRECT3DDEVICE9pd3dDevice)
{
D3DXVECTOR3startp=D3DXVECTOR3(1,5,0);
D3DXVECTOR3endp=D3DXVECTOR3(3,1,0);
m_pDevice=pd3dDevice;
m_ParticleSize=5.0f;
m_fDspeed=endp-startp;
D3DXVec3Normalize(&m_fDspeed,&m_fDspeed);
//创建顶点缓冲区
if(FAILED(m_pDevice->CreateVertexBuffer(sizeof(ParticleVertex)*2,
D3DUSAGE_DYNAMIC|D3DUSAGE_WRITEONLY|D3DUSAGE_POINTS,
D3DFVF_PV,D3DPOOL_DEFAULT,&m_pVB,NULL)))
return;
//将粒子从粒子池转移到顶点缓冲区
ParticleVertex*p;
if(FAILED(m_pVB->Lock(0,0,(void**)&p,0)))
return;
p[0].pos=startp;
p[0].psize=m_ParticleSize;
p[0].color=0xffffffff;
p[1].pos=startp+m_fDspeed*m_ParticleSize;
p[1].psize=m_ParticleSize;
p[1].color=0xffffffff;
m_pVB->Unlock();
}
CRain:
:
~CRain(void)
{
}
boolCRain:
:
Init(intnum)
{
///**初始化粒子数目为num个*/
if(CParticle:
:
Init(num))
{
for(inti=0;i{/**初始化位置*/
floatx,y,z;
x=float(rand()%400-200);
z=float(rand()%400-200);
y=(float)(rand()%250);
m_pList[i].position=D3DXVECTOR3(x,y,z);
m_pList[i].velocity=D3DXVECTOR3(rand()%40,rand()%40,rand()%40);
/**初始化加速度—>速度的方向//计算雨点下降方向*/
m_pList[i].acceleration=m_fDspeed;
/**初始化粒子生命时间*/
m_pList[i].lifetime=1;
/**初始化粒子的尺寸*/
m_pList[i].size=1.0f+(rand()%100);
/**初始化粒子的消失速度*/
m_pList[i].dec=0.2;
/**初始化粒子的颜色*/
m_pList[i].color=0xffffffff;//D3DXCOLOR(1.0f,1.0f,1.0f,1.0f);
}
returntrue;
}
else
returnfalse;
}
/**雨的渲染*/
voidCRain:
:
Render()
{
/**开始渲染雨*/
for(inti=0;i{
/**如果该粒子消失或生命结束则不绘制*/
if(m_pList[i].position.y<=0&&m_pList[i].lifetime<=0)
continue;
D3DXMatrixTranslation(&m_matRain,m_pList[i].position.x,m_pList[i].position.y,m_pList[i].position.z);
m_pDevice->SetTransform(D3DTS_WORLD,&m_matRain);
m_pDevice->SetStreamSource(0,m_pVB,0,sizeof(ParticleVertex));
m_pDevice->SetFVF(D3DFVF_PV);
m_pDevice->DrawPrimitive(D3DPT_LINELIST,0,1);
}
/**更新粒子属性*/
Update();
}
/**雨粒子的更新*/
voidCRain:
:
Update()
{
for(inti=0;i{
if(m_pList[i].position.y<0)
m_pList[i].position.y=250.0f;
if(m_pList[i].position.x>200||m_pList[i].position.x<-200)
m_pList[i].position.x=(float)(rand()%400-200);
if(m_pList[i].position.z>200||m_pList[i].position.z<-200)
m_pList[i].position.z=(float)(rand()%400-200);
/**更新位置*/
m_pList[i].position.x+=m_pList[i].velocity.x*m_pList[i].acceleration.x*m_pList[i].size;
m_pList[i].position.y+=m_pList[i].velocity.y*m_pList[i].acceleration.y*m_pList[i].size;
m_pList[i].position.z+=m_pList[i].velocity.z*m_pList[i].acceleration.z*m_pList[i].size;
/**更新生存时间*/
m_pList[i].lifetime-=m_pList[i].dec;
/**如果粒子消失或生命结束*/
if(m_pList[i].position.y<=0||m_pList[i].lifetime<=0)
{
/**初始化位置*/
floatx,y,z;
x=float(rand()%400-200);
z=float(rand()%400-200);
y=(float)(rand()%250);
m_pList[i].position=D3DXVECTOR3(x,y,z);
/**初始化生命时间*/
m_pList[i].lifetime=1;
/**初始化消失速度*/
m_pList[i].dec=0.2;
}
}
}
实现效果:
雪粒子系统的实现
(1)定义CSnowPartcileSystem类
SnowPartcileSystem.h文件
//=====================================================================
//Desc:
雪花粒子系统类头文件
//=====================================================================
#pragmaonce
#include"UtilMacro.h";
//-----------------------------------------------------------------------------
//点精灵顶点结构和顶点格式
//-----------------------------------------------------------------------------
structPOINTVERTEX
{
floatx,y,z;//顶点位置
floatu,v;//顶点纹理坐标
};
#defineD3DFVF_POINTVERTEX(D3DFVF_XYZ|D3DFVF_TEX1)
//-----------------------------------------------------------------------------
//Desc:
雪花粒子结构
//-----------------------------------------------------------------------------
structSNOWPARTICLE
{
floatx,y,z;//位置
floatfYaw;//雪花绕自身Y轴旋转角度
floatfPitch;//雪花绕自身X旋转角度
floatDspeed;//雪花下降速度
floatRspeed;//雪花旋转速度
intTexIndex;//纹理
};
//-----------------------------------------------------------------------------
//Desc:
粒子系统类的定义
//-----------------------------------------------------------------------------
classCSnowParticleSystem
{
private:
intm_num;
SNOWPARTICLE*m_Snows;//雪花粒子数组
LPDIRECT3DVERTEXBUFFER9m_pVB;//保存粒子数据的顶点缓存
LPDIRECT3DDEVICE9m_pd3dDevice;
LPDIRECT3DTEXTURE9m_pTex[3];//雪花纹理
public:
CSnowParticleSystem(LPDIRECT3DDEVICE9pd3dDevice);
~CSnowParticleSystem();
boolInit(intnum);
voidUpdate(floatfElapsedTime);
voidRender(floatfElapsedTime);
voidDestroy();
};
(2)类的实现snowparticlesystem.cpp文件
//=====================================================================
//Desc:
雪花粒子系统类源文件
//=====================================================================
#include"d3dx9.h"
#include"SnowParticleSystem.h"
#defineSAFE_DELETE(p){if(p){delete(p);(p)=NULL;}}
#defineSAFE_DELETE_ARRAY(p){if(p){delete[](p);(p)=NULL;}}
#defineSAFE_RELEASE(p){if(p){(p)->Release();(p)=NULL;}}
//-----------------------------------------------------------------------------
//Desc:
构造函数
//-----------------------------------------------------------------------------
CSnowParticleSystem:
:
CSnowParticleSystem(LPDIRECT3DDEVICE9pd3dDevice)
{
m_pd3dDevice=pd3dDevice;
m_pTex[0]=NULL;
m_pTex[1]=NULL;
m_pTex[2]=NULL;
m_pVB=NULL;
}
//-----------------------------------------------------------------------------
//Desc:
析构函数
//-----------------------------------------------------------------------------
CSnowParticleSystem:
:
~CSnowParticleSystem()
{}
//-----------------------------------------------------------------------------
//Desc:
创建粒子纹理
//-----------------------------------------------------------------------------
boolCSnowParticleSystem:
:
Init(intnum)
{
m_num=num;
m_Snows=newSNOWPARTICLE[m_num];
//初始化雪花粒子数组
srand(GetTickCount());
for(inti=0;i{
m_Snows[i].x=float(rand()%200-100);
m_Snows[i].z=float(rand()%200-100);
m_Snows[i].y=float(rand()%250);
m_Snows[i].fYaw=(rand()%100)/50.0f*D3DX_PI;
m_Snows[i].fPitch=(rand()%100)/50.0f*D3DX_PI;
m_Snows[i].Dspeed=20.0f+rand()%5;
m_Snows[i].Rspeed=1.0f+rand()%10/10.0f;
m_Snows[i].TexIndex=rand()%3;
}
//创建雪花粒子顶点缓存
if(FAILED(m_pd3dDevice->CreateVertexBuffer(4*sizeof(POINTVERTEX),0,
D3DFVF_POINTVERTEX,D3DPOOL_MANAGED,&m_pVB,NULL)))
returnfalse;
//填充雪花粒子顶点缓存
POINTVERTEXvertices[]=
{
{-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*pVertices;
m_pVB->Lock(0,0,(void**)&pVertices,0);
memcpy(pVertices,vertices,sizeof(vertices));
m_pVB->Unlock();
//创建雪花纹理
D3DXCreateTextureFromFile(m_pd3dDevice,L"Media\\snow1.bmp",&m_pTex[0]);
D3DXCreateTextureFromFile(m_pd3dDevice,L"Media\\snow2.bmp",&m_pTex[1]);
D3DXCreateTextureFromFile(m_pd3dDevice,L"Media\\snow3.bm