]> git.tdb.fi Git - libs/gl.git/blob - source/render/object.h
Check the flat qualifier from the correct member
[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 for a complete model.
18
19 An object does not have a model matrix and will be rendered at origin if used
20 by itself.  The ObjectInstance class provides a way to position objects in a
21 scene and customize them in other ways.
22
23 Objects can have multiple levels of detail, with different resources.  The most
24 detailed level has index 0, with increasing indices having less detail.  When
25 rendering an instance, the instance's get_level_of_detail method is called to
26 determine which LoD to use.
27
28 An Object can be rendered with any tag its Technique supports.  Unknown tags
29 are silently ignored.
30 */
31 class Object: public Renderable, private ResourceObserver
32 {
33 private:
34         struct LevelOfDetail;
35
36         class LodLoader: public DataFile::CollectionObjectLoader<Object>
37         {
38         private:
39                 unsigned index;
40                 LevelOfDetail &lod;
41
42         public:
43                 LodLoader(Object &, unsigned, Collection &);
44
45         private:
46                 void mesh(const std::string &);
47                 void mesh_inline();
48                 void technique(const std::string &);
49                 void technique_inline();
50         };
51
52 public:
53         class Loader: public LodLoader
54         {
55         public:
56                 Loader(Object &, Collection &);
57         private:
58                 virtual void finish();
59
60                 void bounding_sphere_hint(float, float, float, float);
61                 void level_of_detail(unsigned);
62         };
63
64 private:
65         struct LevelOfDetail
66         {
67                 const Mesh *mesh;
68                 const Technique *technique;
69         };
70
71         std::vector<LevelOfDetail> lods;
72         Geometry::BoundingSphere<float, 3> bounding_sphere;
73         bool lod0_watched = false;
74
75         static const Matrix identity_matrix;
76
77 public:
78         Object();
79         Object(const Mesh *, const Technique *);
80         Object(const Object &);
81         Object(Object &&);
82         ~Object();
83
84 private:
85         LevelOfDetail &get_lod(unsigned, const char *);
86         void watch_lod0();
87
88 public:
89         /** Sets the mesh for the highest level of detail (index 0). */
90         void set_mesh(const Mesh *m) { set_mesh(0, m); }
91
92         /** Sets the mesh for a specific level of detail.  LoDs must be defined in
93         order, without gaps.  If this call creates a new LoD, technique is copied
94         from the previous one. */
95         void set_mesh(unsigned, const Mesh *);
96
97 private:
98         void update_bounding_sphere();
99 public:
100         const Mesh *get_mesh(unsigned = 0) const;
101
102         /** Sets the technique for the highest level of detail (index 0). */
103         void set_technique(const Technique *t) { set_technique(0, t); }
104
105         /** Sets the technique for a specific level of detail.  LoDs must be defined
106         in order, without gaps.  If this call creates a new LoD, mesh is copied from
107         the previous one. */
108         void set_technique(unsigned, const Technique *);
109
110         const Technique *get_technique(unsigned = 0) const;
111         unsigned get_n_lods() const { return lods.size(); }
112
113         virtual const Matrix *get_matrix() const { return &identity_matrix; }
114         virtual const Geometry::BoundingSphere<float, 3> *get_bounding_sphere() const { return &bounding_sphere; }
115
116         virtual void render(Renderer &, Tag = Tag()) const;
117
118         /** Renders an instance of the object.  The instance's hook functions are
119         called before and after drawing the mesh. */
120         virtual void render(Renderer &, const ObjectInstance &, Tag = Tag()) const;
121
122 protected:
123         virtual void setup_render(Renderer &, Tag) const { }
124         virtual void finish_render(Renderer &, Tag) const { }
125
126 private:
127         const RenderMethod *get_method(Tag, unsigned) const;
128
129         virtual void resource_loaded(Resource &);
130         virtual void resource_removed(Resource &);
131 };
132
133 } // namespace GL
134 } // namespace Msp
135
136 #endif