X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Frender%2Fzsortedscene.cpp;fp=source%2Frender%2Fzsortedscene.cpp;h=46b14dbb6a672dbfd044b1ffa7463695e9212244;hb=7aaec9a70b8d7733429bec043f8e33e02956f266;hp=0000000000000000000000000000000000000000;hpb=bec07999d95b76f4b47cffcc564d0cd0afc0435e;p=libs%2Fgl.git diff --git a/source/render/zsortedscene.cpp b/source/render/zsortedscene.cpp new file mode 100644 index 00000000..46b14dbb --- /dev/null +++ b/source/render/zsortedscene.cpp @@ -0,0 +1,132 @@ +#include "camera.h" +#include "renderer.h" +#include "zsortedscene.h" + +using namespace std; + +namespace Msp { +namespace GL { + +ZSortedScene::ZSortedScene(): + order(BACK_TO_FRONT), + 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; +} + +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) + { + for(SortedArray::const_iterator i=sorted_cache.begin(); i!=sorted_cache.end(); ++i) + renderer.render(*i->renderable, tag); + return; + } + + 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; + + 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; + + 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; + } + + for(SortedArray::iterator i=sorted_cache.begin(), j=i; i!=sorted_cache.end(); ++i) + if(i->in_frustum) + { + if(i!=j) + swap(*i, *j); + + if(j!=sorted_cache.begin() && *j<*(j-1)) + { + SortedRenderable sr = *j; + SortedArray::iterator k = j-1; + *j = *k; + while(k!=sorted_cache.begin() && sr<*(k-1)) + { + *k = *(k-1); + --k; + } + *k = sr; + } + + ++j; + } + + for(SortedArray::const_iterator i=sorted_cache.begin(); (i!=sorted_cache.end() && i->in_frustum); ++i) + renderer.render(*i->renderable, tag); +} + + +ZSortedScene::SortedRenderable::SortedRenderable(Renderable *r): + renderable(r), + in_frustum(false), + depth(0.0f) +{ } + +} // namespace GL +} // namespace Msp