const vector<PipelineTemplate::Pass> &passes = tmpl.get_passes();
for(vector<PipelineTemplate::Pass>::const_iterator i=passes.begin(); i!=passes.end(); ++i)
renderables[i->renderable_name] = 0;
+ const vector<PipelineTemplate::PostProcessor> &postprocs = tmpl.get_postprocessors();
+ for(PipelineTemplate::PostProcessorArray::const_iterator i=postprocs.begin(); i!=postprocs.end(); ++i)
+ if(!i->slot_name.empty())
+ postprocessors[i->slot_name] = 0;
}
void PipelineBuilder::set_renderable(const string &name, Renderable &rend)
get_item(renderables, name) = &rend;
}
+void PipelineBuilder::set_postprocessor(const string &name, PostProcessor &pproc)
+{
+ get_item(postprocessors, name) = &pproc;
+}
+
void PipelineBuilder::build(Pipeline &pipeline) const
{
pipeline.set_hdr(tmpl.get_hdr());
const PipelineTemplate::PostProcessorArray &postprocs = tmpl.get_postprocessors();
for(PipelineTemplate::PostProcessorArray::const_iterator i=postprocs.begin(); i!=postprocs.end(); ++i)
{
- PostProcessor *proc = (*i)->create(pipeline.get_width(), pipeline.get_height());
- pipeline.add_postprocessor_owned(proc);
+ PostProcessor *proc = 0;
+ if(!i->slot_name.empty())
+ proc = get_item(postprocessors, i->slot_name);
+ if(!proc && i->postprocessor_template)
+ proc = i->postprocessor_template->create(pipeline.get_width(), pipeline.get_height());
+ if(proc)
+ pipeline.add_postprocessor_owned(proc);
}
}
class Framebuffer;
class Pipeline;
class PipelineTemplate;
+class PostProcessor;
class Renderable;
class View;
private:
const PipelineTemplate &tmpl;
std::map<std::string, Renderable *> renderables;
+ std::map<std::string, PostProcessor *> postprocessors;
public:
PipelineBuilder(const PipelineTemplate &);
void set_renderable(const std::string &, Renderable &);
+ void set_postprocessor(const std::string &, PostProcessor &);
void build(Pipeline &) const;
Pipeline *build(unsigned, unsigned) const;
PipelineTemplate::~PipelineTemplate()
{
for(PostProcessorArray::iterator i=postprocessors.begin(); i!=postprocessors.end(); ++i)
- delete *i;
+ delete i->postprocessor_template;
}
{ }
+PipelineTemplate::PostProcessor::PostProcessor(GL::PostProcessor::Template *ppt):
+ postprocessor_template(ppt)
+{ }
+
+
+PipelineTemplate::PostProcLoader::PostProcLoader()
+{
+ get_postprocessor_registry().add_all(*this);
+}
+
+
PipelineTemplate::Loader::Loader(PipelineTemplate &t):
DataFile::CollectionObjectLoader<PipelineTemplate>(t, 0)
{
add("multisample", &Loader::multisample);
add("multisample", &Loader::multisample_range);
add("pass", &Loader::pass);
+ add("postprocessor", &Loader::postprocessor);
+}
- get_postprocessor_registry().add_all(*this);
+void PipelineTemplate::Loader::postprocessor_loaded()
+{
+ obj.postprocessors.push_back(get_postprocessor_template());
}
void PipelineTemplate::Loader::multisample(unsigned samples)
obj.passes.push_back(pss);
}
+void PipelineTemplate::Loader::postprocessor(const std::string &slot)
+{
+ PostProcLoader ldr;
+ load_sub_with(ldr);
+ PostProcessor pp;
+ pp.postprocessor_template = ldr.get_postprocessor_template();
+ pp.slot_name = slot;
+ obj.postprocessors.push_back(pp);
+}
+
PipelineTemplate::Pass::Loader::Loader(Pass &p):
DataFile::CollectionObjectLoader<Pass>(p, 0)
class PipelineTemplate
{
-public:
- class Loader: public DataFile::CollectionObjectLoader<PipelineTemplate>
+private:
+ class PostProcLoader: virtual public DataFile::Loader
{
private:
template<typename T>
struct AddPostProc
{
- static void add(Loader &ldr, const std::string &kw) { ldr.add(kw, &Loader::postprocessor<T>); }
+ static void add(PostProcLoader &ldr, const std::string &kw) { ldr.add(kw, &PostProcLoader::postprocessor<T>); }
};
+ protected:
+ RefPtr<PostProcessor::Template> postproc;
+
+ public:
+ PostProcLoader();
+
+ PostProcessor::Template *get_postprocessor_template() { return postproc.release(); }
+
+ protected:
+ virtual void postprocessor_loaded() { }
+
+ private:
+ template<typename T>
+ void postprocessor();
+
+ friend class PipelineTemplate;
+ };
+
+public:
+ class Loader: public DataFile::CollectionObjectLoader<PipelineTemplate>, public PostProcLoader
+ {
public:
Loader(PipelineTemplate &);
Loader(PipelineTemplate &, Collection &);
private:
void init();
+ virtual void postprocessor_loaded();
void multisample(unsigned);
void multisample_range(unsigned, unsigned);
void pass(const std::string &, const std::string &);
-
- template<typename T>
- void postprocessor();
-
- friend class PipelineTemplate;
+ void postprocessor(const std::string &);
};
struct Pass
~Pass();
};
+ struct PostProcessor
+ {
+ GL::PostProcessor::Template *postprocessor_template;
+ std::string slot_name;
+
+ PostProcessor(GL::PostProcessor::Template * = 0);
+ };
+
typedef std::vector<Pass> PassArray;
- typedef std::vector<PostProcessor::Template *> PostProcessorArray;
+ typedef std::vector<PostProcessor> PostProcessorArray;
private:
- typedef DataFile::LoadableTypeRegistry<Loader, Loader::AddPostProc> PostProcessorRegistry;
+ typedef DataFile::LoadableTypeRegistry<PostProcLoader, PostProcLoader::AddPostProc> PostProcessorRegistry;
bool hdr;
unsigned required_multisample;
}
template<typename T>
-void PipelineTemplate::Loader::postprocessor()
+void PipelineTemplate::PostProcLoader::postprocessor()
{
- RefPtr<typename T::Template> postproc = new typename T::Template;
- load_sub(*postproc);
- obj.postprocessors.push_back(postproc.release());
+ if(postproc)
+ throw std::logic_error("Only one postprocessor allowed per slot");
+ RefPtr<typename T::Template> pp = new typename T::Template;
+ load_sub(*pp);
+ postproc = pp;
+ pp = 0;
+ postprocessor_loaded();
}
} // namespace GL