#include <string>
#include <vector>
#include <msp/core/typeregistry.h>
+#include <msp/datafile/dynamicobjectloader.h>
#include <msp/datafile/objectloader.h>
-#include "blend.h"
+#include "depthtest.h"
+#include "effect.h"
#include "postprocessor.h"
-#include "predicate.h"
+#include "resources.h"
+#include "stenciltest.h"
namespace Msp {
namespace GL {
-class DepthTest;
class Lighting;
class Renderable;
class SequenceTemplate
{
private:
- class PostProcLoader: virtual public DataFile::Loader
+ template<typename T>
+ class TemplateLoader: public DataFile::DynamicObjectLoader<typename T::Template>
{
- private:
- template<typename T>
- struct AddPostProc
- {
- void operator()(const std::string &kw, PostProcLoader &ldr) const { ldr.add(kw, &PostProcLoader::postprocessor<T>); }
- };
-
- protected:
- RefPtr<PostProcessor::Template> postproc;
+ friend class SequenceTemplate;
public:
- PostProcLoader();
-
- PostProcessor::Template *get_postprocessor_template() { return postproc.release(); }
-
- protected:
- virtual void postprocessor_loaded() { }
+ TemplateLoader(typename DataFile::DynamicObjectLoader<typename T::Template>::Collection &c): DataFile::DynamicObjectLoader<typename T::Template>(&c) { }
private:
- template<typename T>
- void postprocessor();
-
- friend class SequenceTemplate;
+ virtual typename DataFile::DynamicObjectLoader<typename T::Template>::TypeRegistry &get_type_registry() const { return get_registry<T>(); }
};
+ template<typename T>
+ using TemplateRegistry = typename TemplateLoader<T>::TypeRegistry;
+
public:
- class Loader: public DataFile::CollectionObjectLoader<SequenceTemplate, Resources>, public PostProcLoader
+ class Loader: public DataFile::CollectionObjectLoader<SequenceTemplate>
{
+ private:
+ static ActionMap shared_actions;
+
public:
Loader(SequenceTemplate &, Collection &);
+ private:
+ virtual void init_actions();
- virtual void postprocessor_loaded();
+ void clear();
+ void effect(const std::string &);
void multisample(unsigned);
void multisample_range(unsigned, unsigned);
- void postprocessor(const std::string &);
- void step(const std::string &);
- void step_with_slot(const std::string &, const std::string &);
+ 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<std::string, std::string> sequence_renderables;
+ std::string slot_name;
};
struct Step
{
class Loader: public DataFile::CollectionObjectLoader<Step>
{
+ private:
+ std::string inline_base_name;
+
+ static ActionMap shared_actions;
+
public:
- Loader(Step &);
Loader(Step &, Collection &);
private:
- void init();
+ virtual void init_actions();
+
+ public:
+ void set_inline_base_name(const std::string &);
- void blend(BlendFactor, BlendFactor);
- void blend_predefined(const std::string &);
- void depth_test(Predicate);
- void depth_test_predefined(const std::string &);
+ private:
+ void depth_test();
+ void depth_compare(Predicate);
void lighting(const std::string &);
void lighting_inline();
- void object(const std::string &);
- void scene(const std::string &);
+ void stencil_test();
};
std::string tag;
- RefPtr<Lighting> lighting;
- RefPtr<const DepthTest> depth_test;
- RefPtr<const Blend> blend;
- std::string slot_name;
- Renderable *default_renderable;
-
- ~Step();
+ const Lighting *lighting = 0;
+ DepthTest depth_test;
+ StencilTest stencil_test;
+ std::string renderable_name;
};
struct PostProcessor
PostProcessor(GL::PostProcessor::Template * = 0);
};
- typedef std::vector<PostProcessor> PostProcessorArray;
-
private:
- typedef TypeRegistry<PostProcLoader::AddPostProc, PostProcLoader &> PostProcessorRegistry;
+ class ClearLoader: public DataFile::ObjectLoader<SequenceTemplate>
+ {
+ private:
+ static ActionMap shared_actions;
- bool hdr;
- bool alpha;
- unsigned required_multisample;
- unsigned max_multisample;
+ public:
+ ClearLoader(SequenceTemplate &);
+ private:
+ virtual void init_actions();
+
+ void color(float, float, float, float);
+ void depth(float);
+ void stencil(int);
+ };
+
+ class SequenceLoader: public DataFile::ObjectLoader<Renderable>
+ {
+ private:
+ static ActionMap shared_actions;
+
+ public:
+ SequenceLoader(Renderable &);
+ private:
+ virtual void init_actions();
+
+ void renderable(const std::string &, const std::string &);
+ };
+
+ bool hdr = false;
+ unsigned required_multisample = 0;
+ unsigned max_multisample = 0;
+ std::vector<Renderable> renderables;
std::vector<Step> steps;
- PostProcessorArray postprocessors;
+ std::vector<PostProcessor> postprocessors;
+ bool clear_enabled = false;
+ std::vector<Color> clear_colors;
+ float clear_depth = 1.0f;
+ int clear_stencil = 0;
public:
- SequenceTemplate();
~SequenceTemplate();
bool get_hdr() const { return hdr; }
- bool get_alpha() const { return alpha; }
unsigned get_required_multisample() const { return required_multisample; }
unsigned get_maximum_multisample() const { return max_multisample; }
+ const std::vector<Renderable> &get_renderables() const { return renderables; }
const std::vector<Step> &get_steps() const { return steps; }
- const PostProcessorArray &get_postprocessors() const { return postprocessors; }
+ const std::vector<PostProcessor> &get_postprocessors() const { return postprocessors; }
+ bool is_clear_enabled() const { return clear_enabled; }
+ const std::vector<Color> &get_clear_colors() const { return clear_colors; }
+ float get_clear_depth() const { return clear_depth; }
+ int get_clear_stencil() const { return clear_stencil; }
+
+ template<typename T>
+ static void register_effect(const std::string &);
template<typename T>
static void register_postprocessor(const std::string &);
+
private:
- static PostProcessorRegistry &get_postprocessor_registry();
+ template<typename T>
+ static TemplateRegistry<T> &get_registry();
};
template<typename T>
-void SequenceTemplate::register_postprocessor(const std::string &kw)
+void SequenceTemplate::register_effect(const std::string &kw)
{
- get_postprocessor_registry().register_type<T>(kw);
+ get_registry<Effect>().register_type<typename T::Template>(kw);
}
template<typename T>
-void SequenceTemplate::PostProcLoader::postprocessor()
+void SequenceTemplate::register_postprocessor(const std::string &kw)
{
- 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();
+ get_registry<GL::PostProcessor>().register_type<typename T::Template>(kw);
}
} // namespace GL