+++ /dev/null
-#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
+++ /dev/null
-#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
+++ /dev/null
-#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
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);
}
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);
}
#include <msp/datafile/collection.h>
#include "animatedobject.h"
-#include "culler.h"
+#include "camera.h"
#include "renderer.h"
#include "scene.h"
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;
}
#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,
protected:
std::list<Renderable *> owned_data;
- std::list<Culler *> cullers;
+ mutable Vector3 frustum_edges[4];
Scene() { }
private:
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
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);
}
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())