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 alpha_cutoff(float);
31 void alpha_cutoff_feather(float, float);
32 void sampler(const std::string &);
40 const Texture *texture;
42 Property(): value(T()), texture(0) { }
46 class PropertyLoader: public DataFile::DerivedObjectLoader<Material, Loader>
49 PropertyLoader(C &m, Collection &c): DerivedObjectLoader<Material, Loader>(m, c) { }
51 void add_property(const std::string &, void (C::*)(float), void (C::*)(const Texture *));
52 void add_property(const std::string &, void (C::*)(const Color &), void (C::*)(const Texture *), bool);
53 void add_property(const std::string &, void (C::*)(const Texture *));
55 void property_value_scalar(void (C::*)(float), float);
56 void property_value_rgb(void (C::*)(const Color &), float, float, float);
57 void property_value_rgba(void (C::*)(const Color &), float, float, float, float);
58 void property_value_srgb(void (C::*)(const Color &), float, float, float);
59 void property_value_srgb_alpha(void (C::*)(const Color &), float, float, float, float);
60 void property_texture(void (C::*)(const Texture *), const std::string &);
64 class GenericLoader: public DataFile::DynamicObjectLoader<Material>
66 friend class Material;
69 GenericLoader(Collection &c): DynamicObjectLoader<Material>(&c) { }
72 virtual const TypeRegistry &get_type_registry() const { return get_material_registry(); }
76 const Sampler *sampler = 0;
77 float alpha_cutoff = 0.0f;
78 float alpha_feather = 1.0f;
83 virtual ~Material() = default;
85 /** Returns a shader appropriate for this material. The same shader is
86 returned for materials with the same set of features. Additional
87 specialization values can be passed in to customize the shader. */
88 virtual const Program *create_compatible_shader(const std::map<std::string, int> & = std::map<std::string, int>()) const;
90 virtual void fill_program_info(std::string &, std::map<std::string, int> &) const = 0;
93 /** Returns the uniform values for the material. */
94 const ProgramData &get_shader_data() const { return shdata; }
96 /** Returns texture tags used by the material. The returned array is
97 terminated by an empty tag. */
98 virtual const Tag *get_texture_tags() const = 0;
100 virtual const Texture *get_texture(Tag) const = 0;
101 virtual const Sampler *get_sampler(Tag) const { return sampler; }
103 void set_alpha_cutoff(float);
104 void set_alpha_feather(float);
105 float get_alpha_cutoff() const { return alpha_cutoff; }
106 float get_alpha_feather() const { return alpha_feather; }
108 void set_debug_name(const std::string &);
111 static void register_type(const std::string &);
113 static GenericLoader::TypeRegistry &get_material_registry();
117 void Material::register_type(const std::string &kw)
119 get_material_registry().register_type<T>(kw);
124 void Material::PropertyLoader<C>::add_property(const std::string &kw, void (C::*set_value)(float), void (C::*set_texture)(const Texture *))
126 add(kw, &PropertyLoader<C>::property_value_scalar, set_value);
128 add(kw+"_map", &PropertyLoader<C>::property_texture, set_texture);
132 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)
134 add(kw, &PropertyLoader<C>::property_value_rgb, set_value);
135 add(kw+"_srgb", &PropertyLoader<C>::property_value_srgb, set_value);
138 add(kw, &PropertyLoader<C>::property_value_rgba, set_value);
139 add(kw+"_srgb", &PropertyLoader<C>::property_value_srgb_alpha, set_value);
142 add(kw+"_map", &PropertyLoader<C>::property_texture, set_texture);
146 void Material::PropertyLoader<C>::add_property(const std::string &kw, void (C::*set_texture)(const Texture *))
148 add(kw+"_map", &PropertyLoader<C>::property_texture, set_texture);
152 void Material::PropertyLoader<C>::property_value_scalar(void (C::*set_value)(float), float value)
154 (static_cast<C &>(obj).*set_value)(value);
158 void Material::PropertyLoader<C>::property_value_rgb(void (C::*set_value)(const Color &), float r, float g, float b)
160 (static_cast<C &>(obj).*set_value)(Color(r, g, b));
164 void Material::PropertyLoader<C>::property_value_rgba(void (C::*set_value)(const Color &), float r, float g, float b, float a)
166 (static_cast<C &>(obj).*set_value)(Color(r, g, b, a));
170 void Material::PropertyLoader<C>::property_value_srgb(void (C::*set_value)(const Color &), float r, float g, float b)
172 (static_cast<C &>(obj).*set_value)(Color(r, g, b).to_linear());
176 void Material::PropertyLoader<C>::property_value_srgb_alpha(void (C::*set_value)(const Color &), float r, float g, float b, float a)
178 (static_cast<C &>(obj).*set_value)(Color(r, g, b, a).to_linear());
182 void Material::PropertyLoader<C>::property_texture(void (C::*set_texture)(const Texture *), const std::string &name)
184 /* The static_cast around get_collection is needed because otherwise Android
185 SDK's g++ 4.9 fails to parse get<Texture> as a template function call */
186 (static_cast<C &>(obj).*set_texture)(&static_cast<Collection &>(get_collection()).get<Texture>(name));