]> git.tdb.fi Git - libs/gl.git/blob - source/builders/sequencetemplate.cpp
Support effects and subordinate sequences inside sequence templates
[libs/gl.git] / source / builders / sequencetemplate.cpp
1 #include <msp/core/maputils.h>
2 #include <msp/datafile/collection.h>
3 #include <msp/strings/format.h>
4 #include "ambientocclusion.h"
5 #include "blend.h"
6 #include "bloom.h"
7 #include "colorcurve.h"
8 #include "environmentmap.h"
9 #include "lighting.h"
10 #include "object.h"
11 #include "resources.h"
12 #include "scene.h"
13 #include "sequencetemplate.h"
14 #include "shadowmap.h"
15 #include "sky.h"
16
17 using namespace std;
18
19 namespace Msp {
20 namespace GL {
21
22 SequenceTemplate::~SequenceTemplate()
23 {
24         for(const Renderable &r: renderables)
25                 delete r.effect_template;
26         for(const PostProcessor &p: postprocessors)
27                 delete p.postprocessor_template;
28 }
29
30 template<>
31 SequenceTemplate::TemplateRegistry<GL::PostProcessor> &SequenceTemplate::get_registry<GL::PostProcessor>()
32 {
33         static TemplateRegistry<GL::PostProcessor> registry;
34         static bool initialized = false;
35         if(!initialized)
36         {
37                 registry.register_type<AmbientOcclusion::Template>("ambient_occlusion");
38                 registry.register_type<Bloom::Template>("bloom");
39                 registry.register_type<ColorCurve::Template>("colorcurve");
40                 initialized = true;
41         }
42         return registry;
43 }
44
45 template<>
46 SequenceTemplate::TemplateRegistry<Effect> &SequenceTemplate::get_registry<Effect>()
47 {
48         static TemplateRegistry<Effect> registry;
49         static bool initialized = false;
50         if(!initialized)
51         {
52                 registry.register_type<EnvironmentMap::Template>("environment_map");
53                 registry.register_type<ShadowMap::Template>("shadow_map");
54                 registry.register_type<Sky::Template>("sky");
55                 initialized = true;
56         }
57         return registry;
58 }
59
60
61 SequenceTemplate::PostProcessor::PostProcessor(GL::PostProcessor::Template *ppt):
62         postprocessor_template(ppt)
63 { }
64
65
66 DataFile::Loader::ActionMap SequenceTemplate::Loader::shared_actions;
67
68 SequenceTemplate::Loader::Loader(SequenceTemplate &t, Collection &c):
69         CollectionObjectLoader<SequenceTemplate>(t, &c)
70 {
71         set_actions(shared_actions);
72 }
73
74 void SequenceTemplate::Loader::init_actions()
75 {
76         add("hdr", &SequenceTemplate::hdr);
77         add("alpha", &SequenceTemplate::alpha);
78         add("clear", &Loader::clear);
79         add("effect", &Loader::effect);
80         add("multisample", &Loader::multisample);
81         add("multisample", &Loader::multisample_range);
82         add("postprocessor", &Loader::postprocessor);
83         add("postprocessor", &Loader::postprocessor_with_slot);
84         add("renderable", &Loader::renderable);
85         add("renderable", &Loader::renderable_with_default);
86         add("sequence", &Loader::sequence);
87         add("step", &Loader::step);
88 }
89
90 void SequenceTemplate::Loader::clear()
91 {
92         ClearLoader ldr(obj);
93         load_sub_with(ldr);
94         obj.clear_enabled = true;
95 }
96
97 void SequenceTemplate::Loader::effect(const string &slot)
98 {
99         TemplateLoader<Effect> ldr(get_collection());
100         load_sub_with(ldr);
101         Renderable rend;
102         rend.slot_name = slot;
103         rend.effect_template = ldr.get_object();
104         obj.renderables.push_back(rend);
105 }
106
107 void SequenceTemplate::Loader::multisample(unsigned samples)
108 {
109         obj.required_multisample = samples;
110         obj.max_multisample = samples;
111 }
112
113 void SequenceTemplate::Loader::multisample_range(unsigned req, unsigned max)
114 {
115         obj.required_multisample = req;
116         obj.max_multisample = max;
117 }
118
119 void SequenceTemplate::Loader::postprocessor()
120 {
121         postprocessor_with_slot(string());
122 }
123
124 void SequenceTemplate::Loader::postprocessor_with_slot(const string &slot)
125 {
126         TemplateLoader<GL::PostProcessor> ldr(get_collection());
127         load_sub_with(ldr);
128         PostProcessor pp;
129         pp.postprocessor_template = ldr.get_object();
130         pp.slot_name = slot;
131         obj.postprocessors.push_back(pp);
132 }
133
134 void SequenceTemplate::Loader::renderable(const string &slot)
135 {
136         Renderable rend;
137         rend.slot_name = slot;
138         obj.renderables.push_back(rend);
139 }
140
141 void SequenceTemplate::Loader::renderable_with_default(const string &slot, const string &name)
142 {
143         Renderable rend;
144         rend.renderable = &get_collection().get<GL::Renderable>(name);
145         rend.slot_name = slot;
146         obj.renderables.push_back(rend);
147 }
148
149 void SequenceTemplate::Loader::sequence(const string &slot, const string &name)
150 {
151         Renderable rend;
152         rend.sequence_template = &get_collection().get<SequenceTemplate>(name);
153         rend.slot_name = slot;
154         SequenceLoader ldr(rend);
155         load_sub_with(ldr);
156         obj.renderables.push_back(rend);
157 }
158
159 void SequenceTemplate::Loader::step(const string &tag, const string &rend)
160 {
161         Step stp;
162         stp.tag = tag;
163         stp.renderable_name = rend;
164         Step::Loader ldr(stp, get_collection());
165         ldr.set_inline_base_name(format("%s/%d.step", get_source(), obj.steps.size()));
166         load_sub_with(ldr);
167
168         obj.steps.push_back(stp);
169 }
170
171
172 DataFile::Loader::ActionMap SequenceTemplate::ClearLoader::shared_actions;
173
174 SequenceTemplate::ClearLoader::ClearLoader(SequenceTemplate &t):
175         ObjectLoader<SequenceTemplate>(t)
176 {
177         set_actions(shared_actions);
178 }
179
180 void SequenceTemplate::ClearLoader::init_actions()
181 {
182         add("color", &ClearLoader::color);
183         add("depth", &ClearLoader::depth);
184         add("stencil", &ClearLoader::stencil);
185 }
186
187 void SequenceTemplate::ClearLoader::color(float r, float g, float b, float a)
188 {
189         obj.clear_colors.push_back(Color(r, g, b, a));
190 }
191
192 void SequenceTemplate::ClearLoader::depth(float d)
193 {
194         obj.clear_depth = d;
195 }
196
197 void SequenceTemplate::ClearLoader::stencil(int s)
198 {
199         obj.clear_stencil = s;
200 }
201
202
203 DataFile::Loader::ActionMap SequenceTemplate::SequenceLoader::shared_actions;
204
205 SequenceTemplate::SequenceLoader::SequenceLoader(Renderable &r):
206         ObjectLoader<Renderable>(r)
207 {
208         set_actions(shared_actions);
209 }
210
211 void SequenceTemplate::SequenceLoader::init_actions()
212 {
213         add("renderable", &SequenceLoader::renderable);
214 }
215
216 void SequenceTemplate::SequenceLoader::renderable(const string &slot, const string &name)
217 {
218         obj.sequence_renderables[slot] = name;
219 }
220
221
222 DataFile::Loader::ActionMap SequenceTemplate::Step::Loader::shared_actions;
223
224 SequenceTemplate::Step::Loader::Loader(Step &p, Collection &c):
225         DataFile::CollectionObjectLoader<Step>(p, &c)
226 {
227         set_actions(shared_actions);
228 }
229
230 void SequenceTemplate::Step::Loader::init_actions()
231 {
232         add("depth_test", &Loader::depth_test);
233         add("depth_test", &Loader::depth_compare);
234         add("lighting", &Loader::lighting);
235         add("lighting", &Loader::lighting_inline);
236         add("stencil_test", &Loader::stencil_test);
237 }
238
239 void SequenceTemplate::Step::Loader::set_inline_base_name(const string &n)
240 {
241         inline_base_name = n;
242 }
243
244 void SequenceTemplate::Step::Loader::depth_test()
245 {
246         load_sub(obj.depth_test);
247 }
248
249 void SequenceTemplate::Step::Loader::depth_compare(Predicate c)
250 {
251         obj.depth_test = DepthTest(c);
252 }
253
254 void SequenceTemplate::Step::Loader::lighting_inline()
255 {
256         RefPtr<Lighting> lightn = new Lighting;
257         load_sub(*lightn, get_collection());
258         get_collection().add(inline_base_name+".lightn", lightn.get());
259         obj.lighting = lightn.release();
260 }
261
262 void SequenceTemplate::Step::Loader::lighting(const string &name)
263 {
264         obj.lighting = &get_collection().get<Lighting>(name);
265 }
266
267 void SequenceTemplate::Step::Loader::stencil_test()
268 {
269         load_sub(obj.stencil_test);
270 }
271
272 } // namespace GL
273 } // namespace Msp