#ifndef MSP_GL_MATERIAL_H_
#define MSP_GL_MATERIAL_H_
+#include <msp/core/typeregistry.h>
#include <msp/datafile/collection.h>
-#include <msp/datafile/loadabletyperegistry.h>
#include <msp/datafile/objectloader.h>
#include "color.h"
#include "programdata.h"
namespace Msp {
namespace GL {
-class Texturing;
+class Sampler;
class Material
{
{
private:
template<typename T>
- struct AddType
+ struct CreateMaterial
{
- static void add(GenericLoader &ldr, const std::string &kw) { ldr.add(kw, &GenericLoader::typed_material<T>); }
+ void operator()(const std::string &, GenericLoader &) const;
};
DataFile::Collection *coll;
- RefPtr<Material> material;
+ Material *material;
+ Loader *mat_loader;
static ActionMap shared_actions;
public:
GenericLoader(DataFile::Collection * = 0);
+ ~GenericLoader();
- Material *get_material() { return material.release(); }
+ Material *get_material() { Material *m = material; material = 0; return m; }
private:
virtual void init_actions();
- template<typename T>
- void typed_material();
+ void type(const DataFile::Symbol &);
friend class Material;
};
private:
- typedef DataFile::LoadableTypeRegistry<GenericLoader, GenericLoader::AddType> MaterialRegistry;
+ typedef TypeRegistry<GenericLoader::CreateMaterial, GenericLoader &> MaterialRegistry;
protected:
const Sampler *sampler;
public:
virtual ~Material() { }
- virtual Program *create_compatible_shader() const;
- virtual const Program *create_compatible_shader(DataFile::Collection &) const;
+ 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. */
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;
+ 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_debug_name(const std::string &);
template<typename T>
static void register_type(const std::string &);
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>
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>
template<typename T>
-void Material::GenericLoader::typed_material()
+void Material::GenericLoader::CreateMaterial<T>::operator()(const std::string &, GenericLoader &ldr) const
{
- if(material)
- throw std::logic_error("Material was already loaded");
- RefPtr<T> mat = new T;
- if(coll)
- load_sub(*mat, *coll);
+ if(ldr.material)
+ throw std::logic_error("Material type was already specified");
+
+ T *mat = new T;
+ ldr.material = mat;
+ if(ldr.coll)
+ ldr.mat_loader = new typename T::Loader(*mat, *ldr.coll);
else
- load_sub(*mat);
- material = mat;
+ ldr.mat_loader = new typename T::Loader(*mat);
+ ldr.add_auxiliary_loader(*ldr.mat_loader);
}
} // namespace GL