Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStijn Buys <ingar@osirion.org>2015-01-10 23:30:34 +0000
committerStijn Buys <ingar@osirion.org>2015-01-10 23:30:34 +0000
commit8f996cd439b42f834c3263f518d73c4a3e630929 (patch)
tree9696c5de09f050d7946c186431cdf95ae9c54266
parent2aba6b4976cd81ea1af2af6d8adb77072cd3e0be (diff)
Use a draw list for entities and globes.
-rw-r--r--src/render/draw.cc160
1 files changed, 109 insertions, 51 deletions
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<float, core::EntityGlobe *> Globes;
-Globes globes_list;
+typedef std::list<core::Entity *> DrawlistEntities;
+typedef std::list<core::EntityGlobe *> 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<core::EntityGlobe *>(entity);
- // globes
- if (entity->type() == core::Entity::Globe) {
- core::EntityGlobe *globe = static_cast<core::EntityGlobe *>(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();
}