X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=blobdiff_plain;f=source%2Fzsortedscene.cpp;h=46b14dbb6a672dbfd044b1ffa7463695e9212244;hp=f61de57720fc8f394f72aa752f678964a2046ace;hb=71240e5c5ef7165313664ee9fe81df95c0eff10b;hpb=3919a742c65783a9ebce05a88427bdcd8f6a6c92 diff --git a/source/zsortedscene.cpp b/source/zsortedscene.cpp index f61de577..46b14dbb 100644 --- a/source/zsortedscene.cpp +++ b/source/zsortedscene.cpp @@ -12,6 +12,18 @@ ZSortedScene::ZSortedScene(): reference(FURTHEST) { } +void ZSortedScene::add(Renderable &r) +{ + if(renderables.insert(&r).second && !sorted_cache.empty()) + sorted_cache.push_back(&r); +} + +void ZSortedScene::remove(Renderable &r) +{ + renderables.erase(&r); + sorted_cache.clear(); +} + void ZSortedScene::set_order(SortOrder o) { order = o; @@ -22,45 +34,98 @@ void ZSortedScene::set_reference(DepthReference r) reference = r; } +void ZSortedScene::populate_cache() const +{ + if(sorted_cache.empty() && !renderables.empty()) + { + sorted_cache.reserve(renderables.size()); + sorted_cache.insert(sorted_cache.end(), renderables.begin(), renderables.end()); + } +} + +void ZSortedScene::setup_frame(Renderer &renderer) +{ + populate_cache(); + for(SortedArray::const_iterator i=sorted_cache.begin(); i!=sorted_cache.end(); ++i) + i->renderable->setup_frame(renderer); +} + +void ZSortedScene::finish_frame() +{ + for(SortedArray::const_iterator i=sorted_cache.begin(); i!=sorted_cache.end(); ++i) + i->renderable->finish_frame(); +} + void ZSortedScene::render(Renderer &renderer, const Tag &tag) const { + if(renderables.empty()) + return; + + populate_cache(); + const Camera *camera = renderer.get_camera(); if(!camera) - return SimpleScene::render(renderer, tag); + { + for(SortedArray::const_iterator i=sorted_cache.begin(); i!=sorted_cache.end(); ++i) + renderer.render(*i->renderable, tag); + return; + } - const Matrix &view_matrix = camera->get_matrix(); + const Vector3 &camera_pos = camera->get_position(); + const Vector3 &look_dir = camera->get_look_direction(); + float radius_factor = reference-1.0f; + float sign = 1.0f-order*2.0f; - std::vector sorted_renderables; - sorted_renderables.reserve(renderables.size()); + bool use_frustum = setup_frustum(renderer); + for(SortedArray::iterator i=sorted_cache.begin(); i!=sorted_cache.end(); ++i) + { + i->in_frustum = (!use_frustum || !frustum_cull(*i->renderable)); + if(!i->in_frustum) + continue; - float radius_factor = 1.0f-reference; - float sign = order*2.0f-1.0f; + if(const Matrix *matrix = i->renderable->get_matrix()) + { + if(const Geometry::BoundingSphere *bsphere = i->renderable->get_bounding_sphere()) + i->depth = dot(*matrix*bsphere->get_center()-camera_pos, look_dir)+bsphere->get_radius()*radius_factor; + else + i->depth = dot(*matrix*Vector3()-camera_pos, look_dir); + i->depth *= sign; + } + else + i->depth = 0; + } - bool use_frustum = setup_frustum(renderer); - for(RenderableSet::const_iterator i=renderables.begin(); i!=renderables.end(); ++i) - if(!use_frustum || !frustum_cull(**i)) + for(SortedArray::iterator i=sorted_cache.begin(), j=i; i!=sorted_cache.end(); ++i) + if(i->in_frustum) { - float z = 0; - if(const Matrix *model_matrix = (*i)->get_matrix()) + if(i!=j) + swap(*i, *j); + + if(j!=sorted_cache.begin() && *j<*(j-1)) { - if(const Geometry::BoundingSphere *bsphere = (*i)->get_bounding_sphere()) - z = (view_matrix**model_matrix*compose(bsphere->get_center(), 1.0f)).z+bsphere->get_radius()*radius_factor; - else - z = (view_matrix**model_matrix*Vector4(0.0f, 0.0f, 0.0f, 1.0f)).z; + SortedRenderable sr = *j; + SortedArray::iterator k = j-1; + *j = *k; + while(k!=sorted_cache.begin() && sr<*(k-1)) + { + *k = *(k-1); + --k; + } + *k = sr; } - sorted_renderables.push_back(DepthRenderable(z*sign, *i)); - } - sort(sorted_renderables.begin(), sorted_renderables.end()); + ++j; + } - for(vector::const_iterator i=sorted_renderables.begin(); i!=sorted_renderables.end(); ++i) - i->renderable->render(renderer, tag); + for(SortedArray::const_iterator i=sorted_cache.begin(); (i!=sorted_cache.end() && i->in_frustum); ++i) + renderer.render(*i->renderable, tag); } -ZSortedScene::DepthRenderable::DepthRenderable(float d, const Renderable *r): - depth(d), - renderable(r) +ZSortedScene::SortedRenderable::SortedRenderable(Renderable *r): + renderable(r), + in_frustum(false), + depth(0.0f) { } } // namespace GL