]> git.tdb.fi Git - libs/gl.git/blob - source/render/renderer.h
Redesign depth and stencil test and blend state management
[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                 const DepthTest *depth_test;
99                 const StencilTest *stencil_test;
100                 const Blend *blend;
101                 unsigned object_lod_bias;
102
103                 State();
104         };
105
106         enum ChangeMask
107         {
108                 MATRIX = 2,
109                 SHADER_DATA = 16
110         };
111
112         unsigned char changed;
113         std::vector<State> state_stack;
114         State *state;
115         std::vector<BoundTexture> texture_stack;
116         ProgramData standard_shdata;
117         std::vector<BoundProgramData> shdata_stack;
118         std::set<const Renderable *> excluded;
119         PipelineState pipeline_state;
120
121 public:
122         Renderer();
123         ~Renderer();
124
125         /** Sets the camera to render from.  The model matrix is reset to identity. */
126         void set_camera(const Camera &);
127
128         const Camera *get_camera() const { return state->camera; }
129
130         /** Replaces the Renderer's model matrix. */
131         void set_matrix(const Matrix &);
132
133         /** Applies a transform to the Renderer's model matrix. */
134         void transform(const Matrix &);
135
136         /** Returns the current model matrix. */
137         const Matrix &get_matrix() const { return state->model_matrix; }
138
139         void set_texture(Tag, const Texture *, const Sampler * = 0);
140 private:
141         void flush_textures();
142 public:
143         DEPRECATED void set_material(const Material *);
144
145         DEPRECATED void set_lighting(const Lighting *);
146         void set_clipping(const Clipping *);
147
148         /** Sets the shader program to use.  An initial set of data can be set as
149         well, with the same semantics as add_shader_data. */
150         void set_shader_program(const Program *prog, const ProgramData *data = 0);
151
152         /** Adds another set of data to be use with shader programs.  The data is
153         independent of any shader program changes and remains in effect until the
154         Renderer state is popped. */
155         void add_shader_data(const ProgramData &data);
156
157         DEPRECATED void flush_shader_data() { flush_shader_data_(); }
158 private:
159         void flush_shader_data_();
160
161 public:
162         void set_vertex_setup(const VertexSetup *);
163         void set_front_face(FaceWinding);
164         void set_face_cull(CullMode);
165
166         void set_depth_test(const DepthTest *);
167         void set_stencil_test(const StencilTest *);
168         void set_blend(const Blend *);
169
170         void set_object_lod_bias(unsigned);
171         unsigned get_object_lod_bias() const { return state->object_lod_bias; }
172
173         /** Saves the current state so it can be restored later. */
174         void push_state();
175
176         /** Restores a previously saved state.  Must be matched with an earlier
177         push_state call. */
178         void pop_state();
179
180         /** Unbinds all objects and resets related state.  There must be no unpopped
181         state in the stack.  The Renderer remains valid and may be reused for
182         further rendering. */
183         void end();
184
185         void exclude(const Renderable &);
186         void include(const Renderable &);
187
188         void render(const Renderable &, Tag = Tag());
189         void draw(const Batch &);
190         void draw_instanced(const Batch &, unsigned);
191
192 private:
193         void apply_state();
194 };
195
196 } // namespace GL
197 } // namespace Msp
198
199 #endif