⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 particle_system.cpp

📁 030_Particle_system using opengl
💻 CPP
字号:
// Particle_system.cpp: implementation of the Particle_system class.
//
//////////////////////////////////////////////////////////////////////

#include "Particle_system.h"
#include <time.h>

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

Particle_system::Particle_system()
{
	srand( (unsigned)time( NULL ) );

//	color[1].load("data/paletta01.bmp");
	color[0].set_fire();
	color[3].set_ice();
	color[4].set_smoke();
	color[5].set_rainbow();
	color[1].add(vec(1,0.5f,0));
	color[1].add(vec(1,0.0f,0));
	color[1].add(vec(0.5f,0.0f,0));
	color[1].add(vec(0.f,0.f,0));
	
	color[2].add(vec(1,0.8f,1.0f));
	color[2].add(vec(1,0.0f,0.0f));
	color[2].add(vec(1,0.0f,0));
	color[2].add(vec(0.5f,0.0f,0));
	color[2].add(vec(0.f,0.f,0));

	for(int i=5; i<10; i++)
		for(int j=0; j<6; j++)
			color[i].add(vec(frand(),frand(),frand()));

	func[0].add(0.05f);
	func[0].add(0.05f);
	func[0].add(0.05f);
	func[0].add(0.05f);
	func[0].add(0.05f);
	func[0].add(0.05f);
	func[0].add(0.004f);
	func[0].add(0.002f);

	func[1].add(0.1f);

	Emiter_stream *em;
/*	em = new Emiter_stream;
	em->max_particles=500;
	em->pos.set(2.5f,1.5f,0);
	em->vel.set(-1,-0.4f,0);
	em->grav.set(0,0,0);
	em->r = &func[0];
	em->color_par.clear();
	em->color_emiter = &color[2];
	em->time_to_add_particle = 0.f;
	em->t_of_color_cycle = 0.f;
	em->period_of_color_cycle = 4.f;
	em->lifetime = 4.f;
	em->angle_of_scatter = 8.f;
	em->angle_of_cut_out = 0.f;
	emiter.push_back(em);

	em = new Emiter_stream;
	em->max_particles=500;
	em->pos.set(2.5f,1.5f,0);
	em->vel.set(-1,-0.4f,0);
	em->grav.set(0,0,0);
	em->r = &func[0];
	em->color_par.clear();
	em->color_emiter = &color[1];
	em->time_to_add_particle = 0.f;
	em->t_of_color_cycle = 0.f;
	em->period_of_color_cycle = 4.f;
	em->lifetime = 4.f;
	em->angle_of_scatter = 14.f;
	em->angle_of_cut_out = 8.f;
	emiter.push_back(em);*/

	for( i=0; i<10; i++)
	{
		em = new Emiter_stream;
		em->max_particles=500;
		em->pos.set(-2.5f+5.5f*(float)i/10.f,-2,0);
		em->vel.set(0,3.0f,0);
		em->grav.set(0,-1,0);
		em->r = &func[0];
		em->color_par.clear();
		em->color_emiter = &color[rand()%10];
		em->time_to_add_particle = 0.f;
		em->t_of_color_cycle = 0.f;
		em->period_of_color_cycle = 2.f;
		em->lifetime = 1.f;
		em->angle_of_scatter = 5.f+5.f*frand();
		em->angle_of_cut_out = 0.f;
		em->period_of_effect = 10;
		em->max_time = 3.0f;
		em->time = (float)i/10.f;
		emiter.push_back(em);
	}

	Emiter_sphere *es;
	for( i=0; i<100; i++)
	{
		es = new Emiter_sphere;
		es->max_particles=500;
		es->pos.set(0,-2,0);
		es->vel.set(1.5f*frand2(),4.0f,1.5f*frand2());
		es->grav.set(0,-1,0);
		es->r_rocket = &func[1];
		es->r_sphere = &func[0];
		es->color_par.set(1,1,1);
		es->lifetime_rocket = 1.0f;
		es->lifetime_sphere = 1.5f;
		es->period_of_effect = 10.f*frand2()+50.f;
		es->angle_of_scatter = 14.f;
		es->times=frand()*es->period_of_effect;
		es->gen=600;
		emiter.push_back(es);
	}
}

Particle_system::~Particle_system()
{
	for(int i=0; i<emiter.size(); i++)
		delete emiter[i];
}

inline void DrawQuad(const vec &p, const vec &s, const vec &t)
{
	// 3 4
	// 1 2
	glTexCoord2f(0,0);glVertex3f( p.v[0], p.v[1], p.v[2]);
	glTexCoord2f(1,0);glVertex3f( p.v[0]+s.v[0],p.v[1]+s.v[1],p.v[2]+s.v[2]);
	glTexCoord2f(0,1);glVertex3f( p.v[0]+t.v[0],p.v[1]+t.v[1],p.v[2]+t.v[2]);
	glTexCoord2f(1,1);glVertex3f( p.v[0]+s.v[0]+t.v[0],p.v[1]+s.v[1]+t.v[1],p.v[2]+s.v[2]+t.v[2]);
}

void Particle_system::Render(vec vr, vec vu)
{
	for(int i=0; i<par.size(); i++)
	{
		glBegin(GL_TRIANGLE_STRIP);				// 3  4  order of points
		//	glNormal3fv(n.v);					// 1  2
			if(par[i].pal_color)
				glColor3fv( par[i].getColor().v);
			else
				glColor3fv( par[i].color.v);
			DrawQuad( par[i].pos-par[i].get_r()*vr-par[i].get_r()*vu, 2.f*par[i].get_r()*vr, 2.f*par[i].get_r()*vu);
		glEnd();
	}
}

void Particle_system::Update(float timeframe)
{
	for(int i=0; i<par.size(); i++)
	{
		par[i].pos += timeframe*par[i].vel;
		par[i].vel += timeframe*par[i].grav;
		
	/*	if(par[i].r<0.f)
		{
			par.erase( par.begin() + i);
			i--;
			continue;
		}
		*/
		par[i].t += timeframe/par[i].lifetime;
		if(par[i].t>1)
		{
			par[i] = par[par.size()-1];
			par.pop_back();
			i--;
			continue;
		}
	}
}

void Particle_system::Emit(float timeframe)
{
	for(int i=0; i<emiter.size();i++)
	{
		if(keys['V'] && i<20)continue;
		if(keys['B'] && i>=20)break;
		if(emiter[i]->Emit_next_frame(timeframe))
			while(emiter[i]->Emit_test())
				par.push_back(emiter[i]->Emit());
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -