From 8f996cd439b42f834c3263f518d73c4a3e630929 Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Sat, 10 Jan 2015 23:30:34 +0000 Subject: Use a draw list for entities and globes. --- src/render/draw.cc | 160 ++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 109 insertions(+), 51 deletions(-) (limited to 'src/render') diff --git a/src/render/draw.cc b/src/render/draw.cc index 47fcb40..5fcc740 100644 --- a/src/render/draw.cc +++ b/src/render/draw.cc @@ -57,8 +57,39 @@ core::Zone *zone = 0; bool draw_particles = true; bool draw_lights = true; -typedef std::map Globes; -Globes globes_list; +typedef std::list DrawlistEntities; +typedef std::list DrawlistGlobes; + +DrawlistEntities drawlist_entities; +DrawlistGlobes drawlist_globes; + +bool compare_globe_distance(const core::EntityGlobe * globefirst, const core::EntityGlobe * globesecond) +{ + const float d1 = ext_render(globefirst)->distance(); + const float d2 = ext_render(globesecond)->distance(); + if (d1 < d2) + { + return false; + } + else + { + return true; + } +} + +bool compare_entity_distance(const core::Entity * entityfirst, const core::Entity * entitysecond) +{ + const float d1 = ext_render(entityfirst)->distance(); + const float d2 = ext_render(entitysecond)->distance(); + if (d1 < d2) + { + return false; + } + else + { + return true; + } +} LightEnvironment lightenv_zone; @@ -82,9 +113,6 @@ void pass_prepare(float seconds) // initialize lights lightenv_zone.clear(); - // clear current list of globes - globes_list.clear(); - // zone ambient light GLfloat zone_ambient[4]; for (size_t i = 0; i < 3; i++) { @@ -93,40 +121,63 @@ void pass_prepare(float seconds) zone_ambient[3] = 1.0f; gl::lightmodel(GL_LIGHT_MODEL_AMBIENT, zone_ambient); - // zone light sources - for (core::Zone::Content::iterator it = zone->content().begin(); it != zone->content().end(); it++) { + // initialize draw lists + drawlist_entities.clear(); + drawlist_globes.clear(); + + for (core::Zone::Content::iterator it = zone->content().begin(); it != zone->content().end(); ++it) + { core::Entity *entity = (*it); + + if (entity->visible() && !entity->serverside()) + { + // add render extension if required + if (!ext_render(entity)) { + new RenderExt(entity); + } + entity->extension((size_t) core::Extension::Render)->frame(seconds); - if (!ext_render(entity)) { - new RenderExt(entity); - } - entity->extension((size_t) core::Extension::Render)->frame(seconds); + if (entity->type() == core::Entity::Globe) + { + core::EntityGlobe *globe = static_cast(entity); - // globes - if (entity->type() == core::Entity::Globe) { - core::EntityGlobe *globe = static_cast(entity); + // add the globe to the draw list + if (globe->visible() && !ext_render(globe)->behind()) + { + drawlist_globes.push_back(globe); + } - // add the globe to the globes list - if (globe->visible() && !ext_render(globe)->behind()) { - globes_list[ext_render(globe)->distance()] = globe; - } + // add zone lights to the light environment + if (globe->has_flag(core::Entity::Bright)) + { + float zone_light_brightness = math::max(globe->color().r, math::max(globe->color().g, globe->color().b)); + Light *zone_light = new Light(globe->location(), globe->color()); + zone_light->set_attenuation(zone_light_brightness * 1.5f, zone_light_brightness * 0.00001f, zone_light_brightness * 0.000000001f); + lightenv_zone.add(zone_light); + } - // add zone lights - if (globe->has_flag(core::Entity::Bright)) { - float zone_light_brightness = math::max(globe->color().r, math::max(globe->color().g, globe->color().b)); - Light *zone_light = new Light(globe->location(), globe->color()); - zone_light->set_attenuation(zone_light_brightness * 1.5f, zone_light_brightness * 0.00001f, zone_light_brightness * 0.000000001f); - lightenv_zone.add(zone_light); } - - } else { - // this reloads entity models if required by r_restart - if (!entity->model() && entity->modelname().size()) { - entity->set_model(model::Model::load(entity->modelname())); + else + { + // add entity to draw lists + if (entity->visible() || !ext_render(entity)->behind()) + { + drawlist_entities.push_back(entity); + } + + // loads entity models if required + if (!entity->model() && entity->modelname().size()) { + + entity->set_model(model::Model::load(entity->modelname())); + } } } } + // sort draw lists by distance + drawlist_entities.sort(compare_entity_distance); + drawlist_globes.sort(compare_globe_distance); + // zone lights are draw in world space coordinates lightenv_zone.draw(); lightenv_zone.enable(); @@ -366,8 +417,9 @@ void draw_pass_globes() // Globes have to be rendered distance sorted, closest last. // Globes behind farplane are rescaled and repositioned. - for (Globes::reverse_iterator rit = globes_list.rbegin(); rit != globes_list.rend(); rit++) { - const core::EntityGlobe *globe = (*rit).second; + for (DrawlistGlobes::const_iterator it = drawlist_globes.begin(); it != drawlist_globes.end(); ++it) + { + const core::EntityGlobe *globe = (*it); math::Vector3f location(globe->location()); float radius = globe->radius(); @@ -590,20 +642,22 @@ void draw_entity_axis(const core::Entity* entity) void draw_pass_default() { - for (core::Zone::Content::iterator it = zone->content().begin(); it != zone->content().end(); ++it) { - - core::Entity *entity = (*it); - if (!entity->model() && (entity->type() != core::Entity::Globe) && !entity->serverside() && !ext_render(entity)->behind()) { - + for (DrawlistEntities::const_iterator it = drawlist_entities.begin(); it != drawlist_entities.end(); ++it) + { + const core::Entity *entity = (*it); + if (!entity->model() && ext_render(entity)->visible()) + { gl::push(); gl::translate(entity->location()); gl::multmatrix(entity->axis()); - if (entity->has_flag(core::Entity::Bright)) { + if (entity->has_flag(core::Entity::Bright)) + { gl::disable(GL_LIGHTING); } - switch (entity->shape()) { + switch (entity->shape()) + { case core::Entity::Sphere: draw_entity_sphere(entity); break; @@ -623,7 +677,8 @@ void draw_pass_default() break; } - if (entity->has_flag(core::Entity::Bright)) { + if (entity->has_flag(core::Entity::Bright)) + { gl::enable(GL_LIGHTING); } @@ -710,8 +765,8 @@ void draw_model_fragments(model::Model *model, State::set_color_engine(model->enginecolor() * thrust); State::set_power(power); - for (model::Model::Groups::const_iterator git = model->groups().begin(); git != model->groups().end(); git++) { - + for (model::Model::Groups::const_iterator git = model->groups().begin(); git != model->groups().end(); git++) + { const model::FragmentGroup *group = (*git); gl::push(); @@ -733,17 +788,20 @@ void draw_model_fragments(model::Model *model, gl::translate(translation); } - for (model::FragmentGroup::Fragments::const_iterator fit = group->fragments().begin(); fit != group->fragments().end(); fit++) { + for (model::FragmentGroup::Fragments::const_iterator fit = group->fragments().begin(); fit != group->fragments().end(); fit++) + { const model::Fragment *fragment = (*fit); - for (model::Material::Layers::const_iterator lit = fragment->material()->layers().begin(); lit != fragment->material()->layers().end(); ++lit) { + for (model::Material::Layers::const_iterator lit = fragment->material()->layers().begin(); lit != fragment->material()->layers().end(); ++lit) + { State::use_material_layer(fragment->material(), (*lit)); draw_fragment(fragment, detail); State::reset(); } - if (r_normals->value()) { + if (r_normals->value()) + { // force reset of material settings for the next fragment State::reset(); gl::color(0.75f, 0.0f, 0.0f); @@ -804,10 +862,11 @@ void draw_pass_model_fragments() * to sync core and render movement of fragmentgroups without sacrificing * the functionality of the FragmentGroup::engine() flag. */ - for (core::Zone::Content::iterator it = zone->content().begin(); it != zone->content().end(); it++) { + for (DrawlistEntities::iterator it = drawlist_entities.begin(); it != drawlist_entities.end(); ++it) + { core::Entity *entity = (*it); - if (entity->model() && ext_render(entity)->visible() && !ext_render(entity)->behind()) { + if (entity->model() && ext_render(entity)->visible()) { gl::push(); gl::translate(entity->location()); gl::multmatrix(entity->axis()); @@ -1087,7 +1146,8 @@ void draw_pass_model_fx(float elapsed) // enable texturing gl::enable(GL_TEXTURE_2D); - for (core::Zone::Content::iterator it = zone->content().begin(); it != zone->content().end(); it++) { + for (DrawlistEntities::iterator it = drawlist_entities.begin(); it != drawlist_entities.end(); ++it) + { core::Entity *entity = (*it); if (entity->model() && ext_render(entity)->detailvisible()) { @@ -1123,7 +1183,8 @@ void draw_pass_model_fx(float elapsed) void draw_pass_model_radius() { - for (core::Zone::Content::iterator it = zone->content().begin(); it != zone->content().end(); it++) { + for (DrawlistEntities::iterator it = drawlist_entities.begin(); it != drawlist_entities.end(); ++it) + { core::Entity *entity = (*it); if (entity->model() && ext_render(entity)->visible()) { @@ -1320,9 +1381,6 @@ void draw(float seconds) // clear current zone light environment lightenv_zone.disable(); lightenv_zone.clear(); - - // clear current list of globes - globes_list.clear(); } -- cgit v1.2.3