--- /dev/null
+#ifndef MSP_GL_SPLATMATERIAL_H_
+#define MSP_GL_SPLATMATERIAL_H_
+
+#include "material.h"
+
+namespace Msp {
+namespace GL {
+
+class Texture;
+class Texture2DArray;
+
+class SplatMaterial: public Material, public NonCopyable
+{
+private:
+ struct MapArray;
+
+public:
+ class Loader: public DataFile::DerivedObjectLoader<SplatMaterial, PropertyLoader<SplatMaterial>>
+ {
+ private:
+ static ActionMap shared_actions;
+
+ public:
+ Loader(SplatMaterial &, Collection &);
+
+ private:
+ virtual void init_actions();
+ virtual void finish();
+
+ void map_storage(MapArray SplatMaterial::*, PixelFormat, unsigned, unsigned);
+ void sub();
+ };
+
+private:
+ struct SubMap
+ {
+ std::string source_fn;
+ int layer = -1;
+ };
+
+ struct SubMaterial
+ {
+ class Loader: public DataFile::ObjectLoader<SubMaterial>
+ {
+ private:
+ static ActionMap shared_actions;
+
+ public:
+ Loader(SubMaterial &);
+
+ private:
+ virtual void init_actions();
+
+ void base_color(float, float, float);
+ void emission(float, float, float);
+ void map(SubMap SubMaterial::*, const std::string &);
+ void tint(float, float, float, float);
+ };
+
+ Color base_color = { 0.8f };
+ Color tint = { 1.0f };
+ float metalness = 0.0f;
+ float roughness = 0.5f;
+ Color emission = { 0.0f };
+ SubMap base_color_map;
+ SubMap normal_map;
+ SubMap metalness_map;
+ SubMap roughness_map;
+ SubMap occlusion_map;
+ SubMap emission_map;
+ };
+
+ struct MapArray
+ {
+ Texture2DArray *texture = 0;
+ PixelFormat format = NO_PIXELFORMAT;
+ unsigned width = 0;
+ unsigned height = 0;
+ unsigned max_layers = 0;
+
+ void create();
+ };
+
+ std::vector<SubMaterial> sub_materials;
+ MapArray base_color_array;
+ MapArray normal_array;
+ MapArray metalness_array;
+ MapArray roughness_array;
+ MapArray occlusion_array;
+ MapArray emission_array;
+ const Texture2D &fresnel_lookup;
+ const Sampler &fresnel_sampler;
+
+ static const Tag texture_tags[];
+
+public:
+ SplatMaterial();
+ ~SplatMaterial();
+
+protected:
+ virtual void fill_program_info(std::string &, std::map<std::string, int> &) const;
+
+public:
+ virtual const Tag *get_texture_tags() const { return texture_tags; }
+ virtual const Texture *get_texture(Tag) const;
+ virtual const Sampler *get_sampler(Tag) const;
+
+private:
+ void set_sub_uniforms(unsigned);
+ void upload_sub(DataFile::Collection &, unsigned);
+ void upload_sub_map(DataFile::Collection &, unsigned, SubMap SubMaterial::*, MapArray &, const char *);
+};
+
+} // namespace GL
+} // namespace Msp
+
+#endif