Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Material.h
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Material.h	(revision 3042)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Material.h	(revision 3045)
@@ -4,4 +4,5 @@
 #include "glInterface.h"
 #include "common.h"
+#include "ShaderProgram.h"
 
 
@@ -22,6 +23,4 @@
 public:
 
-	float r, g, b, a;
-
 	RgbaColor(): r(1), g(1), b(1), a(1)
 	{}
@@ -31,4 +30,9 @@
 
 	friend RgbaColor RandomColor(float a = 0.0f, float b = 1.0f);
+
+
+	/////////////////////
+
+	float r, g, b, a;
 };
 
@@ -50,4 +54,6 @@
 	*/
 	Technique();
+
+	Technique(const Technique &tech);
 
 	~Technique();
@@ -88,9 +94,11 @@
 	ShaderProgram *GetVertexProgram() { return mVertexProgram; }
 
-	void SetFragmentProgramParameters(GPUProgramParameters *p) { mGPUFragmentParameters = p; }
-	void SetVertexProgramParameters(GPUProgramParameters *p) { mGPUVertexParameters = p; }
+	//void SetFragmentProgramParameters(const GPUProgramParameters &p) { mGPUFragmentParameters = p; }
+	//void SetVertexProgramParameters(const GPUProgramParameters &p) { mGPUVertexParameters = p; }
 
-	GPUProgramParameters *GetFragmentProgramParameters() { return mGPUFragmentParameters; }
-	GPUProgramParameters *GetVertexProgramParameters() { return mGPUVertexParameters; }
+	/** Each technique has a distict set of parameters.
+	*/
+	GPUProgramParameters * const GetFragmentProgramParameters() { return &mFragmentProgramParameters; }
+	GPUProgramParameters * const GetVertexProgramParameters() { return &mVertexProgramParameters; }
 
 
@@ -109,6 +117,6 @@
 	Texture *mTexture;
 
-	GPUProgramParameters *mGPUVertexParameters;
-	GPUProgramParameters *mGPUFragmentParameters;
+	GPUProgramParameters mVertexProgramParameters;
+	GPUProgramParameters mFragmentProgramParameters;
 
 	ShaderProgram *mFragmentProgram;
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ShaderManager.h
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ShaderManager.h	(revision 3045)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ShaderManager.h	(revision 3045)
@@ -0,0 +1,135 @@
+#ifndef __ResourceManager_H__
+#define __ResourceManager_H__
+
+
+#include <string>
+#include <iostream>
+#include <fstream>
+#include <map>
+#include "common.h"
+
+
+
+class igzstream;
+
+
+namespace CHCDemoEngine
+{
+
+class SceneEntity;
+class Material;
+class Geometry;
+class Texture;
+class Matrix4x4;
+class Transform3;
+class ShaderProgram;
+
+
+/** Loads a scene and also handles the cleanup
+*/
+class ResourceManager
+{
+public:
+
+	/** Returns the resource manager as a singleton.
+	*/
+	static ResourceManager *GetSingleton()
+	{
+		if (!sResourceManager)
+		{
+			sResourceManager = new ResourceManager();
+		}
+
+		return sResourceManager;
+	}
+
+	/** We also want full control over the delete.
+	*/
+	static void DelSingleton()
+	{
+		DEL_PTR(sResourceManager);
+	}
+
+	/** Loads a model
+	*/
+	bool Load(const std::string &filename, SceneEntityContainer &geometry);
+
+	int GetNumEntities() const { return (int)mSceneEntities.size(); }
+
+	/** Creates new gpu program parameters.
+	*/
+	GPUProgramParameters *CreateGPUProgramParameters(ShaderProgram *p);
+	/** Creates a new shader program.
+	*/
+	ShaderProgram *CreateFragmentProgram(const std::string &filename, const std::string &funcName);
+	ShaderProgram *CreateVertexProgram(const std::string &filename, const std::string &funcName);
+
+	void EnableFragmentProfile();
+	void EnableVertexProfile();
+
+	void DisableFragmentProfile();
+	void DisableVertexProfile();
+
+
+protected:
+	
+	/** Default constructor. The constructor is protected
+		to have control over instantiation using the 
+		singleton pattern.
+	*/
+	ResourceManager();
+
+	~ResourceManager();
+
+
+	void InitCg();
+
+	void LoadTextures(igzstream &str);
+	void LoadShapes(igzstream &str);
+	void LoadSceneEntities(igzstream &str, SceneEntityContainer &entities);
+
+	SceneEntity *LoadSceneEntity(igzstream &str);
+	Material *LoadMaterial(igzstream &str);
+	Geometry *LoadGeometry(igzstream &str);
+
+	std::map<int, Texture *> mTextureTable;
+	std::map<int, Material *> mMaterialTable;
+	std::map<int, Geometry *> mGeometryTable;
+	//std::map<int, Shape *> mShapesTable;
+
+
+	/////////////
+	//-- these are kept to be able to delete these resources afterwards
+
+	TextureContainer mTextures;
+	MaterialContainer mMaterials;
+	GeometryContainer mGeometry;
+	TransformContainer mTrafos;
+	GPUParamContainer mGPUParameters;
+	ShaderContainer mShaders;
+	ShapeContainer mShapes;
+	LODContainer mLODs;
+
+	////////
+
+	/// the scene entities
+
+	SceneEntityContainer mSceneEntities;
+
+
+	////////////
+	//-- default shader programs
+
+	ShaderProgram *mMrtDefaultVertexProgram;
+	ShaderProgram *mMrtDefaultFragmentProgram;
+	ShaderProgram *mMrtDefaultFragmentTexProgram;
+
+
+private:
+
+	static ResourceManager *sResourceManager;
+};
+
+
+}
+#endif
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Camera.h
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Camera.h	(revision 2986)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Camera.h	(revision 3045)
@@ -42,4 +42,5 @@
 {
 	friend class ShadowMap;
+
 public:
 	
@@ -76,5 +77,6 @@
 	*/
 	void GetModelViewMatrix(Matrix4x4 &mat) const;
-
+	/** Returns the view orientation (the model view matrix without the translation)
+	*/
 	void GetViewOrientationMatrix(Matrix4x4 &mat) const;
 	/** Calculates a frustum from the projection and the modelview matrix.
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ShaderProgram.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ShaderProgram.cpp	(revision 3043)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ShaderProgram.cpp	(revision 3045)
@@ -2,4 +2,6 @@
 #include "Matrix4x4.h"
 #include "Timer/PerfTimer.h"
+#include "Vector3.h"
+#include "Camera.h"
 
 
@@ -9,9 +11,25 @@
 { 
 
+//////////
+//-- changing shader parameters
 static float sCurrentTimer = 0;
-
-
-GPUProgramParameters::GPUProgramParameters(ShaderProgram *p)
-: mProgram(p), mTimer(-1)
+static Matrix4x4 sCurrentViewMatrix = IdentityMatrix();
+static Vector3 sCurrentViewVector = Vector3::UNIT_Y();
+
+
+GPUProgramParameters::GPUProgramParameters(ShaderProgram *p): 
+mProgram(p), 
+mTimerParam(-1),
+mViewVectorParam(-1),
+mViewMatrixParam(-1)
+{
+}
+
+
+GPUProgramParameters::GPUProgramParameters(): 
+mProgram(NULL),
+mTimerParam(-1),
+mViewVectorParam(-1),
+mViewMatrixParam(-1)
 {
 }
@@ -25,5 +43,7 @@
 	mArrays.clear();
 
-	mTimer = -1;
+	mTimerParam = -1;
+	mViewVectorParam = -1;
+	mViewMatrixParam = -1;
 }
 
@@ -107,5 +127,17 @@
 void GPUProgramParameters::SetTimerParam(int idx)
 {
-	mTimer = idx;
+	mTimerParam = idx;
+}
+
+
+void GPUProgramParameters::SetViewMatrixParam(int idx)
+{
+	mViewMatrixParam = idx;
+}
+
+
+void GPUProgramParameters::SetViewVectorParam(int idx)
+{
+	mViewVectorParam = idx;
 }
 
@@ -161,4 +193,6 @@
 void GPUProgramParameters::UpdateParameters()
 {
+	if (!mProgram) return;
+
 	for (int i = 0; i < (int)mFloats.size(); ++ i)
 	{
@@ -221,16 +255,22 @@
 	}
 
-	if (mTimer >= 0)
-	{
-		static PerfTimer mytimer;
-		mProgram->SetValue1f(mTimer, sCurrentTimer);
-	}
-}
-
-
-void GPUProgramParameters::InitFrame()
+	if (mTimerParam >= 0)
+		mProgram->SetValue1f(mTimerParam, sCurrentTimer);
+
+	if (mViewVectorParam >= 0)
+		mProgram->SetValue3f(mViewVectorParam, sCurrentViewVector.x, sCurrentViewVector.y, sCurrentViewVector.z);
+
+	if (mViewMatrixParam >= 0)
+		mProgram->SetMatrix(mViewMatrixParam, sCurrentViewMatrix);
+}
+
+
+void GPUProgramParameters::InitFrame(Camera *cam)
 {
 	static PerfTimer mytimer;
 	sCurrentTimer = mytimer.Elapsedms(false) * M_PI / 180.0f;
+
+	cam->GetModelViewMatrix(sCurrentViewMatrix);
+	sCurrentViewVector = cam->GetDirection();
 }
 
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ShaderManager.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ShaderManager.cpp	(revision 3045)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ShaderManager.cpp	(revision 3045)
@@ -0,0 +1,504 @@
+#include "ResourceManager.h"
+#include "Matrix4x4.h"
+#include "Geometry.h"
+#include "SceneEntity.h"
+#include "Material.h"
+#include "Texture.h"
+#include "gzstream.h"
+#include "Matrix4x4.h"
+#include "Vector3.h"
+#include "Transform3.h"
+#include "Shape.h"
+#include "LODInfo.h"
+#include "RenderState.h"
+#include "ShaderProgram.h"
+#include <Cg/cg.h>
+#include <Cg/cgGL.h>
+
+
+#ifdef _CRT_SET
+	#define _CRTDBG_MAP_ALLOC
+	#include <stdlib.h>
+	#include <crtdbg.h>
+
+	// redefine new operator
+	#define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__)
+	#define new DEBUG_NEW
+#endif
+
+
+using namespace std;
+
+
+namespace CHCDemoEngine
+{
+
+
+/////////
+//-- cg stuff
+
+static CGcontext sCgContext = NULL;
+
+static CGprofile sCgFragmentProfile;
+static CGprofile sCgVertexProfile; 
+static ShaderProgram *sTreeAnimation;
+
+// only instance of the resource manager
+ResourceManager *ResourceManager::sResourceManager = NULL;
+
+
+static void cgErrorCallback()
+{
+	CGerror lastError = cgGetError();
+
+	if(lastError)
+	{
+		printf("%s\n\n", cgGetErrorString(lastError));
+		printf("%s\n", cgGetLastListing(sCgContext));
+		
+		printf("Cg error, exiting...\n");
+
+		exit(0);
+	}
+}
+
+
+ResourceManager::ResourceManager()
+{ 
+	InitCg(); 
+}
+
+
+ResourceManager::~ResourceManager()
+{
+	// delete all resources.
+	CLEAR_CONTAINER(mSceneEntities);
+	CLEAR_CONTAINER(mGeometry);
+	CLEAR_CONTAINER(mMaterials);
+	CLEAR_CONTAINER(mTextures);
+	CLEAR_CONTAINER(mTrafos);
+	CLEAR_CONTAINER(mShapes);
+	CLEAR_CONTAINER(mLODs);
+	CLEAR_CONTAINER(mGPUParameters);
+	CLEAR_CONTAINER(mShaders);
+	
+	if (sCgContext)
+		cgDestroyContext(sCgContext);
+}
+
+
+SceneEntity *ResourceManager::LoadSceneEntity(igzstream &str)
+{	
+	bool hasTrafo;
+	str.read(reinterpret_cast<char *>(&hasTrafo), sizeof(bool));
+	
+	SceneEntity *sceneGeom;
+	Transform3 *trafo;
+
+	if (!hasTrafo)
+	{
+		// identity
+		trafo = new Transform3();
+	}
+	else
+	{
+		Matrix4x4 m;
+		str.read(reinterpret_cast<char *>(m.x), sizeof(Matrix4x4));
+		
+		trafo = new Transform3(m);
+	}
+
+	mTrafos.push_back(trafo);
+
+	sceneGeom = new SceneEntity(trafo);
+
+
+	///////////////
+	//-- load lod levels
+
+	// note: lods must be ordered from smallest distance to largest
+	int numLODs;
+	str.read(reinterpret_cast<char *>(&numLODs), sizeof(int));
+
+	for (int i = 0; i < numLODs; ++ i)
+	{
+		float dist;
+		str.read(reinterpret_cast<char *>(&dist), sizeof(float));
+
+		int numShapes;
+		str.read(reinterpret_cast<char *>(&numShapes), sizeof(int));
+
+		LODLevel *lodLevel = new LODLevel(dist);
+
+		for (int j = 0; j < numShapes; ++ j)
+		{
+			int shapeId;
+			str.read(reinterpret_cast<char *>(&shapeId), sizeof(int));
+
+			Geometry *geom = mGeometryTable[shapeId];
+			Material *mat = mMaterialTable[shapeId];
+
+			// create shape
+			Shape *shape = new Shape(geom, mat, sceneGeom);
+
+			mShapes.push_back(shape);
+
+			sceneGeom->AddShape(shape);
+			lodLevel->AddShape(shape);
+		}
+
+		mLODs.push_back(lodLevel);
+		sceneGeom->AddLODLevel(lodLevel);
+	}
+
+	///////////
+	//-- hack: tree animation
+
+	if (numLODs > 1)
+	{
+		for (int i = 0; i < min(numLODs, 2); ++ i)
+		{
+			ShapeContainer::iterator sstart, send;
+			sceneGeom->GetLODLevel(i, sstart, send);
+
+			for (ShapeContainer::iterator it = sstart; it != send; ++ it)
+			{
+				Shape *shape = *it;
+
+				Material *mat = shape->GetMaterial();
+
+				// add the vertex animation program
+				for (int i = 0; i < 2; ++ i)
+				{
+					Technique *tech = mat->GetTechnique(i);
+					tech->SetVertexProgram(sTreeAnimation);
+
+					GPUProgramParameters *vtxParams = tech->GetVertexProgramParameters();
+
+					vtxParams->SetTimerParam(0);
+					// wind direction
+					static Vector3 windDir = Normalize(Vector3(0.8f, 0.2f, 0.0f));
+					vtxParams->SetValue3f(1, windDir.x, windDir.y, windDir.z);
+					// amplitude
+					vtxParams->SetValue1f(2, 0.3f);
+
+					AxisAlignedBox3 box = sceneGeom->GetBoundingBox();
+					vtxParams->SetValue2f(3, box.Min().z, box.Max().z);
+					// frequency
+					vtxParams->SetValue1f(4, 0.1f);
+				}
+			}
+		}
+	}
+
+	return sceneGeom;
+}
+
+
+void ResourceManager::LoadTextures(igzstream &str)
+{
+	int numTextures;
+	str.read(reinterpret_cast<char *>(&numTextures), sizeof(int));
+	
+	for (int i = 0; i < numTextures; ++ i)
+	{
+		// load texture name
+		int texnameSize;
+		str.read(reinterpret_cast<char *>(&texnameSize), sizeof(int));
+
+		char *texname = new char[texnameSize];
+		str.read(texname, sizeof(char) * texnameSize);
+
+		Texture *tex = new Texture(model_path + texname);
+
+		int boundS, boundT;
+
+		str.read(reinterpret_cast<char *>(&boundS), sizeof(int));
+		str.read(reinterpret_cast<char *>(&boundT), sizeof(int));
+
+		tex->SetBoundaryModeS(boundS);
+		tex->SetBoundaryModeT(boundT);
+
+		tex->Create();
+
+		mTextureTable[i] = tex;
+		mTextures.push_back(tex);
+
+		delete [] texname;
+	}
+
+	cout << "loaded " << (int)mTextureTable.size() << " textures" << endl;
+}
+
+
+void ResourceManager::LoadShapes(igzstream &str)
+{
+	int numShapes;
+	str.read(reinterpret_cast<char *>(&numShapes), sizeof(int));
+
+	for (int i = 0; i < numShapes; ++ i)
+	{
+		Geometry *geom = LoadGeometry(str);
+		Material *mat = LoadMaterial(str);
+
+		mGeometryTable[i] = geom;
+		mMaterialTable[i] = mat;		
+
+		mGeometry.push_back(geom);
+		mMaterials.push_back(mat);
+	}
+
+	cout << "loaded " << (int)mGeometryTable.size() << " shapes" << endl;
+}
+
+
+Material *ResourceManager::LoadMaterial(igzstream &str)
+{
+	// default material
+	Material *mat = new Material();
+	
+	// set default fragment + vertex programs
+	Technique *tech = mat->GetDefaultTechnique();
+
+	// texture
+	int texId;
+	str.read(reinterpret_cast<char *>(&texId), sizeof(int));
+
+	if (texId >= 0)
+		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 *>(&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));
+	}
+
+
+	///////////////
+	//-- add technique for deferred shading
+
+	Technique *deferred = new Technique(*tech);
+
+	if (deferred->GetTexture())
+	{
+		deferred->SetFragmentProgram(mMrtDefaultFragmentTexProgram);
+		deferred->GetFragmentProgramParameters()->SetTexture(0, tech->GetTexture()->GetId());
+	}	
+	else
+	{
+		deferred->SetFragmentProgram(mMrtDefaultFragmentProgram);
+	}
+
+	deferred->SetVertexProgram(mMrtDefaultVertexProgram);
+	
+	mat->AddTechnique(deferred);
+
+	return mat;
+}
+
+
+Geometry *ResourceManager::LoadGeometry(igzstream &str)
+{
+	Vector3 *vertices;
+	Vector3 *normals;
+	Texcoord2 *texcoords;
+
+
+	//////////////
+	//-- read in vertices
+
+	int vertexCount;
+	str.read(reinterpret_cast<char *>(&vertexCount), sizeof(int));
+	
+	// end of file reached
+	if (str.eof()) return NULL;
+
+	//cout << "vertexcount: " << vertexCount << endl;
+
+	vertices = new Vector3[vertexCount];
+    str.read(reinterpret_cast<char *>(vertices), sizeof(Vector3) * vertexCount);
+	
+	normals = new Vector3[vertexCount];
+	str.read(reinterpret_cast<char *>(normals), sizeof(Vector3) * vertexCount);
+
+	int texCoordCount;
+	str.read(reinterpret_cast<char *>(&texCoordCount), sizeof(int));
+
+	if (texCoordCount)
+	{
+		texcoords = new Texcoord2[texCoordCount];
+		str.read(reinterpret_cast<char *>(texcoords), sizeof(Texcoord2) * texCoordCount);
+	}
+	else
+	{
+		texcoords = NULL;
+	}
+
+	return new Geometry(vertices, normals, texcoords, vertexCount, true);
+	//return new Geometry(vertices, normals, texcoords, vertexCount, false);
+}
+
+
+void ResourceManager::LoadSceneEntities(igzstream &str, SceneEntityContainer &entities)
+{
+	int entityCount;
+	str.read(reinterpret_cast<char *>(&entityCount), sizeof(int));
+
+	entities.reserve(entityCount);
+
+	for (int i = 0; i < entityCount; ++ i)
+	{
+		SceneEntity *ent = LoadSceneEntity(str);
+
+		// return loaded entities
+		entities.push_back(ent);
+		// also store internally
+		mSceneEntities.push_back(ent);
+	}
+
+	cout << "loaded " << entityCount << " scene entities" << endl;
+}
+
+
+bool ResourceManager::Load(const std::string &filename, SceneEntityContainer &entities)
+{
+	igzstream istr(filename.c_str());
+	
+	if (!istr.is_open())
+		return false;
+
+	cout << "loading textures" << endl;
+	
+	// load the texture table
+	LoadTextures(istr);
+
+	cout << "loading shapes (geometry + materials)" << endl;
+
+	// load the shapees
+	LoadShapes(istr);
+
+	cout << "loading scene entites" << endl;
+	LoadSceneEntities(istr, entities);
+	
+	cout << "bin loading finished" << endl;
+
+	// clean up
+	mTextureTable.clear();
+	mGeometryTable.clear();
+	mMaterialTable.clear();
+
+	return true;
+}
+
+
+
+ShaderProgram *ResourceManager::CreateFragmentProgram(const std::string &filename, 
+													  const std::string &funcName)
+{
+	const string fullName = "src/shaders/" + filename + ".cg";
+
+	ShaderProgram *p = new ShaderProgram(sCgContext, fullName, sCgFragmentProfile, funcName);
+
+	mShaders.push_back(p);
+
+	if (!p->IsValid())
+	{
+		DEL_PTR(p);
+		cerr << "Program " << funcName << " in " << fullName << " failed to load" << endl;
+	}
+	
+	cout << "Program " << funcName << " in " << fullName << " loaded" << endl;
+
+	return p;
+}
+
+
+ShaderProgram *ResourceManager::CreateVertexProgram(const std::string &filename, const std::string &funcName)
+{
+	const string fullName = "src/shaders/" + filename + ".cg";
+	
+	ShaderProgram *p = new ShaderProgram(sCgContext, fullName, sCgVertexProfile, funcName);
+	mShaders.push_back(p);
+
+	if (!p->IsValid())
+	{
+		DEL_PTR(p);
+		cerr << "Program " << funcName << " in " << fullName << " failed to load" << endl;
+	}
+	
+	cout << "Program " << funcName << " in " << fullName << " loaded" << endl;
+
+	return p;
+}
+
+
+void ResourceManager::InitCg() 
+{
+	// setup cg
+	cgSetErrorCallback(cgErrorCallback);
+	// create context.
+	sCgContext = cgCreateContext();
+	// get the optimal fragment profile
+	sCgFragmentProfile = cgGLGetLatestProfile(CG_GL_FRAGMENT);
+	cgGLSetOptimalOptions(sCgFragmentProfile);
+	// get the optimal vertex profile
+	sCgVertexProfile = cgGLGetLatestProfile(CG_GL_VERTEX);
+	cgGLSetOptimalOptions(sCgVertexProfile);
+
+	// set textures to auto load
+	cgGLSetManageTextureParameters(sCgContext, false);
+
+	mMrtDefaultVertexProgram = CreateVertexProgram("mrt", "vtx");
+	mMrtDefaultFragmentProgram = CreateFragmentProgram("mrt", "frag");
+	mMrtDefaultFragmentTexProgram = CreateFragmentProgram("mrt", "fragtex");
+	mMrtDefaultFragmentTexProgram->AddParameter("tex", 0);
+
+	sTreeAnimation = CreateVertexProgram("treeanimation", "animateVtxMrt");
+
+	sTreeAnimation->AddParameter("timer", 0);
+	sTreeAnimation->AddParameter("windDir", 1);
+	sTreeAnimation->AddParameter("windStrength", 2);
+	sTreeAnimation->AddParameter("minMaxPos", 3);
+	sTreeAnimation->AddParameter("frequency", 4);
+
+	cout << "cg initialization successful" << endl;
+}
+
+
+void ResourceManager::EnableFragmentProfile()
+{
+	cgGLEnableProfile(sCgFragmentProfile);
+}
+
+
+void ResourceManager::EnableVertexProfile()
+{
+	cgGLEnableProfile(sCgVertexProfile);
+}
+
+
+void ResourceManager::DisableFragmentProfile()
+{
+	cgGLDisableProfile(sCgFragmentProfile);
+}
+
+
+void ResourceManager::DisableVertexProfile()
+{
+	cgGLDisableProfile(sCgVertexProfile);
+	
+}
+
+
+}
+
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/treeanimation.cg
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/treeanimation.cg	(revision 3044)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/treeanimation.cg	(revision 3045)
@@ -1,5 +1,5 @@
-//--------------------------------------------------------------------------------------
-// Input and Output structs
-//--------------------------------------------------------------------------------------
+/***********************************************/
+/*     Vertex shaders for tree animation       */
+/***********************************************/
 
 
@@ -7,6 +7,9 @@
 {
 	float4 position: POSITION;
-	float3 normal: NORMAL;
+	float4 normal: NORMAL;
+	
 	float4 color: COLOR;
+	//float4 color1: COLOR1;
+
 	float4 texCoord: TEXCOORD0;
 };
@@ -19,4 +22,5 @@
 
 	float4 color: COLOR0;  
+	//float4 color1: COLOR1;  
 	float4 eyePos: TEXCOORD1; // eye position
 	float3 normal: TEXCOORD2;
@@ -24,9 +28,7 @@
 
 
-//--------------------------------------------------------------------------------------
-// Vertex Shaders
-//--------------------------------------------------------------------------------------
-
-
+/** Vertex shader which conducts an simple tree animation
+	that bends the tree depending quadratically on the height
+*/
 vtxout animateVtx(vtxin IN,
 				  uniform float3 windDir,
@@ -34,13 +36,77 @@
 				  uniform float frequency,
 				  uniform float2 minMaxPos,
-				  uniform float timer)
+				  uniform float timer,
+				  uniform float3 lightDir)
 {
 	vtxout OUT;
 
-	OUT.color = float4(0);//IN.color;
+/*
+// Transform vertex position into homogenous clip-space.
+OUT.HPosition = mul(ModelViewProj, IN.Position);
+// Transform normal from model-space to view-space.
+float3 normalVec = normalize(mul(ModelViewIT,
+IN.Normal).xyz);
+// Store normalized light vector.
+float3 lightVec = normalize(LightVec.xyz);
+// Calculate half angle vector.
+float3 eyeVec = float3(0.0, 0.0, 1.0);
+float3 halfVec = normalize(lightVec + eyeVec);
+// Calculate diffuse component.
+float diffuse = dot(normalVec, lightVec);
+// Calculate specular component.
+float specular = dot(normalVec, halfVec);
+// Use the lit function to compute lighting vector from
+// diffuse and specular values.
+float4 lighting = lit(diffuse, specular, 32);
+// Blue diffuse material
+float3 diffuseMaterial = float3(0.0, 0.0, 1.0);
+// White specular material
+float3 specularMaterial = float3(1.0, 1.0, 1.0);
+// Combine diffuse and specular contributions and
+// output final vertex color.
+OUT.Color.rgb = lighting.y * diffuseMaterial +
+lighting.z * specularMaterial;
+OUT.Color.a = 1.0;
+return OUT;
+}
+*/
 	OUT.texCoord = IN.texCoord;
 		
 	const float pos = (minMaxPos.x - IN.position.z) / (minMaxPos.x - minMaxPos.y);
+	float factor = pos * pos * windStrength * sin(timer * frequency);
 
+	// transform the vertex position into post projection space
+	OUT.position = mul(glstate.matrix.mvp, IN.position);
+	// displace the input position
+	OUT.position += float4(factor * windDir, 0);
+
+	OUT.normal = mul(glstate.matrix.invtrans.modelview[0], IN.normal);
+
+	Out.color = IN.color * max(0, dot(OUT.normal, lightDir));
+	//OUT.color1 = IN.color1;
+
+	return OUT;
+}
+
+/** vertex shader which conducts an simple tree animation
+	that bends the tree depending quadratically on the height
+	This version of the shader is used for deferred shading and thus only 
+	displaces the vertices and outputs the color, put does not do any shading.
+*/
+vtxout animateVtxMrt(vtxin IN,
+					 uniform float3 windDir,
+					 uniform float windStrength,
+					 uniform float frequency,
+					 uniform float2 minMaxPos,
+					 uniform float timer)
+{
+	vtxout OUT;
+
+	OUT.color = IN.color;
+	//OUT.color1 = IN.color1;
+
+	OUT.texCoord = IN.texCoord;
+		
+	const float pos = (minMaxPos.x - IN.position.z) / (minMaxPos.x - minMaxPos.y);
 	float factor = pos * pos * windStrength * sin(timer * frequency);
 
@@ -54,6 +120,6 @@
 	OUT.eyePos += float4(factor * windDir, 0);
 
-	OUT.normal = IN.normal;
-
+	OUT.normal = mul(glstate.matrix.invtrans.modelview[0], IN.normal);
+	
 	return OUT;
 }
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/mrt.cg
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/mrt.cg	(revision 3041)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/mrt.cg	(revision 3045)
@@ -3,5 +3,5 @@
 {
   float4 position: POSITION;
-  float3 normal: NORMAL;
+  float4 normal: NORMAL;
   float4 color: COLOR0;
   float4 texCoord: TEXCOORD0;
@@ -17,5 +17,5 @@
 	float4 color: COLOR0;  
 	float4 eyePos: TEXCOORD1; // eye position
-	float3 normal: TEXCOORD2;
+	float4 normal: TEXCOORD2;
 };
 
@@ -30,5 +30,5 @@
 	float4 winPos: WPOS;
 	float4 eyePos: TEXCOORD1; // eye position
-	float3 normal: TEXCOORD2;
+	float4 normal: TEXCOORD2;
 };
 
@@ -56,5 +56,5 @@
 	OUT.position = mul(glstate.matrix.mvp, IN.position);
 
-	OUT.normal = IN.normal;
+	OUT.normal = mul(glstate.matrix.invtrans.modelview[0], IN.normal);
 
 	return OUT;
@@ -63,5 +63,6 @@
 
 pixel fragtex(fragin IN, 
-			  uniform sampler2D tex
+			  uniform sampler2D tex,
+			  uniform float4x4 viewMatrix
 			  )
 {
@@ -76,6 +77,8 @@
 	// hack: use combination of emmisive + diffuse (emmisive used as constant ambient term)
 	pix.col = (glstate.material.emission + glstate.material.diffuse) * texColor; 
-	// save world space normal in rt
-	pix.norm = IN.normal;
+	// save world space normal in rt => transform back into world space by
+	// multiplying with inverse view. since transforming normal with T means to 
+	// multiply with the inverse transpose of T, we multiple with Transp(Inv(Inv(view))) = Transp(view)
+	pix.norm = mul(transpose(viewMatrix), IN.normal);
 	// compute eye linear depth
 	pix.col.w = length(IN.eyePos.xyz);
@@ -87,11 +90,13 @@
 
 
-pixel frag(fragin IN)
+pixel frag(fragin IN,  uniform float4x4 viewMatrix)
 {
 	pixel pix;
 	// hack: use comination of emmisive + diffuse (emmisive used as constant ambient term)
 	pix.col = glstate.material.diffuse + glstate.material.emission;
-	// save world space normal in rt
-	pix.norm = IN.normal;
+	// save world space normal in rt => transform back into world space by
+	// multiplying with inverse view. since transforming normal with T means to 
+	// multiply with the inverse transpose of T, we multiple with Transp(Inv(Inv(view))) = Transp(view)
+	pix.norm = mul(transpose(viewMatrix), IN.normal);
 	// eye space depth
 	pix.col.w = length(IN.eyePos.xyz);
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ResourceManager.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ResourceManager.cpp	(revision 3042)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ResourceManager.cpp	(revision 3045)
@@ -165,22 +165,27 @@
 			{
 				Shape *shape = *it;
+
 				Material *mat = shape->GetMaterial();
-				Technique *tech = mat->GetDefaultTechnique();
-				
-				tech->SetVertexProgram(sTreeAnimation);
-
-				GPUProgramParameters *vtxParams = tech->GetVertexProgramParameters();
-
-				vtxParams->SetTimerParam(0);
-				// wind direction
-				static Vector3 windDir = Normalize(Vector3(0.8f, 0.2f, 0.0f));
-				vtxParams->SetValue3f(1, windDir.x, windDir.y, windDir.z);
-				// amplitude
-				vtxParams->SetValue1f(2, 0.3f);
-
-				AxisAlignedBox3 box = sceneGeom->GetBoundingBox();
-				vtxParams->SetValue2f(3, box.Min().z, box.Max().z);
-				// frequency
-				vtxParams->SetValue1f(4, 0.1f);
+
+				// add the vertex animation program
+				for (int i = 0; i < 2; ++ i)
+				{
+					Technique *tech = mat->GetTechnique(i);
+					tech->SetVertexProgram(sTreeAnimation);
+
+					GPUProgramParameters *vtxParams = tech->GetVertexProgramParameters();
+
+					vtxParams->SetTimerParam(0);
+					// wind direction
+					static Vector3 windDir = Normalize(Vector3(0.8f, 0.2f, 0.0f));
+					vtxParams->SetValue3f(1, windDir.x, windDir.y, windDir.z);
+					// amplitude
+					vtxParams->SetValue1f(2, 0.3f);
+
+					AxisAlignedBox3 box = sceneGeom->GetBoundingBox();
+					vtxParams->SetValue2f(3, box.Min().z, box.Max().z);
+					// frequency
+					vtxParams->SetValue1f(4, 0.1f);
+				}
 			}
 		}
@@ -279,20 +284,26 @@
 	}
 
-	if (tech->GetTexture())
-	{
-		tech->mFragmentProgram = mMrtDefaultFragmentTexProgram;
-
-		tech->mGPUFragmentParameters = CreateGPUProgramParameters(tech->mFragmentProgram);
-		tech->mGPUFragmentParameters->SetTexture(0, tech->GetTexture()->GetId());
+
+	///////////////
+	//-- add technique for deferred shading
+
+	Technique *deferred = new Technique(*tech);
+
+	if (deferred->GetTexture())
+	{
+		deferred->SetFragmentProgram(mMrtDefaultFragmentTexProgram);
+		deferred->GetFragmentProgramParameters()->SetViewMatrixParam(0);
+		deferred->GetFragmentProgramParameters()->SetTexture(1, tech->GetTexture()->GetId());
 	}	
 	else
 	{
-		tech->mFragmentProgram = mMrtDefaultFragmentProgram;
-		tech->mGPUFragmentParameters = CreateGPUProgramParameters(tech->mFragmentProgram);
-	}
-
-	tech->mVertexProgram = mMrtDefaultVertexProgram;
-	tech->mGPUVertexParameters = CreateGPUProgramParameters(tech->mVertexProgram);
-	
+		deferred->SetFragmentProgram(mMrtDefaultFragmentProgram);
+		deferred->GetFragmentProgramParameters()->SetViewMatrixParam(0);
+	}
+
+	deferred->SetVertexProgram(mMrtDefaultVertexProgram);
+	
+	mat->AddTechnique(deferred);
+
 	return mat;
 }
@@ -393,14 +404,7 @@
 
 
-GPUProgramParameters *ResourceManager::CreateGPUProgramParameters(ShaderProgram *p)
-{
-	GPUProgramParameters *gpuParams = new GPUProgramParameters(p);
-	mGPUParameters.push_back(gpuParams);
-
-	return gpuParams;
-}
-
-
-ShaderProgram *ResourceManager::CreateFragmentProgram(const std::string &filename, const std::string &funcName)
+
+ShaderProgram *ResourceManager::CreateFragmentProgram(const std::string &filename, 
+													  const std::string &funcName)
 {
 	const string fullName = "src/shaders/" + filename + ".cg";
@@ -460,7 +464,13 @@
 	mMrtDefaultFragmentProgram = CreateFragmentProgram("mrt", "frag");
 	mMrtDefaultFragmentTexProgram = CreateFragmentProgram("mrt", "fragtex");
-	mMrtDefaultFragmentTexProgram->AddParameter("tex", 0);
-
-	sTreeAnimation = CreateVertexProgram("treeanimation", "animateVtx");
+
+	// provide the current view matrix
+	mMrtDefaultFragmentProgram->AddParameter("viewMatrix", 0);
+	mMrtDefaultFragmentTexProgram->AddParameter("viewMatrix", 0);
+
+	// add a texture parameter
+	mMrtDefaultFragmentTexProgram->AddParameter("tex", 1);
+
+	sTreeAnimation = CreateVertexProgram("treeanimation", "animateVtxMrt");
 
 	sTreeAnimation->AddParameter("timer", 0);
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SkyPreetham.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SkyPreetham.cpp	(revision 3043)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SkyPreetham.cpp	(revision 3045)
@@ -80,6 +80,9 @@
 	Material *mat = shape->GetMaterial();
 
-	mat->GetDefaultTechnique()->SetFragmentProgram(mSkyFragProgram);
-	mat->GetDefaultTechnique()->SetVertexProgram(mSkyVtxProgram);
+	mat->GetTechnique(0)->SetFragmentProgram(mSkyFragProgram);
+	mat->GetTechnique(0)->SetVertexProgram(mSkyVtxProgram);
+
+	mat->GetTechnique(1)->SetFragmentProgram(mSkyFragProgram);
+	mat->GetTechnique(1)->SetVertexProgram(mSkyVtxProgram);
 }
 
@@ -115,5 +118,11 @@
 	
 	Material *mat = mSkyDome->GetShape(0)->GetMaterial();
-	Technique *tech = mat->GetDefaultTechnique();
+
+	Technique *tech;
+
+	if (state->GetRenderPassType() == RenderState::DEFERRED)
+		tech = mat->GetTechnique(1);
+	else
+		tech = mat->GetTechnique(0);
 
 	GPUProgramParameters *vtxParams = tech->GetVertexProgramParameters();
@@ -140,11 +149,5 @@
 		vtxParams->SetValue1f(8, 8e-5f);
 	}
-/*
-	tech->GetVertexProgramParameters()->UpdateParameters();
-	tech->GetVertexProgram()->Bind();
-
-	tech->GetFragmentProgramParameters()->UpdateParameters();
-	tech->GetFragmentProgram()->Bind();
-*/
+
 	// render sky dome
 	mSkyDome->Render(state);
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ShaderProgram.h
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ShaderProgram.h	(revision 3043)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ShaderProgram.h	(revision 3045)
@@ -32,4 +32,7 @@
 {
 public:
+	/** Default construction.
+	*/
+	GPUProgramParameters();
 
 	/** Constructor which initialized this parameter set for a given program.
@@ -54,6 +57,4 @@
 	void SetArray3f(int idx, float *vals, int numElements);
 
-	void SetTimerParam(int idx);
-
 	/** Sets the texture parameter.
 	*/
@@ -63,4 +64,20 @@
 	void SetMatrix(int idx, Matrix4x4 *mat);
 
+	////////////
+	//-- The following parameters are updated and set automatically once per frame.
+
+	/** This parameter is connected to a timer that is updated once per frame.
+	*/
+	void SetTimerParam(int idx);
+	/** This parameter is connected to the current view matrix that is updated
+		once per frame.
+	*/
+	void SetViewMatrixParam(int idx);
+	/** This parameter is connected to the current view vector that is updated
+		once per frame.
+	*/
+	void SetViewVectorParam(int idx);
+
+	
 
 	///////////
@@ -84,7 +101,8 @@
 	*/
 	void UpdateParameters();
-
-
-	static void InitFrame();
+	/** Function should be called once per frame to update frame related parameters.
+	*/
+	static void InitFrame(Camera *cam);
+
 
 protected:
@@ -142,8 +160,11 @@
 	};
 
-
+	/// the program this parameter set is connected to
 	ShaderProgram *mProgram;
 
-	int mTimer;
+	int mTimerParam;
+	int mViewVectorParam;
+	int mViewMatrixParam;
+
 	std::vector<FloatParam> mFloats;
 	std::vector<IntParam> mTextures;
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ResourceManager.h
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ResourceManager.h	(revision 3038)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ResourceManager.h	(revision 3045)
@@ -24,5 +24,4 @@
 class Transform3;
 class ShaderProgram;
-class GPUProgramParameters;
 
 
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Material.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Material.cpp	(revision 3042)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Material.cpp	(revision 3045)
@@ -4,5 +4,5 @@
 #include "glInterface.h"
 #include "RenderState.h"
-#include "ShaderProgram.h"
+
 
 using namespace std;
@@ -24,8 +24,8 @@
 	mCullFaceEnabled = true;
 	
-	mGPUVertexParameters = NULL;
+	mVertexProgramParameters.Reset();
+	mFragmentProgramParameters.Reset();
+	
 	mVertexProgram = NULL;
-	
-	mGPUFragmentParameters = NULL;
 	mFragmentProgram = NULL;
 }
@@ -42,11 +42,4 @@
 
 
-Technique::~Technique()
-{
-	//DEL_PTR(mGPUFragmentParameters);
-	//DEL_PTR(mGPUVertexParameters);
-}
-
-
 Technique::Technique(const RgbaColor &color):
 mDiffuseColor(color),
@@ -56,4 +49,29 @@
 {
 	InitMaterial();
+}
+
+
+Technique::Technique(const Technique &tech)
+{
+	mAmbientColor = tech.mAmbientColor;
+	mDiffuseColor = tech.mDiffuseColor;
+	mSpecularColor = tech.mSpecularColor;
+	mEmmisiveColor = tech.mEmmisiveColor;
+
+	mVertexProgram = tech.mVertexProgram;
+	mFragmentProgram = tech.mFragmentProgram;
+
+	mAlphaTestEnabled = tech.mAlphaTestEnabled;
+	mCullFaceEnabled =tech.mCullFaceEnabled;
+
+	mTexture = tech.mTexture;
+
+	mVertexProgramParameters = tech.mVertexProgramParameters;
+	mFragmentProgramParameters = tech.mFragmentProgramParameters;
+}
+
+
+Technique::~Technique()
+{
 }
 
@@ -74,6 +92,6 @@
 	mFragmentProgram = p; 
 
-	mGPUFragmentParameters->Reset();
-	mGPUFragmentParameters->SetProgram(p);
+	mFragmentProgramParameters.Reset();
+	mFragmentProgramParameters.SetProgram(p);
 }
 	
@@ -83,12 +101,20 @@
 	mVertexProgram = p; 
 
-	mGPUVertexParameters->Reset();
-	mGPUVertexParameters->SetProgram(p);
+	mVertexProgramParameters.Reset();
+	mVertexProgramParameters.SetProgram(p);
 }
+
+
+/***********************************************/
+/*        class Material implementation        */
+/***********************************************/
 
 
 void Material::Render(RenderState *state)
 {
-	mTechniques[0]->Render(state);
+	if (state->GetRenderPassType() == RenderState::DEFERRED)
+		mTechniques[1]->Render(state);
+	else
+		mTechniques[0]->Render(state);
 }
 
@@ -126,3 +152,9 @@
 
 
+void Material::AddTechnique(Technique *tech)
+{
+	mTechniques.push_back(tech);
 }
+
+
+}
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/chcdemo.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/chcdemo.cpp	(revision 3044)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/chcdemo.cpp	(revision 3045)
@@ -868,6 +868,4 @@
 	}
 	
-	GPUProgramParameters::InitFrame();
-
 
 	if ((!shadowMap || !shadowTraverser) && (showShadowMap || renderLightView))
@@ -883,4 +881,8 @@
 	// bring eye modelview matrix up-to-date
 	SetupEyeView();
+
+	// set GPU related parameters
+	GPUProgramParameters::InitFrame(camera);
+
 
 	// hack
@@ -1857,7 +1859,4 @@
 void RenderSky()
 {
-	//loader->EnableVertexProfile();
-	//loader->EnableFragmentProfile();
-
 	if ((renderMethod == RENDER_DEFERRED) || (renderMethod == RENDER_DEPTH_PASS_DEFERRED))
 		state.SetRenderPassType(RenderState::DEFERRED);
