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