]> git.tdb.fi Git - libs/gl.git/blob - source/render/renderer.h
75c8cc8b58aaada99b371eb1bfc553d47d3d4ad7
[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 BoundTexture
67         {
68                 Tag tag;
69                 mutable int binding = -1;
70                 const Texture *texture = 0;
71                 const Sampler *sampler = 0;
72                 int level = -1;
73                 int replaced = -1;
74         };
75
76         struct BoundProgramData
77         {
78                 const ProgramData *shdata;
79                 mutable unsigned generation = 0;
80
81                 BoundProgramData(const ProgramData *);
82         };
83
84         struct State
85         {
86                 std::uintptr_t pipeline_key = 0;
87                 const Camera *camera = 0;
88                 Matrix model_matrix;
89                 const Framebuffer *framebuffer = 0;
90                 const Rect *viewport = 0;
91                 const Rect *scissor = 0;
92                 unsigned texture_count = 0;
93                 const Program *shprog = 0;
94                 unsigned shdata_count = 0;
95                 const VertexSetup *vertex_setup = 0;
96                 FaceWinding front_face = NON_MANIFOLD;
97                 CullMode face_cull = NO_CULL;
98                 const DepthTest *depth_test = 0;
99                 const StencilTest *stencil_test = 0;
100                 const Blend *blend = 0;
101                 unsigned object_lod_bias = 0;
102         };
103
104         enum ChangeMask
105         {
106                 PIPELINE_KEY = 1,
107                 MATRIX = 2,
108                 SHADER_DATA = 16
109         };
110
111         unsigned frame_index = 0;
112         unsigned char changed = 0;
113         std::vector<State> state_stack;
114         State *current_state = 0;
115         ProgramData standard_shdata;
116         std::vector<BoundProgramData> shdata_stack;
117         std::vector<BoundTexture> texture_stack;
118         const Texture &placeholder_texture;
119         PipelineState *last_pipeline = 0;
120         Commands commands;
121
122 public:
123         Renderer();
124
125         /** Begins rendering, allowing commands to be issued. */
126         void begin();
127
128         /** Ends rendering.  Any global state is reset to defaults.  No further
129         commands are allowed before the next call to begin(). */
130         void end();
131
132         using RendererBackend::begin;
133         using RendererBackend::end;
134
135         /** Saves the current state so it can be restored later. */
136         void push_state();
137
138         /** Restores a previously saved state.  Must be matched with an earlier
139         push_state call. */
140         void pop_state();
141
142 private:
143         State &get_state() const;
144
145 public:
146         void set_pipeline_key(std::uintptr_t);
147         void set_pipeline_key(const void *p) { set_pipeline_key(reinterpret_cast<uintptr_t>(p)); }
148
149         template<typename T>
150         void set_pipeline_key(std::uintptr_t k, T d)
151         { set_pipeline_key(k^(static_cast<uintptr_t>(d)<<((sizeof(std::uintptr_t)-sizeof(T))*std::numeric_limits<char>::digits))); }
152
153         template<typename T>
154         void set_pipeline_key(const void *p, T d) { set_pipeline_key(reinterpret_cast<uintptr_t>(p), d); }
155
156         /** Sets the camera to render from.  The model matrix is reset to identity. */
157         void set_camera(const Camera &);
158
159         const Camera *get_camera() const { return get_state().camera; }
160
161         /** Replaces the Renderer's model matrix. */
162         void set_matrix(const Matrix &);
163
164         /** Returns the current model matrix. */
165         const Matrix &get_matrix() const { return get_state().model_matrix; }
166
167         void set_framebuffer(const Framebuffer *);
168         void set_viewport(const Rect *);
169         void set_scissor(const Rect *);
170
171         const Framebuffer *get_framebuffer() const { return get_state().framebuffer; }
172
173         /** Sets the shader program to use.  As a convenience, uniform values may be
174         specified at the same time. */
175         void set_shader_program(const Program *prog, const ProgramData *data = 0);
176
177         /** Adds uniform values, which will be available for shader programs.  If
178         multiple ProgramData objects with the same uniforms are added, the one added
179         last will be used. */
180         void add_shader_data(const ProgramData &data);
181
182         void set_texture(Tag, const Texture *, const Sampler * = 0);
183         void set_texture(Tag, const Texture *, int, const Sampler * = 0);
184
185 private:
186         void flush_shader_data();
187         void flush_textures();
188
189 public:
190         void set_vertex_setup(const VertexSetup *);
191         void set_front_face(FaceWinding);
192         void set_face_cull(CullMode);
193
194         void set_depth_test(const DepthTest *);
195         void set_stencil_test(const StencilTest *);
196         void set_blend(const Blend *);
197
198         void set_object_lod_bias(unsigned);
199         unsigned get_object_lod_bias() const { return get_state().object_lod_bias; }
200
201         /** Clears framebuffer contents.  If values is not null, it must contain one
202         element for each attachment.  Otherwise the framebuffer contents are
203         discarded and become undefined. */
204         void clear(const ClearValue *values);
205
206         /** Draws a batch of primitives.  A shader must be active. */
207         void draw(const Batch &);
208
209         /** Draws multiple instances of a batch of primitives.  A shader must be active. */
210         void draw_instanced(const Batch &, unsigned);
211
212         /** Resolves multisample attachments from the active framebuffer into
213         target. */
214         void resolve_multisample(Framebuffer &target);
215
216         void begin_query(const QueryPool &, unsigned);
217         void end_query(const QueryPool &, unsigned);
218
219 private:
220         PipelineState &get_pipeline_state();
221         void apply_framebuffer();
222         void apply_state();
223 };
224
225 } // namespace GL
226 } // namespace Msp
227
228 #endif