1 #ifndef MSP_GL_MATERIAL_H_
2 #define MSP_GL_MATERIAL_H_
4 #include <msp/datafile/collection.h>
5 #include <msp/datafile/loadabletyperegistry.h>
6 #include <msp/datafile/objectloader.h>
8 #include "programdata.h"
23 const Texture *texture;
25 Property(): value(T()), texture(0) { }
29 class LoaderBase: public DataFile::CollectionObjectLoader<Material>
32 LoaderBase(C &m): CollectionObjectLoader<Material>(m, 0) { }
33 LoaderBase(C &m, Collection &c): CollectionObjectLoader<Material>(m, &c) { }
35 void add_property(const std::string &, void (C::*)(float), void (C::*)(const Texture *));
36 void add_property(const std::string &, void (C::*)(const Color &), void (C::*)(const Texture *), bool);
37 void add_property(const std::string &, void (C::*)(const Texture *));
39 void property_value_scalar(void (C::*)(float), float);
40 void property_value_rgb(void (C::*)(const Color &), float, float, float);
41 void property_value_rgba(void (C::*)(const Color &), float, float, float, float);
42 void property_value_srgb(void (C::*)(const Color &), float, float, float);
43 void property_value_srgb_alpha(void (C::*)(const Color &), float, float, float, float);
44 void property_texture(void (C::*)(const Texture *), const std::string &);
48 class GenericLoader: public DataFile::Loader
54 static void add(GenericLoader &ldr, const std::string &kw) { ldr.add(kw, &GenericLoader::typed_material<T>); }
57 DataFile::Collection *coll;
58 RefPtr<Material> material;
60 static ActionMap shared_actions;
63 GenericLoader(DataFile::Collection * = 0);
65 Material *get_material() { return material.release(); }
67 virtual void init_actions();
70 void typed_material();
72 friend class Material;
76 typedef DataFile::LoadableTypeRegistry<GenericLoader, GenericLoader::AddType> MaterialRegistry;
83 virtual ~Material() { }
86 /** Returns the uniforms for the material. */
87 const ProgramData &get_shader_data() const { return shdata; }
90 void attach_texture_to(const Texture *, Texturing &, ProgramData &, const std::string &) const;
92 virtual void attach_textures_to(Texturing &, ProgramData &) const = 0;
95 static void register_type(const std::string &);
97 static MaterialRegistry &get_material_registry();
101 void Material::register_type(const std::string &kw)
103 get_material_registry().register_type<T>(kw);
108 void Material::LoaderBase<C>::add_property(const std::string &kw, void (C::*set_value)(float), void (C::*set_texture)(const Texture *))
110 add(kw, &LoaderBase<C>::property_value_scalar, set_value);
111 add(kw+"_map", &LoaderBase<C>::property_texture, set_texture);
115 void Material::LoaderBase<C>::add_property(const std::string &kw, void (C::*set_value)(const Color &), void (C::*set_texture)(const Texture *), bool allow_alpha)
117 add(kw, &LoaderBase<C>::property_value_rgb, set_value);
118 add(kw+"_srgb", &LoaderBase<C>::property_value_srgb, set_value);
121 add(kw, &LoaderBase<C>::property_value_rgba, set_value);
122 add(kw+"_srgb", &LoaderBase<C>::property_value_srgb_alpha, set_value);
124 add(kw+"_map", &LoaderBase<C>::property_texture, set_texture);
128 void Material::LoaderBase<C>::add_property(const std::string &kw, void (C::*set_texture)(const Texture *))
130 add(kw+"_map", &LoaderBase<C>::property_texture, set_texture);
134 void Material::LoaderBase<C>::property_value_scalar(void (C::*set_value)(float), float value)
136 (static_cast<C &>(obj).*set_value)(value);
140 void Material::LoaderBase<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::LoaderBase<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::LoaderBase<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::LoaderBase<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::LoaderBase<C>::property_texture(void (C::*set_texture)(const Texture *), const std::string &name)
166 (static_cast<C &>(obj).*set_texture)(&get_collection().get<GL::Texture>(name));
171 void Material::GenericLoader::typed_material()
174 throw std::logic_error("Material was already loaded");
175 RefPtr<T> mat = new T;
177 load_sub(*mat, *coll);