]> git.tdb.fi Git - libs/gl.git/blobdiff - source/materials/material.h
Check the flat qualifier from the correct member
[libs/gl.git] / source / materials / material.h
index 571f4cb027c4da3a41e8d317e1e4c042603a2706..3210c96612fcfc2739d7fb99134f086c0c3761f9 100644 (file)
@@ -2,7 +2,7 @@
 #define MSP_GL_MATERIAL_H_
 
 #include <msp/datafile/collection.h>
-#include <msp/datafile/loadabletyperegistry.h>
+#include <msp/datafile/dynamicobjectloader.h>
 #include <msp/datafile/objectloader.h>
 #include "color.h"
 #include "programdata.h"
 namespace Msp {
 namespace GL {
 
-class Texturing;
+class Sampler;
 
+/**
+Base class for materials.  Subclasses provide different shading models.
+*/
 class Material
 {
 private:
        class Loader: public DataFile::CollectionObjectLoader<Material>
        {
        protected:
-               Loader(Material &);
                Loader(Material &, Collection &);
 
                virtual void init_actions();
 
        private:
+               void alpha_cutoff(float);
+               void alpha_cutoff_feather(float, float);
                void sampler(const std::string &);
        };
 
@@ -42,7 +46,6 @@ protected:
        class PropertyLoader: public DataFile::DerivedObjectLoader<Material, Loader>
        {
        protected:
-               PropertyLoader(C &m): DerivedObjectLoader<Material, Loader>(m) { }
                PropertyLoader(C &m, Collection &c): DerivedObjectLoader<Material, Loader>(m, c) { }
 
                void add_property(const std::string &, void (C::*)(float), void (C::*)(const Texture *));
@@ -58,62 +61,56 @@ protected:
        };
 
 public:
-       class GenericLoader: public DataFile::Loader
+       class GenericLoader: public DataFile::DynamicObjectLoader<Material>
        {
-       private:
-               template<typename T>
-               struct AddType
-               {
-                       static void add(GenericLoader &ldr, const std::string &kw) { ldr.add(kw, &GenericLoader::typed_material<T>); }
-               };
-
-               DataFile::Collection *coll;
-               RefPtr<Material> material;
-
-               static ActionMap shared_actions;
+               friend class Material;
 
        public:
-               GenericLoader(DataFile::Collection * = 0);
-
-               Material *get_material() { return material.release(); }
-       private:
-               virtual void init_actions();
-
-               template<typename T>
-               void typed_material();
+               GenericLoader(Collection &c): DynamicObjectLoader<Material>(&c) { }
 
-               friend class Material;
+       protected:
+               virtual const TypeRegistry &get_type_registry() const { return get_material_registry(); }
        };
 
-private:
-       typedef DataFile::LoadableTypeRegistry<GenericLoader, GenericLoader::AddType> MaterialRegistry;
-
 protected:
-       const Sampler *sampler;
+       const Sampler *sampler = 0;
+       float alpha_cutoff = 0.0f;
+       float alpha_feather = 1.0f;
        ProgramData shdata;
 
-       Material(): sampler(0) { }
+       Material();
 public:
-       virtual ~Material() { }
+       virtual ~Material() = default;
 
-       virtual Program *create_compatible_shader() const;
-       virtual const Program *create_compatible_shader(DataFile::Collection &) const;
+       /** Returns a shader appropriate for this material.  The same shader is
+       returned for materials with the same set of features.  Additional
+       specialization values can be passed in to customize the shader. */
+       virtual const Program *create_compatible_shader(const std::map<std::string, int> & = std::map<std::string, int>()) const;
 protected:
-       virtual std::string create_program_source() const = 0;
+       virtual void fill_program_info(std::string &, std::map<std::string, int> &) const = 0;
 
 public:
-       /** Returns the uniforms for the material. */
+       /** Returns the uniform values for the material. */
        const ProgramData &get_shader_data() const { return shdata; }
 
-protected:
-       void attach_texture_to(const Texture *, Texturing &, ProgramData &, const std::string &) const;
-public:
-       virtual void attach_textures_to(Texturing &, ProgramData &) const = 0;
+       /** Returns texture tags used by the material.  The returned array is
+       terminated by an empty tag. */
+       virtual const Tag *get_texture_tags() const = 0;
+
+       virtual const Texture *get_texture(Tag) const = 0;
+       virtual const Sampler *get_sampler(Tag) const { return sampler; }
+
+       void set_alpha_cutoff(float);
+       void set_alpha_feather(float);
+       float get_alpha_cutoff() const { return alpha_cutoff; }
+       float get_alpha_feather() const { return alpha_feather; }
+
+       void set_debug_name(const std::string &);
 
        template<typename T>
        static void register_type(const std::string &);
 private:
-       static MaterialRegistry &get_material_registry();
+       static GenericLoader::TypeRegistry &get_material_registry();
 };
 
 template<typename T>
@@ -127,7 +124,8 @@ template<typename C>
 void Material::PropertyLoader<C>::add_property(const std::string &kw, void (C::*set_value)(float), void (C::*set_texture)(const Texture *))
 {
        add(kw, &PropertyLoader<C>::property_value_scalar, set_value);
-       add(kw+"_map", &PropertyLoader<C>::property_texture, set_texture);
+       if(set_texture)
+               add(kw+"_map", &PropertyLoader<C>::property_texture, set_texture);
 }
 
 template<typename C>
@@ -140,7 +138,8 @@ void Material::PropertyLoader<C>::add_property(const std::string &kw, void (C::*
                add(kw, &PropertyLoader<C>::property_value_rgba, set_value);
                add(kw+"_srgb", &PropertyLoader<C>::property_value_srgb_alpha, set_value);
        }
-       add(kw+"_map", &PropertyLoader<C>::property_texture, set_texture);
+       if(set_texture)
+               add(kw+"_map", &PropertyLoader<C>::property_texture, set_texture);
 }
 
 template<typename C>
@@ -187,20 +186,6 @@ void Material::PropertyLoader<C>::property_texture(void (C::*set_texture)(const
        (static_cast<C &>(obj).*set_texture)(&static_cast<Collection &>(get_collection()).get<Texture>(name));
 }
 
-
-template<typename T>
-void Material::GenericLoader::typed_material()
-{
-       if(material)
-               throw std::logic_error("Material was already loaded");
-       RefPtr<T> mat = new T;
-       if(coll)
-               load_sub(*mat, *coll);
-       else
-               load_sub(*mat);
-       material = mat;
-}
-
 } // namespace GL
 } // namespace Msp