天天看點

基于DIRECTX的3D粒子系統建構3

3、 粒子發射器

class CPemitter

{

public:

int                 m_iParticleType; //粒子的類型

void*        m_lpParticleMesh;//粒子的實際使用元素,他可能是任意的可見元素

//(BILLBOARD或Point Sprites),是以我們把它設為

// void*類型

int                 m_iEmitterLife;   //發射器的生存時間

float                     m_fWidth, m_fHeight;       //發射器的長寬(這裡建立的是一個矩形發射器)

int                 m_iMinParticleLife, m_iMaxParticleLife; //粒子的生命值範圍

float                     m_fMinSpeed, m_fMaxSpeed;//粒子的速度範圍

float                     m_fMinAngle, m_fMaxAngle;//粒子發散的角度範圍

float                     m_fMinScale, m_fMaxScale;//粒子的大小變化範圍

float                     m_fMinRotate, m_fMaxRotate;//粒子的旋轉角度範圍

float                     m_fAlphaStart, m_fAlphaEnd;//粒子的透明度範圍

LPPARTICLENODE    m_lpParticleNode;//粒子的渲染連結清單

MY_MATRIX              m_TM;//發射器的世界變換矩陣

MyVector             m_Speed3;//粒子發射的初始速度向量

MyVector             m_Force3;//粒子受力

int                        m_iMaxParticle;//最大粒子數

CollisionMesh      m_ParticleBoudingMesh;//粒子的包圍盒子

public:    

BOOL RenderEmitter();//渲染發射器的渲染連結清單中的每一個粒子

bool EmitterShoot();//發射粒子,在這個函數中,粒子發射器首先檢查哪些粒子已經死//亡,并把死亡粒子從渲染連結清單m_lpParticleNode中删除,把死亡粒子對應的編号壓入粒//子池所管理的空閑棧中。然後粒子發射器發射新的粒子(從空閑棧中取得),他從自己//的參數範圍中取随機值賦給新生成的粒子,并将新粒子加入渲染連結清單中。

bool EmitterNextFrame();//這個函數處理每個在生存期内的粒子變換,包括位置,大小,//旋轉,以及透明度的變化

};

下面是一些主要函數的部分代碼:

bool CPemitter::EmitterNextFrame()

{

       LPPARTICLENODE lpParticleNode = m_lpParticleNode;

       while( 該粒子有效 )

       {

              if(該粒子在生存期内 )

              {

                     粒子生命減少

                     粒子目前幀數增加;

粒子世界矩陣變換;

                     粒子透明度變換;

                     if( 粒子受力 )

                     {

粒子速度變化;

                     }

                     取得下一粒子

              }

              Else//如果粒子生命期結束

              {

                     删除該粒子

                     粒子總數減少;

                     粒子池将死亡粒子放入空閑棧;

              }

       }

       if(發射器壽命期内)

       {

              發射器壽命減少;

              發射粒子;

       }

       Else

{

    删除該發射器

}

       return TRUE;

}

//産生新的粒子

bool CPemitter::EmitterShoot()

{

int iShootNum = ( DWORD )m_iMaxParticle - m_iParticleCount;//確定每次螢幕上的粒子//是最大數目(這樣可以一次申請固定大小BUFFER)

       for( int iPIndex = 0; iPIndex < iShootNum; iPIndex++ )

       {

              如果粒子總數大于最大粒子數則跳出

              從粒子池中取得空閑粒子;

              将該空閑粒子放入渲染連結清單頭

              粒子目前幀數為0;

初始化粒子世界矩陣

初始化粒子受力矩陣;

粒子壽命取發射器粒子壽命範圍間的随機值

              粒子透明度取基本透明度;

粒子透明度增量取發射器粒子透明度範圍間的随機值;

粒子旋轉角度取發射器粒子旋轉角度範圍間的随機值;

粒子位置取發射器範圍内的随機值

粒子速度取發射器範圍内的随機值

粒子大小取發射器粒子大小的随機值

              粒子總數增加;

       }

       return TRUE;

}

繼續閱讀