From: Mikko Rasa Date: Sat, 21 Sep 2013 09:59:22 +0000 (+0300) Subject: Add a Scene type that sorts its renderables by depth X-Git-Url: http://git.tdb.fi/?a=commitdiff_plain;h=c87860db3b23a98eda1adfe59acddffdb6eb8420;p=libs%2Fgl.git Add a Scene type that sorts its renderables by depth --- diff --git a/source/scene.h b/source/scene.h index e3aa1fab..fbc57a80 100644 --- a/source/scene.h +++ b/source/scene.h @@ -10,7 +10,7 @@ class Culler; /** Scenes are containers for other Renderables. This is a base class that can't -be instantiated. At the moment the available Scene types are SimpleScene, +be instantiated. Examples of available Scene types are SimpleScene, InstancedScene and OrderedScene. */ class Scene: public Renderable diff --git a/source/simplescene.h b/source/simplescene.h index be86285b..deba4d5f 100644 --- a/source/simplescene.h +++ b/source/simplescene.h @@ -12,7 +12,7 @@ The simplest possible Scene. Rendering order is unspecified. */ class SimpleScene: public Scene { -private: +protected: typedef std::set RenderableSet; RenderableSet renderables; diff --git a/source/zsortedscene.cpp b/source/zsortedscene.cpp new file mode 100644 index 00000000..da406b7e --- /dev/null +++ b/source/zsortedscene.cpp @@ -0,0 +1,67 @@ +#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::set_order(SortOrder o) +{ + order = o; +} + +void ZSortedScene::set_reference(DepthReference r) +{ + reference = r; +} + +void ZSortedScene::render(Renderer &renderer, const Tag &tag) const +{ + const Camera *camera = renderer.get_camera(); + if(!camera) + return SimpleScene::render(renderer, tag); + + const Matrix &view_matrix = camera->get_matrix(); + + std::vector sorted_renderables; + sorted_renderables.reserve(renderables.size()); + + float radius_factor = 1.0f-reference; + float sign = order*2.0f-1.0f; + + setup_cullers(renderer); + for(RenderableSet::const_iterator i=renderables.begin(); i!=renderables.end(); ++i) + if(!cull(renderer, **i)) + { + float z = 0; + if(const Matrix *model_matrix = (*i)->get_matrix()) + { + if(const Geometry::BoundingSphere *bsphere = (*i)->get_bounding_sphere()) + z = (view_matrix**model_matrix*Vector4(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; + } + sorted_renderables.push_back(DepthRenderable(z*sign, *i)); + } + + sort(sorted_renderables.begin(), sorted_renderables.end()); + + for(vector::const_iterator i=sorted_renderables.begin(); i!=sorted_renderables.end(); ++i) + i->renderable->render(renderer, tag); +} + + +ZSortedScene::DepthRenderable::DepthRenderable(float d, const Renderable *r): + depth(d), + renderable(r) +{ } + +} // namespace GL +} // namespace Msp diff --git a/source/zsortedscene.h b/source/zsortedscene.h new file mode 100644 index 00000000..f9f6f7ee --- /dev/null +++ b/source/zsortedscene.h @@ -0,0 +1,57 @@ +#ifndef MSP_GL_ZSORTEDSCENE_H_ +#define MSP_GL_ZSORTEDSCENE_H_ + +#include "simplescene.h" + +namespace Msp { +namespace GL { + +enum SortOrder +{ + FRONT_TO_BACK, + BACK_TO_FRONT +}; + +enum DepthReference +{ + CLOSEST, + CENTER, + FURTHEST +}; + +/** +Sorts renderables by their distance from the camera before rendering. Requires +renderables to have a matrix. +*/ +class ZSortedScene: public SimpleScene +{ +private: + struct DepthRenderable + { + float depth; + const Renderable *renderable; + + DepthRenderable(float, const Renderable *); + + bool operator<(const DepthRenderable &o) const { return depth