diff options
-rw-r--r-- | src/render/particles.cc | 145 | ||||
-rw-r--r-- | src/render/particles.h | 23 | ||||
-rw-r--r-- | src/render/render.cc | 13 | ||||
-rw-r--r-- | src/render/renderext.cc | 5 |
4 files changed, 135 insertions, 51 deletions
diff --git a/src/render/particles.cc b/src/render/particles.cc index f9271ab..3a9521b 100644 --- a/src/render/particles.cc +++ b/src/render/particles.cc @@ -31,6 +31,31 @@ Particle::Particle(const math::Vector3f &location, const math::Axis &axis, float ParticleScript::Registry ParticleScript::particles_registry; +void ParticleScript::list() +{ + std::string str; + for (Registry::iterator it = particles_registry.begin(); it != particles_registry.end(); it++) { + + ParticleScript *script = (*it).second; + switch (script->type()) { + case Flame: + str.assign("flame"); + break; + case Jet: + str.assign("jet"); + break; + case Spray: + str.assign("spray"); + break; + case Trail: + str.assign("trail"); + break; + } + con_print << " " << script->label() << " " << str << std::endl; + con_print << particles_registry.size() << " particle scripts" << std::endl; + } +} + void ParticleScript::clear() { for (Registry::iterator it = particles_registry.begin(); it != particles_registry.end(); it++) { @@ -50,22 +75,24 @@ ParticleScript *ParticleScript::find(const std::string &label) return 0; } } - -void ParticleScript::init() -{ - clear(); - ParticleScript *script = 0; +ParticleScript *ParticleScript::load(const std::string &label) +{ + ParticleScript *script = find(label); + if (script) + return script; filesystem::IniFile inifile; - inifile.open("particles"); + + inifile.open("particles/" + label); if (!inifile.is_open()) { - con_error << "Could not open " << inifile.name() << std::endl; - return; + con_warn << "Could not open " << inifile.name() << std::endl; + return 0; } - con_print << "^BLoading particle systems..." << std::endl; + script = new ParticleScript(label); + con_debug << " " << inifile.name() << std::endl; std::string strval; @@ -73,29 +100,16 @@ void ParticleScript::init() if (inifile.got_section()) { if (inifile.got_section("particles")) { - if (script) { - if (script->label().size()) { - if (find(script->label())) { - con_warn << "Duplicate particle system '" << script->label() << "'" << std::endl; - delete script; - } else { - particles_registry[script->label()] = script; - } - } else { - con_warn << "Particle system without label" << std::endl; - delete script; - } - } - script = new ParticleScript(); + continue; + } else { + inifile.unknown_section(); } } else if (inifile.got_key()) { if (inifile.in_section("particles")) { - if (inifile.got_key_string("label", script->particles_label)) { - continue; - } else if (inifile.got_key_string("type", strval)) { + if (inifile.got_key_string("type", strval)) { aux::to_label(strval); if (strval.compare("flame") == 0) { script->particles_type = ParticleScript::Flame; @@ -132,28 +146,17 @@ void ParticleScript::init() } } } + inifile.close(); - if (script) { - if (script->label().size()) { - if (find(script->label())) { - con_warn << "Duplicate particle system '" << script->label() << "'" << std::endl; - delete script; - } else { - particles_registry[script->label()] = script; - } - } else { - con_warn << "Particle system without label" << std::endl; - delete script; - } - } + particles_registry[script->label()] = script; - con_debug << " " << inifile.name() << " " << particles_registry.size() << " " << aux::plural("particle system", particles_registry.size()) << std::endl; + return script; } /* ---- class ParticleScript --------------------------------------- */ -ParticleScript::ParticleScript() +ParticleScript::ParticleScript(const std::string label) : particles_label(label) { particles_radius = 1.0f; particles_alpha = 1.0f; @@ -324,6 +327,66 @@ void Jet::draw(float elapsed) { gl::end(); } } +/* ---- class Spray ------------------------------------------------ */ + +Spray::Spray(ParticleScript *script, core::Entity *entity, model::Particles *modelclass) : + ParticleSystem(script, entity, modelclass) { +} + +Spray::~Spray() +{} + +void Spray::draw(float elapsed) { + if (!particlesystem_script) + return; + + ParticleSystem::draw(elapsed); + + math::Vector3f quad[4]; + + if (particlesystem_stream.size()) { + Textures::bind(particlesystem_texture); + gl::begin(gl::Quads); + + for (Stream::iterator it = particlesystem_stream.begin(); it != particlesystem_stream.end(); it++) { + Particle *particle = (*it); + + quad[0].assign(Camera::axis().up() - Camera::axis().left()); + quad[1].assign(Camera::axis().up() + Camera::axis().left()); + quad[2].assign(Camera::axis().up() * -1 + Camera::axis().left()); + quad[3].assign(Camera::axis().up() * -1 - Camera::axis().left()); + + float t = now - particle->time(); + float f = 0; + + if (t < particlesystem_script->timeout() * 0.1f) { + f = t / (0.1f * particlesystem_script->timeout()); + } else { + t = t - particlesystem_script->timeout() * 0.1f; + f = t / (0.9f * particlesystem_script->timeout()); + f = 1.0 - f; + } + + f *= f; + float radius = particlesystem_script->radius() * f; + color.a = f * particlesystem_script->alpha(); + gl::color(color); + + glTexCoord2f(0,1); + gl::vertex(particle->location() + quad[0] * radius); + glTexCoord2f(0,0); + gl::vertex(particle->location() + quad[1] * radius); + glTexCoord2f(1,0); + gl::vertex(particle->location() + quad[2] * radius); + glTexCoord2f(1,1); + gl::vertex(particle->location() + quad[3] * radius); + Stats::quads++; + } + + gl::end(); + } +} + /* ---- class Trail ------------------------------------------------ */ diff --git a/src/render/particles.h b/src/render/particles.h index 9c9d44b..88789a5 100644 --- a/src/render/particles.h +++ b/src/render/particles.h @@ -45,7 +45,7 @@ protected: class ParticleScript { public: - enum Type {Jet=0, Trail=1, Flame=2 }; + enum Type {Jet=0, Trail=1, Flame=2, Spray=3 }; inline const Type type() const { return particles_type; } @@ -66,15 +66,16 @@ public: inline float alpha() const { return particles_alpha; } inline float offset() const { return particles_offset; } - - static ParticleScript *find(const std::string &label); - static void init(); + static ParticleScript *load(const std::string &label); static void clear(); + static void list(); private: - ParticleScript(); + static ParticleScript *find(const std::string &label); + + ParticleScript(const std::string label); ~ParticleScript(); std::string particles_label; @@ -171,6 +172,18 @@ public: virtual void draw(float elapsed); }; +/* ---- class Spray ----------------------------------------------- */ + +/// spray style particles +class Spray : public ParticleSystem +{ +public: + Spray(ParticleScript *script, core::Entity *entity, model::Particles *modelclass); + virtual ~Spray(); + + virtual void draw(float elapsed); +}; + /* ---- class Trail ------------------------------------------------ */ /// trail style particles, like an engine trail diff --git a/src/render/render.cc b/src/render/render.cc index 1abd197..dcede48 100644 --- a/src/render/render.cc +++ b/src/render/render.cc @@ -37,6 +37,11 @@ void func_list_textures(std::string const &args) Textures::list(); } +void func_list_particles(std::string const &args) +{ + ParticleScript::list(); +} + void init(int width, int height) { con_print << "^BInitializing renderer..." << std::endl; @@ -56,8 +61,6 @@ void init(int width, int height) Dust::init(); - ParticleScript::init(); - // size of the vertex array in megabytes r_arraysize = core::Cvar::get("r_arraysize", 0.0f , core::Cvar::Archive); r_arraysize->set_info("[int] size of the vertex array in Mb"); @@ -95,6 +98,9 @@ void init(int width, int height) // engine functions core::Func *func = core::Func::add("list_textures", func_list_textures); func->set_info("list loaded textures"); + + func = core::Func::add("list_particles", func_list_particles); + func->set_info("list loaded particle scripts"); } // unload game assets (zone change) @@ -177,8 +183,6 @@ void reset() Textures::init(); - ParticleScript::init(); - size_t mb = (size_t) r_arraysize->value(); if (mb < 4 * sizeof(float)) mb = 4 * sizeof(float); @@ -199,6 +203,7 @@ void shutdown() { con_print << "^BShutting down renderer..." << std::endl; + core::Func::remove("list_particles"); core::Func::remove("list_textures"); clear(); diff --git a/src/render/renderext.cc b/src/render/renderext.cc index d2d5a71..7c514df 100644 --- a/src/render/renderext.cc +++ b/src/render/renderext.cc @@ -57,7 +57,7 @@ RenderExt::RenderExt(core::Entity *entity) : core::Extension(core::Extension::Re model::Particles *particlesystem = (*pit); // load particle systems - ParticleScript *script = ParticleScript::find(particlesystem->script()); + ParticleScript *script = ParticleScript::load(particlesystem->script()); if (script) { if (script->type() == render::ParticleScript::Trail) { Trail *trail = new Trail(script, entity, particlesystem); @@ -65,6 +65,9 @@ RenderExt::RenderExt(core::Entity *entity) : core::Extension(core::Extension::Re } else if (script->type() == render::ParticleScript::Jet) { Jet *jet = new Jet(script, entity, particlesystem); state_particles.push_back(jet); + } else if (script->type() == render::ParticleScript::Spray) { + Spray *spray = new Spray(script, entity, particlesystem); + state_particles.push_back(spray); } else if (script->type() == render::ParticleScript::Flame) { Flame *flame = new Flame(script, entity, particlesystem); state_particles.push_back(flame); |