1 #ifndef MSP_GL_MATERIAL_H_
2 #define MSP_GL_MATERIAL_H_
4 #include <msp/core/typeregistry.h>
5 #include <msp/datafile/collection.h>
6 #include <msp/datafile/objectloader.h>
8 #include "programdata.h"
19 class Loader: public DataFile::CollectionObjectLoader<Material>
23 Loader(Material &, Collection &);
25 virtual void init_actions();
28 void sampler(const std::string &);
36 const Texture *texture;
38 Property(): value(T()), texture(0) { }
42 class PropertyLoader: public DataFile::DerivedObjectLoader<Material, Loader>
45 PropertyLoader(C &m): DerivedObjectLoader<Material, Loader>(m) { }
46 PropertyLoader(C &m, Collection &c): DerivedObjectLoader<Material, Loader>(m, c) { }
48 void add_property(const std::string &, void (C::*)(float), void (C::*)(const Texture *));
49 void add_property(const std::string &, void (C::*)(const Color &), void (C::*)(const Texture *), bool);
50 void add_property(const std::string &, void (C::*)(const Texture *));
52 void property_value_scalar(void (C::*)(float), float);
53 void property_value_rgb(void (C::*)(const Color &), float, float, float);
54 void property_value_rgba(void (C::*)(const Color &), float, float, float, float);
55 void property_value_srgb(void (C::*)(const Color &), float, float, float);
56 void property_value_srgb_alpha(void (C::*)(const Color &), float, float, float, float);
57 void property_texture(void (C::*)(const Texture *), const std::string &);
61 class GenericLoader: public DataFile::Loader
67 void operator()(const std::string &, GenericLoader &) const;
70 DataFile::Collection *coll;
74 static ActionMap shared_actions;
77 GenericLoader(DataFile::Collection * = 0);
80 Material *get_material() { Material *m = material; material = 0; return m; }
82 virtual void init_actions();
84 void type(const DataFile::Symbol &);
86 friend class Material;
90 typedef TypeRegistry<GenericLoader::CreateMaterial, GenericLoader &> MaterialRegistry;
93 const Sampler *sampler;
96 Material(): sampler(0) { }
98 virtual ~Material() { }
100 virtual const Program *create_compatible_shader(const std::map<std::string, int> & = std::map<std::string, int>()) const;
102 virtual void fill_program_info(std::string &, std::map<std::string, int> &) const = 0;
105 /** Returns the uniforms for the material. */
106 const ProgramData &get_shader_data() const { return shdata; }
109 DEPRECATED void attach_texture_to(const Texture *, Texturing &, ProgramData &, const std::string &) const;
111 DEPRECATED virtual void attach_textures_to(Texturing &, ProgramData &) const = 0;
113 virtual const Tag *get_texture_tags() const = 0;
114 virtual const Texture *get_texture(Tag) const = 0;
115 const Sampler *get_sampler() const { return sampler; }
117 void set_debug_name(const std::string &);
120 static void register_type(const std::string &);
122 static MaterialRegistry &get_material_registry();
126 void Material::register_type(const std::string &kw)
128 get_material_registry().register_type<T>(kw);
133 void Material::PropertyLoader<C>::add_property(const std::string &kw, void (C::*set_value)(float), void (C::*set_texture)(const Texture *))
135 add(kw, &PropertyLoader<C>::property_value_scalar, set_value);
137 add(kw+"_map", &PropertyLoader<C>::property_texture, set_texture);
141 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)
143 add(kw, &PropertyLoader<C>::property_value_rgb, set_value);
144 add(kw+"_srgb", &PropertyLoader<C>::property_value_srgb, set_value);
147 add(kw, &PropertyLoader<C>::property_value_rgba, set_value);
148 add(kw+"_srgb", &PropertyLoader<C>::property_value_srgb_alpha, set_value);
151 add(kw+"_map", &PropertyLoader<C>::property_texture, set_texture);
155 void Material::PropertyLoader<C>::add_property(const std::string &kw, void (C::*set_texture)(const Texture *))
157 add(kw+"_map", &PropertyLoader<C>::property_texture, set_texture);
161 void Material::PropertyLoader<C>::property_value_scalar(void (C::*set_value)(float), float value)
163 (static_cast<C &>(obj).*set_value)(value);
167 void Material::PropertyLoader<C>::property_value_rgb(void (C::*set_value)(const Color &), float r, float g, float b)
169 (static_cast<C &>(obj).*set_value)(Color(r, g, b));
173 void Material::PropertyLoader<C>::property_value_rgba(void (C::*set_value)(const Color &), float r, float g, float b, float a)
175 (static_cast<C &>(obj).*set_value)(Color(r, g, b, a));
179 void Material::PropertyLoader<C>::property_value_srgb(void (C::*set_value)(const Color &), float r, float g, float b)
181 (static_cast<C &>(obj).*set_value)(Color(r, g, b).to_linear());
185 void Material::PropertyLoader<C>::property_value_srgb_alpha(void (C::*set_value)(const Color &), float r, float g, float b, float a)
187 (static_cast<C &>(obj).*set_value)(Color(r, g, b, a).to_linear());
191 void Material::PropertyLoader<C>::property_texture(void (C::*set_texture)(const Texture *), const std::string &name)
193 /* The static_cast around get_collection is needed because otherwise Android
194 SDK's g++ 4.9 fails to parse get<Texture> as a template function call */
195 (static_cast<C &>(obj).*set_texture)(&static_cast<Collection &>(get_collection()).get<Texture>(name));
200 void Material::GenericLoader::CreateMaterial<T>::operator()(const std::string &, GenericLoader &ldr) const
203 throw std::logic_error("Material type was already specified");
208 ldr.mat_loader = new typename T::Loader(*mat, *ldr.coll);
210 ldr.mat_loader = new typename T::Loader(*mat);
211 ldr.add_auxiliary_loader(*ldr.mat_loader);