From 360e51a9e672e301e2147eb06100f7e68dd74654 Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Tue, 30 Nov 2010 19:46:10 +0000 Subject: Render lights and flares in ui::ModelView. --- src/render/draw.cc | 348 +++++++++++++++++++++++++--------------------------- src/render/draw.h | 11 +- src/ui/modelview.cc | 100 ++++++--------- 3 files changed, 212 insertions(+), 247 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(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(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(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); diff --git a/src/render/draw.h b/src/render/draw.h index da5115f..4a758b1 100644 --- a/src/render/draw.h +++ b/src/render/draw.h @@ -29,10 +29,17 @@ void reset(); /// draw a sphere void draw_sphere(math::Color const & color, float radius); +/// draw mode lights and flares +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 +); + /// draw a model void draw_model_fragments(model::Model *model, - const math::Color & color_primary, const math::Color & color_secondary, - const float enginetime, const bool detail, const bool power, const float thrust); + const math::Color & color_primary, const math::Color & color_secondary, + const float enginetime, const bool detail, const bool power, const float thrust +); class Stats { diff --git a/src/ui/modelview.cc b/src/ui/modelview.cc index 0b01fb2..8d8adfc 100755 --- a/src/ui/modelview.cc +++ b/src/ui/modelview.cc @@ -13,6 +13,8 @@ #include "render/camera.h" #include "render/draw.h" #include "render/render.h" +#include +#include namespace ui { @@ -169,14 +171,9 @@ void ModelView::draw() // enable lighting gl::enable(GL_LIGHTING); - // apply manipulation - gl::push(); - gl::multmatrix(modelview_axis); - gl::scale(modelscale, modelscale, modelscale); - gl::disable(GL_BLEND); gl::depthmask(GL_TRUE); // enable writing to the depth buffer - gl::enable(GL_DEPTH_TEST); + gl::enable(GL_DEPTH_TEST); // enable depth test gl::enable(GL_CULL_FACE); // enable culling gl::enable(GL_COLOR_MATERIAL); // enable color tracking @@ -186,73 +183,54 @@ void ModelView::draw() glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnableClientState(GL_NORMAL_ARRAY); + // apply manipulation + gl::push(); + gl::multmatrix(modelview_axis); + gl::scale(modelscale, modelscale, modelscale); + render::State::set_normalize(true); + + const float thrust = 1.0f; - render::draw_model_fragments(model, core::localplayer()->color(), core::localplayer()->color_second(), core::application()->time(), true, true, 0.0f); + render::draw_model_fragments(model, core::localplayer()->color(), core::localplayer()->color_second(), core::application()->time(), true, true, thrust); render::State::set_normalize(false); + + gl::pop(); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_NORMAL_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); gl::disable(GL_LIGHTING); - gl::disable(GL_COLOR_MATERIAL); // disable color tracking - gl::disable(GL_CULL_FACE); // disable culling + gl::enable(GL_TEXTURE_2D); + gl::enable(GL_BLEND); + gl::depthmask(GL_FALSE); // disable depth buffer writing + + // load model light textures + for (model::Model::Lights::iterator lit = model->lights().begin(); lit != model->lights().end(); lit++) { + model::Light *light = (*lit); + + // load light texture + std::stringstream texturename; + texturename << "textures/fx/flare" << std::setfill('0') << std::setw(2) << light->flare(); + light->set_texture(render::Textures::load(texturename.str())); + } + + for (model::Model::Flares::iterator flit = model->flares().begin(); flit != model->flares().end(); flit++) { + model::Flare *flare = (*flit); + + // load flare texture + std::stringstream texturename; + texturename << "textures/fx/flare" << std::setfill('0') << std::setw(2) << flare->flare(); + flare->set_texture(render::Textures::load(texturename.str())); + } - gl::enable(GL_BLEND); // enable alpha blending - gl::pop(); + render::draw_model_lights(model, modelscale, math::Vector3f(), modelview_axis, core::localplayer()->color(), thrust, 0.0f); - /* - // draw manipulation marker - if (has_mouse_focus() && modelview_dragging) { - - gl::push(); - gl::multmatrix(modelview_manipaxis); - - const float r = model->radius(); - glAlphaFunc(GL_GREATER, 0.5f); - gl::enable(GL_ALPHA_TEST); - - gl::color(1.0f, 1.0f, 1.0f, 1.0f); - render::Textures::bind("bitmaps/ui/rotate"); - gl::enable(GL_TEXTURE_2D); - - gl::begin(gl::Quads); - - gl::texcoord(0.0f, 0.0f); - gl::vertex(r, 0.0f, r); - - gl::texcoord(1.0f, 0.0f); - gl::vertex(r, 0.0f, -r); - - gl::texcoord(1.0f, 1.0f); - gl::vertex(-r, 0.0f, -r); - - gl::texcoord(0.0f, 1.0f); - gl::vertex(-r, 0.0f, r); - - - gl::texcoord(1.0f, 1.0f); - gl::vertex(r, r, 0.0f); - - gl::texcoord(0.0f, 1.0f); - gl::vertex(r, -r, 0.0f); - - gl::texcoord(0.0f, 0.0f); - gl::vertex(-r, -r, 0.0f); - - gl::texcoord(1.0f, 0.0f); - gl::vertex(-r, r, 0.0f); - - gl::end(); - - gl::disable(GL_TEXTURE_2D); - gl::disable(GL_ALPHA_TEST); - - gl::pop(); - } - */ + gl::disable(GL_TEXTURE_2D); + gl::disable(GL_COLOR_MATERIAL); // disable color tracking + gl::disable(GL_CULL_FACE); // disable culling gl::depthmask(GL_TRUE); // enable depth buffer writing gl::disable(GL_DEPTH_TEST); // disable depth buffer testing -- cgit v1.2.3