OpenGL de プログラミング - 実践編04
現在地: メニュー >> 実践編04
INDEX:実践編03 << 実践編04 >> 実践編05

パーティクル


パーティクルでは、点を1つ粒子と考え、それぞれの動作を計算する。
(※簡単にいうと、点のアニメーション)

この項目はnehe lesson 19を引用・参考にしています)

パーティクルの基本データ構造


例えば以下のようなデータ構造がある。
struct Particles
{
	float life; //生存期間
	float fadeSpeed; //消滅速度
	float x,y,z; //現在値
	float r,g,b,a; //色
	float MoveX,MoveY,MoveZ; //移動方向
	float xg,yg,zg; //重力
};

基本的な流れ


基本的な流れは、
  1. 各パーティクルの初期化
  2. 描画
  3. 次の状態の計算
となる。

[1].初期化


初期位置や移動方向などを設定する。
[例]:
//パーティクルの初期化
void InitParticles()
{
	srand( static_cast<unsigned int>( time(NULL) ) );
	
	for(int loop = 0; loop < MaxParticle; ++loop){
		//生存時間の設定
		balls[loop].life = 1.0; //初期生存時間
		balls[loop].fadeSpeed = static_cast<float>((rand() % 100)) / 1000 + 0.003f; //消滅速度(0.001〜0.099 + 0.003)
		//初期位置の設定
		balls[loop].x = balls[loop].y = balls[loop].z = 0;

		//各移動量決定
		balls[loop].MoveX = static_cast<float>( (rand() % 50 - 26.0) ) * 10;
		balls[loop].MoveY = static_cast<float>( (rand() % 50 - 25.0 ) ) * 10;
		balls[loop].MoveZ = static_cast<float>( (rand() % 50 - 25.0 ) ) * 10; 

		balls[loop].xg = 0;
		balls[loop].yg = -1.0;
		balls[loop].zg = 0;
	}
}

[2].描画


描画は、だんだん消滅するように、ブレンド処理をしながら描画する。

[例]
void DrawParticles()
{
	glEnable(GL_BLEND);
	glPointSize(3);
	glBegin(GL_POINTS);
	for(int loop = 0; loop < MaxParticle; ++loop){
			glColor4f(0,0,1,balls[loop].life);
			glVertex3f(balls[loop].x,balls[loop].y,balls[loop].z);
	}
	glEnd();
	glDisable(GL_BLEND);
	glPointSize(1);

}

[3].次の状態の計算


もしも「life」がなくなったらデータを再設定する。

[例]

float SlowDown = 10.0; //速度調整

void CalcNextStatus()
{
	for(int loop = 0; loop < MaxParticle; ++loop){
		balls[loop].life -= balls[loop].fadeSpeed;//ライフを減らす
		
		if (balls[loop].life <= 0)//ライフチェック
		{
			//ライフがなくなったら、再設定
		}else{
			//位置更新
			balls[loop].x += balls[loop].MoveX/(SlowDown*1000);
			balls[loop].y += balls[loop].MoveY/(SlowDown*1000);
			balls[loop].z += balls[loop].MoveZ/(SlowDown*1000);

			balls[loop].MoveX += balls[loop].xg;
			balls[loop].MoveY += balls[loop].yg;
			balls[loop].MoveZ += balls[loop].zg;
		}
	}
}
「SlowDown」を使って移動量を調整している。

nehe lesson 19に記述があるが、本当のパーティクルは複雑で難しい。

サンプル