Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorStijn Buys <ingar@osirion.org>2008-11-16 13:53:44 +0000
committerStijn Buys <ingar@osirion.org>2008-11-16 13:53:44 +0000
commit315a8c2dff9b76ac5e1ebbef265f13ac19d65e3d (patch)
treedec6de0bcf7f19dd95b7121f27b185da67cee4e2 /src
parent28ba97bdd8fb6ca352dc49dba01a66bd155ad523 (diff)
engine trails
Diffstat (limited to 'src')
-rw-r--r--src/game/base/ship.cc7
-rw-r--r--src/model/engine.cc7
-rw-r--r--src/model/engine.h29
-rw-r--r--src/model/flare.cc1
-rw-r--r--src/model/flare.h6
-rw-r--r--src/model/map.cc36
-rw-r--r--src/render/Makefile.am9
-rw-r--r--src/render/draw.cc114
-rw-r--r--src/render/particles.cc144
-rw-r--r--src/render/particles.h73
-rw-r--r--src/render/renderext.cc32
-rw-r--r--src/render/renderext.h20
-rw-r--r--src/render/tgafile.cc2
13 files changed, 376 insertions, 104 deletions
diff --git a/src/game/base/ship.cc b/src/game/base/ship.cc
index 214d234..5473581 100644
--- a/src/game/base/ship.cc
+++ b/src/game/base/ship.cc
@@ -60,7 +60,12 @@ void Ship::reset()
}
void Ship::func_impulse()
{
- if ((entity_eventstate == core::Entity::Impulse) || (entity_eventstate == core::Entity::ImpulseInitiate)) {
+ if (entity_eventstate == core::Entity::Impulse) {
+ entity_eventstate = core::Entity::Normal;
+ target_thrust = 1.0f;
+ entity_thrust = 1.0f;
+
+ } else if (entity_eventstate == core::Entity::ImpulseInitiate) {
entity_eventstate = core::Entity::Normal;
} else if (entity_eventstate != core::Entity::Normal) {
diff --git a/src/model/engine.cc b/src/model/engine.cc
index 97011d9..959f2ce 100644
--- a/src/model/engine.cc
+++ b/src/model/engine.cc
@@ -11,17 +11,12 @@ namespace model
{
-/* ---------- core::Engine ------------------------------------------ */
+/* ---- class Engine ----------------------------------------------- */
Engine::Engine() :
engine_location()
{
engine_radius = 1.0f;
- engine_flare = 0;
- render_texture = 0;
-
- engine_notrail = false;
- engine_noflare = false;
}
Engine::Engine(math::Vector3f const & location) :
diff --git a/src/model/engine.h b/src/model/engine.h
index 724c060..68f16e5 100644
--- a/src/model/engine.h
+++ b/src/model/engine.h
@@ -31,36 +31,9 @@ public:
{
return engine_radius;
}
-
- inline unsigned int flare() const
- {
- return engine_flare;
- }
-
- inline unsigned int texture() const
- {
- return render_texture;
- }
-
- inline bool noflare() const
- {
- return engine_noflare;
- }
-
- inline bool notrail() const
- {
- return engine_notrail;
- }
-
+
math::Vector3f engine_location;
float engine_radius;
- unsigned int engine_flare;
-
-
- bool engine_noflare;
- bool engine_notrail;
-
- unsigned int render_texture;
};
}
diff --git a/src/model/flare.cc b/src/model/flare.cc
index 0669a49..5491dd2 100644
--- a/src/model/flare.cc
+++ b/src/model/flare.cc
@@ -12,6 +12,7 @@ namespace model
Flare::Flare() : Light()
{
flare_angle = 0;
+ flare_engine = false;
}
Flare::~Flare()
diff --git a/src/model/flare.h b/src/model/flare.h
index 6f96d8c..6affe55 100644
--- a/src/model/flare.h
+++ b/src/model/flare.h
@@ -24,7 +24,13 @@ public:
return flare_angle;
}
+ inline bool engine() const
+ {
+ return flare_engine;
+ }
+
float flare_angle;
+ bool flare_engine;
};
}
diff --git a/src/model/map.cc b/src/model/map.cc
index 6f3ff9e..1767743 100644
--- a/src/model/map.cc
+++ b/src/model/map.cc
@@ -822,6 +822,10 @@ Model * Map::load(std::string const &name)
continue;
} else if (mapfile.got_key_color("enginecolor", model->model_enginecolor) ==0) {
continue;
+
+ } else if (mapfile.got_key()) {
+ con_warn "unknown key " << mapfile.classname() << ":" << mapfile.key() << std::endl;
+
}
} else if (mapfile.got_classend("func_group")) {
@@ -856,6 +860,9 @@ Model * Map::load(std::string const &name)
} else if (mapfile.got_key_float("light", light->light_radius)) {
light->light_radius /= 100.0f;
+ } else if (mapfile.got_key_float("radius", light->light_radius)) {
+ light->light_radius /= 100.0f;
+
} else if (mapfile.got_key_float("frequency", light->light_frequency)) {
continue;
@@ -868,6 +875,9 @@ Model * Map::load(std::string const &name)
} else if (mapfile.got_key_int("flare", light->light_flare)) {
continue;
+ } else if (mapfile.got_key()) {
+ con_warn "unknown key " << mapfile.classname() << ":" << mapfile.key() << std::endl;
+
}
} else if (mapfile.got_classname("trigger_dock")) {
@@ -886,7 +896,13 @@ Model * Map::load(std::string const &name)
} else if (mapfile.got_key_float("radius", dock->dock_radius)) {
dock->dock_radius /= 100.0f;
continue;
-
+
+ } else if (mapfile.got_key("angle")) {
+ continue;
+
+ } else if (mapfile.got_key()) {
+ con_warn "unknown key " << mapfile.classname() << ":" << mapfile.key() << std::endl;
+
}
} else if (mapfile.got_classname("target_flare")) {
@@ -908,6 +924,7 @@ Model * Map::load(std::string const &name)
} else if (mapfile.got_key_int("spawnflags", u)) {
flare->light_strobe = spawnflag_isset(u, 1);
flare->light_entity = spawnflag_isset(u, 2);
+ flare->flare_engine = spawnflag_isset(u, 4);
} else if (mapfile.got_key_float("radius", flare->light_radius)) {
flare->light_radius /= 100.0f;
@@ -923,11 +940,13 @@ Model * Map::load(std::string const &name)
} else if (mapfile.got_key_int("flare", flare->light_flare)) {
continue;
-
+
} else if (mapfile.got_key_float("angle", flare->flare_angle)) {
flare->flare_angle = math::degrees360f(flare->flare_angle);
continue;
+ } else if (mapfile.got_key()) {
+ con_warn "unknown key " << mapfile.classname() << ":" << mapfile.key() << std::endl;
}
} else if (mapfile.got_classname("target_engine")) {
@@ -945,15 +964,14 @@ Model * Map::load(std::string const &name)
} else if (mapfile.got_key_float("radius", engine->engine_radius)) {
engine->engine_radius /= 100.0f;
continue;
-
- } else if (mapfile.got_key_int("flare", engine->engine_flare)) {
- continue;
-
- } else if (mapfile.got_key_int("spawnflags", u)) {
- engine->engine_noflare = spawnflag_isset(u, 1);
- engine->engine_notrail = spawnflag_isset(u, 2);
+
+ } else if (mapfile.got_key("angle")) {
continue;
+
+ } else if (mapfile.got_key()) {
+ con_warn "unknown key " << mapfile.classname() << ":" << mapfile.key() << std::endl;
}
+
}
}
diff --git a/src/render/Makefile.am b/src/render/Makefile.am
index 4054490..9fd8f50 100644
--- a/src/render/Makefile.am
+++ b/src/render/Makefile.am
@@ -10,7 +10,8 @@ endif
librender_la_LDFLAGS = -avoid-version -no-undefined @GL_LIBS@
librender_la_LIBADD = $(top_builddir)/src/math/libmath.la
librender_la_SOURCES = camera.cc draw.cc dust.cc gl.cc image.cc jpgfile.cc \
- pngfile.cc render.cc renderext.cc screenshot.cc state.cc text.cc textures.cc \
- tgafile.cc
-noinst_HEADERS = camera.h draw.h dust.h gl.h image.h jpgfile.h pngfile.h \
- render.h renderext.h screenshot.h state.h text.h textures.h tgafile.h
+ particles.cc pngfile.cc render.cc renderext.cc screenshot.cc state.cc text.cc \
+ textures.cc tgafile.cc
+noinst_HEADERS = camera.h draw.h dust.h gl.h image.h jpgfile.h particles.h \
+ pngfile.h render.h renderext.h screenshot.h state.h text.h \
+ textures.h tgafile.h
diff --git a/src/render/draw.cc b/src/render/draw.cc
index 4f58f3d..a700d14 100644
--- a/src/render/draw.cc
+++ b/src/render/draw.cc
@@ -225,8 +225,19 @@ void draw_globe(core::EntityGlobe *globe)
glLightfv(GL_LIGHT1, GL_POSITION, fake_light);
}
}
+
gl::push();
gl::translate(location);
+ gl::multmatrix(globe->axis());
+
+ if (globe->rotationspeed()) {
+ float angle = math::degrees360f(core::application()->time() * globe->rotationspeed());
+ gl::rotate(angle, math::Vector3f::Zaxis());
+ }
+
+ draw_sphere(globe->color(), radius);
+ gl::pop();
+
if(flag_is_set(globe->flags(), core::Entity::Bright)) {
@@ -234,19 +245,16 @@ void draw_globe(core::EntityGlobe *globe)
v.normalize();
float a = dotproduct(v, Camera::axis().forward());
if (a > 0.1f) {
- // FIXME a corona is actually just a giant flare
+ // FIXME a corona is actually just a giant flare
if (!globe->render_texture) {
gl::enable(GL_TEXTURE_2D);
}
Textures::bind("bitmaps/fx/corona");
-
+ /*
if (ext_render(globe)->distance() <= farplane) {
gl::depthmask(GL_FALSE);
- }
-
- //glDisableClientState(GL_VERTEX_ARRAY);
- //glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- //glDisableClientState(GL_NORMAL_ARRAY);
+ }*/
+ gl::disable(GL_DEPTH_TEST);
math::Color color(globe->color());
color.a = a - 0.1f;
@@ -256,42 +264,30 @@ void draw_globe(core::EntityGlobe *globe)
gl::begin(gl::Quads);
glTexCoord2f(0,1);
- gl::vertex((Camera::axis().up() - Camera::axis().left()) * radius * 4.0f);
+ gl::vertex(location+ (Camera::axis().up() - Camera::axis().left()) * radius * 4.0f);
glTexCoord2f(0,0);
- gl::vertex((Camera::axis().up() + Camera::axis().left()) * radius * 4.0f);
+ gl::vertex(location+ (Camera::axis().up() + Camera::axis().left()) * radius * 4.0f);
glTexCoord2f(1,0);
- gl::vertex((Camera::axis().up() * -1 + Camera::axis().left()) * radius * 4.0f);
+ gl::vertex(location+ (Camera::axis().up() * -1 + Camera::axis().left()) * radius * 4.0f);
glTexCoord2f(1,1);
- gl::vertex((Camera::axis().up() * -1 - Camera::axis().left()) * radius * 4.0f);
+ gl::vertex(location+ (Camera::axis().up() * -1 - Camera::axis().left()) * radius * 4.0f);
gl::end();
Stats::quads++;
-
- //glEnableClientState(GL_VERTEX_ARRAY);
- //glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- //glEnableClientState(GL_NORMAL_ARRAY);
gl::disable(GL_BLEND);
+ /*
if (ext_render(globe)->distance() <= farplane) {
gl::depthmask(GL_TRUE);
- }
+ }*/
if (!globe->render_texture) {
gl::disable(GL_TEXTURE_2D);
}
- }
- }
-
- gl::multmatrix(globe->axis());
-
- if (globe->rotationspeed()) {
- float angle = math::degrees360f(core::application()->time() * globe->rotationspeed());
- gl::rotate(angle, math::Vector3f::Zaxis());
+ gl::enable(GL_DEPTH_TEST);
+ }
}
- draw_sphere(globe->color(), radius);
-
- gl::pop();
if (ext_render(globe)->distance() > farplane) {
@@ -713,28 +709,29 @@ void draw_pass_model_fragments()
void draw_pass_model_fx(float elapsed)
{
- const size_t count = 8; // number of engine trail particles
+ //const size_t count = 8; // number of engine trail particles
float t = 0.0f;
- float u = 0.0f;
+ //float u = 0.0f;
float a = 0.0f;
float light_size = 0.0f;
- float engine_size = 0.0f;
- float trail_size = 0.0f;
+ //float engine_size = 0.0f;
+ //float trail_size = 0.0f;
bool power = true;
+ float thrust;
- math::Vector3f quad[4];
+ //math::Vector3f quad[4];
math::Vector3f location;
math::Vector3f offset;
math::Color color;
model::Light *light;
model::Flare *flare;
- model::Engine *engine;
+ //model::Engine *engine;
math::Axis flare_axis;
- size_t circle_texture = Textures::load("bitmaps/fx/circle01");
+ //size_t circle_texture = Textures::load("bitmaps/fx/circle01");
size_t current_texture = Textures::bind("bitmaps/fx/flare00");
gl::enable(GL_TEXTURE_2D);
@@ -744,6 +741,7 @@ void draw_pass_model_fx(float elapsed)
core::Entity *entity = (*it);
power = true;
+
if ((entity->type() == core::Entity::Dynamic) &&
(static_cast<core::EntityDynamic *>(entity)->eventstate() == core::Entity::NoPower)) {
power = false;
@@ -794,13 +792,24 @@ void draw_pass_model_fx(float elapsed)
// draw flares
for (model::Model::Flares::iterator flit = entity->model()->flares().begin(); flit != entity->model()->flares().end(); flit++) {
flare = (*flit);
-
+
+ // engine flares
+ thrust = 1.0f;
+ if (flare->engine() && ( entity->type() == core::Entity::Controlable)) {
+ core::EntityControlable *ec = static_cast<core::EntityControlable *>(entity);
+ if ((ec->eventstate() == core::Entity::ImpulseInitiate) || (ec->eventstate() == core::Entity::Impulse)) {
+ thrust = 1.0f;
+ } else {
+ thrust = ec->thrust();
+ }
+ }
+
// strobe frequency
t = 1.0f;
if (flare->strobe())
t = (core::application()->time() + ext_render(entity)->fuzz() - flare->offset()) * flare->frequency();
- if ((!flare->strobe()) || (( t - floorf(t)) <= flare->time())) {
+ if ((thrust > 0 ) && ((!flare->strobe()) || (( t - floorf(t)) <= flare->time()))) {
flare_axis.assign(entity->axis());
if (flare->angle())
flare_axis.change_direction(flare->angle());
@@ -819,10 +828,19 @@ void draw_pass_model_fx(float elapsed)
} else {
color.assign(flare->color());
}
-
+
a = dotproduct(flare_axis.forward(), Camera::axis().forward());
if (a < -0.1f) {
- color.a = -a - 0.1f;
+ a = -a - 0.1f;
+ if (flare->entity()) {
+ color.assign(entity->color());
+ } else if (flare->engine()) {
+ color.assign(entity->model()->enginecolor());
+ a *= thrust;
+ } else {
+ color.assign(flare->color());
+ }
+ color.a = a;
gl::color(color);
glTexCoord2f(0,1);
@@ -840,6 +858,7 @@ void draw_pass_model_fx(float elapsed)
}
}
+/*
// draw model engines for Controlable entities
if ((entity->type() == core::Entity::Controlable) && entity->model()->engines().size()) {
core::EntityControlable *ec = static_cast<core::EntityControlable *>(entity);
@@ -936,10 +955,27 @@ void draw_pass_model_fx(float elapsed)
}
}
}
- }
+ */
+
+ // draw particles
+ if (ext_render(entity)->particles().size()) {
+ gl::end();
+ gl::disable(GL_CULL_FACE);
+
+ for (RenderExt::Particles::iterator it = ext_render(entity)->particles().begin(); it != ext_render(entity)->particles().end(); it++) {
+ ParticleStream *particles = (*it);
+ particles->draw();
+ }
+
+ gl::enable(GL_CULL_FACE);
+ current_texture = Textures::bind("bitmaps/fx/flare00");
+ gl::begin(gl::Quads);
+ }
+ }
}
gl::end();
+
gl::disable(GL_TEXTURE_2D);
}
diff --git a/src/render/particles.cc b/src/render/particles.cc
new file mode 100644
index 0000000..94a3a07
--- /dev/null
+++ b/src/render/particles.cc
@@ -0,0 +1,144 @@
+/*
+ render/particles.cc
+ This file is part of the Osirion project and is distributed under
+ the terms of the GNU General Public License version 2
+*/
+
+#include "render/particles.h"
+#include "render/camera.h"
+#include "render/gl.h"
+#include "render/draw.h"
+#include "render/textures.h"
+
+#include "core/application.h"
+namespace render {
+
+/* ---- class Particle --------------------------------------------- */
+
+Particle::Particle(const math::Vector3f &location, float time) : particle_location(location)
+{
+ particle_time = time;
+}
+
+Particle::Particle(const math::Vector3f &location, const math::Vector3f &up, const math::Vector3f &left, float time) : particle_location(location), particle_up(up), particle_left(left)
+{
+ particle_time = time;
+}
+
+/* ---- class ParticleStream --------------------------------------- */
+
+ParticleStream::ParticleStream(const math::Vector3f &location, const math::Color &color, float radius, size_t texture, core::EntityControlable *entity, bool oriented) : particles_location(location), particles_color(color)
+{
+ particles_texture = texture;
+ particles_entity = entity;
+ if (!entity) {
+ particles_oriented = false;
+ } else {
+ particles_oriented = oriented;
+ }
+
+ particles_radius = radius;
+
+ particles_timeout = 1.5f; // a particles lives for 3 seconds
+ particles_eject = 0.02f; // a particle is ejected every 0.2 seconds
+
+ particles_last_eject = 0; // timestamp of the last eject
+}
+
+ParticleStream::~ParticleStream()
+{
+ for (Particles::iterator it = particles_stream.begin(); it != particles_stream.end(); it++) {
+ delete (*it);
+ }
+ particles_stream.clear();
+}
+
+void ParticleStream::draw() {
+ float now = core::application()->time();
+
+ // remove dead particles
+ Particles::iterator it = particles_stream.begin();
+ while ((it != particles_stream.end()) && ((*it)->time() + particles_timeout <= now)) {
+ delete (*it);
+ particles_stream.erase(it);
+ it = particles_stream.begin();
+ }
+
+ // add new particles
+ if (particles_last_eject + particles_eject <= now) {
+ if (particles_entity) {
+ float u = 0;
+ if ((particles_entity->eventstate() == core::Entity::ImpulseInitiate ) || (particles_entity->eventstate() == core::Entity::Impulse)) {
+ u = 1.0f;
+ } else if(particles_entity->eventstate() == core::Entity::Normal) {
+ u = particles_entity->thrust();
+ }
+ if (u > 0.0f) {
+ math::Vector3f l(particles_entity->location() + (particles_entity->axis() * location()));
+ Particle *p = 0;
+ if (particles_oriented) {
+ p = new Particle(l, particles_entity->axis().up(), particles_entity->axis().left(), now);
+ } else {
+ p = new Particle(l, now);
+ }
+ particles_stream.push_back(p);
+ }
+ } else {
+ particles_stream.push_back(new Particle(location(), now));
+ }
+ particles_last_eject = now;
+ }
+
+ math::Vector3f quad[4];
+
+ if (particles_stream.size()) {
+ Textures::bind(particles_texture);
+ gl::begin(gl::Quads);
+
+ for (Particles::reverse_iterator rit = particles_stream.rbegin(); rit != particles_stream.rend(); rit++) {
+ Particle *particle = (*rit);
+
+ if (particles_oriented) {
+ quad[0].assign(particle->up() - particle->left());
+ quad[1].assign(particle->up() + particle->left());
+ quad[2].assign(particle->up() * -1 + particle->left());
+ quad[3].assign(particle->up() * -1 - particle->left());
+ } else {
+ 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 < particles_timeout * 0.1f) {
+ f = t / (0.1f * particles_timeout);
+ } else {
+ t = t - particles_timeout * 0.1f;
+ f = t / (0.9f * particles_timeout);
+ f = 1.0 - f;
+ }
+
+ f *= f;
+ float radius = particles_radius * f;
+ particles_color.a = f;
+ gl::color(particles_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();
+ }
+}
+
+} // namespace render
diff --git a/src/render/particles.h b/src/render/particles.h
new file mode 100644
index 0000000..400971c
--- /dev/null
+++ b/src/render/particles.h
@@ -0,0 +1,73 @@
+/*
+ render/particles.h
+ This file is part of the Osirion project and is distributed under
+ the terms of the GNU General Public License version 2
+*/
+
+#ifndef __INCLUDED_RENDER_PARTICLES_H__
+#define __INCLUDED_RENDER_PARTICLES_H__
+
+#include <deque>
+
+#include "math/color.h"
+#include "math/vector3f.h"
+#include "core/entity.h"
+
+namespace render {
+
+class Particle {
+public:
+ Particle(const math::Vector3f &location, float time);
+ Particle(const math::Vector3f &location, const math::Vector3f &up, const math::Vector3f &left, float time);
+
+ inline const math::Vector3f &location() const { return particle_location; }
+
+ inline const math::Vector3f &up() const { return particle_up; }
+
+ inline const math::Vector3f &left() const { return particle_left; }
+
+ inline const float time() const { return particle_time; }
+
+protected:
+ math::Vector3f particle_location;
+ math::Vector3f particle_up;
+ math::Vector3f particle_left;
+
+ float particle_time;
+};
+
+
+class ParticleStream {
+public:
+ ParticleStream(const math::Vector3f &location, const math::Color &color, float radius, size_t texture, core::EntityControlable *entity = 0, bool oriented = false);
+ ~ParticleStream();
+
+ void draw();
+
+ inline const size_t texture() const { return particles_texture; }
+
+ inline const math::Vector3f &location() const { return particles_location; }
+
+protected:
+ typedef std::deque<Particle *> Particles;
+
+ math::Vector3f particles_location;
+ math::Color particles_color;
+ size_t particles_texture;
+ bool particles_oriented;
+
+ float particles_radius;
+ float particles_timeout;
+ float particles_eject;
+
+ float particles_last_eject;
+
+ core::EntityControlable *particles_entity;
+
+ Particles particles_stream;
+};
+
+
+} // namespace render
+
+#endif // __INCLUDED_RENDER_PARTICLES_H__
diff --git a/src/render/renderext.cc b/src/render/renderext.cc
index ffe462f..5b6f3b4 100644
--- a/src/render/renderext.cc
+++ b/src/render/renderext.cc
@@ -23,10 +23,16 @@ RenderExt::RenderExt(core::Entity *entity) : core::Extension(core::Extension::Re
state_detailvisible = false;
state_fuzz = math::randomf();
- state_engine_trail_offset = 0;
+ //state_engine_trail_offset = 0;
using namespace model;
+ if (!entity->model() && entity->modelname().size()) {
+ entity->set_modelname(entity->modelname());
+ if (!entity->model())
+ entity->set_modelname("");
+ }
+
if (entity->model()) {
model::Model *model = entity->model();
@@ -39,17 +45,20 @@ RenderExt::RenderExt(core::Entity *entity) : core::Extension(core::Extension::Re
light->render_texture = Textures::load(flarename.str());
}
- for(Model::Engines::iterator eit = model->engines().begin(); eit != model->engines().end(); eit++) {
- Engine *engine = (*eit);
+ if ((entity->type() == core::Entity::Controlable) && entity->model()->engines().size()) {
- if (!engine->flare()) engine->engine_flare = 1;
+ size_t trail_texure = Textures::load("bitmaps/fx/circle00");
- // load engine texture
- std::stringstream flarename;
- flarename << "bitmaps/fx/flare" << std::setfill('0') << std::setw(2) << engine->flare();
- engine->render_texture = Textures::load(flarename.str());
+ for(Model::Engines::iterator eit = model->engines().begin(); eit != model->engines().end(); eit++) {
+ Engine *engine = (*eit);
+
+ // add trail particles
+ math::Color c;
+ ParticleStream *p = new ParticleStream(engine->location(), c, 0.0625 * engine->radius(), trail_texure, static_cast<core::EntityControlable *>(entity), true);
+ state_particles.push_back(p);
+ }
}
-
+
for (Model::Flares::iterator flit = model->flares().begin(); flit != model->flares().end(); flit++) {
Flare *flare = (*flit);
@@ -58,6 +67,7 @@ RenderExt::RenderExt(core::Entity *entity) : core::Extension(core::Extension::Re
flarename << "bitmaps/fx/flare" << std::setfill('0') << std::setw(2) << flare->flare();
flare->render_texture = Textures::load(flarename.str());
}
+
} else if (entity->type() == core::Entity::Globe) {
core::EntityGlobe *globe = static_cast<core::EntityGlobe *>(entity);
@@ -74,6 +84,10 @@ RenderExt::RenderExt(core::Entity *entity) : core::Extension(core::Extension::Re
RenderExt::~RenderExt()
{
+ for (Particles::iterator it = state_particles.begin(); it != state_particles.end(); it++) {
+ delete (*it);
+ }
+ state_particles.clear();
}
void RenderExt::frame(float elapsed)
diff --git a/src/render/renderext.h b/src/render/renderext.h
index eafa707..eb2ae67 100644
--- a/src/render/renderext.h
+++ b/src/render/renderext.h
@@ -7,7 +7,10 @@
#ifndef __INCLUDED_RENDER_RENDEREXT_H__
#define __INCLUDED_RENDER_RENDEREXT_H__
+#include <list>
+
#include "core/extension.h"
+#include "render/particles.h"
namespace render
{
@@ -18,6 +21,8 @@ public:
RenderExt(core::Entity *entity);
~RenderExt();
+ typedef std::list<ParticleStream *> Particles;
+
virtual void frame(float elapsed);
inline bool visible() const { return state_visible; }
@@ -28,15 +33,16 @@ public:
/// distance to the camera
inline float distance() const { return state_distance; }
- // FIXME
- float state_engine_trail_offset;
-
+ /// particles
+ inline Particles &particles() { return state_particles; }
private:
- bool state_visible;
- bool state_detailvisible;
+ bool state_visible;
+ bool state_detailvisible;
- float state_fuzz;
- float state_distance;
+ float state_fuzz;
+ float state_distance;
+
+ Particles state_particles;
};
} // namespace render
diff --git a/src/render/tgafile.cc b/src/render/tgafile.cc
index 5a27648..c4e6b56 100644
--- a/src/render/tgafile.cc
+++ b/src/render/tgafile.cc
@@ -298,7 +298,7 @@ void TGA::save(const char *filename, Image & image)
} else {
- // compressed block and pixel data is identical
+ // compressed block and pixel data are identical
if (memcmp(block_data, pixel_data, image.channels()) == 0) {
block_length++;