]> git.tdb.fi Git - libs/gl.git/blob - source/render/scene.h
Unify the loader wrappers for Material and Scene
[libs/gl.git] / source / render / scene.h
1 #ifndef MSP_GL_SCENE_H_
2 #define MSP_GL_SCENE_H_
3
4 #include <map>
5 #include <msp/core/typeregistry.h>
6 #include <msp/datafile/objectloader.h>
7 #include "matrix.h"
8 #include "renderable.h"
9
10 namespace Msp {
11 namespace GL {
12
13 /**
14 Scenes are containers for other Renderables.  This is a base class that can't
15 be instantiated.  Examples of available Scene types are SimpleScene,
16 InstancedScene and OrderedScene.
17 */
18 class Scene: public Renderable
19 {
20 protected:
21         class Loader: public DataFile::CollectionObjectLoader<Scene>
22         {
23         public:
24                 typedef std::map<std::string, Renderable *> ContentMap;
25
26         private:
27                 ContentMap *content;
28                 unsigned inst_counter;
29
30         public:
31                 Loader(Scene &s, Collection &c): Loader(s, c, 0) { }
32                 Loader(Scene &s, Collection &c, ContentMap &m) : Loader(s, c, &m) { }
33         private:
34                 Loader(Scene &, Collection &, ContentMap *);
35
36                 void object(const std::string &);
37                 void object_tagged(const std::string &, const std::string &);
38                 void scene(const std::string &);
39         };
40
41 public:
42         class GenericLoader: public DataFile::Loader
43         {
44         private:
45                 template<typename T>
46                 struct CreateScene
47                 {
48                         void operator()(const std::string &, GenericLoader &) const;
49                 };
50
51                 DataFile::Collection &coll;
52                 Scene *scene;
53                 Loader *scene_loader;
54
55                 static ActionMap shared_actions;
56
57         public:
58                 GenericLoader(DataFile::Collection &);
59                 ~GenericLoader();
60
61                 Scene *get_object() { Scene *s = scene; scene = 0; return s; }
62         private:
63                 virtual void init_actions();
64
65                 void type(const DataFile::Symbol &);
66
67                 friend class Scene;
68         };
69
70 private:
71         typedef TypeRegistry<GenericLoader::CreateScene, GenericLoader &> SceneRegistry;
72
73 protected:
74         mutable Matrix culling_matrix;
75         mutable Vector4 frustum_edges[6];
76
77         Scene() { }
78 private:
79         Scene(const Scene &);
80         Scene &operator=(const Scene &);
81 public:
82         virtual ~Scene() { }
83
84         virtual void add(Renderable &) = 0;
85         virtual void remove(Renderable &) = 0;
86
87 protected:
88         bool setup_frustum(const Renderer &) const;
89         bool frustum_cull(const Renderable &) const;
90
91 public:
92         template<typename T>
93         static void register_type(const std::string &);
94 private:
95         static SceneRegistry &get_scene_registry();
96 };
97
98 template<typename T>
99 void Scene::register_type(const std::string &kw)
100 {
101         get_scene_registry().register_type<T>(kw);
102 }
103
104 template<typename T>
105 void Scene::GenericLoader::CreateScene<T>::operator()(const std::string &, GenericLoader &ldr) const
106 {
107         if(ldr.scene)
108                 throw std::logic_error("Scene type was already specified");
109
110         T *scene = new T;
111         ldr.scene = scene;
112         ldr.scene_loader = new typename T::Loader(*scene, ldr.coll);
113         ldr.add_auxiliary_loader(*ldr.scene_loader);
114 }
115
116 } // namespace GL
117 } // namespace Msp
118
119 #endif