]> git.tdb.fi Git - libs/gl.git/blob - source/renderer.h
Add an object LoD bias parameter to Renderer
[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                 unsigned object_lod_bias;
85
86                 State();
87         };
88
89         enum ChangeMask
90         {
91                 LEGACY_MATRIX = 1,
92                 MODERN_MATRIX = 2,
93                 MATRIX = LEGACY_MATRIX|MODERN_MATRIX,
94                 LEGACY_LIGHTING = 4,
95                 LEGACY_CLIPPING = 8,
96                 SHADER_DATA = 16,
97                 MATERIAL_SHDATA = 32,
98                 STANDARD_SHDATA = 64,
99                 LEGACY_PROJECTION = 128
100         };
101
102         const Camera *default_camera;
103         unsigned char changed;
104         bool matrices_loaded;
105         std::vector<State> state_stack;
106         State *state;
107         ProgramData standard_shdata;
108         std::vector<const ProgramData *> shdata_stack;
109         std::set<const Renderable *> excluded;
110
111 public:
112         Renderer(const Camera *);
113         ~Renderer();
114
115         /** Resets all internal state and restarts rendering.  There must be no
116         unpopped state in the stack.  It is permissible to call begin() multiple
117         times without an intervening end().
118
119         Deprecated; use end() and set_camera() instead.*/
120         void begin(const Camera *);
121
122         /** Sets the camera to render from.  The modelview matrix is reset to the
123         camera's view matrix. */
124         void set_camera(const Camera &);
125
126         const Camera *get_camera() const { return state->camera; }
127
128         /** Replaces the Renderer's modelview matrix. */
129         void set_matrix(const Matrix &);
130
131         /** Applies a transform to the Renderer's modelview matrix. */
132         void transform(const Matrix &);
133
134         /** Returns the current modelview matrix. */
135         const Matrix &get_matrix() const { return state->modelview_matrix; }
136
137         void set_texture(const Texture *);
138         void set_texturing(const Texturing *);
139         unsigned allocate_effect_texunit();
140         void set_material(const Material *);
141
142         void set_lighting(const Lighting *);
143         void set_clipping(const Clipping *);
144
145         /** Sets the shader program to use.  An initial set of data can be set as
146         well, with the same semantics as add_shader_data. */
147         void set_shader_program(const Program *prog, const ProgramData *data = 0);
148
149         /** Adds another set of data to be use with shader programs.  The data is
150         independent of any shader program changes and remains in effect until the
151         Renderer state is popped. */
152         void add_shader_data(const ProgramData &data);
153
154         void set_mesh(const Mesh *);
155         void set_vertex_setup(const VertexSetup *);
156         void set_winding_test(const WindingTest *);
157         void set_reverse_winding(bool);
158
159         void set_object_lod_bias(unsigned);
160         unsigned get_object_lod_bias() const { return state->object_lod_bias; }
161
162         /** Saves the current state so it can be restored later. */
163         void push_state();
164
165         /** Restores a previously saved state.  Must be matched with an earlier
166         push_state call. */
167         void pop_state();
168
169         /** Unbinds all objects and resets related state.  There must be no unpopped
170         state in the stack.  The Renderer remains valid and may be reused for
171         further rendering. */
172         void end();
173
174         void exclude(const Renderable &);
175         void include(const Renderable &);
176
177         void render(const Renderable &, const Tag & = Tag());
178         void draw(const Batch &);
179         void draw_instanced(const Batch &, unsigned);
180
181 private:
182         void apply_state();
183 };
184
185 } // namespace GL
186 } // namespace Msp
187
188 #endif