1 module meld.material;
2 
3 import meld;
4 
5 class Material
6 {
7 private:
8 	struct MaterialProperty
9 	{
10 		byte[64] value;
11 		void function(string property, ref MaterialProperty prop, ref Shader shader) setParameter;
12 
13 		void SetValue(T)(T value)
14 		{
15 			static assert(T.sizeof <= this.value.sizeof);
16 			byte* valPtr = cast(byte*)&value;
17 			foreach (i; 0..T.sizeof)
18 				this.value[i] = valPtr[i];
19 		}
20 
21 		T GetValue(T)()
22 		{
23 			const int floatWidth = T.sizeof / float.sizeof;
24 			static assert(T.sizeof <= this.value.sizeof);
25 			T value;
26 			byte* valPtr = cast(byte*)&value;
27 			foreach (i; 0..T.sizeof)
28 				valPtr[i] = this.value[i];
29 			return value;
30 		}
31 	}
32 
33 	Shader m_shader;
34 	MaterialProperty[string] m_properties;
35 	static Material m_currentMaterial;
36 	static MaterialProperty[string] m_globalProperties;
37 	static bool m_globalPropsChanged = false;
38 
39 public:
40 	this(Shader shader)
41 	{
42 		m_shader = shader;
43 	}
44 
45 	Material SetParameter(T)(string property, T value)
46 	{
47 		MaterialProperty prop;
48 		prop.SetValue!T(value);
49 
50 		prop.setParameter = function(string property, ref MaterialProperty value, ref Shader shader)
51 		{
52 			shader.SetParameter(property, value.GetValue!T());
53 		};
54 		m_properties[property] = prop;
55 		return this;
56 	}
57 
58 	static void SetGlobalParameter(T)(string property, T value)
59 	{
60 		MaterialProperty prop;
61 		prop.SetValue!T(value);
62 
63 		prop.setParameter = function(string property, ref MaterialProperty value, ref Shader shader)
64 		{
65 			shader.SetParameter(property, value.GetValue!T());
66 		};
67 		m_globalProperties[property] = prop;
68 		m_globalPropsChanged = true;
69 	}
70 
71 	void SetParameters(ref MaterialProperty[string] propList)
72 	{
73 		foreach (string property, MaterialProperty value; propList)
74 			value.setParameter(property, value, m_shader);
75 	}
76 
77 	void Bind( mat4 world )
78 	{
79 		m_shader.Bind();
80 		m_shader.SetParameter("world", world);
81 		SetParameters(m_globalProperties);
82 		SetParameters(m_properties);
83 		/*if (m_globalPropsChanged)
84 		{
85 			
86 			m_globalPropsChanged = false;
87 		}
88 
89 		if (m_currentMaterial == this)
90 			return;
91 
92 		m_currentMaterial = this;
93 
94 		//If the shader has changed, rebind all global variables onto the new shader
95 		if (m_shader.Bind())
96 			
97 		
98 		SetParameters(m_properties);*/
99 	}
100 
101 	void Test()
102 	{
103 		SetParameter!vec3("Test", vec3.zero);
104 	}
105 }