]> git.tdb.fi Git - libs/gl.git/blob - source/render/object.h
Use default member initializers for simple types
[libs/gl.git] / source / render / object.h
1 #ifndef MSP_GL_OBJECT_H_
2 #define MSP_GL_OBJECT_H_
3
4 #include <vector>
5 #include "renderable.h"
6 #include "rendermethod.h"
7 #include "resourceobserver.h"
8
9 namespace Msp {
10 namespace GL {
11
12 class Mesh;
13 class ObjectInstance;
14 class Technique;
15
16 /**
17 Combines a Mesh with a Technique to give it an appearance.  The Technique will
18 define which render passes the Object supports.
19
20 In many cases, it's desirable to include multiple copies of an Object in a
21 Scene, with different model matrices.  ObjectInstances can be used to alter the
22 rendering of an object on a per-instance basis.
23
24 Objects can have multiple levels of detail.  The most detailed level has index
25 0, with increasing indices having less detail.  When rendering an instance, the
26 instance's get_level_of_detail method is called to determine which LoD to use.
27 */
28 class Object: public Renderable, private ResourceObserver
29 {
30 private:
31         struct LevelOfDetail;
32
33         class LodLoader: public DataFile::CollectionObjectLoader<Object>
34         {
35         private:
36                 unsigned index;
37                 LevelOfDetail &lod;
38
39         public:
40                 LodLoader(Object &, unsigned, Collection &);
41
42         private:
43                 void mesh(const std::string &);
44                 void mesh_inline();
45                 void technique(const std::string &);
46                 void technique_inline();
47         };
48
49 public:
50         class Loader: public LodLoader
51         {
52         public:
53                 Loader(Object &, Collection &);
54         private:
55                 virtual void finish();
56
57                 void bounding_sphere_hint(float, float, float, float);
58                 void level_of_detail(unsigned);
59         };
60
61 private:
62         struct LevelOfDetail
63         {
64                 const Mesh *mesh;
65                 const Technique *technique;
66         };
67
68         std::vector<LevelOfDetail> lods;
69         Geometry::BoundingSphere<float, 3> bounding_sphere;
70         bool lod0_watched = false;
71
72         static const Matrix identity_matrix;
73
74 public:
75         Object();
76         Object(const Mesh *, const Technique *);
77         ~Object();
78
79 private:
80         LevelOfDetail &get_lod(unsigned, const char *);
81
82 public:
83         /** Sets the mesh for the highest level of detail (index 0). */
84         void set_mesh(const Mesh *m) { set_mesh(0, m); }
85
86         /** Sets the mesh for a given level of detail.  Previous LoDs must have been
87         defined. */
88         void set_mesh(unsigned, const Mesh *);
89
90 private:
91         void update_bounding_sphere();
92 public:
93         const Mesh *get_mesh(unsigned = 0) const;
94
95         /** Sets the technique for the highest level of detail (index 0). */
96         void set_technique(const Technique *t) { set_technique(0, t); }
97
98         /** Sets the technique for a given level of detail.  Previous LoDs must have
99         been defined. */
100         void set_technique(unsigned, const Technique *);
101
102         const Technique *get_technique(unsigned = 0) const;
103         unsigned get_n_lods() const { return lods.size(); }
104
105         virtual const Matrix *get_matrix() const { return &identity_matrix; }
106         virtual const Geometry::BoundingSphere<float, 3> *get_bounding_sphere() const { return &bounding_sphere; }
107
108         virtual void render(Renderer &, Tag = Tag()) const;
109
110         /** Renders an instance of the object.  The instance's hook functions are
111         called before and after drawing the mesh. */
112         virtual void render(Renderer &, const ObjectInstance &, Tag = Tag()) const;
113
114 protected:
115         virtual void setup_render(Renderer &, Tag) const { }
116         virtual void finish_render(Renderer &, Tag) const { }
117
118 private:
119         const RenderMethod *get_method(Tag, unsigned) const;
120
121         virtual void resource_loaded(Resource &);
122         virtual void resource_removed(Resource &);
123 };
124
125 } // namespace GL
126 } // namespace Msp
127
128 #endif