OpenGL|OpenGL系统设计-粒子系统(1)

在前面的章节中我们看到了通过OpenGL提供的几种基本图元来模拟实现显示世界中的各种物体。但是,实际上有些物体很难用这几个简单图元能够完全表示出来的,即便加上透明、纹理映射、混合、雾的效果等,也很难逼真的反映真实物体,达不到理想的效果。因为这些物体要么在逻辑结构上难以表达,要么就是动态的,或者根本没有固体的表面。如烟、云、火焰、水等自然物体就属于这一范畴。
为了解决类似的问题,在1982年William T.Reeves提出了粒子系统(Particle System)的概念,模拟不规则模糊物体的生成。在粒子系统中,一个物体由一系列的粒子来表示,每一个粒子都有自己的生命周期,都要经历出生、生长和死亡的三个阶段,并且有自己的位置、速度、颜色、大小等等,充分体现了不规则物体的动态和随机性,从而能够很好地模拟火、云、水、森林和原野等许多自然景象。利用粒子系统,Reeves模拟了电影《Star Trek Ⅱ: The Wrath of Khan》 中的一系列特技镜头。
此后,Reeves和Blau对粒子系统进行了发展,他们用“volume filling ”基本单元生成随时可能改变形状但又基本保持不变的实体,如草叶的随风抖动,并提出了一个巧妙的绘制模型,并且用于电影《The Adventures of Andre and Wally B. 》中的三维森林和草的生成。
粒子系统生成物体的基本步骤是
1、产生新的粒子加入到当前的粒子系统中
2、赋予每一个新粒子唯一的属性
3、将那些已经超过生存期的粒子标记为死亡
4、根据粒子的动态属性对粒子进行移动和变换
5、显示由有生命的粒子组成的图象。

在大型的3D游戏中,粒子系统是一个必不可少的部分。象发射的子弹、激光霰弹,燃烧的火焰都是粒子系统是具体实现。
当然,一个完整的功能强大的粒子系统的设计并不是一蹴而就的。我们这里只对粒子系统作一个基本的介绍,然后实现一个简单的粒子系统。

首先,我们来设计一个粒子类:
class CParticle
{
private:
CParticleSystem * mParent; //本粒子所在的粒子系统,后面介绍
public:
VERTEX3D mPreviousLocation; // 粒子上一次的位置
【OpenGL|OpenGL系统设计-粒子系统(1)】VERTEX3D mCurrentLocation; // 粒子当前位置
VECTOR3D mVelocity; // 粒子当前速度

float mColor[4]; // 粒子颜色
float mColorCounter[4]; // 颜色计数器

float mAlpha; // 粒子当前透明度
float mAlphaCounter; // 增加减少透明度计数器

float mSize; // 粒子当前大小
float mSizeCounter; //增加减少大小计数器

float mAge; //粒子当前生命
float mDyingAge; //粒子死亡期

void SetParentSystem(CParticleSystem* parent);
void Create(CParticleSystem* parent, float TimeCounter);
bool Update(float TimeCounter);

CParticle();
~CParticle();
};

私有成员mParent用于设置本粒子所属的粒子系统,从粒子系统中得到相关的信息来创建新的粒子。其他的成员都有简单说明,容易理解。
mColorCounter则表示粒子生命周期内颜色变换的计算。例如,如果定义一个粒子的生成时的颜色是黄色,死亡时的颜色是红色,那么在生长过程中的颜色则线性变化,变化的次数就是mColorCounter=(红色-黄色)/mDyingAge。而粒子的大小、透明度也是采用同样的方法处理的。为了计算粒子的生命,可以给粒子附上一个在整个粒子系统生命基础上的一个随机值。

    推荐阅读