1 #ifndef MSP_GL_MATERIAL_H_
2 #define MSP_GL_MATERIAL_H_
4 #include <msp/datafile/collection.h>
5 #include <msp/datafile/dynamicobjectloader.h>
6 #include <msp/datafile/objectloader.h>
8 #include "programdata.h"
19 class Loader: public DataFile::CollectionObjectLoader<Material>
22 Loader(Material &, Collection &);
24 virtual void init_actions();
27 void sampler(const std::string &);
35 const Texture *texture;
37 Property(): value(T()), texture(0) { }
41 class PropertyLoader: public DataFile::DerivedObjectLoader<Material, Loader>
44 PropertyLoader(C &m, Collection &c): DerivedObjectLoader<Material, Loader>(m, c) { }
46 void add_property(const std::string &, void (C::*)(float), void (C::*)(const Texture *));
47 void add_property(const std::string &, void (C::*)(const Color &), void (C::*)(const Texture *), bool);
48 void add_property(const std::string &, void (C::*)(const Texture *));
50 void property_value_scalar(void (C::*)(float), float);
51 void property_value_rgb(void (C::*)(const Color &), float, float, float);
52 void property_value_rgba(void (C::*)(const Color &), float, float, float, float);
53 void property_value_srgb(void (C::*)(const Color &), float, float, float);
54 void property_value_srgb_alpha(void (C::*)(const Color &), float, float, float, float);
55 void property_texture(void (C::*)(const Texture *), const std::string &);
59 class GenericLoader: public DataFile::DynamicObjectLoader<Material>
61 friend class Material;
64 GenericLoader(Collection &c): DynamicObjectLoader<Material>(&c) { }
67 virtual const TypeRegistry &get_type_registry() const { return get_material_registry(); }
71 const Sampler *sampler = 0;
76 virtual ~Material() = default;
78 virtual const Program *create_compatible_shader(const std::map<std::string, int> & = std::map<std::string, int>()) const;
80 virtual void fill_program_info(std::string &, std::map<std::string, int> &) const = 0;
83 /** Returns the uniforms for the material. */
84 const ProgramData &get_shader_data() const { return shdata; }
86 virtual const Tag *get_texture_tags() const = 0;
87 virtual const Texture *get_texture(Tag) const = 0;
88 virtual const Sampler *get_sampler(Tag) const { return sampler; }
90 void set_debug_name(const std::string &);
93 static void register_type(const std::string &);
95 static GenericLoader::TypeRegistry &get_material_registry();
99 void Material::register_type(const std::string &kw)
101 get_material_registry().register_type<T>(kw);
106 void Material::PropertyLoader<C>::add_property(const std::string &kw, void (C::*set_value)(float), void (C::*set_texture)(const Texture *))
108 add(kw, &PropertyLoader<C>::property_value_scalar, set_value);
110 add(kw+"_map", &PropertyLoader<C>::property_texture, set_texture);
114 void Material::PropertyLoader<C>::add_property(const std::string &kw, void (C::*set_value)(const Color &), void (C::*set_texture)(const Texture *), bool allow_alpha)
116 add(kw, &PropertyLoader<C>::property_value_rgb, set_value);
117 add(kw+"_srgb", &PropertyLoader<C>::property_value_srgb, set_value);
120 add(kw, &PropertyLoader<C>::property_value_rgba, set_value);
121 add(kw+"_srgb", &PropertyLoader<C>::property_value_srgb_alpha, set_value);
124 add(kw+"_map", &PropertyLoader<C>::property_texture, set_texture);
128 void Material::PropertyLoader<C>::add_property(const std::string &kw, void (C::*set_texture)(const Texture *))
130 add(kw+"_map", &PropertyLoader<C>::property_texture, set_texture);
134 void Material::PropertyLoader<C>::property_value_scalar(void (C::*set_value)(float), float value)
136 (static_cast<C &>(obj).*set_value)(value);
140 void Material::PropertyLoader<C>::property_value_rgb(void (C::*set_value)(const Color &), float r, float g, float b)
142 (static_cast<C &>(obj).*set_value)(Color(r, g, b));
146 void Material::PropertyLoader<C>::property_value_rgba(void (C::*set_value)(const Color &), float r, float g, float b, float a)
148 (static_cast<C &>(obj).*set_value)(Color(r, g, b, a));
152 void Material::PropertyLoader<C>::property_value_srgb(void (C::*set_value)(const Color &), float r, float g, float b)
154 (static_cast<C &>(obj).*set_value)(Color(r, g, b).to_linear());
158 void Material::PropertyLoader<C>::property_value_srgb_alpha(void (C::*set_value)(const Color &), float r, float g, float b, float a)
160 (static_cast<C &>(obj).*set_value)(Color(r, g, b, a).to_linear());
164 void Material::PropertyLoader<C>::property_texture(void (C::*set_texture)(const Texture *), const std::string &name)
166 /* The static_cast around get_collection is needed because otherwise Android
167 SDK's g++ 4.9 fails to parse get<Texture> as a template function call */
168 (static_cast<C &>(obj).*set_texture)(&static_cast<Collection &>(get_collection()).get<Texture>(name));