Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/FriendlyCulling.sln
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/FriendlyCulling.sln	(revision 3107)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/FriendlyCulling.sln	(revision 3207)
@@ -12,4 +12,6 @@
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VboFormatConverter", "VboFormatConverter.vcproj", "{93A522E1-76F0-4D46-9C97-30DC2DDB531B}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "IrradianceMapping", "IrradianceMapping.vcproj", "{91680C49-A358-48AE-A02C-66CB884B7D7F}"
 EndProject
 Global
@@ -35,4 +37,8 @@
 		{93A522E1-76F0-4D46-9C97-30DC2DDB531B}.Release|Win32.ActiveCfg = Release|Win32
 		{93A522E1-76F0-4D46-9C97-30DC2DDB531B}.Release|Win32.Build.0 = Release|Win32
+		{91680C49-A358-48AE-A02C-66CB884B7D7F}.Debug|Win32.ActiveCfg = Debug|Win32
+		{91680C49-A358-48AE-A02C-66CB884B7D7F}.Debug|Win32.Build.0 = Debug|Win32
+		{91680C49-A358-48AE-A02C-66CB884B7D7F}.Release|Win32.ActiveCfg = Release|Win32
+		{91680C49-A358-48AE-A02C-66CB884B7D7F}.Release|Win32.Build.0 = Release|Win32
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/deferred.cg
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/deferred.cg	(revision 3206)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/deferred.cg	(revision 3207)
@@ -267,5 +267,8 @@
 	// actually 0 means pixel is valid
 	const float pixelIsValid = 0.0f;
+	// means that we only use slight temporal coherence over some frames
+	// so that there si no noticeable drag
 	const float pixelCouldBeValid = 2.0f;
+	// this pixel information has to be discarded in order to not create artifacts
 	const float pixelNotValid = 10.0f;
 
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/irradiance.cpp
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/irradiance.cpp	(revision 3037)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/irradiance.cpp	(revision 3207)
@@ -18,7 +18,4 @@
 #include <time.h>
 #include "glInterface.h"
-
-#include <Cg/cg.h>
-#include <Cg/cgGL.h>
 
 
@@ -53,8 +50,11 @@
 #include "Light.h"
 #include "SceneEntityConverter.h"
-#include "ObjConverter.h"
 #include "SkyPreetham.h"
 #include "Texture.h"
-#include "EntityMerger.h"
+#include "ShaderManager.h"
+#include "MotionPath.h"
+#include "ShaderProgram.h"
+#include "Shape.h"
+
 
 using namespace std;
@@ -62,16 +62,14 @@
 
 
+/// the environment for the program parameter
 static Environment env;
 
-#define MAX_DEPTH_CONST 10.0f
-
-// fbo
+
+GLuint fontTex;
+/// the fbo used for MRT
 FrameBufferObject *fbo = NULL;
-
-GLuint fontTex;
-
 /// the renderable scene geometry
 SceneEntityContainer sceneEntities;
-
+SceneEntityContainer dynamicObjects;
 // traverses and renders the hierarchy
 RenderTraverser *traverser = NULL;
@@ -79,35 +77,44 @@
 Bvh *bvh = NULL;
 /// handles scene loading
-ResourceManager *loader = NULL;
+ResourceManager *resourceManager = NULL;
+/// handles scene loading
+ShaderManager *shaderManager = NULL;
 /// the scene camera
-Camera *camera = NULL;
+PerspectiveCamera *camera = NULL;
 /// the scene camera
-Camera *visCamera = NULL;
+PerspectiveCamera *visCamera = NULL;
 /// the visualization
 Visualization *visualization = NULL;
-/// the current render state
-RenderState state;
+/// the current render renderState
+RenderState renderState;
 /// the rendering algorithm
 int renderMode = RenderTraverser::CHCPLUSPLUS;
-// eye near plane distance
-float nearDist = 0.2f;
+/// eye near plane distance
+const float nearDist = 0.2f;
+//const float nearDist = 1.0f;
+/// eye far plane distance
 float farDist = 1e6f;
 /// the field of view
-float fov = 50.0f;
-/// the pixel threshold where a node is still considered invisible
-int threshold;
-
-int assumedVisibleFrames = 10;
-int maxBatchSize = 50;
-
-int trianglesPerVirtualLeaf = INITIAL_TRIANGLES_PER_VIRTUAL_LEAVES;
+const float fov = 50.0f;
 
 SceneQuery *sceneQuery = NULL;
 RenderQueue *renderQueue = NULL;
-
-// traverses and renders the hierarchy
+/// traverses and renders the hierarchy
 RenderTraverser *shadowTraverser = NULL;
-
+/// the skylight + skydome model
 SkyPreetham *preetham = NULL;
+
+MotionPath *motionPath = NULL;
+/// max depth where candidates for tighter bounds are searched
+int maxDepthForTestingChildren = 3;
+
+
+/// the technique used for rendering
+enum RenderTechnique
+{
+	FORWARD,
+	DEFERRED,
+	DEPTH_PASS
+};
 
 
@@ -115,5 +122,5 @@
 enum RenderMethod
 {
-	RENDER_FIXED,
+	RENDER_FORWARD,
 	RENDER_DEPTH_PASS,
 	RENDER_DEFERRED,
@@ -123,6 +130,9 @@
 
 /// one of four possible render methods
-int renderMethod = RENDER_FIXED;
-
+int renderMethod = RENDER_FORWARD;
+
+static int winWidth = 1024;
+static int winHeight = 768;
+static float winAspectRatio = 1.0f;
 
 /// these values get scaled with the frame rate
@@ -131,17 +141,12 @@
 
 /// elapsed time in milliseconds
-double elapsedTime = 1000.0f;
-double algTime = 1000.0f;
-
-static int winWidth = 1024;
-static int winHeight = 768;
+double elapsedTime = 1000.0;
+double algTime = 1000.0;
+double accumulatedTime = 1000.0;
+float fps = 1e3f;
+float turbitity = 5.0f;
 
 int shadowSize = 2048;
-
-static float winAspectRatio = 1.0f;
-
-double accumulatedTime = 1000;
-float fps = 1e3f;
-
+/// the hud font
 glfont::GLFont myfont;
 
@@ -161,6 +166,5 @@
 int numBatches = 0;
 
-
-// mouse navigation state
+// mouse navigation renderState
 int xEyeBegin = 0;
 int yEyeBegin = 0;
@@ -168,5 +172,4 @@
 int verticalMotionBegin = 0;
 int horizontalMotionBegin = 0;
-
 
 bool leftKeyPressed = false;
@@ -176,4 +179,8 @@
 bool descendKeyPressed = false;
 bool ascendKeyPressed = false;
+bool leftStrafeKeyPressed = false;
+bool rightStrafeKeyPressed = false;
+
+bool altKeyPressed = false;
 
 bool showHelp = false;
@@ -200,17 +207,31 @@
 bool showShadowMap = false;
 bool renderLightView = false;
-
-bool altKeyPressed = false;
-
 bool useHDR = true;
-
-static float ssaoTempCohFactor = 255.0;
-
+bool useAntiAliasing = true;
 
 PerfTimer frameTimer, algTimer;
-
-static int sCurrentMrtSet = 0;
-
+/// the performance window
 PerformanceGraph *perfGraph = NULL;
+
+float ssaoTempCohFactor = 255.0;
+bool sortSamples = true;
+int sCurrentMrtSet = 0;
+
+static Matrix4x4 invTrafo = IdentityMatrix();
+
+
+//////////////
+//-- algorithm parameters
+
+/// the pixel threshold where a node is still considered invisible 
+/// (should be zero for conservative visibility)
+int threshold;
+int assumedVisibleFrames = 10;
+int maxBatchSize = 50;
+int trianglesPerVirtualLeaf = INITIAL_TRIANGLES_PER_VIRTUAL_LEAVES;
+
+//////////////
+
+enum {CAMERA_PASS = 0, LIGHT_PASS = 1};
 
 
@@ -220,88 +241,76 @@
 ShadowMap *shadowMap = NULL;
 DirectionalLight *light = NULL;
-DeferredRenderer *ssaoShader = NULL;
-
-SceneEntity *cube = NULL;
-SceneEntity *aeroplane = NULL;
+DeferredRenderer *deferredShader = NULL;
+
+
+SceneEntity *buddha = NULL;
 SceneEntity *skyDome = NULL;
 
 
-
-// function forward declarations
+////////////////////
+//--- function forward declarations
+
 void InitExtensions();
+void InitGLstate();
+
 void DisplayVisualization();
-void InitGLstate();
-void InitRenderTexture();
-void InitCg();
+/// destroys all allocated resources
 void CleanUp();
 void SetupEyeView();
-void UpdateEyeMtx();
 void SetupLighting();
 void DisplayStats();
-void Output(int x, int y, const char *string);
+/// draw the help screen
 void DrawHelpMessage();
+/// render the sky dome
 void RenderSky();
+/// render the objects found visible in the depth pass
 void RenderVisibleObjects();
 
 void Begin2D();
 void End2D();
+/// the main loop
+void MainLoop();
+
 void KeyBoard(unsigned char c, int x, int y);
-void DrawStatistics();
-void Display();
 void Special(int c, int x, int y);
 void KeyUp(unsigned char c, int x, int y);
 void SpecialKeyUp(int c, int x, int y);
 void Reshape(int w, int h);
-void Mouse(int button, int state, int x, int y);
+void Mouse(int button, int renderState, int x, int y);
 void LeftMotion(int x, int y);
 void RightMotion(int x, int y);
 void MiddleMotion(int x, int y);
-void CalcDecimalPoint(string &str, int d);
-
-RenderTraverser *CreateTraverser(Camera *cam);
-
 void KeyHorizontalMotion(float shift);
 void KeyVerticalMotion(float shift);
-
+/// returns the string representation of a number with the decimal points
+void CalcDecimalPoint(string &str, int d);
+/// Creates the traversal method (vfc, stopandwait, chc, chc++)
+RenderTraverser *CreateTraverser(PerspectiveCamera *cam);
+/// place the viewer on the floor plane
 void PlaceViewer(const Vector3 &oldPos);
+// initialise the frame buffer objects
+void InitFBO();
+/// changes the sunlight direction
+void RightMotionLight(int x, int y);
+/// render the shader map
+void RenderShadowMap(float newfar);
+/// function that touches each material once in order to accelarate render queue
+void PrepareRenderQueue();
+/// loads the specified model
+void LoadModel(const string &model, SceneEntityContainer &entities);
 
 inline float KeyRotationAngle() { return keyRotation * elapsedTime * 1e-3f; }
 inline float KeyShift() { return keyForwardMotion * elapsedTime * 1e-3f; }
-// initialise the frame buffer objects
-void InitFBO();
-
-void RightMotionLight(int x, int y);
-
-void RenderShadowMap(float newfar);
-
-
-
-/////////
-//-- cg stuff
-
-static CGcontext sCgContext = NULL;
-
-static CGparameter sEyePosParamTex;
-static CGparameter sEyePosParam;
-
+
+void CreateAnimation();
+
+SceneQuery *GetOrCreateSceneQuery();
+
+
+// new view projection matrix of the camera
 static Matrix4x4 viewProjMat = IdentityMatrix();
+// the old view projection matrix of the camera
 static Matrix4x4 oldViewProjMat = IdentityMatrix();
 
-
-
-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);
-	}
-}
 
 
@@ -321,7 +330,5 @@
 int main(int argc, char* argv[])
 {
-/*
 #ifdef _CRT_SET
-
 	//Now just call this function at the start of your program and if you're
 	//compiling in debug mode (F5), any leaks will be displayed in the Output
@@ -334,5 +341,5 @@
 	_CrtSetReportFile(_CRT_ASSERT,_CRTDBG_FILE_STDERR); 
 #endif
-*/
+
 	cout << "=== reading environment file ===" << endl << endl;
 
@@ -355,21 +362,25 @@
 		env.GetIntParam(string("maxBatchSize"), maxBatchSize);
 		env.GetIntParam(string("trianglesPerVirtualLeaf"), trianglesPerVirtualLeaf);
+		env.GetIntParam(string("winWidth"), winWidth);
+		env.GetIntParam(string("winHeight"), winHeight);
+		env.GetIntParam(string("shadowSize"), shadowSize);
+		env.GetIntParam(string("maxDepthForTestingChildren"), maxDepthForTestingChildren);
 
 		env.GetFloatParam(string("keyForwardMotion"), keyForwardMotion);
 		env.GetFloatParam(string("keyRotation"), keyRotation);
-
-		env.GetIntParam(string("winWidth"), winWidth);
-		env.GetIntParam(string("winHeight"), winHeight);
-
-		env.GetBoolParam(string("useFullScreen"), useFullScreen);
 		env.GetFloatParam(string("tempCohFactor"), ssaoTempCohFactor);
+		env.GetFloatParam(string("turbitity"), turbitity);
+		
 		env.GetVectorParam(string("camPosition"), camPos);
 		env.GetVectorParam(string("camDirection"), camDir);
 		env.GetVectorParam(string("lightDirection"), lightDir);
 
+		env.GetBoolParam(string("useFullScreen"), useFullScreen);
 		env.GetBoolParam(string("useLODs"), useLODs);
-		env.GetIntParam(string("shadowSize"), shadowSize);
-
 		env.GetBoolParam(string("useHDR"), useHDR);
+		env.GetBoolParam(string("useAA"), useAntiAliasing);
+		env.GetBoolParam(string("useAdvancedShading"), useAdvancedShading);
+
+		env.GetIntParam(string("renderMethod"), renderMethod);
 
 		//env.GetStringParam(string("modelPath"), model_path);
@@ -389,7 +400,10 @@
 		cout << "temporal coherence: " << ssaoTempCohFactor << endl;
 		cout << "shadow size: " << shadowSize << endl;
+		cout << "render method: " << renderMethod << endl;
+		cout << "use antialiasing: " << useAntiAliasing << endl;
+		cout << "use advanced shading: " << useAdvancedShading << endl;
+		cout << "turbitity: " << turbitity << endl;
 
 		//cout << "model path: " << model_path << endl;
-
 		cout << "**** end parameters ****" << endl << endl;
 	}
@@ -397,5 +411,5 @@
 	///////////////////////////
 
-	camera = new Camera(winWidth, winHeight, fov);
+	camera = new PerspectiveCamera(winWidth / winHeight, fov);
 	camera->SetNear(nearDist);
 	camera->SetFar(1000);
@@ -404,5 +418,5 @@
 	camera->SetPosition(camPos);
 
-	visCamera = new Camera(winWidth, winHeight, fov);
+	visCamera = new PerspectiveCamera(winWidth / winHeight, fov);
 	visCamera->SetNear(0.0f);
 	visCamera->Yaw(.5 * M_PI);
@@ -410,7 +424,6 @@
 	// create a new light
 	light = new DirectionalLight(lightDir, RgbaColor(1, 1, 1, 1), RgbaColor(1, 1, 1, 1));
-
-
-	renderQueue = new RenderQueue(&state, camera);
+	// the render queue for material sorting
+	renderQueue = new RenderQueue(&renderState);
 
 	glutInitWindowSize(winWidth, winHeight);
@@ -432,10 +445,10 @@
 	}
 
-	glutDisplayFunc(Display);
+	glutDisplayFunc(MainLoop);
 	glutKeyboardFunc(KeyBoard);
 	glutSpecialFunc(Special);
 	glutReshapeFunc(Reshape);
 	glutMouseFunc(Mouse);
-	glutIdleFunc(Display);
+	glutIdleFunc(MainLoop);
 	glutKeyboardUpFunc(KeyUp);
 	glutSpecialUpFunc(SpecialKeyUp);
@@ -452,26 +465,65 @@
 	MiddleMotion(0, 0);
 
-	// init cg shader programs
-	InitCg();
-
 	perfGraph = new PerformanceGraph(1000);
 
-	loader = ResourceManager::GetSingleton();
-
-	const string filename = string(model_path + "city.dem");
-	
-	if (loader->Load(filename, sceneEntities))
-		cout << "model " << filename << " loaded" << endl;
-	else
-	{
-		cerr << "loading model " << filename << " failed" << endl;
-		CleanUp();
-		exit(0);
-	}
-	
+	resourceManager = ResourceManager::GetSingleton();
+	shaderManager = ShaderManager::GetSingleton();
+
+	///////////
+	//-- load the static scene geometry
+
+	LoadModel("city.dem", sceneEntities);
+
+
+	//////////
+	//-- load some dynamic stuff
+
+	//resourceManager->mUseNormalMapping = true;
+	//resourceManager->mUseNormalMapping = false;
+
+	//LoadModel("fisch.dem", dynamicObjects);
+	LoadModel("hbuddha.dem", dynamicObjects);
+	//LoadModel("venusm.dem", dynamicObjects);
+	//LoadModel("camel.dem", dynamicObjects);
+	//LoadModel("toyplane2.dem", dynamicObjects);
+	//LoadModel("elephal.dem", dynamicObjects);
+
+	resourceManager->mUseNormalMapping = false;
+
+	buddha = dynamicObjects.back();
+	
+	const Vector3 sceneCenter(470.398f, 240.364f, 181.7f);
+	//const Vector3 sceneCenter(470.398f, 240.364f, 180.3);
+	
+	Matrix4x4 transl = TranslationMatrix(sceneCenter);
+	buddha->GetTransform()->SetMatrix(transl);
+
+	for (int i = 0; i < 10; ++ i)
+	{
+		SceneEntity *ent = new SceneEntity(*buddha);
+		resourceManager->AddSceneEntity(ent);
+
+		Vector3 offs = Vector3::ZERO();
+
+		offs.x = RandomValue(.0f, 50.0f);
+		offs.y = RandomValue(.0f, 50.0f);
+
+		Vector3 newPos = sceneCenter + offs;
+
+		transl = TranslationMatrix(newPos);
+		Transform3 *transform = resourceManager->CreateTransform(transl);
+
+		ent->SetTransform(transform);
+		dynamicObjects.push_back(ent);
+	}
+
+
+	///////////
+	//-- load the associated static bvh
 
 	const string bvh_filename = string(model_path + "city.bvh");
+
 	BvhLoader bvhLoader;
-	bvh = bvhLoader.Load(bvh_filename, sceneEntities);
+	bvh = bvhLoader.Load(bvh_filename, sceneEntities, dynamicObjects, maxDepthForTestingChildren);
 
 	if (!bvh)
@@ -482,44 +534,37 @@
 	}
 
+	/// set the depth of the bvh depending on the triangles per leaf node
+	bvh->SetVirtualLeaves(trianglesPerVirtualLeaf);
+
 	// set far plane based on scene extent
 	farDist = 10.0f * Magnitude(bvh->GetBox().Diagonal());
-	bvh->SetVirtualLeaves(trianglesPerVirtualLeaf);
-
-	camera->SetFar(Magnitude(bvh->GetBox().Diagonal()));
-	
-	Vector3 cubeCenter(470.398f, 240.364f, 182.5f);
-	
-	Matrix4x4 transl = TranslationMatrix(cubeCenter);
-
-	SceneEntityContainer dummy;
-	
-	string skyDomeStr(model_path + "sky.dem");
-
-	if (loader->Load(skyDomeStr, sceneEntities))
-	{
-		cout << "successfully loaded " << sceneEntities.size() << " scene entities" << endl;
-	}
-	else
-	{
-		cerr << "loading file " << skyDomeStr << " failed" << endl;
-
-		CleanUp();
-		exit(0);
-	}
-
+	camera->SetFar(farDist);
+
+
+	//////////////////
+	//-- setup the skydome model
+
+	LoadModel("sky.dem", sceneEntities);
 	skyDome = sceneEntities.back();
 
-	//InitCg();
-
-	const float turbitiy = 5.0f;
-	preetham = new SkyPreetham(turbitiy, skyDome);
-
-	// initialize the render traverser
+	/// the turbitity of the sky (from clear to hazy, use <3 for clear sky)
+	preetham = new SkyPreetham(turbitity, skyDome);
+
+	CreateAnimation();
+
+
+	//////////
+	//-- initialize the traversal algorithm
+
 	traverser = CreateTraverser(camera);
-
-	visualization = new Visualization(bvh, camera, NULL, &state);
-	
-	state.SetRenderPassType(RenderState::FIXED);
-
+	
+	// the bird-eye visualization
+	visualization = new Visualization(bvh, camera, NULL, &renderState);
+
+	// this function assign the render queue bucket ids of the materials in beforehand
+	// => probably a little less overhead for new parts of the scene that are not yet assigned
+	PrepareRenderQueue();
+	/// forward rendering is the default
+	renderState.SetRenderTechnique(FORWARD);
 	// frame time is restarted every frame
 	frameTimer.Start();
@@ -527,5 +572,5 @@
 	// the rendering loop
 	glutMainLoop();
-
+	
 	// clean up
 	CleanUp();
@@ -535,53 +580,4 @@
 
 
-void InitCg(void) 
-{
-	// setup cg
-	cgSetErrorCallback(cgErrorCallback);
-
-	// create context.
-	sCgContext = cgCreateContext();
-
-	// get the optimal profile
-	RenderState::sCgFragmentProfile = cgGLGetLatestProfile(CG_GL_FRAGMENT);
-	cgGLSetOptimalOptions(RenderState::sCgFragmentProfile);
-
-	RenderState::sCgVertexProfile = cgGLGetLatestProfile(CG_GL_VERTEX);
-	cgGLSetOptimalOptions(RenderState::sCgVertexProfile);
-
-	// set textures to auto load
-	cgGLSetManageTextureParameters(sCgContext, false);
-
-	RenderState::sCgMrtVertexProgram = 
-		new ShaderProgram(sCgContext, "src/shaders/mrt.cg", RenderState::sCgVertexProfile, "vtx");
-
-	if (!RenderState::sCgMrtVertexProgram->IsValid())
-		cerr << "fragment program failed to load" << endl;
-
-	RenderState::sCgMrtFragmentTexProgram = 
-		new ShaderProgram(sCgContext, "src/shaders/mrt.cg", RenderState::sCgFragmentProfile, "fragtex");
-
-	
-	if (!RenderState::sCgMrtFragmentTexProgram->IsValid())
-		cerr << "fragment tex program failed to load" << endl;
-
-	RenderState::sCgMrtFragmentTexProgram->AddParameter("tex", 0);
-
-	RenderState::sCgMrtFragmentProgram = 
-		new ShaderProgram(sCgContext, "src/shaders/mrt.cg", RenderState::sCgFragmentProfile, "frag");
-
-	if (!RenderState::sCgMrtFragmentProgram->IsValid())
-		cerr << "fragment program failed to load" << endl;
-	
-
-	PrintGLerror("init");
-
-	DeferredRenderer::InitCG(sCgContext);
-	SkyPreetham::InitCG(sCgContext);
-
-	cout << "cg initialization successful" << endl;
-}
-
-
 void InitFBO()
 {
@@ -589,19 +585,23 @@
 
 	// this fbo basicly stores the scene information we get from standard rendering of a frame
-	// we store colors, normals, positions (for the ssao)
+	// we store diffuse colors, eye space depth and normals
 	fbo = new FrameBufferObject(texWidth, texHeight, FrameBufferObject::DEPTH_32);
-	//fbo = new FrameBufferObject(texWidth, texHeight, FrameBufferObject::DEPTH_24);
 
 	// the diffuse color buffer
 	fbo->AddColorBuffer(ColorBufferObject::RGBA_FLOAT_32, ColorBufferObject::WRAP_CLAMP_TO_EDGE, ColorBufferObject::FILTER_LINEAR, ColorBufferObject::FILTER_NEAREST);
 	// the normals buffer
-	fbo->AddColorBuffer(ColorBufferObject::RGB_FLOAT_16, ColorBufferObject::WRAP_CLAMP_TO_EDGE, ColorBufferObject::FILTER_NEAREST);
-	// the positions buffer
-	//fbo->AddColorBuffer(ColorBufferObject::RGBA_FLOAT_32, ColorBufferObject::WRAP_CLAMP_TO_EDGE, ColorBufferObject::FILTER_NEAREST);
-	fbo->AddColorBuffer(ColorBufferObject::RGB_UBYTE, ColorBufferObject::WRAP_CLAMP_TO_EDGE, ColorBufferObject::FILTER_NEAREST);
+	//fbo->AddColorBuffer(ColorBufferObject::RGB_FLOAT_16, ColorBufferObject::WRAP_CLAMP_TO_EDGE, ColorBufferObject::FILTER_NEAREST);
+	fbo->AddColorBuffer(ColorBufferObject::RGB_FLOAT_16, ColorBufferObject::WRAP_CLAMP_TO_EDGE, ColorBufferObject::FILTER_LINEAR);
+	// a rgb buffer which could hold material properties
+	//fbo->AddColorBuffer(ColorBufferObject::RGB_UBYTE, ColorBufferObject::WRAP_CLAMP_TO_EDGE, ColorBufferObject::FILTER_NEAREST);
+	// buffer holding the difference vector to the old frame
+	fbo->AddColorBuffer(ColorBufferObject::RGB_FLOAT_16, ColorBufferObject::WRAP_CLAMP_TO_EDGE, ColorBufferObject::FILTER_LINEAR);
 	// another color buffer
 	fbo->AddColorBuffer(ColorBufferObject::RGBA_FLOAT_32, ColorBufferObject::WRAP_CLAMP_TO_EDGE, ColorBufferObject::FILTER_LINEAR, ColorBufferObject::FILTER_NEAREST);
 
-	PrintGLerror("fbo");
+	for (int i = 0; i < 4; ++ i)
+		FrameBufferObject::InitBuffer(fbo, i);
+	
+	PrintGLerror("init fbo");
 }
 
@@ -741,10 +741,8 @@
 
 
-RenderTraverser *CreateTraverser(Camera *cam)
+RenderTraverser *CreateTraverser(PerspectiveCamera *cam)
 {
 	RenderTraverser *tr;
 	
-	bvh->ResetNodeClassifications();
-
 	switch (renderMode)
 	{
@@ -769,5 +767,5 @@
 	tr->SetHierarchy(bvh);
 	tr->SetRenderQueue(renderQueue);
-	tr->SetRenderState(&state);
+	tr->SetRenderState(&renderState);
 	tr->SetUseOptimization(useOptimization);
 	tr->SetUseRenderQueue(useRenderQueue);
@@ -779,9 +777,14 @@
 	tr->SetUseDepthPass((renderMethod == RENDER_DEPTH_PASS) || (renderMethod == RENDER_DEPTH_PASS_DEFERRED));
 	tr->SetRenderQueue(renderQueue);
+	tr->SetShowBounds(showBoundingVolumes);
+
+	bvh->ResetNodeClassifications();
+
 
 	return tr;
 }
 
-
+/** Setup sunlight
+*/
 void SetupLighting()
 {
@@ -800,10 +803,14 @@
 	
 
-	const bool useToneMapping = ((renderMethod == RENDER_DEPTH_PASS_DEFERRED) || (renderMethod == RENDER_DEFERRED)) && useHDR;
+	const bool useHDRValues = 
+		((renderMethod == RENDER_DEPTH_PASS_DEFERRED) || 
+		 (renderMethod == RENDER_DEFERRED)) && useHDR;
+
 
 	Vector3 sunAmbient;
 	Vector3 sunDiffuse;
 
-	preetham->ComputeSunColor(lightDir, sunAmbient, sunDiffuse, !useToneMapping);
+#if 1
+	preetham->ComputeSunColor(lightDir, sunAmbient, sunDiffuse, !useHDRValues);
 
 	ambient[0] = sunAmbient.x;
@@ -811,15 +818,20 @@
 	ambient[2] = sunAmbient.z;
 
-	// no tone mapping => scale
-	if (!useToneMapping)
-	{
-		const float maxComponent = sunDiffuse.MaxComponent();
-		sunDiffuse /= maxComponent;
-	}
-
 	diffuse[0] = sunDiffuse.x;
 	diffuse[1] = sunDiffuse.y;
 	diffuse[2] = sunDiffuse.z;
 
+#else
+	
+	ambient[0] = .2f;
+	ambient[1] = .2f;
+	ambient[2] = .2f;
+
+	diffuse[0] = 1.0f;
+	diffuse[1] = 1.0f;
+	diffuse[2] = 1.0f;
+
+#endif
+
 	glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
 	glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
@@ -836,15 +848,9 @@
 	oldViewProjMat = viewProjMat;
 
-	glMatrixMode(GL_PROJECTION);
-	glLoadIdentity();
-	gluPerspective(fov, winAspectRatio, nearDist, farDist);
-
-	glMatrixMode(GL_MODELVIEW);
-	
-	// set up the camera view
-	camera->SetupCameraView();
-
-		
+	camera->SetupViewProjection();
+
+
 	/////////////////
+	//-- compute view projection matrix and store for later use
 
 	Matrix4x4 matViewing, matProjection;
@@ -853,5 +859,4 @@
 	camera->GetProjectionMatrix(matProjection);
 
-	// store matrix for later use
 	viewProjMat = matViewing * matProjection;
 }
@@ -881,17 +886,23 @@
 
 
-static void ComputeViewVectors(Vector3 &tl, Vector3 &tr, Vector3 &bl, Vector3 &br)
-{
-	Vector3 ftl, ftr, fbl, fbr, ntl, ntr, nbl, nbr;
-
-	camera->ComputePoints(ftl, ftr, fbl, fbr, ntl, ntr, nbl, nbr);
-
-	bl = Normalize(nbl - fbl);
-	br = Normalize(nbr - fbr);
-	tl = Normalize(ntl - ftl);
-	tr = Normalize(ntr - ftr);
-}
-
-
+void KeyStrafe(float shift)
+{
+	Vector3 viewDir = camera->GetDirection();
+	Vector3 pos = camera->GetPosition();
+
+	// the 90 degree rotated view vector 
+	// z zero so we don't move in the vertical
+	Vector3 rVec(viewDir[0], viewDir[1], 0);
+
+	Matrix4x4 rot = RotationZMatrix(M_PI * 0.5f);
+	rVec = rot * rVec;
+	pos += rVec * shift;
+
+	camera->SetPosition(pos);
+}
+
+
+/** Initialize the deferred rendering pass.
+*/
 void InitDeferredRendering()
 {
@@ -901,27 +912,17 @@
 	// multisampling does not work with deferred shading
 	glDisable(GL_MULTISAMPLE_ARB);
-
-	state.SetRenderPassType(RenderState::DEFERRED);
-
-	cgGLEnableProfile(RenderState::sCgVertexProfile);
-	RenderState::sCgMrtVertexProgram->Bind();
-
-	cgGLEnableProfile(RenderState::sCgFragmentProfile);
-	RenderState::sCgMrtFragmentProgram->Bind();
-
-	const Vector3 pos = camera->GetPosition();
-
-
-	// draw to 3 color buffers
-	// a color, normal, and positions buffer
+	renderState.SetRenderTechnique(DEFERRED);
+
+
+	// draw to 3 render targets
 	if (sCurrentMrtSet == 0)
 	{
 		DeferredRenderer::colorBufferIdx = 0;
-		glDrawBuffers(2, mrt);
+		glDrawBuffers(3, mrt);
 	}
 	else 
 	{
 		DeferredRenderer::colorBufferIdx = 3;
-		glDrawBuffers(2, mrt2);
+		glDrawBuffers(3, mrt2);
 	}
 
@@ -930,7 +931,44 @@
 
 
-// the main rendering loop
-void Display() 
+/** the main rendering loop
+*/
+void MainLoop() 
 {	
+#if 1
+	GPUProgramParameters *vtxParams = 
+		buddha->GetShape(0)->GetMaterial()->GetTechnique(1)->GetVertexProgramParameters();
+
+	Matrix4x4 oldTrafo = buddha->GetTransform()->GetMatrix();
+	Vector3 buddhaPos = motionPath->GetCurrentPosition();
+	Matrix4x4 trafo = TranslationMatrix(buddhaPos);
+	
+	buddha->GetTransform()->SetMatrix(trafo);
+
+	/*for (int i = 0; i < 10; ++ i)
+	{
+		SceneEntity *ent = dynamicObjects[i];
+		Vector3 newPos = ent->GetWorldCenter();
+
+		if (GetOrCreateSceneQuery()->CalcIntersection(newPos))
+		{
+			Matrix4x4 mat = TranslationMatrix(newPos - ent->GetCenter());
+			ent->GetTransform()->SetMatrix(mat);
+		}
+	}*/
+
+	Matrix4x4 rotMatrix = RotationZMatrix(M_PI * 1e-3f);
+	dynamicObjects[1]->GetTransform()->MultMatrix(rotMatrix);
+
+
+	/////////////////////////
+	//-- update animations
+	
+	motionPath->Move(0.01f);
+
+#endif
+
+
+	/////////////
+
 	Vector3 oldPos = camera->GetPosition();
 
@@ -947,4 +985,9 @@
 	if (descendKeyPressed)
 		KeyVerticalMotion(-KeyShift());
+	if (leftStrafeKeyPressed)
+		KeyStrafe(KeyShift());
+	if (rightStrafeKeyPressed)
+		KeyStrafe(-KeyShift());
+
 
 	// place view on ground
@@ -958,5 +1001,4 @@
 	
 
-
 	if ((!shadowMap || !shadowTraverser) && (showShadowMap || renderLightView))
 	{
@@ -971,31 +1013,26 @@
 	// bring eye modelview matrix up-to-date
 	SetupEyeView();
-
-	// hack
+	// set frame related parameters for GPU programs
+	GPUProgramParameters::InitFrame(camera, light);
+
+	// hack: store current rendering method and restore later
 	int oldRenderMethod = renderMethod;
-
-	if (renderLightView)
-		renderMethod = RenderState::FIXED;
-
+	// for rendering the light view, we use forward rendering
+	if (renderLightView) renderMethod = FORWARD;
+
+	/// enable vbo vertex array
 	glEnableClientState(GL_VERTEX_ARRAY);
-
 
 	// render with the specified method (forward rendering, forward + depth, deferred)
 	switch (renderMethod)
 	{
-	case RENDER_FIXED:
+	case RENDER_FORWARD:
 	
 		glEnable(GL_MULTISAMPLE_ARB);
-		
-		state.SetRenderPassType(RenderState::FIXED);
-		glEnable(GL_LIGHTING);
-
-		cgGLDisableProfile(RenderState::sCgFragmentProfile);
-		cgGLDisableProfile(RenderState::sCgVertexProfile);
+		renderState.SetRenderTechnique(FORWARD);
+		//glEnable(GL_LIGHTING);
 
 		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
 		glEnableClientState(GL_NORMAL_ARRAY);
-
 		break;
 
@@ -1003,23 +1040,17 @@
 
 		glDisable(GL_MULTISAMPLE_ARB);
-		state.SetUseAlphaToCoverage(false);
-
-		state.SetRenderPassType(RenderState::DEPTH_PASS);
-
-		if (!fbo) InitFBO(); fbo->Bind();
+		renderState.SetUseAlphaToCoverage(false);
+		renderState.SetRenderTechnique(DEPTH_PASS);
+
+		if (!fbo) InitFBO(); 
+		fbo->Bind();
 
 		glDrawBuffers(1, mrt);
 
-		cgGLDisableProfile(RenderState::sCgFragmentProfile);
-		cgGLDisableProfile(RenderState::sCgVertexProfile);
-
 		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
-		// the scene is rendered withouth any shading	
+		// the scene is rendered withouth any shading 
+		// (should be handled by render renderState)
 		glShadeModel(GL_FLAT);
-		glDisable(GL_LIGHTING);
-		glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
-
-
 		break;
 
@@ -1027,21 +1058,14 @@
 
 		glEnable(GL_MULTISAMPLE_ARB);
-
-		cgGLDisableProfile(RenderState::sCgFragmentProfile);
-		cgGLDisableProfile(RenderState::sCgVertexProfile);
-
-		state.SetRenderPassType(RenderState::DEPTH_PASS);
-
-		// the scene is rendered withouth any shading	
+		renderState.SetRenderTechnique(DEPTH_PASS);
+
+		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+		// the scene is rendered withouth any shading 
+		// (should be handled by render renderState)
 		glShadeModel(GL_FLAT);
-		glDisable(GL_LIGHTING);
-	
-		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-		glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
-
-
-		break;
-	
-	case RenderState::DEFERRED:
+		break;
+	
+	case RENDER_DEFERRED:
 
 		if (showShadowMap && !renderLightView)
@@ -1055,18 +1079,15 @@
 		glEnableClientState(GL_NORMAL_ARRAY);
 		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
 		break;
 	}
 
 	glDepthFunc(GL_LESS);
-
 	glDisable(GL_TEXTURE_2D);
 	glDisableClientState(GL_TEXTURE_COORD_ARRAY);
 		
 
-	// reset lod levels for current frame
+	// set proper lod levels for current frame using current eye point
 	LODLevel::InitFrame(camera->GetPosition());
-
-	// set up lights
+	// set up sunlight
 	SetupLighting();
 
@@ -1074,9 +1095,10 @@
 	if (renderLightView)
 	{
-		// change CHC++ set of state variables (must be done for each change of camera because
-		// otherwise the temporal coherency is broken
-		BvhNode::SetCurrentState(1);
+		// change CHC++ set of renderState variables: 
+		// must be done for each change of camera because otherwise 
+		// the temporal coherency is broken
+		BvhNode::SetCurrentState(LIGHT_PASS);
 		shadowMap->RenderShadowView(shadowTraverser, viewProjMat);
-		BvhNode::SetCurrentState(0);
+		BvhNode::SetCurrentState(CAMERA_PASS);
 	}
 	else
@@ -1112,9 +1134,6 @@
 		FrameBufferObject::Release();
 
-		cgGLDisableProfile(RenderState::sCgVertexProfile);
-		cgGLDisableProfile(RenderState::sCgFragmentProfile);
-
-		if (!ssaoShader) ssaoShader = 
-			new DeferredRenderer(texWidth, texHeight, camera, farDist / MAX_DEPTH_CONST);
+		if (!deferredShader) deferredShader = 
+			new DeferredRenderer(texWidth, texHeight, camera);
 		
 		DeferredRenderer::SHADING_METHOD shadingMethod;
@@ -1130,16 +1149,16 @@
 			shadingMethod = DeferredRenderer::DEFAULT;
 
-
-		ssaoShader->SetShadingMethod(shadingMethod);
-		ssaoShader->SetSamplingMethod(samplingMethod);
-		ssaoShader->SetUseTemporalCoherence(useTemporalCoherence);
+		deferredShader->SetShadingMethod(shadingMethod);
+		deferredShader->SetSamplingMethod(samplingMethod);
+		deferredShader->SetUseTemporalCoherence(useTemporalCoherence);
+		deferredShader->SetSortSamples(sortSamples);
 
 		ShadowMap *sm = showShadowMap ? shadowMap : NULL;
-		ssaoShader->Render(fbo, oldViewProjMat, viewProjMat, ssaoTempCohFactor, light, useHDR, sm);
-	}
-
-
-	state.SetRenderPassType(RenderState::FIXED);
-	state.Reset();
+		deferredShader->Render(fbo, ssaoTempCohFactor, light, useHDR, useAntiAliasing, sm);
+	}
+
+
+	renderState.SetRenderTechnique(FORWARD);
+	renderState.Reset();
 
 
@@ -1184,7 +1203,9 @@
 	{
 	case 27:
+		Debug << "camPosition=" << camera->GetPosition().x << " " << camera->GetPosition().y << " " << camera->GetPosition().z << endl;
+		Debug << "camDirection=" << camera->GetDirection().x << " " << camera->GetDirection().y << " " << camera->GetDirection().z << endl;
+
 		CleanUp();
 		exit(0);
-		break;
 	case 32: // space
 		renderMode = (renderMode + 1) % RenderTraverser::NUM_TRAVERSAL_TYPES;
@@ -1250,5 +1271,6 @@
 		//if (ssaoTempCohFactor > 1.0f) ssaoExpFactor = 1.0f;
 		break;
-	case '9':
+	case 'l':
+	case 'L':
 		useLODs = !useLODs;
 		SceneEntity::SetUseLODs(useLODs);
@@ -1292,9 +1314,16 @@
 		downKeyPressed = true;
 		break;
+	case 'j':
+	case 'J':
+		leftStrafeKeyPressed = true;
+		break;
+	case 'k':
+	case 'K':
+		rightStrafeKeyPressed = true;
+		break;
 	case 'r':
 	case 'R':
 		useRenderQueue = !useRenderQueue;
 		traverser->SetUseRenderQueue(useRenderQueue);
-		
 		break;
 	case 'b':
@@ -1303,6 +1332,6 @@
 		traverser->SetUseTightBounds(useTightBounds);
 		break;
-	case 'l':
-	case 'L':
+	case 'v':
+	case 'V':
 		renderLightView = !renderLightView;
 		break;
@@ -1311,4 +1340,11 @@
 		useHDR = !useHDR;
 		break;
+	case 'i':
+	case 'I':
+		useAntiAliasing = !useAntiAliasing;
+		break;
+	case '9':
+		sortSamples = !sortSamples;
+		break;
 	default:
 		return;
@@ -1371,5 +1407,12 @@
 		ascendKeyPressed = false;
 		break;
-	
+	case 'j':
+	case 'J':
+		leftStrafeKeyPressed = false;
+		break;
+	case 'k':
+	case 'K':
+		rightStrafeKeyPressed = false;
+		break;
 	default:
 		return;
@@ -1479,7 +1522,7 @@
 
 
-void Mouse(int button, int state, int x, int y) 
-{
-	if ((button == GLUT_LEFT_BUTTON) && (state == GLUT_DOWN))
+void Mouse(int button, int renderState, int x, int y) 
+{
+	if ((button == GLUT_LEFT_BUTTON) && (renderState == GLUT_DOWN))
 	{
 		xEyeBegin = x;
@@ -1488,5 +1531,5 @@
 		glutMotionFunc(LeftMotion);
 	}
-	else if ((button == GLUT_RIGHT_BUTTON) && (state == GLUT_DOWN))
+	else if ((button == GLUT_RIGHT_BUTTON) && (renderState == GLUT_DOWN))
 	{
 		xEyeBegin = x;
@@ -1499,5 +1542,5 @@
 			glutMotionFunc(RightMotionLight);
 	}
-	else if ((button == GLUT_MIDDLE_BUTTON) && (state == GLUT_DOWN))
+	else if ((button == GLUT_MIDDLE_BUTTON) && (renderState == GLUT_DOWN))
 	{
 		horizontalMotionBegin = x;
@@ -1579,5 +1622,6 @@
 
 
-// strafe
+/** strafe
+*/
 void MiddleMotion(int x, int y) 
 {
@@ -1683,5 +1727,4 @@
 
 	glLoadIdentity();
-	
 	glOrtho(-offs, offs, -offs, offs, 0.0f, box.Size().z * 100.0f); 
 
@@ -1711,5 +1754,5 @@
 	//-- visualization of the occlusion culling
 
-	visualization->Render();
+	visualization->Render(showShadowMap);
 
 	
@@ -1735,5 +1778,5 @@
 	DEL_PTR(perfGraph);
 	DEL_PTR(fbo);
-	DEL_PTR(ssaoShader);
+	DEL_PTR(deferredShader);
 	DEL_PTR(light);
 	DEL_PTR(visCamera);
@@ -1741,16 +1784,11 @@
 	DEL_PTR(shadowMap);
 	DEL_PTR(shadowTraverser);
-	DEL_PTR(RenderState::sCgMrtFragmentProgram);
-	DEL_PTR(RenderState::sCgMrtFragmentTexProgram);
-	DEL_PTR(RenderState::sCgMrtVertexProgram);
-	
+	DEL_PTR(motionPath);
+
 	ResourceManager::DelSingleton();
-	loader = NULL;
-
-	DeferredRenderer::ReleaseCG();
-	SkyPreetham::ReleaseCG();
-
-	if (sCgContext)
-		cgDestroyContext(sCgContext);
+	ShaderManager::DelSingleton();
+
+	resourceManager = NULL;
+	shaderManager = NULL;
 }
 
@@ -1878,5 +1916,4 @@
 
 		glEnable(GL_TEXTURE_2D);
-
 		myfont.Begin();
 
@@ -1884,16 +1921,12 @@
 		{
 			glColor3f(0.0f, 1.0f, 0.0f);
-
 			int i = 0;
 
-			static char *renderMethodStr[] = {"forward", "depth pass + forward", "deferred shading", "depth pass + deferred"};
-	
+			static char *renderMethodStr[] = 
+				{"forward", "depth pass + forward", "deferred shading", "depth pass + deferred"};
 			sprintf(msg[i ++], "multiqueries: %d, tight bounds: %d, render queue: %d", 
-							useMultiQueries, useTightBounds, useRenderQueue);
-
+					useMultiQueries, useTightBounds, useRenderQueue);
 			sprintf(msg[i ++], "render technique: %s, SSAO: %d", renderMethodStr[renderMethod], useAdvancedShading);
-
 			sprintf(msg[i ++], "triangles per virtual leaf: %5d", trianglesPerVirtualLeaf);
-
 			sprintf(msg[i ++], "assumed visible frames: %4d, max batch size: %4d", 
 				assumedVisibleFrames, maxBatchSize);
@@ -1912,5 +1945,5 @@
 			int len = 10;
 			CalcDecimalPoint(objStr, renderedObjects, len);
-			CalcDecimalPoint(totalObjStr, (int)loader->GetNumEntities(), len);
+			CalcDecimalPoint(totalObjStr, (int)resourceManager->GetNumEntities(), len);
 
 			CalcDecimalPoint(triStr, renderedTriangles, len);
@@ -1932,6 +1965,5 @@
 			sprintf(msg[i ++], "traversed: %5d, frustum culled: %5d, query culled: %5d",
 				traversedNodes, frustumCulledNodes, queryCulledNodes);
-
-			sprintf(msg[i ++], "issued queries: %5d, state changes: %5d, render batches: %5d", 
+			sprintf(msg[i ++], "issued queries: %5d, renderState changes: %5d, render batches: %5d", 
 				issuedQueries, stateChanges, numBatches);
 
@@ -1944,5 +1976,5 @@
 		
 		if (!showAlgorithmTime)
-				sprintf(msg[7], "%s:  %6.1f fps", alg_str[renderMode], fps);
+			sprintf(msg[7], "%s:  %6.1f fps", alg_str[renderMode], fps);
 		else
 			sprintf(msg[7], "%s:  %6.1f ms", alg_str[renderMode], rTime);
@@ -1963,17 +1995,14 @@
 void RenderSky()
 {
-	cgGLEnableProfile(RenderState::sCgVertexProfile);
-
 	if ((renderMethod == RENDER_DEFERRED) || (renderMethod == RENDER_DEPTH_PASS_DEFERRED))
-		state.SetRenderPassType(RenderState::DEFERRED);
+		renderState.SetRenderTechnique(DEFERRED);
 
 	const bool useToneMapping = 
 		((renderMethod == RENDER_DEPTH_PASS_DEFERRED) || 
 		 (renderMethod == RENDER_DEFERRED)) && useHDR;
-
-	preetham->RenderSkyDome(-light->GetDirection(), camera, &state, !useToneMapping);
-
-	cgGLDisableProfile(RenderState::sCgVertexProfile);
-	cgGLDisableProfile(RenderState::sCgFragmentProfile);
+	
+	preetham->RenderSkyDome(-light->GetDirection(), camera, &renderState, !useToneMapping);
+	/// once again reset the renderState
+	renderState.Reset();
 }
 
@@ -1986,34 +2015,36 @@
 		if (showShadowMap && !renderLightView)
 		{
-			float minVisibleDist = min(camera->GetFar(), traverser->GetMaxVisibleDistance());
-			RenderShadowMap(minVisibleDist);
+			// usethe maximal visible distance to focus shadow map
+			float maxVisibleDist = min(camera->GetFar(), traverser->GetMaxVisibleDistance());
+			RenderShadowMap(maxVisibleDist);
 		}
-
-		glDisable(GL_LIGHTING);
-		glViewport(0, 0, texWidth, texHeight);
-
+		// initialize deferred rendering
 		InitDeferredRendering();
 	}
 	else
 	{
-		glEnable(GL_LIGHTING);
-		state.SetRenderPassType(RenderState::FIXED);
-	}
-
+		renderState.SetRenderTechnique(FORWARD);
+	}
+
+
+	/////////////////
+	//-- reset gl renderState before the final visible objects pass
+
+	renderState.Reset();
+
+	glEnableClientState(GL_NORMAL_ARRAY);
+	/// switch back to smooth shading
 	glShadeModel(GL_SMOOTH);
-	glEnableClientState(GL_NORMAL_ARRAY);
-
-	// draw all objects that have exactly the same depth as the current sample
-	glDepthFunc(GL_LEQUAL);
-	glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
-
+	/// reset alpha to coverage flag
+	renderState.SetUseAlphaToCoverage(true);
+	// clear color
 	glClear(GL_COLOR_BUFFER_BIT);
-
-	state.SetUseAlphaToCoverage(true);
-	state.Reset();
+	
+	// draw only objects having exactly the same depth as the current sample
+	glDepthFunc(GL_EQUAL);
 
 	//cout << "visible: " << (int)traverser->GetVisibleObjects().size() << endl;
 
-	SceneEntityContainer::const_iterator sit, 
+	SceneEntityContainer::const_iterator sit,
 		sit_end = traverser->GetVisibleObjects().end();
 
@@ -2022,9 +2053,10 @@
 		renderQueue->Enqueue(*sit);
 	}
-
+	/// now render out everything in one giant pass
 	renderQueue->Apply();
 
+	// switch back to standard depth func
 	glDepthFunc(GL_LESS);
-	state.Reset();
+	renderState.Reset();
 
 	PrintGLerror("visibleobjects");
@@ -2032,11 +2064,17 @@
 
 
+SceneQuery *GetOrCreateSceneQuery()
+{
+	if (!sceneQuery)
+		sceneQuery = new SceneQuery(bvh->GetBox(), traverser, &renderState);
+
+	return sceneQuery;
+}
+
+
 void PlaceViewer(const Vector3 &oldPos)
 {
-	if (!sceneQuery)
-		sceneQuery = new SceneQuery(bvh->GetBox(), traverser);
-
 	Vector3 playerPos = camera->GetPosition();
-	bool validIntersect = sceneQuery->CalcIntersection(playerPos);
+	bool validIntersect = GetOrCreateSceneQuery()->CalcIntersection(playerPos);
 
 	if (validIntersect) 
@@ -2050,34 +2088,103 @@
 void RenderShadowMap(float newfar)
 {
-	cgGLDisableProfile(RenderState::sCgFragmentProfile);
-	cgGLDisableProfile(RenderState::sCgVertexProfile);
-
 	glDisableClientState(GL_NORMAL_ARRAY);
-
-	state.SetRenderPassType(RenderState::DEPTH_PASS);
-	state.LockCullFaceEnabled(true);
-	state.SetUseAlphaToCoverage(false);
-
-	// change CHC++ set of state variables 
+	renderState.SetRenderTechnique(DEPTH_PASS);
+	
+	// hack: disable cull face because of alpha textured balconies
+	glDisable(GL_CULL_FACE);
+	renderState.LockCullFaceEnabled(true);
+
+	/// don't use alpha to coverage for the depth map (problems with fbo rendering)
+	renderState.SetUseAlphaToCoverage(false);
+
+	// change CHC++ set of renderState variables 
 	// this must be done for each change of camera because
 	// otherwise the temporal coherency is broken
-	BvhNode::SetCurrentState(1);
-
+	BvhNode::SetCurrentState(LIGHT_PASS);
 	// hack: temporarily change camera far plane
 	camera->SetFar(newfar);
-	glDisable(GL_CULL_FACE);
-	
 	// the scene is rendered withouth any shading	
 	shadowMap->ComputeShadowMap(shadowTraverser, viewProjMat);
 
+	camera->SetFar(farDist);
+
+	renderState.SetUseAlphaToCoverage(true);
+	renderState.LockCullFaceEnabled(false);
 	glEnable(GL_CULL_FACE);
-	camera->SetFar(farDist);
-
-	state.SetUseAlphaToCoverage(true);
-	state.LockCullFaceEnabled(false);
 
 	glEnableClientState(GL_NORMAL_ARRAY);
-
-	// change back state
-	BvhNode::SetCurrentState(0);
-}
+	// change back renderState
+	BvhNode::SetCurrentState(CAMERA_PASS);
+}
+
+
+/** Touch each material once in order to preload the render queue 
+	bucket id of each material
+*/
+void PrepareRenderQueue()
+{
+	for (int i = 0; i < 3; ++ i)
+	{
+		renderState.SetRenderTechnique(i);
+
+		// fill all shapes into the render queue	once so we can establish the buckets
+		ShapeContainer::const_iterator sit, sit_end = (*resourceManager->GetShapes()).end();
+
+		for (sit = (*resourceManager->GetShapes()).begin(); sit != sit_end; ++ sit)
+		{
+			static Transform3 dummy(IdentityMatrix());
+			renderQueue->Enqueue(*sit, NULL);
+		}
+	
+		// just clear queue again
+		renderQueue->Clear();
+	}
+}
+
+
+void LoadModel(const string &model, SceneEntityContainer &entities)
+{
+	const string filename = string(model_path + model);
+
+	cout << "\nloading model " << filename << endl;
+	if (resourceManager->Load(filename, entities))
+		cout << "model " << filename << " successfully loaded" << endl;
+	else
+	{
+		cerr << "loading model " << filename << " failed" << endl;
+		CleanUp();
+		exit(0);
+	}
+}
+
+
+void CreateAnimation()
+{
+	const float radius = 5.0f;
+	const Vector3 center(480.398f, 268.364f, 181.3);
+
+	VertexArray vertices;
+
+	/*for (int i = 0; i < 360; ++ i)
+	{
+		float angle = (float)i * M_PI / 180.0f;
+
+		Vector3 offs = Vector3(cos(angle) * radius, sin(angle) * radius, 0);
+		vertices.push_back(center + offs);
+	}*/
+
+	for (int i = 0; i < 5; ++ i)
+	{
+		Vector3 offs = Vector3(i, 0, 0);
+		vertices.push_back(center + offs);
+	}
+
+	
+	for (int i = 0; i < 5; ++ i)
+	{
+		Vector3 offs = Vector3(4 -i, 0, 0);
+		vertices.push_back(center + offs);
+	}
+
+	motionPath = new MotionPath(vertices);
+}
