]> git.tdb.fi Git - libs/gl.git/blob - source/pipelinetemplate.cpp
Use a type registry to manage postprocessor types for pipeline templates
[libs/gl.git] / source / pipelinetemplate.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 "pipelinetemplate.h"
9 #include "tests.h"
10
11 using namespace std;
12
13 namespace Msp {
14 namespace GL {
15
16 PipelineTemplate::PipelineTemplate():
17         hdr(false),
18         required_multisample(0),
19         max_multisample(0)
20 { }
21
22 PipelineTemplate::~PipelineTemplate()
23 {
24         for(PostProcessorArray::iterator i=postprocessors.begin(); i!=postprocessors.end(); ++i)
25                 delete *i;
26 }
27
28
29 PipelineTemplate::PostProcessorRegistry &PipelineTemplate::get_postprocessor_registry()
30 {
31         static PostProcessorRegistry registry;
32         static bool initialized = false;
33         if(!initialized)
34         {
35                 registry.register_type<AmbientOcclusion>("ambient_occlusion");
36                 registry.register_type<Bloom>("bloom");
37                 registry.register_type<ColorCurve>("colorcurve");
38                 initialized = true;
39         }
40         return registry;
41 }
42
43
44 PipelineTemplate::Pass::~Pass()
45 { }
46
47
48 PipelineTemplate::Loader::Loader(PipelineTemplate &t):
49         DataFile::CollectionObjectLoader<PipelineTemplate>(t, 0)
50 {
51         init();
52 }
53
54 PipelineTemplate::Loader::Loader(PipelineTemplate &t, Collection &c):
55         DataFile::CollectionObjectLoader<PipelineTemplate>(t, &c)
56 {
57         init();
58 }
59
60 void PipelineTemplate::Loader::init()
61 {
62         add("hdr", &PipelineTemplate::hdr);
63         add("multisample", &Loader::multisample);
64         add("multisample", &Loader::multisample_range);
65         add("pass", &Loader::pass);
66
67         get_postprocessor_registry().add_all(*this);
68 }
69
70 void PipelineTemplate::Loader::multisample(unsigned samples)
71 {
72         obj.required_multisample = samples;
73         obj.max_multisample = samples;
74 }
75
76 void PipelineTemplate::Loader::multisample_range(unsigned req, unsigned max)
77 {
78         obj.required_multisample = req;
79         obj.max_multisample = max;
80 }
81
82 void PipelineTemplate::Loader::pass(const string &tag, const string &rend)
83 {
84         Pass pss;;
85         pss.tag = tag;
86         pss.renderable_name = rend;
87         if(coll)
88                 load_sub(pss, *coll);
89         else
90                 load_sub(pss);
91
92         obj.passes.push_back(pss);
93 }
94
95
96 PipelineTemplate::Pass::Loader::Loader(Pass &p):
97         DataFile::CollectionObjectLoader<Pass>(p, 0)
98 {
99         init();
100 }
101
102 PipelineTemplate::Pass::Loader::Loader(Pass &p, Collection &c):
103         DataFile::CollectionObjectLoader<Pass>(p, &c)
104 {
105         init();
106 }
107
108 void PipelineTemplate::Pass::Loader::init()
109 {
110         add("blend", &Loader::blend);
111         add("blend", &Loader::blend_predefined);
112         add("depth_test", &Loader::depth_test);
113         add("depth_test", &Loader::depth_test_predefined);
114         add("lighting", &Loader::lighting);
115         add("lighting", &Loader::lighting_inline);
116 }
117
118 void PipelineTemplate::Pass::Loader::blend_predefined(const string &name)
119 {
120         const Blend *bln = 0;
121         if(name=="alpha")
122                 bln = &Blend::alpha();
123         else if(name=="additive")
124                 bln = &Blend::additive();
125         else if(name=="additive_alpha")
126                 bln = &Blend::additive_alpha();
127         else
128                 throw key_error(name);
129
130         obj.blend = bln;
131         obj.blend.keep();
132 }
133
134 void PipelineTemplate::Pass::Loader::blend(BlendFactor src, BlendFactor dest)
135 {
136         obj.blend = new Blend(src, dest);
137 }
138
139 void PipelineTemplate::Pass::Loader::depth_test_predefined(const string &name)
140 {
141         const DepthTest *dtest = 0;
142         if(name=="lequal")
143                 dtest = &DepthTest::lequal();
144         else
145                 throw key_error(name);
146
147         obj.depth_test = dtest;
148         obj.depth_test.keep();
149 }
150
151 void PipelineTemplate::Pass::Loader::depth_test(Predicate pred)
152 {
153         obj.depth_test = new DepthTest(pred);
154 }
155
156 void PipelineTemplate::Pass::Loader::lighting_inline()
157 {
158         RefPtr<Lighting> lightn = new Lighting;
159         load_sub(*lightn);
160         obj.lighting = lightn;
161 }
162
163 void PipelineTemplate::Pass::Loader::lighting(const string &name)
164 {
165         obj.lighting = &get_collection().get<Lighting>(name);
166         obj.lighting.keep();
167 }
168
169 /*void PipelineTemplate::Pass::Loader::scene(const string &name)
170 {
171         obj.default_renderable = get_collection().get<Scene>(name);
172 }*/
173
174 } // namespace GL
175 } // namespace Msp