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