]> git.tdb.fi Git - libs/gl.git/blob - source/builders/sequencetemplate.cpp
Allow renderables to be specified in SequenceTemplate passes
[libs/gl.git] / source / builders / sequencetemplate.cpp
1 #include <msp/core/maputils.h>
2 #include <msp/datafile/collection.h>
3 #include "ambientocclusion.h"
4 #include "blend.h"
5 #include "bloom.h"
6 #include "colorcurve.h"
7 #include "lighting.h"
8 #include "object.h"
9 #include "resources.h"
10 #include "scene.h"
11 #include "sequencetemplate.h"
12 #include "tests.h"
13
14 using namespace std;
15
16 namespace Msp {
17 namespace GL {
18
19 SequenceTemplate::SequenceTemplate():
20         resources(0),
21         hdr(false),
22         alpha(false),
23         required_multisample(0),
24         max_multisample(0)
25 { }
26
27 SequenceTemplate::~SequenceTemplate()
28 {
29         for(PostProcessorArray::iterator i=postprocessors.begin(); i!=postprocessors.end(); ++i)
30                 delete i->postprocessor_template;
31 }
32
33 Resources &SequenceTemplate::get_resources() const
34 {
35         if(!resources)  
36                 throw logic_error("no resources");
37         return *resources;
38 }
39
40
41 SequenceTemplate::PostProcessorRegistry &SequenceTemplate::get_postprocessor_registry()
42 {
43         static PostProcessorRegistry registry;
44         static bool initialized = false;
45         if(!initialized)
46         {
47                 registry.register_type<AmbientOcclusion>("ambient_occlusion");
48                 registry.register_type<Bloom>("bloom");
49                 registry.register_type<ColorCurve>("colorcurve");
50                 initialized = true;
51         }
52         return registry;
53 }
54
55
56 SequenceTemplate::Step::~Step()
57 { }
58
59
60 SequenceTemplate::PostProcessor::PostProcessor(GL::PostProcessor::Template *ppt):
61         postprocessor_template(ppt)
62 { }
63
64
65 SequenceTemplate::PostProcLoader::PostProcLoader()
66 {
67         get_postprocessor_registry().invoke_all(*this);
68 }
69
70
71 SequenceTemplate::Loader::Loader(SequenceTemplate &t, Collection &c):
72         DataFile::CollectionObjectLoader<SequenceTemplate, Resources>(t, &c)
73 {
74         add("hdr", &SequenceTemplate::hdr);
75         add("alpha", &SequenceTemplate::alpha);
76         add("multisample", &Loader::multisample);
77         add("multisample", &Loader::multisample_range);
78         add("postprocessor", &Loader::postprocessor);
79         add("step", &Loader::step);
80         add("step", &Loader::step_with_slot);
81
82         // Deprecated
83         add("pass", &Loader::step_with_slot);
84
85         obj.resources = &c;
86 }
87
88 void SequenceTemplate::Loader::postprocessor_loaded()
89 {
90         obj.postprocessors.push_back(get_postprocessor_template());
91 }
92
93 void SequenceTemplate::Loader::multisample(unsigned samples)
94 {
95         obj.required_multisample = samples;
96         obj.max_multisample = samples;
97 }
98
99 void SequenceTemplate::Loader::multisample_range(unsigned req, unsigned max)
100 {
101         obj.required_multisample = req;
102         obj.max_multisample = max;
103 }
104
105 void SequenceTemplate::Loader::postprocessor(const string &slot)
106 {
107         PostProcLoader ldr;
108         load_sub_with(ldr);
109         PostProcessor pp;
110         pp.postprocessor_template = ldr.get_postprocessor_template();
111         pp.slot_name = slot;
112         obj.postprocessors.push_back(pp);
113 }
114
115 void SequenceTemplate::Loader::step(const string &tag)
116 {
117         step_with_slot(tag, string());
118 }
119
120 void SequenceTemplate::Loader::step_with_slot(const string &tag, const string &rend)
121 {
122         Step stp;
123         stp.tag = tag;
124         stp.slot_name = rend;
125         if(coll)
126                 load_sub(stp, *coll);
127         else
128                 load_sub(stp);
129
130         obj.steps.push_back(stp);
131 }
132
133
134 SequenceTemplate::Step::Loader::Loader(Step &p):
135         DataFile::CollectionObjectLoader<Step>(p, 0)
136 {
137         init();
138 }
139
140 SequenceTemplate::Step::Loader::Loader(Step &p, Collection &c):
141         DataFile::CollectionObjectLoader<Step>(p, &c)
142 {
143         init();
144 }
145
146 void SequenceTemplate::Step::Loader::init()
147 {
148         add("blend", &Loader::blend);
149         add("blend", &Loader::blend_predefined);
150         add("depth_test", &Loader::depth_test);
151         add("depth_test", &Loader::depth_test_predefined);
152         add("lighting", &Loader::lighting);
153         add("lighting", &Loader::lighting_inline);
154         add("object", &Loader::object);
155         add("scene", &Loader::scene);
156 }
157
158 void SequenceTemplate::Step::Loader::blend_predefined(const string &name)
159 {
160         const Blend *bln = 0;
161         if(name=="alpha")
162                 bln = &Blend::alpha();
163         else if(name=="additive")
164                 bln = &Blend::additive();
165         else if(name=="additive_alpha")
166                 bln = &Blend::additive_alpha();
167         else
168                 throw key_error(name);
169
170         obj.blend = bln;
171         obj.blend.keep();
172 }
173
174 void SequenceTemplate::Step::Loader::blend(BlendFactor src, BlendFactor dest)
175 {
176         obj.blend = new Blend(src, dest);
177 }
178
179 void SequenceTemplate::Step::Loader::depth_test_predefined(const string &name)
180 {
181         const DepthTest *dtest = 0;
182         if(name=="lequal")
183                 dtest = &DepthTest::lequal();
184         else
185                 throw key_error(name);
186
187         obj.depth_test = dtest;
188         obj.depth_test.keep();
189 }
190
191 void SequenceTemplate::Step::Loader::depth_test(Predicate pred)
192 {
193         obj.depth_test = new DepthTest(pred);
194 }
195
196 void SequenceTemplate::Step::Loader::lighting_inline()
197 {
198         RefPtr<Lighting> lightn = new Lighting;
199         load_sub(*lightn);
200         obj.lighting = lightn;
201 }
202
203 void SequenceTemplate::Step::Loader::lighting(const string &name)
204 {
205         obj.lighting = &get_collection().get<Lighting>(name);
206         obj.lighting.keep();
207 }
208
209 void SequenceTemplate::Step::Loader::object(const string &name)
210 {
211         obj.default_renderable = &get_collection().get<GL::Object>(name);
212 }
213
214 void SequenceTemplate::Step::Loader::scene(const string &name)
215 {
216         obj.default_renderable = &get_collection().get<Scene>(name);
217 }
218
219 } // namespace GL
220 } // namespace Msp