diff options
Diffstat (limited to 'src/render/draw.cc')
-rw-r--r-- | src/render/draw.cc | 348 |
1 files changed, 164 insertions, 184 deletions
diff --git a/src/render/draw.cc b/src/render/draw.cc index ac74c9c..6f97e99 100644 --- a/src/render/draw.cc +++ b/src/render/draw.cc @@ -906,236 +906,216 @@ void draw_pass_model_fragments() /* ---- Model FX --------------------------------------------------- */ -void draw_pass_model_fx(float elapsed) +void draw_model_lights(model::Model *model, const float scale, + const math::Vector3f & entity_location, const math::Axis & entity_axis, + const math::Color & entity_color, const float thrust, const float fuzz) { float t = 0.0f; float a = 0.0f; float light_size = 0.0f; - bool power = true; - float thrust = 0.0f; math::Vector3f location; math::Vector3f offset; math::Color color; math::Axis flare_axis; - - // FIXME - // setting the depth buffer comparison function to less-or-equal - // this should prevent z-fighting with model geometry, - // but doesn't seem to perform as generally expected - gl::depthfunc(GL_LEQUAL); - - for (core::Zone::Content::iterator it = zone->content().begin(); it != zone->content().end(); it++) { - core::Entity *entity = (*it); - power = true; + // disable culling by default + gl::disable(GL_CULL_FACE); + model::Cull current_cull = model::CullNone; + + size_t current_texture = Textures::bind("textures/fx/flare00"); + + gl::begin(gl::Quads); - if ((entity->type() == core::Entity::Controlable) || (entity->type() == core::Entity::Dynamic)) { - int state = static_cast<core::EntityDynamic *>(entity)->state(); + // draw model lights + for (model::Model::Lights::iterator lit = model->lights().begin(); lit != model->lights().end(); lit++) { + model::Light *light = (*lit); - if ((state == core::Entity::NoPower) || (state == core::Entity::Destroyed)) { - power = false; + // engine activated lights + if (light->engine()) { + if (thrust < 0.001f) { + continue; // next light } } - if (entity->model() && ext_render(entity)->detailvisible() && power) { - - const float modelscale = entity->radius() / entity->model()->radius(); + // strobe frequency + if (light->strobe()) { + t = (core::application()->time() + fuzz - light->offset()) * light->frequency(); + if ((t - floorf(t)) > light->time()) { + continue; // next light + } + } + + // entity color overrides light color + // light color overrides engine color + if (light->entity()) { + color.assign(entity_color); + } else if (light->has_color()) { + color.assign(light->color()); + } else if (light->engine()) { + color.assign(model->enginecolor()); + } else { + color.assign(light->color()); + } - // disable culling by default - gl::disable(GL_CULL_FACE); - model::Cull current_cull = model::CullNone; + // default alpha is 0.8, engine flag alters alpha + a = 0.8f; + if (light->engine()) { + a *= thrust; + } + color.a = a; - // default light texture - size_t current_texture = Textures::bind("textures/fx/flare00"); - gl::enable(GL_TEXTURE_2D); - - if (draw_lights) { + location.assign(entity_location + (entity_axis * light->location()) * scale); + light_size = light->radius() * scale; - gl::begin(gl::Quads); + // track OpenGL state changes + if (current_texture != light->texture()) { + gl::end(); + current_texture = Textures::bind(light->texture()); + gl::begin(gl::Quads); + } - // draw model lights - for (model::Model::Lights::iterator lit = entity->model()->lights().begin(); lit != entity->model()->lights().end(); lit++) { - model::Light *light = (*lit); + // draw the quad + gl::color(color); - // engine activated lights - if (light->engine()) { - if (entity->type() == core::Entity::Controlable) { - core::EntityControlable *ec = static_cast<core::EntityControlable *>(entity); - if ((ec->state() == core::Entity::ImpulseInitiate) || (ec->state() == core::Entity::Impulse)) { - thrust = 1.0f; - } else { - thrust = ec->thrust(); - if (thrust < 0.001f) { - continue; // next light - } - } - } else { - continue; // next light - } - } + glTexCoord2f(1, 0); + gl::vertex(location + (Camera::axis().up() - Camera::axis().left()) * light_size); + glTexCoord2f(0, 0); + gl::vertex(location + (Camera::axis().up() + Camera::axis().left()) * light_size); + glTexCoord2f(0, 1); + gl::vertex(location + (Camera::axis().up() * -1 + Camera::axis().left()) * light_size); + glTexCoord2f(1, 1); + gl::vertex(location + (Camera::axis().up() * -1 - Camera::axis().left()) * light_size); + Stats::quads++; - // strobe frequency - if (light->strobe()) { - t = (core::application()->time() + ext_render(entity)->fuzz() - light->offset()) * light->frequency(); - if ((t - floorf(t)) > light->time()) { - continue; // next light - } - } - - // entity color overrides light color - // light color overrides engine color - if (light->entity()) { - color.assign(entity->color()); - } else if (light->has_color()) { - color.assign(light->color()); - } else if (light->engine()) { - color.assign(entity->model()->enginecolor()); - } else { - color.assign(light->color()); - } + } - // default alpha is 0.8, engine flag alters alpha - a = 0.8f; - if (light->engine()) { - a *= thrust; - } - color.a = a; + // draw flares + for (model::Model::Flares::iterator flit = model->flares().begin(); flit != model->flares().end(); flit++) { + model::Flare *flare = (*flit); - location.assign(entity->location() + (entity->axis() * light->location()) * modelscale); - light_size = light->radius() * modelscale; + // engine activated flares + if (flare->engine()) { + if (thrust < 0.001f) { + continue; // next flare + } + } - // track OpenGL state changes - if (current_texture != light->texture()) { - gl::end(); - current_texture = Textures::bind(light->texture()); - gl::begin(gl::Quads); - } + // strobe frequency + if (flare->strobe()) { + t = (core::application()->time() + fuzz - flare->offset()) * flare->frequency(); + if ((t - floorf(t)) > flare->time()) { + continue; // next flare + } + } - // draw the quad - gl::color(color); + // calulcate viewing angle factor + flare_axis.assign(entity_axis * flare->axis()); + a = math::absf(dotproduct(flare_axis.forward(), Camera::axis().forward())); + if (a < 0.001f) { + continue; // next flare + } - glTexCoord2f(1, 0); - gl::vertex(location + (Camera::axis().up() - Camera::axis().left()) * light_size); - glTexCoord2f(0, 0); - gl::vertex(location + (Camera::axis().up() + Camera::axis().left()) * light_size); - glTexCoord2f(0, 1); - gl::vertex(location + (Camera::axis().up() * -1 + Camera::axis().left()) * light_size); - glTexCoord2f(1, 1); - gl::vertex(location + (Camera::axis().up() * -1 - Camera::axis().left()) * light_size); - Stats::quads++; + // entity color overrides light color + // light color overrides engine color + if (flare->entity()) { + color.assign(entity_color); + } else if (flare->has_color()) { + color.assign(flare->color()); + } else if (flare->engine()) { + color.assign(model->enginecolor()); + } else { + color.assign(flare->color()); + } - } + // default alpha is 0.8, engine flag alters alpha + // alpha decreases with viewing angle + a *= 0.8f; + if (flare->engine()) { + a *= thrust; + } + color.a = a; - // draw flares - for (model::Model::Flares::iterator flit = entity->model()->flares().begin(); flit != entity->model()->flares().end(); flit++) { - model::Flare *flare = (*flit); + location.assign(entity_location + (entity_axis * flare->location()) * scale); + light_size = flare->radius() * scale; - // engine activated flares - if (flare->engine()) { - if (entity->type() == core::Entity::Controlable) { - core::EntityControlable *ec = static_cast<core::EntityControlable *>(entity); - if ((ec->state() == core::Entity::ImpulseInitiate) || (ec->state() == core::Entity::Impulse)) { - thrust = 1.0f; - } else { - thrust = ec->thrust(); - if (thrust < 0.001f) { - continue; // next flare - } - } - } else { - continue; // next flare - } - } + // track OpenGL state changes + if ((current_cull != flare->cull()) || (current_texture != flare->texture())) { + gl::end(); - // strobe frequency - if (flare->strobe()) { - t = (core::application()->time() + ext_render(entity)->fuzz() - flare->offset()) * flare->frequency(); - if ((t - floorf(t)) > flare->time()) { - continue; // next flare - } - } + if (current_texture != flare->texture()) { + current_texture = Textures::bind(flare->texture()); + } - // calulcate viewing angle factor - flare_axis.assign(entity->axis() * flare->axis()); - a = math::absf(dotproduct(flare_axis.forward(), Camera::axis().forward())); - if (a < 0.001f) { - continue; // next flare + if (current_cull != flare->cull()) { + if (flare->cull() == model::CullNone) { + gl::disable(GL_CULL_FACE); + current_cull = model::CullNone; + } else { + if (current_cull == model::CullNone) { + gl::enable(GL_CULL_FACE); } - // entity color overrides light color - // light color overrides engine color - if (flare->entity()) { - color.assign(entity->color()); - } else if (flare->has_color()) { - color.assign(flare->color()); - } else if (flare->engine()) { - color.assign(entity->model()->enginecolor()); + if (flare->cull() == model::CullBack) { + gl::cullface(GL_BACK); + current_cull = model::CullBack; } else { - color.assign(flare->color()); + gl::cullface(GL_FRONT); + current_cull = model::CullFront; } + } + } - // default alpha is 0.8, engine flag alters alpha - // alpha decreases with viewing angle - a *= 0.8f; - if (flare->engine()) { - a *= thrust; - } - color.a = a; - - location.assign(entity->location() + (entity->axis() * flare->location()) * modelscale ); - light_size = flare->radius() * modelscale; + gl::begin(gl::Quads); + } - // track OpenGL state changes - if ((current_cull != flare->cull()) || (current_texture != flare->texture())) { - gl::end(); + // draw the quad + gl::color(color); - if (current_texture != flare->texture()) { - current_texture = Textures::bind(flare->texture()); - } + glTexCoord2f(1, 0); + gl::vertex(location + (flare_axis.up() + flare_axis.left()) * light_size); + glTexCoord2f(0, 0); + gl::vertex(location + (flare_axis.up() - flare_axis.left()) * light_size); + glTexCoord2f(0, 1); + gl::vertex(location + (flare_axis.up() * -1 - flare_axis.left()) * light_size); + glTexCoord2f(1, 1); + gl::vertex(location + (flare_axis.up() * -1 + flare_axis.left()) * light_size); - if (current_cull != flare->cull()) { - if (flare->cull() == model::CullNone) { - gl::disable(GL_CULL_FACE); - current_cull = model::CullNone; - } else { - if (current_cull == model::CullNone) { - gl::enable(GL_CULL_FACE); - } - - if (flare->cull() == model::CullBack) { - gl::cullface(GL_BACK); - current_cull = model::CullBack; - } else { - gl::cullface(GL_FRONT); - current_cull = model::CullFront; - } - } - } - - gl::begin(gl::Quads); - } + Stats::quads++; + } - // draw the quad - gl::color(color); + gl::end(); + + gl::cullface(GL_BACK); + gl::enable(GL_CULL_FACE); +} - glTexCoord2f(1, 0); - gl::vertex(location + (flare_axis.up() + flare_axis.left()) * light_size); - glTexCoord2f(0, 0); - gl::vertex(location + (flare_axis.up() - flare_axis.left()) * light_size); - glTexCoord2f(0, 1); - gl::vertex(location + (flare_axis.up() * -1 - flare_axis.left()) * light_size); - glTexCoord2f(1, 1); - gl::vertex(location + (flare_axis.up() * -1 + flare_axis.left()) * light_size); +void draw_pass_model_fx(float elapsed) +{ + // enable texturing + gl::enable(GL_TEXTURE_2D); - Stats::quads++; - } + for (core::Zone::Content::iterator it = zone->content().begin(); it != zone->content().end(); it++) { + core::Entity *entity = (*it); - gl::end(); + if (entity->model() && ext_render(entity)->detailvisible() && ext_render(entity)->power()) { + + // draw lights and flares + if (draw_lights) { + const float modelscale = entity->radius() / entity->model()->radius(); + + draw_model_lights(entity->model(), modelscale, + entity->location(), entity->axis(), entity->color(), + ext_render(entity)->thrust(), ext_render(entity)->fuzz() + ); } - + + // draw particle systems if (draw_particles && ext_render(entity)->particles().size()) { + gl::disable(GL_CULL_FACE); + model::Cull current_cull = model::CullNone; + for (RenderExt::ParticleSystems::iterator it = ext_render(entity)->particles().begin(); it != ext_render(entity)->particles().end(); it++) { ParticleSystem *particlesystem = (*it); |