]> git.tdb.fi Git - libs/gl.git/commitdiff
Remove the culler abstraction and move frustum culling to Scene
authorMikko Rasa <tdb@tdb.fi>
Fri, 4 Dec 2015 12:09:48 +0000 (14:09 +0200)
committerMikko Rasa <tdb@tdb.fi>
Fri, 4 Dec 2015 12:25:03 +0000 (14:25 +0200)
It turns out that different culling methods (such as occlusion queries)
have different enough requirements that putting them behind a single
abstraction is not feasible.  This also seems to provide a slight
performance boost.

source/culler.h [deleted file]
source/frustumculler.cpp [deleted file]
source/frustumculler.h [deleted file]
source/instancescene.cpp
source/orderedscene.cpp
source/scene.cpp
source/scene.h
source/simplescene.cpp
source/zsortedscene.cpp

diff --git a/source/culler.h b/source/culler.h
deleted file mode 100644 (file)
index 4d2bdb7..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-#ifndef MSP_GL_CULLER_H_
-#define MSP_GL_CULLER_H_
-
-namespace Msp {
-namespace GL {
-
-class Renderable;
-class Renderer;
-
-/**
-Base class and interface for cullers.  Scenes can use cullers to avoid
-rendering things that are not visible.
-*/
-class Culler
-{
-protected:
-       Culler() { }
-public:
-       virtual ~Culler() { }
-
-       /** Called once at the start of each rendering pass. */
-       virtual void setup_pass(const Renderer &) { };
-
-       /** Decides if a renderable should be culled.  If this returns true, the
-       renderable is skipped. */
-       virtual bool cull(const Renderer &, const Renderable &) const = 0;
-};
-
-} // namespace GL
-} // namespace Msp
-
-#endif
diff --git a/source/frustumculler.cpp b/source/frustumculler.cpp
deleted file mode 100644 (file)
index ca7a3a2..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-#include "camera.h"
-#include "frustumculler.h"
-#include "renderable.h"
-#include "renderer.h"
-
-#include <msp/io/print.h>
-
-namespace Msp {
-namespace GL {
-
-void FrustumCuller::setup_pass(const Renderer &renderer)
-{
-       const Camera *camera = renderer.get_camera();
-       if(!camera)
-               return;
-
-       float y = tan(camera->get_field_of_view()/2.0f);
-       float s = sqrt(y*y+1);
-       edges[0] = Vector3(0, 1/s, y/s);
-       edges[1] = Vector3(0, -1/s, y/s);
-
-       float x = y*camera->get_aspect();
-       s = sqrt(x*x+1);
-       edges[2] = Vector3(1/s, 0, x/s);
-       edges[3] = Vector3(-1/s, 0, x/s);
-}
-
-bool FrustumCuller::cull(const Renderer &renderer, const Renderable &renderable) const
-{
-       const Matrix *matrix = renderable.get_matrix();
-       const Geometry::BoundingSphere<float, 3> *bsphere = renderable.get_bounding_sphere();
-       const Camera *camera = renderer.get_camera();
-       if(!matrix || !bsphere || !camera)
-               return false;
-
-       Matrix mvm = camera->get_matrix()**matrix;
-       float n = camera->get_near_clip();
-       float f = camera->get_far_clip();
-
-       Vector3 center = mvm*bsphere->get_center();
-       float radius = bsphere->get_radius();
-
-       if(center.z-radius>-n || center.z+radius<-f)
-               return true;
-       for(unsigned i=0; i<4; ++i)
-               if(dot(center, edges[i])>radius)
-                       return true;
-
-       return false;
-}
-
-} // namespace GL
-} // namespace Msp
diff --git a/source/frustumculler.h b/source/frustumculler.h
deleted file mode 100644 (file)
index 4d22760..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-#ifndef MSP_GL_FRUSTUMCULLER_H_
-#define MSP_GL_FRUSTUMCULLER_H_
-
-#include "culler.h"
-#include "vector.h"
-
-namespace Msp {
-namespace GL {
-
-/**
-Culls objects that are outside of the view frustum.
-*/
-class FrustumCuller: public Culler
-{
-private:
-       Vector3 edges[4];
-
-public:
-       virtual void setup_pass(const Renderer &);
-
-       virtual bool cull(const Renderer &, const Renderable &) const;
-};
-
-} // namespace GL
-} // namespace Msp
-
-#endif
index 0ff9b520dd30247465719f5609961698cba9ecf3..fef3e9697e602051248bfe35f827078eac8a4117 100644 (file)
@@ -38,10 +38,10 @@ void InstanceScene::finish_frame() const
 
 void InstanceScene::render(Renderer &renderer, const Tag &tag) const
 {
-       setup_cullers(renderer);
+       setup_frustum(renderer);
        for(InstanceMap::const_iterator i=renderables.begin(); i!=renderables.end(); ++i)
                for(RenderableSet::const_iterator j=i->second.begin(); j!=i->second.end(); ++j)
-                       if(!cull(renderer, **j))
+                       if(!frustum_cull(renderer, **j))
                                renderer.render(**j, tag);
 }
 
index fe968f0c430ca2c127458dde5cafa6678047001c..f129cdab33e20b68549a933cb61c2473f729f241 100644 (file)
@@ -49,9 +49,9 @@ void OrderedScene::finish_frame() const
 
 void OrderedScene::render(Renderer &renderer, const Tag &tag) const
 {
-       setup_cullers(renderer);
+       setup_frustum(renderer);
        for(RenderableList::const_iterator i=renderables.begin(); i!=renderables.end(); ++i)
-               if(!cull(renderer, **i))
+               if(!frustum_cull(renderer, **i))
                        renderer.render(**i, tag);
 }
 
index f233a09b31ea39324324db15c11586b789e8be99..7896d23d6246830d0f1716beaf830a0cff4e8665 100644 (file)
@@ -1,6 +1,6 @@
 #include <msp/datafile/collection.h>
 #include "animatedobject.h"
-#include "culler.h"
+#include "camera.h"
 #include "renderer.h"
 #include "scene.h"
 
@@ -15,35 +15,50 @@ Scene::~Scene()
                delete *i;
 }
 
-void Scene::add_culler(Culler &c)
-{
-       cullers.push_back(&c);
-}
-
-void Scene::remove_culler(Culler &c)
-{
-       list<Culler *>::iterator i = find(cullers.begin(), cullers.end(), &c);
-       if(i!=cullers.end())
-               cullers.erase(i);
-}
-
 void Scene::render(const Tag &tag) const
 {
        Renderer renderer(0);
        render(renderer, tag);
 }
 
-void Scene::setup_cullers(const Renderer &renderer) const
+void Scene::setup_frustum(const Renderer &renderer) const
 {
-       for(list<Culler *>::const_iterator i=cullers.begin(); i!=cullers.end(); ++i)
-               (*i)->setup_pass(renderer);
+       const Camera *camera = renderer.get_camera();
+       if(!camera)
+               return;
+
+       float y = tan(camera->get_field_of_view()/2.0f);
+       float s = sqrt(y*y+1);
+       frustum_edges[0] = Vector3(0, 1/s, y/s);
+       frustum_edges[1] = Vector3(0, -1/s, y/s);
+
+       float x = y*camera->get_aspect();
+       s = sqrt(x*x+1);
+       frustum_edges[2] = Vector3(1/s, 0, x/s);
+       frustum_edges[3] = Vector3(-1/s, 0, x/s);
 }
 
-bool Scene::cull(const Renderer &renderer, const Renderable &renderable) const
+bool Scene::frustum_cull(const Renderer &renderer, const Renderable &renderable) const
 {
-       for(list<Culler *>::const_iterator i=cullers.begin(); i!=cullers.end(); ++i)
-               if((*i)->cull(renderer, renderable))
+       const Matrix *matrix = renderable.get_matrix();
+       const Geometry::BoundingSphere<float, 3> *bsphere = renderable.get_bounding_sphere();
+       const Camera *camera = renderer.get_camera();
+       if(!matrix || !bsphere || !camera)
+               return false;
+
+       Matrix mvm = camera->get_matrix()**matrix;
+       float n = camera->get_near_clip();
+       float f = camera->get_far_clip();
+
+       Vector3 center = mvm*bsphere->get_center();
+       float radius = bsphere->get_radius();
+
+       if(center.z-radius>-n || center.z+radius<-f)
+               return true;
+       for(unsigned i=0; i<4; ++i)
+               if(dot(center, frustum_edges[i])>radius)
                        return true;
+
        return false;
 }
 
index 687c581fe5d4070c27d6e62819be4a3f8bff48aa..611f3508e2d7e103a592787aa5e08ea75f0f1625 100644 (file)
@@ -4,12 +4,11 @@
 #include <list>
 #include <msp/datafile/objectloader.h>
 #include "renderable.h"
+#include "vector.h"
 
 namespace Msp {
 namespace GL {
 
-class Culler;
-
 /**
 Scenes are containers for other Renderables.  This is a base class that can't
 be instantiated.  Examples of available Scene types are SimpleScene,
@@ -29,7 +28,7 @@ public:
 
 protected:
        std::list<Renderable *> owned_data;
-       std::list<Culler *> cullers;
+       mutable Vector3 frustum_edges[4];
 
        Scene() { }
 private:
@@ -41,15 +40,12 @@ public:
        virtual void add(const Renderable &) = 0;
        virtual void remove(const Renderable &) = 0;
 
-       void add_culler(Culler &);
-       void remove_culler(Culler &);
-
        using Renderable::render;
        virtual void render(const Tag & = Tag()) const;
 
 protected:
-       virtual void setup_cullers(const Renderer &) const;
-       virtual bool cull(const Renderer &, const Renderable &) const;
+       void setup_frustum(const Renderer &) const;
+       bool frustum_cull(const Renderer &, const Renderable &) const;
 };
 
 } // namespace GL
index c537ff3b87eef6ff3158b206accd0ab7b9d0c9c6..7629a8284b4ef213168f60a6d6973a95cab85834 100644 (file)
@@ -28,9 +28,9 @@ void SimpleScene::finish_frame() const
 
 void SimpleScene::render(Renderer &renderer, const Tag &tag) const
 {
-       setup_cullers(renderer);
+       setup_frustum(renderer);
        for(RenderableSet::const_iterator i=renderables.begin(); i!=renderables.end(); ++i)
-               if(!cull(renderer, **i))
+               if(!frustum_cull(renderer, **i))
                        renderer.render(**i, tag);
 }
 
index 5cbd202133902d1581c7c1be3e2ea118c38ae7da..c9bce6798a83959e8568dde9454b80b2ff28b2b0 100644 (file)
@@ -36,9 +36,9 @@ void ZSortedScene::render(Renderer &renderer, const Tag &tag) const
        float radius_factor = 1.0f-reference;
        float sign = order*2.0f-1.0f;
 
-       setup_cullers(renderer);
+       setup_frustum(renderer);
        for(RenderableSet::const_iterator i=renderables.begin(); i!=renderables.end(); ++i)
-               if(!cull(renderer, **i))
+               if(!frustum_cull(renderer, **i))
                {
                        float z = 0;
                        if(const Matrix *model_matrix = (*i)->get_matrix())