From 083a8227715fa32c841fc2b8126e4ab8d2840ba0 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Tue, 19 Oct 2021 16:02:57 +0300 Subject: [PATCH] Support effects and subordinate sequences inside sequence templates --- source/builders/sequencebuilder.cpp | 50 +++++++++++++++-- source/builders/sequencetemplate.cpp | 61 ++++++++++++++++++++ source/builders/sequencetemplate.h | 28 ++++++++++ source/effects/effect.cpp | 10 ++++ source/effects/effect.h | 19 +++++++ source/effects/environmentmap.cpp | 43 ++++++++++++++ source/effects/environmentmap.h | 30 +++++++++- source/effects/shadowmap.cpp | 84 ++++++++++++++++++++++++++++ source/effects/shadowmap.h | 48 ++++++++++++++++ source/effects/sky.cpp | 25 +++++++++ source/effects/sky.h | 18 ++++++ 11 files changed, 410 insertions(+), 6 deletions(-) diff --git a/source/builders/sequencebuilder.cpp b/source/builders/sequencebuilder.cpp index f007350e..dbb675ac 100644 --- a/source/builders/sequencebuilder.cpp +++ b/source/builders/sequencebuilder.cpp @@ -49,6 +49,48 @@ void SequenceBuilder::build(Sequence &sequence) const sequence.set_debug_name(debug_name); #endif + map final_renderables = renderables; + vector sequences; + for(const SequenceTemplate::Renderable &r: tmpl.get_renderables()) + { + Renderable *&ptr = final_renderables[r.slot_name]; + if(!ptr) + { + if(r.effect_template) + { + Effect *effect = r.effect_template->create(final_renderables); +#ifdef DEBUG + if(!debug_name.empty()) + effect->set_debug_name(format("%s/%s", debug_name, r.slot_name)); +#endif + ptr = effect; + } + else if(r.sequence_template) + { + Sequence *seq = new Sequence; +#ifdef DEBUG + if(!debug_name.empty()) + seq->set_debug_name(format("%s/%s", debug_name, r.slot_name)); +#endif + ptr = seq; + sequences.push_back(&r); + } + else + throw invalid_operation("SequenceBuilder::build"); + + sequence.add_owned(ptr); + } + } + + for(const SequenceTemplate::Renderable *s: sequences) + { + SequenceBuilder bld(*s->sequence_template); + for(const auto &kvp: s->sequence_renderables) + if(Renderable *r = get_item(final_renderables, kvp.second)) + bld.set_renderable(kvp.first, *r); + bld.build(*static_cast(get_item(final_renderables, s->slot_name))); + } + sequence.set_clear_enabled(tmpl.is_clear_enabled()); if(tmpl.is_clear_enabled()) { @@ -59,11 +101,9 @@ void SequenceBuilder::build(Sequence &sequence) const for(const SequenceTemplate::Step &s: tmpl.get_steps()) { - Renderable *renderable = get_item(renderables, s.renderable_name); - if(!renderable) - throw missing_renderable(s.renderable_name); - - Sequence::Step &step = sequence.add_step(s.tag, *renderable); + // Existence is already ensured above + Renderable &renderable = *get_item(final_renderables, s.renderable_name); + Sequence::Step &step = sequence.add_step(s.tag, renderable); step.set_depth_test(s.depth_test); step.set_stencil_test(s.stencil_test); step.set_lighting(s.lighting); diff --git a/source/builders/sequencetemplate.cpp b/source/builders/sequencetemplate.cpp index 03c8c7fe..999d2ae7 100644 --- a/source/builders/sequencetemplate.cpp +++ b/source/builders/sequencetemplate.cpp @@ -5,11 +5,14 @@ #include "blend.h" #include "bloom.h" #include "colorcurve.h" +#include "environmentmap.h" #include "lighting.h" #include "object.h" #include "resources.h" #include "scene.h" #include "sequencetemplate.h" +#include "shadowmap.h" +#include "sky.h" using namespace std; @@ -18,6 +21,8 @@ namespace GL { SequenceTemplate::~SequenceTemplate() { + for(const Renderable &r: renderables) + delete r.effect_template; for(const PostProcessor &p: postprocessors) delete p.postprocessor_template; } @@ -37,6 +42,21 @@ SequenceTemplate::TemplateRegistry &SequenceTemplate::get_reg return registry; } +template<> +SequenceTemplate::TemplateRegistry &SequenceTemplate::get_registry() +{ + static TemplateRegistry registry; + static bool initialized = false; + if(!initialized) + { + registry.register_type("environment_map"); + registry.register_type("shadow_map"); + registry.register_type("sky"); + initialized = true; + } + return registry; +} + SequenceTemplate::PostProcessor::PostProcessor(GL::PostProcessor::Template *ppt): postprocessor_template(ppt) @@ -56,12 +76,14 @@ void SequenceTemplate::Loader::init_actions() add("hdr", &SequenceTemplate::hdr); add("alpha", &SequenceTemplate::alpha); add("clear", &Loader::clear); + add("effect", &Loader::effect); add("multisample", &Loader::multisample); add("multisample", &Loader::multisample_range); add("postprocessor", &Loader::postprocessor); add("postprocessor", &Loader::postprocessor_with_slot); add("renderable", &Loader::renderable); add("renderable", &Loader::renderable_with_default); + add("sequence", &Loader::sequence); add("step", &Loader::step); } @@ -72,6 +94,16 @@ void SequenceTemplate::Loader::clear() obj.clear_enabled = true; } +void SequenceTemplate::Loader::effect(const string &slot) +{ + TemplateLoader ldr(get_collection()); + load_sub_with(ldr); + Renderable rend; + rend.slot_name = slot; + rend.effect_template = ldr.get_object(); + obj.renderables.push_back(rend); +} + void SequenceTemplate::Loader::multisample(unsigned samples) { obj.required_multisample = samples; @@ -114,6 +146,16 @@ void SequenceTemplate::Loader::renderable_with_default(const string &slot, const obj.renderables.push_back(rend); } +void SequenceTemplate::Loader::sequence(const string &slot, const string &name) +{ + Renderable rend; + rend.sequence_template = &get_collection().get(name); + rend.slot_name = slot; + SequenceLoader ldr(rend); + load_sub_with(ldr); + obj.renderables.push_back(rend); +} + void SequenceTemplate::Loader::step(const string &tag, const string &rend) { Step stp; @@ -158,6 +200,25 @@ void SequenceTemplate::ClearLoader::stencil(int s) } +DataFile::Loader::ActionMap SequenceTemplate::SequenceLoader::shared_actions; + +SequenceTemplate::SequenceLoader::SequenceLoader(Renderable &r): + ObjectLoader(r) +{ + set_actions(shared_actions); +} + +void SequenceTemplate::SequenceLoader::init_actions() +{ + add("renderable", &SequenceLoader::renderable); +} + +void SequenceTemplate::SequenceLoader::renderable(const string &slot, const string &name) +{ + obj.sequence_renderables[slot] = name; +} + + DataFile::Loader::ActionMap SequenceTemplate::Step::Loader::shared_actions; SequenceTemplate::Step::Loader::Loader(Step &p, Collection &c): diff --git a/source/builders/sequencetemplate.h b/source/builders/sequencetemplate.h index 3f4b86b9..5c13aebe 100644 --- a/source/builders/sequencetemplate.h +++ b/source/builders/sequencetemplate.h @@ -7,6 +7,7 @@ #include #include #include "depthtest.h" +#include "effect.h" #include "postprocessor.h" #include "resources.h" #include "stenciltest.h" @@ -47,18 +48,23 @@ public: virtual void init_actions(); void clear(); + void effect(const std::string &); void multisample(unsigned); void multisample_range(unsigned, unsigned); void postprocessor(); void postprocessor_with_slot(const std::string &); void renderable(const std::string &); void renderable_with_default(const std::string &, const std::string &); + void sequence(const std::string &, const std::string &); void step(const std::string &, const std::string &); }; struct Renderable { + Effect::Template *effect_template = 0; GL::Renderable *renderable = 0; + SequenceTemplate *sequence_template = 0; + std::map sequence_renderables; std::string slot_name; }; @@ -118,6 +124,19 @@ private: void stencil(int); }; + class SequenceLoader: public DataFile::ObjectLoader + { + private: + static ActionMap shared_actions; + + public: + SequenceLoader(Renderable &); + private: + virtual void init_actions(); + + void renderable(const std::string &, const std::string &); + }; + bool hdr = false; bool alpha = false; unsigned required_multisample = 0; @@ -145,6 +164,9 @@ public: float get_clear_depth() const { return clear_depth; } int get_clear_stencil() const { return clear_stencil; } + template + static void register_effect(const std::string &); + template static void register_postprocessor(const std::string &); @@ -153,6 +175,12 @@ private: static TemplateRegistry &get_registry(); }; +template +void SequenceTemplate::register_effect(const std::string &kw) +{ + get_registry().register_type(kw); +} + template void SequenceTemplate::register_postprocessor(const std::string &kw) { diff --git a/source/effects/effect.cpp b/source/effects/effect.cpp index 4ab867ff..05ef5a10 100644 --- a/source/effects/effect.cpp +++ b/source/effects/effect.cpp @@ -19,5 +19,15 @@ void Effect::disable_for_method(Tag tag) enabled_methods.erase(tag); } + +Effect::Template::Loader::Loader(Template &t, Collection &c): + CollectionObjectLoader