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"
17 Base class for materials. Subclasses provide different shading models.
22 class Loader: public DataFile::CollectionObjectLoader<Material>
25 Loader(Material &, Collection &);
27 virtual void init_actions();
30 void sampler(const std::string &);
38 const Texture *texture;
40 Property(): value(T()), texture(0) { }
44 class PropertyLoader: public DataFile::DerivedObjectLoader<Material, Loader>
47 PropertyLoader(C &m, Collection &c): DerivedObjectLoader<Material, Loader>(m, c) { }
49 void add_property(const std::string &, void (C::*)(float), void (C::*)(const Texture *));
50 void add_property(const std::string &, void (C::*)(const Color &), void (C::*)(const Texture *), bool);
51 void add_property(const std::string &, void (C::*)(const Texture *));
53 void property_value_scalar(void (C::*)(float), float);
54 void property_value_rgb(void (C::*)(const Color &), float, float, float);
55 void property_value_rgba(void (C::*)(const Color &), float, float, float, float);
56 void property_value_srgb(void (C::*)(const Color &), float, float, float);
57 void property_value_srgb_alpha(void (C::*)(const Color &), float, float, float, float);
58 void property_texture(void (C::*)(const Texture *), const std::string &);
62 class GenericLoader: public DataFile::DynamicObjectLoader<Material>
64 friend class Material;
67 GenericLoader(Collection &c): DynamicObjectLoader<Material>(&c) { }
70 virtual const TypeRegistry &get_type_registry() const { return get_material_registry(); }
74 const Sampler *sampler = 0;
79 virtual ~Material() = default;
81 /** Returns a shader appropriate for this material. The same shader is
82 returned for materials with the same set of features. Additional
83 specialization values can be passed in to customize the shader. */
84 virtual const Program *create_compatible_shader(const std::map<std::string, int> & = std::map<std::string, int>()) const;
86 virtual void fill_program_info(std::string &, std::map<std::string, int> &) const = 0;
89 /** Returns the uniform values for the material. */
90 const ProgramData &get_shader_data() const { return shdata; }
92 /** Returns texture tags used by the material. The returned array is
93 terminated by an empty tag. */
94 virtual const Tag *get_texture_tags() const = 0;
96 virtual const Texture *get_texture(Tag) const = 0;
97 virtual const Sampler *get_sampler(Tag) const { return sampler; }
99 void set_debug_name(const std::string &);
102 static void register_type(const std::string &);
104 static GenericLoader::TypeRegistry &get_material_registry();
108 void Material::register_type(const std::string &kw)
110 get_material_registry().register_type<T>(kw);
115 void Material::PropertyLoader<C>::add_property(const std::string &kw, void (C::*set_value)(float), void (C::*set_texture)(const Texture *))
117 add(kw, &PropertyLoader<C>::property_value_scalar, set_value);
119 add(kw+"_map", &PropertyLoader<C>::property_texture, set_texture);
123 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)
125 add(kw, &PropertyLoader<C>::property_value_rgb, set_value);
126 add(kw+"_srgb", &PropertyLoader<C>::property_value_srgb, set_value);
129 add(kw, &PropertyLoader<C>::property_value_rgba, set_value);
130 add(kw+"_srgb", &PropertyLoader<C>::property_value_srgb_alpha, set_value);
133 add(kw+"_map", &PropertyLoader<C>::property_texture, set_texture);
137 void Material::PropertyLoader<C>::add_property(const std::string &kw, void (C::*set_texture)(const Texture *))
139 add(kw+"_map", &PropertyLoader<C>::property_texture, set_texture);
143 void Material::PropertyLoader<C>::property_value_scalar(void (C::*set_value)(float), float value)
145 (static_cast<C &>(obj).*set_value)(value);
149 void Material::PropertyLoader<C>::property_value_rgb(void (C::*set_value)(const Color &), float r, float g, float b)
151 (static_cast<C &>(obj).*set_value)(Color(r, g, b));
155 void Material::PropertyLoader<C>::property_value_rgba(void (C::*set_value)(const Color &), float r, float g, float b, float a)
157 (static_cast<C &>(obj).*set_value)(Color(r, g, b, a));
161 void Material::PropertyLoader<C>::property_value_srgb(void (C::*set_value)(const Color &), float r, float g, float b)
163 (static_cast<C &>(obj).*set_value)(Color(r, g, b).to_linear());
167 void Material::PropertyLoader<C>::property_value_srgb_alpha(void (C::*set_value)(const Color &), float r, float g, float b, float a)
169 (static_cast<C &>(obj).*set_value)(Color(r, g, b, a).to_linear());
173 void Material::PropertyLoader<C>::property_texture(void (C::*set_texture)(const Texture *), const std::string &name)
175 /* The static_cast around get_collection is needed because otherwise Android
176 SDK's g++ 4.9 fails to parse get<Texture> as a template function call */
177 (static_cast<C &>(obj).*set_texture)(&static_cast<Collection &>(get_collection()).get<Texture>(name));