Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SceneEntity.h
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SceneEntity.h	(revision 2980)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SceneEntity.h	(revision 3042)
@@ -35,8 +35,8 @@
 	SceneEntity(Transform3 *trafo);
 
-	~SceneEntity();
+	virtual ~SceneEntity();
 	/** Renders this node.
 	*/
-	void Render(RenderState *state);	
+	virtual void Render(RenderState *state);	
 	/** Set pointer to the shape
 	*/
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Material.h
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Material.h	(revision 3036)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Material.h	(revision 3042)
@@ -15,4 +15,6 @@
 
 
+/** Class representing an rgba color vector.
+*/
 class RgbaColor 
 {
@@ -36,6 +38,8 @@
 
 
-
-class Material 
+/** This class represents a certain rendering technique of a shape.
+	A material consists of one or more techniques
+*/
+class Technique 
 {
 friend class ResourceManager;
@@ -45,12 +49,10 @@
 	/** Sets default material (ambient intensity 0.2f, diffuse intensity 1.0f)
 	*/
-	Material();
+	Technique();
 
-	~Material();
+	~Technique();
 	/** Sets ambient and diffuse color to color
 	*/
-	Material(const RgbaColor &color);
-
-	friend Material RandomMaterial();
+	Technique(const RgbaColor &color);
 
 	inline Texture *GetTexture() const { return mTexture; }
@@ -73,5 +75,5 @@
 	inline bool IsAlphaTestEnabled() const { return mAlphaTestEnabled; } 
 	inline bool IsCullFaceEnabled() const { return mCullFaceEnabled; } 
-	/** Renders this material.
+	/** Renders this technique.
 	*/
 	void Render(RenderState *state);
@@ -115,5 +117,32 @@
 
 
-extern Material RandomMaterial();
+/** A material consists of one or more techniques.
+*/
+class Material
+{
+public:
+	/** Default constructor creating one default technique.
+	*/
+	Material();
+
+	~Material();
+	/** Renders this material.
+	*/
+	void Render(RenderState *state);
+
+	void AddTechnique(Technique *t);
+
+	Technique *GetDefaultTechnique() const;
+
+	Technique *GetTechnique(int i) const;
+
+	int GetNumTechniques() const;
+
+
+
+protected:
+
+	TechniqueContainer mTechniques;
+};
 
 }
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/RenderState.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/RenderState.cpp	(revision 3039)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/RenderState.cpp	(revision 3042)
@@ -95,6 +95,6 @@
 		glDepthMask(GL_FALSE);
 
-		static Material defaultMat;
-		SetState(&defaultMat);
+		static Technique defaultTech;
+		SetState(&defaultTech);
 	}
 	else // mode returns to render
@@ -122,12 +122,12 @@
 
 	
-void RenderState::SetState(Material *mat)
-{
-	Texture *tex = mat->GetTexture();
+void RenderState::SetState(Technique *tech)
+{
+	Texture *tex = tech->GetTexture();
 
 	const bool texturing = (tex != NULL);
 
-	bool alphaTest = mat->IsAlphaTestEnabled();
-	bool cullFace = mat->IsCullFaceEnabled();
+	bool alphaTest = tech->IsAlphaTestEnabled();
+	bool cullFace = tech->IsCullFaceEnabled();
 
 	if (!mLockCullFaceEnabled)
@@ -189,25 +189,29 @@
 	if (mRenderType == DEFERRED)
 	{
-		if (mat->GetFragmentProgram())
-		{
-			if (mat->GetFragmentProgram() != mCurrentFragmentProgram)
+		ShaderProgram *frag = tech->GetFragmentProgram();
+
+		if (frag)
+		{
+			if (frag != mCurrentFragmentProgram)
 			{			
-				mCurrentFragmentProgram = mat->GetFragmentProgram();
+				mCurrentFragmentProgram = frag;
 				mCurrentFragmentProgram->Bind();			
 			}
 			
-			mat->GetFragmentProgramParameters()->UpdateParameters();
-
-		}
-	
-		if (mat->GetVertexProgram())
-		{
-			if (mat->GetVertexProgram() != mCurrentVertexProgram)
-			{
-				mCurrentVertexProgram = mat->GetVertexProgram();
+			tech->GetFragmentProgramParameters()->UpdateParameters();
+
+		}
+
+		ShaderProgram *vert = tech->GetVertexProgram();
+
+		if (vert)
+		{
+			if (vert != mCurrentVertexProgram)
+			{
+				mCurrentVertexProgram = vert;
 				mCurrentVertexProgram->Bind();
 			}
 		
-			mat->GetVertexProgramParameters()->UpdateParameters();
+			tech->GetVertexProgramParameters()->UpdateParameters();
 		}
 	}
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ResourceManager.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ResourceManager.cpp	(revision 3041)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ResourceManager.cpp	(revision 3042)
@@ -166,7 +166,9 @@
 				Shape *shape = *it;
 				Material *mat = shape->GetMaterial();
-				mat->SetVertexProgram(sTreeAnimation);
-
-				GPUProgramParameters *vtxParams = mat->GetVertexProgramParameters();
+				Technique *tech = mat->GetDefaultTechnique();
+				
+				tech->SetVertexProgram(sTreeAnimation);
+
+				GPUProgramParameters *vtxParams = tech->GetVertexProgramParameters();
 
 				vtxParams->SetTimerParam(0);
@@ -251,4 +253,7 @@
 	Material *mat = new Material();
 	
+	// set default fragment + vertex programs
+	Technique *tech = mat->GetDefaultTechnique();
+
 	// texture
 	int texId;
@@ -256,37 +261,37 @@
 
 	if (texId >= 0)
-		mat->SetTexture(mTextureTable[texId]);
-	
-	str.read(reinterpret_cast<char *>(&mat->mAlphaTestEnabled), sizeof(bool));
-	str.read(reinterpret_cast<char *>(&mat->mCullFaceEnabled), sizeof(bool));
+		tech->SetTexture(mTextureTable[texId]);
+	
+	str.read(reinterpret_cast<char *>(&tech->mAlphaTestEnabled), sizeof(bool));
+	str.read(reinterpret_cast<char *>(&tech->mCullFaceEnabled), sizeof(bool));
 
 	// gl material
 	bool hasGlMaterial;
 	str.read(reinterpret_cast<char *>(&hasGlMaterial), sizeof(bool));
-	
+
 	if (hasGlMaterial)
 	{
 		// only write rgb part of the material
-		str.read(reinterpret_cast<char *>(&mat->mAmbientColor), sizeof(Vector3));
-		str.read(reinterpret_cast<char *>(&mat->mDiffuseColor), sizeof(Vector3));
-		str.read(reinterpret_cast<char *>(&mat->mEmmisiveColor), sizeof(Vector3));
-		str.read(reinterpret_cast<char *>(&mat->mSpecularColor), sizeof(Vector3));
-	}
-
-	if (mat->GetTexture())
-	{
-		mat->mFragmentProgram = mMrtDefaultFragmentTexProgram;
-
-		mat->mGPUFragmentParameters = CreateGPUProgramParameters(mat->mFragmentProgram);
-		mat->mGPUFragmentParameters->SetTexture(0, mat->GetTexture()->GetId());
+		str.read(reinterpret_cast<char *>(&tech->mAmbientColor), sizeof(Vector3));
+		str.read(reinterpret_cast<char *>(&tech->mDiffuseColor), sizeof(Vector3));
+		str.read(reinterpret_cast<char *>(&tech->mEmmisiveColor), sizeof(Vector3));
+		str.read(reinterpret_cast<char *>(&tech->mSpecularColor), sizeof(Vector3));
+	}
+
+	if (tech->GetTexture())
+	{
+		tech->mFragmentProgram = mMrtDefaultFragmentTexProgram;
+
+		tech->mGPUFragmentParameters = CreateGPUProgramParameters(tech->mFragmentProgram);
+		tech->mGPUFragmentParameters->SetTexture(0, tech->GetTexture()->GetId());
 	}	
 	else
 	{
-		mat->mFragmentProgram = mMrtDefaultFragmentProgram;
-		mat->mGPUFragmentParameters = CreateGPUProgramParameters(mat->mFragmentProgram);
-	}
-
-	mat->mVertexProgram = mMrtDefaultVertexProgram;
-	mat->mGPUVertexParameters = CreateGPUProgramParameters(mat->mVertexProgram);
+		tech->mFragmentProgram = mMrtDefaultFragmentProgram;
+		tech->mGPUFragmentParameters = CreateGPUProgramParameters(tech->mFragmentProgram);
+	}
+
+	tech->mVertexProgram = mMrtDefaultVertexProgram;
+	tech->mGPUVertexParameters = CreateGPUProgramParameters(tech->mVertexProgram);
 	
 	return mat;
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/RenderQueue.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/RenderQueue.cpp	(revision 2848)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/RenderQueue.cpp	(revision 3042)
@@ -51,15 +51,15 @@
 bool RenderQueue::FitsInBucket(Shape *shape, size_t idx) const
 {
-	Material *mat = shape->GetMaterial();
+	Technique *tech = shape->GetMaterial()->GetDefaultTechnique();
 
 	// test if entity belongs to this bucket
 	// note: rather slows down the application for some reason!!
-	if (mat->IsAlphaTestEnabled() != mBuckets[idx]->mAlphaTestEnabled)
+	if (tech->IsAlphaTestEnabled() != mBuckets[idx]->mAlphaTestEnabled)
 		return false;
 
-	if (mat->IsCullFaceEnabled() != mBuckets[idx]->mCullFaceEnabled)
+	if (tech->IsCullFaceEnabled() != mBuckets[idx]->mCullFaceEnabled)
 		return false;
 
-	const bool hasTexture = (mat->GetTexture() != NULL);
+	const bool hasTexture = (tech->GetTexture() != NULL);
 
 	if (hasTexture != mBuckets[idx]->mHasTexture)
@@ -68,8 +68,8 @@
 	if (hasTexture)
 	{
-		if (mat->GetTexture()->GetWidth() != mBuckets[idx]->mTexWidth)
+		if (tech->GetTexture()->GetWidth() != mBuckets[idx]->mTexWidth)
 			return false;
 
-		if (mat->GetTexture()->GetHeight() != mBuckets[idx]->mTexHeight)
+		if (tech->GetTexture()->GetHeight() != mBuckets[idx]->mTexHeight)
 			return false;
 	}
@@ -119,15 +119,15 @@
 			bucket->mMinDistance = -1;
 
-			Material *mat = shape->GetMaterial();
-
-			bucket->mAlphaTestEnabled = mat->IsAlphaTestEnabled();
-			bucket->mCullFaceEnabled = mat->IsCullFaceEnabled();
-
-			const bool hasTexture = (mat->GetTexture() != NULL);
+			Technique *tech = shape->GetMaterial()->GetDefaultTechnique();
+
+			bucket->mAlphaTestEnabled = tech->IsAlphaTestEnabled();
+			bucket->mCullFaceEnabled = tech->IsCullFaceEnabled();
+
+			const bool hasTexture = (tech->GetTexture() != NULL);
 
 			bucket->mHasTexture = hasTexture; 
 
-			bucket->mTexWidth = hasTexture ? mat->GetTexture()->GetWidth() : 0;
-			bucket->mTexHeight = hasTexture ? mat->GetTexture()->GetHeight() : 0;
+			bucket->mTexWidth = hasTexture ? tech->GetTexture()->GetWidth() : 0;
+			bucket->mTexHeight = hasTexture ? tech->GetTexture()->GetHeight() : 0;
 
 			mBuckets.push_back(bucket);
@@ -204,10 +204,10 @@
 			Shape *shape = *sit;
 			
-			Material *mat = shape->GetMaterial();
-			int tsize = mat->GetTexture() ? mat->GetTexture()->GetByteSize() : 0;
+			Technique *tech = shape->GetMaterial()->GetDefaultTechnique();
+			int tsize = tech->GetTexture() ? tech->GetTexture()->GetByteSize() : 0;
 			
 			float dist = SqrMagnitude(shape->GetBoundingBox().Center() - mCamera->GetPosition());
 			
-			Debug << "e: " << shape << " a: " << mat->IsAlphaTestEnabled() << " s: " << tsize << " d: " << dist << " " << endl;
+			Debug << "e: " << shape << " a: " << tech->IsAlphaTestEnabled() << " s: " << tsize << " d: " << dist << " " << endl;
 		}
 	}
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SkyPreetham.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SkyPreetham.cpp	(revision 3041)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SkyPreetham.cpp	(revision 3042)
@@ -80,6 +80,6 @@
 	Material *mat = shape->GetMaterial();
 
-	mat->SetFragmentProgram(mSkyFragProgram);
-	mat->SetVertexProgram(mSkyVtxProgram);
+	mat->GetDefaultTechnique()->SetFragmentProgram(mSkyFragProgram);
+	mat->GetDefaultTechnique()->SetVertexProgram(mSkyVtxProgram);
 }
 
@@ -114,5 +114,8 @@
 	mSkyDome->GetTransform()->SetMatrix(s * m);
 	
-	GPUProgramParameters *vtxParams = mSkyDome->GetShape(0)->GetMaterial()->GetVertexProgramParameters();
+	Material *mat = mSkyDome->GetShape(0)->GetMaterial();
+	Technique *tech = mat->GetDefaultTechnique();
+
+	GPUProgramParameters *vtxParams = tech->GetVertexProgramParameters();
 
 	vtxParams->SetValue3f(0, sunDir.x, sunDir.y, sunDir.z);
@@ -138,9 +141,9 @@
 	}
 
-	mSkyDome->GetShape(0)->GetMaterial()->GetVertexProgramParameters()->UpdateParameters();
-	mSkyDome->GetShape(0)->GetMaterial()->GetVertexProgram()->Bind();
-
-	mSkyDome->GetShape(0)->GetMaterial()->GetFragmentProgramParameters()->UpdateParameters();
-	mSkyDome->GetShape(0)->GetMaterial()->GetFragmentProgram()->Bind();
+	tech->GetVertexProgramParameters()->UpdateParameters();
+	tech->GetVertexProgram()->Bind();
+
+	tech->GetFragmentProgramParameters()->UpdateParameters();
+	tech->GetFragmentProgram()->Bind();
 
 	// Render sky dome.
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Bvh.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Bvh.cpp	(revision 3021)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Bvh.cpp	(revision 3042)
@@ -1081,5 +1081,5 @@
 
 	// hack: for deferred shading we have to define a material
-	static Material boxMat;
+	static Technique boxMat;
 	boxMat.SetEmmisive(RgbaColor(1.0f, 1.0f, 1.0f, 1.0f));
 
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/RenderState.h
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/RenderState.h	(revision 3038)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/RenderState.h	(revision 3042)
@@ -45,5 +45,5 @@
 	/** Sets the current render state.
 	*/
-	void SetState(Material *mat);
+	void SetState(Technique *tech);
 	/** Returns either query or render mode
 	*/
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Material.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Material.cpp	(revision 3039)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Material.cpp	(revision 3042)
@@ -18,5 +18,5 @@
 
 
-void Material::InitMaterial()
+void Technique::InitMaterial()
 {
 	mTexture = NULL;
@@ -32,5 +32,5 @@
 
 
-Material::Material():
+Technique::Technique():
 mAmbientColor(RgbaColor(0.2f, 0.2f, 0.2f, 1.0f)),
 mDiffuseColor(RgbaColor(1.0f, 1.0f, 1.0f, 1.0f)),
@@ -42,5 +42,5 @@
 
 
-Material::~Material()
+Technique::~Technique()
 {
 	//DEL_PTR(mGPUFragmentParameters);
@@ -49,5 +49,5 @@
 
 
-Material::Material(const RgbaColor &color):
+Technique::Technique(const RgbaColor &color):
 mDiffuseColor(color),
 mAmbientColor(color),
@@ -59,17 +59,5 @@
 
 
-Material RandomMaterial()
-{
-	float a = 0.1f;
-	float b = 0.9f;
-
-	Material m;
-	m.mDiffuseColor = RandomColor(a, b);
-
-	return m;
-}
-
-
-void Material::Render(RenderState *state)
+void Technique::Render(RenderState *state)
 {
 	glMaterialfv(GL_FRONT, GL_AMBIENT, (float *)&mAmbientColor.r);
@@ -82,5 +70,5 @@
 
 
-void Material::SetFragmentProgram(ShaderProgram *p) 
+void Technique::SetFragmentProgram(ShaderProgram *p) 
 { 
 	mFragmentProgram = p; 
@@ -91,5 +79,5 @@
 	
 
-void Material::SetVertexProgram(ShaderProgram *p) 
+void Technique::SetVertexProgram(ShaderProgram *p) 
 { 
 	mVertexProgram = p; 
@@ -99,3 +87,42 @@
 }
 
+
+void Material::Render(RenderState *state)
+{
+	mTechniques[0]->Render(state);
 }
+
+
+Technique *Material::GetDefaultTechnique() const
+{
+	return mTechniques[0];
+}
+
+
+Technique *Material::GetTechnique(int i) const
+{
+	return mTechniques[i];
+}
+
+
+Material::Material()
+{
+	Technique *tech = new Technique();
+
+	mTechniques.push_back(tech);
+}
+
+
+Material::~Material()
+{
+	CLEAR_CONTAINER(mTechniques);
+}
+
+
+int Material::GetNumTechniques() const
+{
+	return (int)mTechniques.size();
+}
+
+
+}
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/common.h
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/common.h	(revision 3038)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/common.h	(revision 3042)
@@ -37,4 +37,5 @@
 class ShaderProgram;
 class FrameBufferObject;
+class Technique;
 
 struct LODLevel;
@@ -501,8 +502,9 @@
 typedef std::vector<Material *> MaterialContainer;
 typedef std::vector<GPUProgramParameters *> GPUParamContainer;
-typedef  std::vector<FrameBufferObject *> FBOContainer;
-typedef  std::vector<ShaderProgram *> ShaderContainer;
-
+typedef std::vector<FrameBufferObject *> FBOContainer;
+typedef std::vector<ShaderProgram *> ShaderContainer;
+typedef std::vector<Technique *> TechniqueContainer;
 typedef std::vector<Vector3> VertexArray;
+
 
 typedef std::pair<float, float> Texcoord2;
