]> git.tdb.fi Git - libs/gl.git/blob - source/render/renderer.h
Store simpler states by value in PipelineState
[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 "commands.h"
7 #include "matrix.h"
8 #include "programdata.h"
9 #include "renderer_backend.h"
10 #include "tag.h"
11
12 namespace Msp {
13 namespace GL {
14
15 class Batch;
16 class Buffer;
17 class Camera;
18 union ClearValue;
19 class Material;
20 class Mesh;
21 class Lighting;
22 class Program;
23 class QueryPool;
24 class Renderable;
25 class Sampler;
26 class Texture;
27 class VertexSetup;
28
29 /**
30 Rendering supervisor.  This is the primary interface for setting state and
31 issuing draw commands.
32
33 The Renderer class allows setting textures and uniform values by names (using
34 ProgramData for the latter).  The names are resolved into binding points when
35 the resources are needed for a draw command.
36
37 A state stack is provided to help with state management in render graphs.
38 Renderables can save the state by pushing it on the stack before beginning
39 their work, and pop it afterwards to restore it without disturbing state set
40 by outer scopes.
41 */
42 class Renderer: public RendererBackend
43 {
44         friend RendererBackend;
45
46 public:
47         /**
48         RAII helper class for pushing state on the stack.
49         */
50         class Push
51         {
52         private:
53                 Renderer &renderer;
54
55         public:
56                 Push(Renderer &r): renderer(r) { renderer.push_state(); }
57                 ~Push() { renderer.pop_state(); }
58         };
59
60 private:
61         struct BoundTexture
62         {
63                 Tag tag;
64                 mutable int binding = -1;
65                 const Texture *texture = 0;
66                 const Sampler *sampler = 0;
67                 int level = -1;
68                 int replaced = -1;
69         };
70
71         struct BoundProgramData
72         {
73                 const ProgramData *shdata;
74                 mutable unsigned generation = 0;
75
76                 BoundProgramData(const ProgramData *);
77         };
78
79         struct State
80         {
81                 const Camera *camera = 0;
82                 Matrix model_matrix;
83                 const Framebuffer *framebuffer = 0;
84                 const Rect *viewport = 0;
85                 const Rect *scissor = 0;
86                 unsigned texture_count = 0;
87                 const Program *shprog = 0;
88                 unsigned shdata_count = 0;
89                 const VertexSetup *vertex_setup = 0;
90                 FaceWinding front_face = NON_MANIFOLD;
91                 CullMode face_cull = NO_CULL;
92                 const DepthTest *depth_test = 0;
93                 const StencilTest *stencil_test = 0;
94                 const Blend *blend = 0;
95                 unsigned object_lod_bias = 0;
96         };
97
98         enum ChangeMask
99         {
100                 MATRIX = 2,
101                 SHADER_DATA = 16
102         };
103
104         unsigned frame_index = 0;
105         unsigned char changed = 0;
106         std::vector<State> state_stack;
107         State *current_state = 0;
108         ProgramData standard_shdata;
109         std::vector<BoundProgramData> shdata_stack;
110         std::vector<BoundTexture> texture_stack;
111         const Texture &placeholder_texture;
112         Commands commands;
113
114 public:
115         Renderer();
116
117         /** Begins rendering, allowing commands to be issued. */
118         void begin();
119
120         /** Ends rendering.  Any global state is reset to defaults.  No further
121         commands are allowed before the next call to begin(). */
122         void end();
123
124         using RendererBackend::begin;
125         using RendererBackend::end;
126
127         /** Saves the current state so it can be restored later. */
128         void push_state();
129
130         /** Restores a previously saved state.  Must be matched with an earlier
131         push_state call. */
132         void pop_state();
133
134 private:
135         State &get_state() const;
136
137 public:
138         /** Sets the camera to render from.  The model matrix is reset to identity. */
139         void set_camera(const Camera &);
140
141         const Camera *get_camera() const { return get_state().camera; }
142
143         /** Replaces the Renderer's model matrix. */
144         void set_matrix(const Matrix &);
145
146         /** Returns the current model matrix. */
147         const Matrix &get_matrix() const { return get_state().model_matrix; }
148
149         void set_framebuffer(const Framebuffer *);
150         void set_viewport(const Rect *);
151         void set_scissor(const Rect *);
152
153         const Framebuffer *get_framebuffer() const { return get_state().framebuffer; }
154
155         /** Sets the shader program to use.  As a convenience, uniform values may be
156         specified at the same time. */
157         void set_shader_program(const Program *prog, const ProgramData *data = 0);
158
159         /** Adds uniform values, which will be available for shader programs.  If
160         multiple ProgramData objects with the same uniforms are added, the one added
161         last will be used. */
162         void add_shader_data(const ProgramData &data);
163
164         void set_texture(Tag, const Texture *, const Sampler * = 0);
165         void set_texture(Tag, const Texture *, int, const Sampler * = 0);
166
167 private:
168         void flush_shader_data();
169         void flush_textures();
170
171 public:
172         void set_vertex_setup(const VertexSetup *);
173         void set_front_face(FaceWinding);
174         void set_face_cull(CullMode);
175
176         void set_depth_test(const DepthTest *);
177         void set_stencil_test(const StencilTest *);
178         void set_blend(const Blend *);
179
180         void set_object_lod_bias(unsigned);
181         unsigned get_object_lod_bias() const { return get_state().object_lod_bias; }
182
183         /** Clears framebuffer contents.  If values is not null, it must contain one
184         element for each attachment.  Otherwise the framebuffer contents are
185         discarded and become undefined. */
186         void clear(const ClearValue *values);
187
188         /** Draws a batch of primitives.  A shader must be active. */
189         void draw(const Batch &);
190
191         /** Draws multiple instances of a batch of primitives.  A shader must be active. */
192         void draw_instanced(const Batch &, unsigned);
193
194         /** Resolves multisample attachments from the active framebuffer into
195         target. */
196         void resolve_multisample(Framebuffer &target);
197
198         void begin_query(const QueryPool &, unsigned);
199         void end_query(const QueryPool &, unsigned);
200
201 private:
202         void apply_framebuffer();
203         void apply_state();
204 };
205
206 } // namespace GL
207 } // namespace Msp
208
209 #endif