1 #include <msp/core/algorithm.h>
2 #include <msp/core/maputils.h>
3 #include <msp/strings/format.h>
7 #include "sequencebuilder.h"
8 #include "sequencetemplate.h"
16 SequenceBuilder::SequenceBuilder(const SequenceTemplate &t):
19 for(const SequenceTemplate::Renderable &r: tmpl.get_renderables())
20 renderables[r.slot_name] = r.renderable;
21 for(const SequenceTemplate::PostProcessor &p: tmpl.get_postprocessors())
22 if(!p.slot_name.empty())
23 postprocessors[p.slot_name] = 0;
26 void SequenceBuilder::set_renderable(const string &name, Renderable &rend)
28 get_item(renderables, name) = &rend;
31 void SequenceBuilder::set_postprocessor(const string &name, PostProcessor &pproc)
33 get_item(postprocessors, name) = &pproc;
36 void SequenceBuilder::set_debug_name(const string &name)
45 void SequenceBuilder::build(Sequence &sequence) const
48 if(!debug_name.empty())
49 sequence.set_debug_name(debug_name);
52 map<string, Renderable *> final_renderables = renderables;
53 vector<const SequenceTemplate::Renderable *> sequences;
54 for(const SequenceTemplate::Renderable &r: tmpl.get_renderables())
56 Renderable *&ptr = final_renderables[r.slot_name];
61 Effect *effect = r.effect_template->create(final_renderables);
63 if(!debug_name.empty())
64 effect->set_debug_name(format("%s/%s", debug_name, r.slot_name));
68 else if(r.sequence_template)
70 Sequence *seq = new Sequence;
72 if(!debug_name.empty())
73 seq->set_debug_name(format("%s/%s", debug_name, r.slot_name));
76 sequences.push_back(&r);
79 throw invalid_operation("SequenceBuilder::build");
81 sequence.add_owned(ptr);
85 for(const SequenceTemplate::Renderable *s: sequences)
87 SequenceBuilder bld(*s->sequence_template);
88 for(const auto &kvp: s->sequence_renderables)
89 if(Renderable *r = get_item(final_renderables, kvp.second))
90 bld.set_renderable(kvp.first, *r);
91 bld.build(*static_cast<Sequence *>(get_item(final_renderables, s->slot_name)));
94 sequence.set_clear_enabled(tmpl.is_clear_enabled());
95 if(tmpl.is_clear_enabled())
97 sequence.set_clear_colors(tmpl.get_clear_colors());
98 sequence.set_clear_depth(tmpl.get_clear_depth());
99 sequence.set_clear_stencil(tmpl.get_clear_stencil());
102 for(const SequenceTemplate::Step &s: tmpl.get_steps())
104 // Existence is already ensured above
105 Renderable &renderable = *get_item(final_renderables, s.renderable_name);
106 Sequence::Step &step = sequence.add_step(s.tag, renderable);
107 step.set_depth_test(s.depth_test);
108 step.set_stencil_test(s.stencil_test);
109 step.set_lighting(s.lighting);
115 for(const SequenceTemplate::PostProcessor &p: tmpl.get_postprocessors())
117 PostProcessor *proc = 0;
118 if(!p.slot_name.empty())
119 proc = get_item(postprocessors, p.slot_name);
122 if(p.postprocessor_template)
124 proc = p.postprocessor_template->create(sequence.get_width(), sequence.get_height());
126 if(!debug_name.empty())
127 proc->set_debug_name(format("%s/%d.pproc", debug_name, index++));
131 throw invalid_operation("SequenceBuilder::build");
133 sequence.add_owned(proc);
136 sequence.add_postprocessor(*proc);
140 Sequence *SequenceBuilder::build() const
142 RefPtr<Sequence> sequence = new Sequence();
144 return sequence.release();
147 Sequence *SequenceBuilder::build(unsigned w, unsigned h) const
149 RefPtr<Sequence> sequence = create_sequence(w, h);
151 return sequence.release();
154 Sequence *SequenceBuilder::build(const View &view) const
156 RefPtr<Sequence> sequence = create_sequence(view.get_width(), view.get_height());
158 return sequence.release();
161 Sequence *SequenceBuilder::build(const Framebuffer &fbo) const
163 RefPtr<Sequence> sequence = create_sequence(fbo.get_width(), fbo.get_height());
165 return sequence.release();
168 Sequence * SequenceBuilder::create_sequence(unsigned w, unsigned h) const
170 if(!w || !h || tmpl.get_postprocessors().empty())
173 unsigned samples = min(tmpl.get_maximum_multisample(), Device::get_current().get_info().limits.max_samples);
174 if(samples<tmpl.get_required_multisample())
175 throw invalid_operation("SequenceBuilder::create_frame_format");
177 DataType color_type = (tmpl.get_hdr() ? HALF_FLOAT : UNSIGNED_BYTE);
178 PixelFormat color_pf = make_pixelformat(RGBA, color_type);
180 FrameFormat format = (COLOR_ATTACHMENT,color_pf, DEPTH_ATTACHMENT).set_samples(samples);
181 return new Sequence(w, h, format);