]> git.tdb.fi Git - libs/gl.git/blob - source/render/renderer.h
Refactor winding-based culling
[libs/gl.git] / source / render / 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 "pipelinestate.h"
8 #include "programdata.h"
9 #include "tag.h"
10
11 namespace Msp {
12 namespace GL {
13
14 class Batch;
15 class Buffer;
16 class Camera;
17 class Clipping;
18 class Material;
19 class Mesh;
20 class Lighting;
21 class Program;
22 class Renderable;
23 class Sampler;
24 class Texture;
25 class VertexSetup;
26 class WindingTest;
27
28 /**
29 A class for supervising the rendering process.  While many Renderables (in
30 particular, Objects and Scenes) can by rendered without a Renderer, using one
31 will often be more efficient.  This is especially true for ObjectInstances.
32
33 The Renderer works by deferring GL state changes until something is actually
34 being drawn.  This avoids many unnecessary GL calls if consecutive renderables
35 use the same resources.
36
37 A state stack is provided to help with state scoping.  Typically a Renderable
38 will push the current state on entry, set whatever state it requires, render
39 itself, and pop the state when it's done.  An RAII helper class is provided for
40 the push/pop operation.
41 */
42 class Renderer
43 {
44 public:
45         class Push
46         {
47         private:
48                 Renderer &renderer;
49
50         public:
51                 Push(Renderer &r): renderer(r) { renderer.push_state(); }
52                 ~Push() { renderer.pop_state(); }
53         };
54
55         class Exclude
56         {
57         private:
58                 Renderer &renderer;
59                 const Renderable &renderable;
60
61         public:
62                 Exclude(Renderer &r, const Renderable &e): renderer(r), renderable(e) { renderer.exclude(renderable); }
63                 ~Exclude() { renderer.include(renderable); }
64         };
65
66 private:
67         struct BoundTexture
68         {
69                 Tag tag;
70                 mutable int unit;
71                 const Texture *texture;
72                 const Sampler *sampler;
73                 int replaced;
74
75                 BoundTexture();
76         };
77
78         struct BoundProgramData
79         {
80                 const ProgramData *shdata;
81                 mutable unsigned generation;
82
83                 BoundProgramData(const ProgramData *);
84         };
85
86         struct State
87         {
88                 const Camera *camera;
89                 Matrix model_matrix;
90                 unsigned texture_count;
91                 unsigned lowest_effect_texunit;
92                 const Clipping *clipping;
93                 const Program *shprog;
94                 unsigned shdata_count;
95                 const VertexSetup *vertex_setup;
96                 FaceWinding front_face;
97                 CullMode face_cull;
98                 unsigned object_lod_bias;
99
100                 State();
101         };
102
103         enum ChangeMask
104         {
105                 MATRIX = 2,
106                 SHADER_DATA = 16
107         };
108
109         unsigned char changed;
110         std::vector<State> state_stack;
111         State *state;
112         std::vector<BoundTexture> texture_stack;
113         ProgramData standard_shdata;
114         std::vector<BoundProgramData> shdata_stack;
115         std::set<const Renderable *> excluded;
116         PipelineState pipeline_state;
117
118 public:
119         Renderer();
120         ~Renderer();
121
122         /** Sets the camera to render from.  The model matrix is reset to identity. */
123         void set_camera(const Camera &);
124
125         const Camera *get_camera() const { return state->camera; }
126
127         /** Replaces the Renderer's model matrix. */
128         void set_matrix(const Matrix &);
129
130         /** Applies a transform to the Renderer's model matrix. */
131         void transform(const Matrix &);
132
133         /** Returns the current model matrix. */
134         const Matrix &get_matrix() const { return state->model_matrix; }
135
136         void set_texture(Tag, const Texture *, const Sampler * = 0);
137 private:
138         void flush_textures();
139 public:
140         DEPRECATED void set_material(const Material *);
141
142         DEPRECATED 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         DEPRECATED void flush_shader_data() { flush_shader_data_(); }
155 private:
156         void flush_shader_data_();
157
158 public:
159         void set_vertex_setup(const VertexSetup *);
160         void set_front_face(FaceWinding);
161         void set_face_cull(CullMode);
162
163         void set_object_lod_bias(unsigned);
164         unsigned get_object_lod_bias() const { return state->object_lod_bias; }
165
166         /** Saves the current state so it can be restored later. */
167         void push_state();
168
169         /** Restores a previously saved state.  Must be matched with an earlier
170         push_state call. */
171         void pop_state();
172
173         /** Unbinds all objects and resets related state.  There must be no unpopped
174         state in the stack.  The Renderer remains valid and may be reused for
175         further rendering. */
176         void end();
177
178         void exclude(const Renderable &);
179         void include(const Renderable &);
180
181         void render(const Renderable &, Tag = Tag());
182         void draw(const Batch &);
183         void draw_instanced(const Batch &, unsigned);
184
185 private:
186         void apply_state();
187 };
188
189 } // namespace GL
190 } // namespace Msp
191
192 #endif