]> git.tdb.fi Git - libs/gl.git/blob - source/renderer.h
dbb2d4905cf57ab2e3c18ef76816af577851da3b
[libs/gl.git] / source / renderer.h
1 #ifndef MSP_GL_RENDERER_H_
2 #define MSP_GL_RENDERER_H_
3
4 #include <set>
5 #include <vector>
6 #include "matrix.h"
7 #include "programdata.h"
8 #include "tag.h"
9
10 namespace Msp {
11 namespace GL {
12
13 class Batch;
14 class Buffer;
15 class Camera;
16 class Clipping;
17 class Material;
18 class Mesh;
19 class Lighting;
20 class Program;
21 class Renderable;
22 class Texture;
23 class Texturing;
24 class VertexSetup;
25 class WindingTest;
26
27 /**
28 A class for supervising the rendering process.  While many Renderables (in
29 particular, Objects and Scenes) can by rendered without a Renderer, using one
30 will often be more efficient.  This is especially true for ObjectInstances.
31
32 The Renderer works by deferring GL state changes until something is actually
33 being drawn.  This avoids many unnecessary GL calls if consecutive renderables
34 use the same resources.
35
36 A state stack is provided to help with state scoping.  Typically a Renderable
37 will push the current state on entry, set whatever state it requires, render
38 itself, and pop the state when it's done.  An RAII helper class is provided for
39 the push/pop operation.
40 */
41 class Renderer
42 {
43 public:
44         class Push
45         {
46         private:
47                 Renderer &renderer;
48
49         public:
50                 Push(Renderer &r): renderer(r) { renderer.push_state(); }
51                 ~Push() { renderer.pop_state(); }
52         };
53
54         class Exclude
55         {
56         private:
57                 Renderer &renderer;
58                 const Renderable &renderable;
59
60         public:
61                 Exclude(Renderer &r, const Renderable &e): renderer(r), renderable(e) { renderer.exclude(renderable); }
62                 ~Exclude() { renderer.include(renderable); }
63         };
64
65 private:
66         struct State
67         {
68                 const Camera *camera;
69                 Matrix modelview_matrix;
70                 const Texture *texture;
71                 const Texturing *texturing;
72                 unsigned lowest_effect_texunit;
73                 const Material *material;
74                 const Lighting *lighting;
75                 Matrix lighting_matrix;
76                 const Clipping *clipping;
77                 Matrix clipping_matrix;
78                 const Program *shprog;
79                 unsigned shdata_count;
80                 const Mesh *mesh;
81                 const VertexSetup *vertex_setup;
82                 const WindingTest *winding_test;
83                 bool reverse_winding;
84
85                 State();
86         };
87
88         enum ChangeMask
89         {
90                 LEGACY_MATRIX = 1,
91                 MODERN_MATRIX = 2,
92                 MATRIX = LEGACY_MATRIX|MODERN_MATRIX,
93                 LEGACY_LIGHTING = 4,
94                 LEGACY_CLIPPING = 8,
95                 SHADER_DATA = 16,
96                 MATERIAL_SHDATA = 32,
97                 STANDARD_SHDATA = 64,
98                 LEGACY_PROJECTION = 128
99         };
100
101         const Camera *default_camera;
102         unsigned char changed;
103         bool matrices_loaded;
104         std::vector<State> state_stack;
105         State *state;
106         ProgramData standard_shdata;
107         std::vector<const ProgramData *> shdata_stack;
108         std::set<const Renderable *> excluded;
109
110 public:
111         Renderer(const Camera *);
112         ~Renderer();
113
114         /** Resets all internal state and restarts rendering.  There must be no
115         unpopped state in the stack.  It is permissible to call begin() multiple
116         times without an intervening end().
117
118         Deprecated; use end() and set_camera() instead.*/
119         void begin(const Camera *);
120
121         /** Sets the camera to render from.  The modelview matrix is reset to the
122         camera's view matrix. */
123         void set_camera(const Camera &);
124
125         const Camera *get_camera() const { return state->camera; }
126
127         /** Replaces the Renderer's modelview matrix. */
128         void set_matrix(const Matrix &);
129
130         /** Applies a transform to the Renderer's modelview matrix. */
131         void transform(const Matrix &);
132
133         /** Returns the current modelview matrix. */
134         const Matrix &get_matrix() const { return state->modelview_matrix; }
135
136         void set_texture(const Texture *);
137         void set_texturing(const Texturing *);
138         unsigned allocate_effect_texunit();
139         void set_material(const Material *);
140
141         void set_lighting(const Lighting *);
142         void set_clipping(const Clipping *);
143
144         /** Sets the shader program to use.  An initial set of data can be set as
145         well, with the same semantics as add_shader_data. */
146         void set_shader_program(const Program *prog, const ProgramData *data = 0);
147
148         /** Adds another set of data to be use with shader programs.  The data is
149         independent of any shader program changes and remains in effect until the
150         Renderer state is popped. */
151         void add_shader_data(const ProgramData &data);
152
153         void set_mesh(const Mesh *);
154         void set_vertex_setup(const VertexSetup *);
155         void set_winding_test(const WindingTest *);
156         void set_reverse_winding(bool);
157
158         /** Saves the current state so it can be restored later. */
159         void push_state();
160
161         /** Restores a previously saved state.  Must be matched with an earlier
162         push_state call. */
163         void pop_state();
164
165         /** Unbinds all objects and resets related state.  There must be no unpopped
166         state in the stack.  The Renderer remains valid and may be reused for
167         further rendering. */
168         void end();
169
170         void exclude(const Renderable &);
171         void include(const Renderable &);
172
173         void render(const Renderable &, const Tag & = Tag());
174         void draw(const Batch &);
175         void draw_instanced(const Batch &, unsigned);
176
177 private:
178         void apply_state();
179 };
180
181 } // namespace GL
182 } // namespace Msp
183
184 #endif