Browse Source

Enhancing material. Arrays are supported

Panagiotis Christopoulos Charitos 13 years ago
parent
commit
2d6e7dccb3
3 changed files with 104 additions and 62 deletions
  1. 42 22
      include/anki/resource/Material.h
  2. 26 16
      src/renderer/Drawer.cpp
  3. 36 24
      src/resource/Material.cpp

+ 42 - 22
include/anki/resource/Material.h

@@ -24,14 +24,24 @@ class ShaderProgramUniformBlock;
 const U32 MATERIAL_MAX_PASSES = 4;
 const U32 MATERIAL_MAX_PASSES = 4;
 const U32 MATERIAL_MAX_LODS = 4;
 const U32 MATERIAL_MAX_LODS = 4;
 
 
-/// Material variable base. Its a visitable
-typedef Visitable<F32, Vec2, Vec3, Vec4, Mat3, Mat4, TextureResourcePointer> 
-	MateriaVariableVisitable;
-
 // Forward
 // Forward
 template<typename T>
 template<typename T>
 class MaterialVariableTemplate;
 class MaterialVariableTemplate;
 
 
+class MaterialVariable;
+
+/// Material variable base. Its a visitable
+typedef VisitableCommonBase<
+	MaterialVariable,
+	MaterialVariableTemplate<F32>,
+	MaterialVariableTemplate<Vec2>,
+	MaterialVariableTemplate<Vec3>,
+	MaterialVariableTemplate<Vec4>,
+	MaterialVariableTemplate<Mat3>,
+	MaterialVariableTemplate<Mat4>,
+	MaterialVariableTemplate<TextureResourcePointer>>
+	MateriaVariableVisitable;
+
 /// Holds the shader variables. Its a container for shader program variables
 /// Holds the shader variables. Its a container for shader program variables
 /// that share the same name
 /// that share the same name
 class MaterialVariable: public MateriaVariableVisitable, public NonCopyable
 class MaterialVariable: public MateriaVariableVisitable, public NonCopyable
@@ -59,19 +69,23 @@ public:
 	/// @name Accessors
 	/// @name Accessors
 	/// @{
 	/// @{
 	template<typename T>
 	template<typename T>
-	const T& getValue() const
+	const T* getValues() const
 	{
 	{
-		ANKI_ASSERT(Base::getVariadicTypeId<T>() == Base::getVisitableTypeId());
+		ANKI_ASSERT(Base::getVariadicTypeId<MaterialVariableTemplate<T>>()
+			== Base::getVisitableTypeId());
 		return static_cast<const MaterialVariableTemplate<T>*>(this)->get();
 		return static_cast<const MaterialVariableTemplate<T>*>(this)->get();
 	}
 	}
 
 
 	template<typename T>
 	template<typename T>
-	void setValue(const T& x)
+	void setValues(const T* x, U32 size)
 	{
 	{
-		ANKI_ASSERT(Base::getVariadicTypeId<T>() == Base::getVisitableTypeId());
-		static_cast<MaterialVariableTemplate<T>*>(this)->set(x);
+		ANKI_ASSERT(Base::getVariadicTypeId<MaterialVariableTemplate<T>>()
+			== Base::getVisitableTypeId());
+		static_cast<MaterialVariableTemplate<T>*>(this)->set(x, size);
 	}
 	}
 
 
+	virtual U32 getValuesCount() const = 0;
+
 	/// Given a key return the uniform. If the uniform is not present in the
 	/// Given a key return the uniform. If the uniform is not present in the
 	/// LOD pass key then returns nullptr
 	/// LOD pass key then returns nullptr
 	const ShaderProgramUniformVariable* findShaderProgramUniformVariable(
 	const ShaderProgramUniformVariable* findShaderProgramUniformVariable(
@@ -95,7 +109,10 @@ public:
 	}
 	}
 
 
 	/// If false then it should be buildin
 	/// If false then it should be buildin
-	virtual Bool hasValue() const = 0;
+	Bool hasValue() const
+	{
+		return getValuesCount() > 0;
+	}
 	/// @}
 	/// @}
 
 
 private:
 private:
@@ -115,6 +132,8 @@ template<typename Data>
 class MaterialVariableTemplate: public MaterialVariable
 class MaterialVariableTemplate: public MaterialVariable
 {
 {
 public:
 public:
+	typedef Data Type;
+
 	/// @name Constructors/Destructor
 	/// @name Constructors/Destructor
 	/// @{
 	/// @{
 	MaterialVariableTemplate(
 	MaterialVariableTemplate(
@@ -122,7 +141,7 @@ public:
 		PassLevelToShaderProgramHashMap& progs)
 		PassLevelToShaderProgramHashMap& progs)
 		: MaterialVariable(shaderProgVarName, progs)
 		: MaterialVariable(shaderProgVarName, progs)
 	{
 	{
-		setupVisitable(&data);
+		setupVisitable(this);
 	}
 	}
 
 
 	~MaterialVariableTemplate()
 	~MaterialVariableTemplate()
@@ -131,27 +150,28 @@ public:
 
 
 	/// @name Accessors
 	/// @name Accessors
 	/// @{
 	/// @{
-	const Data& get() const
+	const Data* get() const
 	{
 	{
-		ANKI_ASSERT(dataSet == true);
-		return data;
+		ANKI_ASSERT(data.size() > 0);
+		return &data[0];
 	}
 	}
 
 
-	void set(const Data& x)
+	void set(const Data* x, U32 size)
 	{
 	{
-		data = x;
-		dataSet = true;
+		if(size > 0)
+		{
+			data.insert(data.begin(), x, x + size);
+		}
 	}
 	}
-	/// @}
 
 
-	Bool hasValue() const
+	U32 getValuesCount() const
 	{
 	{
-		return dataSet;
+		return data.size();
 	}
 	}
+	/// @}
 
 
 private:
 private:
-	Data data;
-	Bool dataSet = false;
+	Vector<Data> data;
 };
 };
 
 
 /// Contains a few properties that other classes may use. For an explanation of
 /// Contains a few properties that other classes may use. For an explanation of

+ 26 - 16
src/renderer/Drawer.cpp

@@ -23,13 +23,14 @@ struct SetupMaterialVariableVisitor
 
 
 	/// Set a uniform in a client block
 	/// Set a uniform in a client block
 	template<typename T>
 	template<typename T>
-	void uniSet(const ShaderProgramUniformVariable& uni, const T& value)
+	void uniSet(const ShaderProgramUniformVariable& uni,
+		const T* value, U32 size)
 	{
 	{
 		ANKI_ASSERT(0);
 		ANKI_ASSERT(0);
 	}
 	}
 
 
-	template<typename TProp>
-	void visit(TProp& x)
+	template<typename MtlVariableTemplate>
+	void visit(MtlVariableTemplate& x)
 	{
 	{
 		const MaterialVariable& mv = rvar->getMaterialVariable();
 		const MaterialVariable& mv = rvar->getMaterialVariable();
 
 
@@ -53,12 +54,13 @@ struct SetupMaterialVariableVisitor
 		switch(rvar->getBuildinId())
 		switch(rvar->getBuildinId())
 		{
 		{
 		case BMV_NO_BUILDIN:
 		case BMV_NO_BUILDIN:
-			uniSet(*uni, x);
+			uniSet<typename MtlVariableTemplate::Type>(
+				*uni, x.get(), x.getValuesCount());
 			break;
 			break;
 		case BMV_MODEL_VIEW_PROJECTION_MATRIX:
 		case BMV_MODEL_VIEW_PROJECTION_MATRIX:
 			{
 			{
 				Mat4 mvpMat = vpMat * mMat;
 				Mat4 mvpMat = vpMat * mMat;
-				uniSet(*uni, mvpMat);
+				uniSet(*uni, &mvpMat, 1);
 			}
 			}
 			break;
 			break;
 		case BMV_MODEL_VIEW_MATRIX:
 		case BMV_MODEL_VIEW_MATRIX:
@@ -67,15 +69,18 @@ struct SetupMaterialVariableVisitor
 				mvMat = fr->getViewMatrix() * mMat;
 				mvMat = fr->getViewMatrix() * mMat;
 				mvMatCalculated = true;
 				mvMatCalculated = true;
 			}
 			}
-			uniSet(*uni, mvMat);
+			uniSet(*uni, &mvMat, 1);
 			break;
 			break;
 		case BMV_NORMAL_MATRIX:
 		case BMV_NORMAL_MATRIX:
-			if(!mvMatCalculated)
 			{
 			{
-				mvMat = fr->getViewMatrix() * mMat;
-				mvMatCalculated = true;
+				if(!mvMatCalculated)
+				{
+					mvMat = fr->getViewMatrix() * mMat;
+					mvMatCalculated = true;
+				}
+				Mat3 rot = mvMat.getRotationPart();
+				uniSet(*uni, &rot, 1);
 			}
 			}
-			uniSet(*uni, mvMat.getRotationPart());
 			break;
 			break;
 		case BMV_INSTANCING_MODEL_VIEW_PROJECTION_MATRICES:
 		case BMV_INSTANCING_MODEL_VIEW_PROJECTION_MATRICES:
 			{
 			{
@@ -96,7 +101,10 @@ struct SetupMaterialVariableVisitor
 			}
 			}
 			break;
 			break;
 		case BMV_BLURRING:
 		case BMV_BLURRING:
-			uniSet(*uni, 0.0);
+			{
+				F32 blurring = 0.0;
+				uniSet(*uni, &blurring, 1);
+			}
 			break;
 			break;
 		default:
 		default:
 			ANKI_ASSERT(0);
 			ANKI_ASSERT(0);
@@ -110,17 +118,18 @@ struct SetupMaterialVariableVisitor
 #define TEMPLATE_SPECIALIZATION(type) \
 #define TEMPLATE_SPECIALIZATION(type) \
 	template<> \
 	template<> \
 	void SetupMaterialVariableVisitor::uniSet<type>( \
 	void SetupMaterialVariableVisitor::uniSet<type>( \
-		const ShaderProgramUniformVariable& uni, const type& value) \
+		const ShaderProgramUniformVariable& uni, const type* values, \
+		U32 size) \
 	{ \
 	{ \
 		if(uni.getUniformBlock()) \
 		if(uni.getUniformBlock()) \
 		{ \
 		{ \
 			uni.setClientMemory(&clientBlock[0], \
 			uni.setClientMemory(&clientBlock[0], \
 				RenderableDrawer::UNIFORM_BLOCK_MAX_SIZE, \
 				RenderableDrawer::UNIFORM_BLOCK_MAX_SIZE, \
-				&value, 1); \
+				values, size); \
 		} \
 		} \
 		else \
 		else \
 		{ \
 		{ \
-			uni.set(value); \
+			uni.set(values, size); \
 		} \
 		} \
 	}
 	}
 
 
@@ -135,9 +144,10 @@ TEMPLATE_SPECIALIZATION(Mat4)
 template<>
 template<>
 void SetupMaterialVariableVisitor::uniSet<TextureResourcePointer>(
 void SetupMaterialVariableVisitor::uniSet<TextureResourcePointer>(
 	const ShaderProgramUniformVariable& uni, 
 	const ShaderProgramUniformVariable& uni, 
-	const TextureResourcePointer& value)
+	const TextureResourcePointer* values, U32 size)
 {
 {
-	const Texture* tex = value.get();
+	ANKI_ASSERT(size == 1);
+	const Texture* tex = values->get();
 	uni.set(*tex);
 	uni.set(*tex);
 }
 }
 
 

+ 36 - 24
src/resource/Material.cpp

@@ -19,23 +19,38 @@ namespace anki {
 //==============================================================================
 //==============================================================================
 
 
 //==============================================================================
 //==============================================================================
-template<typename Type, size_t n>
-static Type setMathType(const StringList& list)
+struct SetMaterialVariableValuesVisitor
 {
 {
-	Type out;
+	const StringList& list;
 
 
-	if(list.size() != n)
-	{
-		throw ANKI_EXCEPTION("Incorrect number of values");
-	}
+	SetMaterialVariableValuesVisitor(const StringList& list_)
+		: list(list_)
+	{}
 
 
-	for(U i = 0; i < n; ++i)
+	template<typename TMaterialVariableTemplate>
+	void visit(TMaterialVariableTemplate& mv)
 	{
 	{
-		out[i] = std::stof(list[i]);
-	}
+		typedef typename TMaterialVariableTemplate::Type Type;
 
 
-	return out;
-}
+		U32 floatsNeeded = mv.getAShaderProgramUniformVariable().getSize()
+			* (sizeof(Type) / sizeof(F32));
+
+		if(list.size() != floatsNeeded)
+		{
+			throw ANKI_EXCEPTION("Incorrect number of values");
+		}
+
+		Vector<F32> floatvec;
+		floatvec.resize(floatsNeeded);
+		for(U i = 0; i < floatsNeeded; ++i)
+		{
+			floatvec[i] = std::stof(list[i]);
+		}
+
+		mv.set((Type*)&floatvec[0],
+			mv.getAShaderProgramUniformVariable().getSize());
+	}
+};
 
 
 //==============================================================================
 //==============================================================================
 /// Given a string that defines blending return the GLenum
 /// Given a string that defines blending return the GLenum
@@ -414,23 +429,20 @@ void Material::populateVariables(const MaterialShaderProgramCreator& mspc)
 			{
 			{
 			// sampler2D
 			// sampler2D
 			case GL_SAMPLER_2D:
 			case GL_SAMPLER_2D:
-				v->setValue(TextureResourcePointer(value[0].c_str()));
+				{
+					TextureResourcePointer tp(value[0].c_str());
+					v->setValues(&tp, 1);
+				}
 				break;
 				break;
-			// F32
+			// Math types
 			case GL_FLOAT:
 			case GL_FLOAT:
-				v->setValue(std::stof(value[0]));
-				break;
-			// vec2
 			case GL_FLOAT_VEC2:
 			case GL_FLOAT_VEC2:
-				v->setValue(setMathType<Vec2, 2>(value));
-				break;
-			// vec3
 			case GL_FLOAT_VEC3:
 			case GL_FLOAT_VEC3:
-				v->setValue(setMathType<Vec3, 3>(value));
-				break;
-			// vec4
 			case GL_FLOAT_VEC4:
 			case GL_FLOAT_VEC4:
-				v->setValue(setMathType<Vec4, 4>(value));
+				{
+					SetMaterialVariableValuesVisitor vis(value);
+					v->acceptVisitor(vis);
+				}
 				break;
 				break;
 			// default is error
 			// default is error
 			default:
 			default: