]> git.tdb.fi Git - libs/gl.git/blob - source/builders/sequencebuilder.cpp
Allow renderables to be specified in SequenceTemplate passes
[libs/gl.git] / source / builders / sequencebuilder.cpp
1 #include <msp/core/algorithm.h>
2 #include <msp/core/maputils.h>
3 #include "error.h"
4 #include "renderbuffer.h"
5 #include "sequence.h"
6 #include "sequencebuilder.h"
7 #include "sequencetemplate.h"
8
9 using namespace std;
10
11 namespace Msp {
12 namespace GL {
13
14 SequenceBuilder::SequenceBuilder(const SequenceTemplate &t):
15         tmpl(t)
16 {
17         const vector<SequenceTemplate::Step> &steps = tmpl.get_steps();
18         for(vector<SequenceTemplate::Step>::const_iterator i=steps.begin(); i!=steps.end(); ++i)
19                 renderables[i->slot_name] = i->default_renderable;
20         const vector<SequenceTemplate::PostProcessor> &postprocs = tmpl.get_postprocessors();
21         for(SequenceTemplate::PostProcessorArray::const_iterator i=postprocs.begin(); i!=postprocs.end(); ++i)
22                 if(!i->slot_name.empty())
23                         postprocessors[i->slot_name] = 0;
24 }
25
26 void SequenceBuilder::set_renderable(const string &name, Renderable &rend)
27 {
28         get_item(renderables, name) = &rend;
29 }
30
31 void SequenceBuilder::set_postprocessor(const string &name, PostProcessor &pproc)
32 {
33         get_item(postprocessors, name) = &pproc;
34 }
35
36 void SequenceBuilder::build(Sequence &sequence) const
37 {
38         sequence.set_hdr(tmpl.get_hdr());
39         sequence.set_alpha(tmpl.get_alpha());
40         unsigned samples = min(tmpl.get_maximum_multisample(), Renderbuffer::get_max_samples());
41         if(samples<tmpl.get_required_multisample())
42                 throw invalid_operation("SequenceBuilder::build");
43
44         sequence.set_multisample(samples);
45
46         const vector<SequenceTemplate::Step> &steps = tmpl.get_steps();
47         for(vector<SequenceTemplate::Step>::const_iterator i=steps.begin(); i!=steps.end(); ++i)
48         {
49                 Renderable *renderable = get_item(renderables, i->slot_name);
50                 if(!renderable)
51                         continue;
52
53                 Sequence::Step &step = sequence.add_step(i->tag, *renderable);
54                 step.set_blend(i->blend.get());
55                 step.set_depth_test(i->depth_test.get());
56                 step.set_lighting(i->lighting.get());
57         }
58
59         const SequenceTemplate::PostProcessorArray &postprocs = tmpl.get_postprocessors();
60         for(SequenceTemplate::PostProcessorArray::const_iterator i=postprocs.begin(); i!=postprocs.end(); ++i)
61         {
62                 PostProcessor *proc = 0;
63                 if(!i->slot_name.empty())
64                         proc = get_item(postprocessors, i->slot_name);
65                 if(proc)
66                         sequence.add_postprocessor(*proc);
67                 else if(i->postprocessor_template)
68                 {
69                         proc = i->postprocessor_template->create(tmpl.get_resources(), sequence.get_width(), sequence.get_height());
70                         if(proc)
71                                 sequence.add_postprocessor_owned(proc);
72                 }
73         }
74 }
75
76 Sequence *SequenceBuilder::build(unsigned w, unsigned h) const
77 {
78         RefPtr<Sequence> sequence = new Sequence(w, h);
79         build(*sequence);
80         return sequence.release();
81 }
82
83 Sequence *SequenceBuilder::build(const View &view) const
84 {
85         RefPtr<Sequence> sequence = new Sequence(view);
86         build(*sequence);
87         return sequence.release();
88 }
89
90 Sequence *SequenceBuilder::build(const Framebuffer &fbo) const
91 {
92         RefPtr<Sequence> sequence = new Sequence(fbo);
93         build(*sequence);
94         return sequence.release();
95 }
96
97 } // namespace GL
98 } // namespace Msp