Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/WalkThroughRecorder.cpp
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/WalkThroughRecorder.cpp	(revision 3211)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/WalkThroughRecorder.cpp	(revision 3219)
@@ -1,5 +1,6 @@
 #include "WalkThroughRecorder.h"
 #include "Camera.h"
-
+#include "Vector3.h"
+#include <sstream>
 
 using namespace std;
@@ -9,21 +10,45 @@
 {
 
-WalkThroughRecorder::WalkThroughRecorder(const std::string &filename)
-{}
+
+WalkThroughRecorder::WalkThroughRecorder(const std::string &filename):
+mFile(filename.c_str())
+{
+}
 
 
 void WalkThroughRecorder::WriteFrame(Camera *cam)
 {
-	mFile << cam->GetDirection() << "" << cam->GetPosition() << endl;
+	FrameInfo info(cam->GetPosition(), cam->GetDirection());
+	mFile << info << endl;
 }
 
 
-WalkThroughPlayer::WalkThroughPlayer(const std::string &filename)
-{}
+WalkThroughPlayer::WalkThroughPlayer(const std::string &filename):
+mFrame(0)
+{
+	ifstream file(filename.c_str());
+	FrameInfo info;
+	int i=0;
+
+	std::string token;
+
+	while(std::getline(file, token)) 
+	{
+		std::stringstream line(token);
+
+		line >> info;
+		mFrameInfos.push_back(info);
+	}
+}
 
 
-void WalkThroughPlayer::ReadNextFrame(Camera *cam)
+bool WalkThroughPlayer::ReadNextFrame(Camera *cam)
 {
-	//mFile >> cam->GetDirection() >> "" >> cam->GetPosition() << endl;
+	cam->SetDirection(mFrameInfos[mFrame].mDirection);
+	cam->SetPosition(mFrameInfos[mFrame].mPosition);
+
+	mFrame = (mFrame + 1) % (int)mFrameInfos.size();
+
+	return mFrame != 0;
 }
 
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Vector3.h
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Vector3.h	(revision 2920)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Vector3.h	(revision 3219)
@@ -514,4 +514,5 @@
 	// read "(x, y, z)"
 	return s >> a >> A.x >> a >> A.y >> a >> A.z >> a;
+	//return s >> A.x >> A.y >> A.z;
 }
 
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SceneQuery.cpp
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SceneQuery.cpp	(revision 3103)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SceneQuery.cpp	(revision 3219)
@@ -91,4 +91,6 @@
 	}
 
+	ilEnable(IL_FILE_OVERWRITE);
+
 	if (!ilSaveImage(filename))
 	{
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/DeferredRenderer.h
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/DeferredRenderer.h	(revision 3216)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/DeferredRenderer.h	(revision 3219)
@@ -83,4 +83,8 @@
 	*/
 	void SetUseTemporalCoherence(bool temporal);
+	/** if set to something other than -1 the current frame is stored on disc
+		using the specified frame number
+	*/
+	void SetSaveFrame(int frameNumber);
 
 
@@ -111,6 +115,11 @@
 	void CombineSsao(FrameBufferObject *fbo);
 	void CombineIllum(FrameBufferObject *fbo);
-
-	void AntiAliasing(FrameBufferObject *fbo, DirectionalLight *light);
+	/** Does some basic antialiasing (searches for edges using a edge detector,
+		smoothes these edges.
+		This function is usually the last function in the pipeline,
+		so one can specify if the frame should be put out directly or stored to 
+		another texture.
+	*/
+	void AntiAliasing(FrameBufferObject *fbo, DirectionalLight *light, bool displayFrame = true);
 	/** Downsample buffer of fbo to buffer of downSampleFbo. The downSampleFbo must have half the
 		resolution of fbo.
@@ -144,4 +153,6 @@
 	void PrepareSsaoFilter();
 
+	void SaveFrame(FrameBufferObject *fbo);
+
 
 	////////////
@@ -189,4 +200,6 @@
 
 	int mSunVisiblePixels;
+
+	int mSavedFrameNumber;
 };
 
@@ -194,3 +207,3 @@
 } // namespace 
 
-#endif // _SsaoShader_H__
+#endif // _SSAOSHADER_H__
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ShadowMapping.cpp
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ShadowMapping.cpp	(revision 3068)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ShadowMapping.cpp	(revision 3219)
@@ -101,4 +101,5 @@
 	}
 
+	ilEnable(IL_FILE_OVERWRITE);
 	if (!ilSaveImage(filename))
 	{
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/chcdemo.cpp
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/chcdemo.cpp	(revision 3216)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/chcdemo.cpp	(revision 3219)
@@ -56,4 +56,5 @@
 #include "ShaderProgram.h"
 #include "Shape.h"
+#include "WalkThroughRecorder.h"
 
 
@@ -112,4 +113,17 @@
 bool ssaoUseFullResolution = false;
 
+/// store the frames as tga
+bool recordFrames = false;
+/// record the taken path
+bool recordPath = false;
+/// replays the recorded path
+bool replayPath = false;
+
+int currentReplayFrame = -1;
+
+/// the walkThroughRecorder
+WalkThroughRecorder *walkThroughRecorder = NULL;
+WalkThroughPlayer *walkThroughPlayer = NULL;
+
 
 /// the technique used for rendering
@@ -581,7 +595,8 @@
 	CreateAnimation();
 
+
 	//////////////////////////
-	//-- a bounding box representing the sun position
-	//-- in order to test sun visibility
+	//-- a bounding box representing the sun pos in order to test visibility
+
 	Transform3 *trafo = resourceManager->CreateTransform(IdentityMatrix());
 
@@ -653,6 +668,8 @@
 
 	for (int i = 0; i < 4; ++ i)
+	{
 		FrameBufferObject::InitBuffer(fbo, i);
-	
+	}
+
 	PrintGLerror("init fbo");
 }
@@ -987,5 +1004,5 @@
 void MainLoop() 
 {	
-#if 1
+#if TODO
 	GPUProgramParameters *vtxParams = 
 		buddha->GetShape(0)->GetMaterial()->GetTechnique(1)->GetVertexProgramParameters();
@@ -1023,5 +1040,6 @@
 	/////////////
 
-	Vector3 oldPos = camera->GetPosition();
+	static Vector3 oldPos = camera->GetPosition();
+	static Vector3 oldDir = camera->GetDirection();
 
 	if (leftKeyPressed)
@@ -1052,4 +1070,18 @@
 	}
 	
+	// don't allow replay on record
+	if (replayPath && !recordPath)
+	{
+		if (!walkThroughPlayer)
+			walkThroughPlayer = new WalkThroughPlayer("frames.log");
+		
+		++ currentReplayFrame;
+
+		if (!walkThroughPlayer->ReadNextFrame(camera)) 
+		{
+			currentReplayFrame = -1;
+			replayPath = false;
+		}
+	}
 
 	if ((!shadowMap || !shadowTraverser) && (showShadowMap || renderLightView))
@@ -1065,6 +1097,19 @@
 	// bring eye modelview matrix up-to-date
 	SetupEyeView();
+	
 	// set frame related parameters for GPU programs
 	GPUProgramParameters::InitFrame(camera, light);
+
+	if (recordPath)
+	{
+		if (!walkThroughRecorder)
+			walkThroughRecorder = new WalkThroughRecorder("frames.log");
+		
+		if ((Distance(oldPos, camera->GetPosition()) > 1e-6f) ||
+			(DotProd(oldDir, camera->GetDirection()) < 1.0f - 1e-6f))
+		{
+			walkThroughRecorder->WriteFrame(camera);
+		}
+	}
 
 	// hack: store current rendering method and restore later
@@ -1216,4 +1261,5 @@
 		deferredShader->SetUseTemporalCoherence(useTemporalCoherence);
 		deferredShader->SetSortSamples(sortSamples);
+		deferredShader->SetSaveFrame((recordFrames && replayPath) ? -1 : currentReplayFrame);
 
 		ShadowMap *sm = showShadowMap ? shadowMap : NULL;
@@ -1257,8 +1303,11 @@
 
 	glutSwapBuffers();
-}
-
-
-#pragma warning( disable : 4100 )
+
+	oldPos = camera->GetPosition();
+	oldDir = camera->GetDirection();
+}
+
+
+#pragma warning(disable : 4100)
 void KeyBoard(unsigned char c, int x, int y) 
 {
@@ -1359,28 +1408,5 @@
 		cout << "new ssao filter radius: " << ssaoFilterRadius << endl;
 		break;
-	case 'l':
-	case 'L':
-		useLODs = !useLODs;
-		SceneEntity::SetUseLODs(useLODs);
-		cout << "using LODs: " << useLODs << endl;
-		break;
-	case 'P':
-	case 'p':
-		samplingMethod = DeferredRenderer::SAMPLING_METHOD((samplingMethod + 1) % 3);
-		cout << "ssao sampling method: " << samplingMethod << endl;
-		break;
-	case 'Y':
-	case 'y':
-		showShadowMap = !showShadowMap;
-		break;
-	case 'g':
-	case 'G':
-		useGlobIllum = !useGlobIllum;
-		break;
-	case 't':
-	case 'T':
-		useTemporalCoherence = !useTemporalCoherence;
-		break;
-/*	case 'o':
+	/*	case 'o':
 	case 'O':
 		useOptimization = !useOptimization;
@@ -1389,4 +1415,27 @@
 		traverser->SetUseOptimization(useOptimization);
 		break;*/
+	case 'l':
+	case 'L':
+		useLODs = !useLODs;
+		SceneEntity::SetUseLODs(useLODs);
+		cout << "using LODs: " << useLODs << endl;
+		break;
+	case 'P':
+	case 'p':
+		samplingMethod = DeferredRenderer::SAMPLING_METHOD((samplingMethod + 1) % 3);
+		cout << "ssao sampling method: " << samplingMethod << endl;
+		break;
+	case 'Y':
+	case 'y':
+		showShadowMap = !showShadowMap;
+		break;
+	case 'g':
+	case 'G':
+		useGlobIllum = !useGlobIllum;
+		break;
+	case 't':
+	case 'T':
+		useTemporalCoherence = !useTemporalCoherence;
+		break;
 	case 'a':
 	case 'A':
@@ -1439,5 +1488,8 @@
 		useLenseFlare = !useLenseFlare;
 		break;
-	
+	case 'u':
+	case 'U':
+		moveLight = !moveLight;
+		break;
 	default:
 		return;
@@ -1550,5 +1602,4 @@
 	case GLUT_KEY_F8:
 		useAdvancedShading = !useAdvancedShading;
-
 		break;
 	case GLUT_KEY_F9:
@@ -1556,5 +1607,39 @@
 		break;
 	case GLUT_KEY_F10:
-		moveLight = !moveLight;
+		replayPath = !replayPath;
+
+		if (replayPath)
+		{
+			cout << "replaying path" << endl;
+			currentReplayFrame = -1;
+		}
+		else
+		{
+			cout << "finished replaying path" << endl;
+		}
+
+		break;
+	case GLUT_KEY_F11:
+		recordPath = !recordPath;
+		
+		if (recordPath)
+		{
+			cout << "recording path" << endl;
+		}
+		else
+		{
+			cout << "finished recording path" << endl;
+			// start over with new frame recording next time
+			DEL_PTR(walkThroughRecorder);
+		}
+
+		break;
+	case GLUT_KEY_F12:
+		recordFrames = !recordFrames;
+
+		if (recordFrames)
+			cout << "recording frames on replaying" << endl;
+		else
+			cout << "finished recording frames on replaying" << endl;
 		break;
 	case GLUT_KEY_LEFT:
@@ -1878,4 +1963,6 @@
 	DEL_PTR(shadowTraverser);
 	DEL_PTR(motionPath);
+	DEL_PTR(walkThroughRecorder);
+	DEL_PTR(walkThroughPlayer);
 
 	ResourceManager::DelSingleton();
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/DeferredRenderer.cpp
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/DeferredRenderer.cpp	(revision 3216)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/DeferredRenderer.cpp	(revision 3219)
@@ -332,5 +332,6 @@
 mSsaoFilterRadius(12.0f),
 mSampleIntensity(0.2f),
-mSunVisiblePixels(0)
+mSunVisiblePixels(0),
+mSavedFrameNumber(-1)
 {
 	///////////
@@ -590,8 +591,17 @@
 	LenseFlare(fbo, light);
 
+	const bool saveFrame = (mSavedFrameNumber != -1);
+	const bool displayAfterAA = !saveFrame;
+
 	// multisampling is difficult / costly with deferred shading
 	// at least do some edge blurring 
-	if (useAntiAliasing) AntiAliasing(fbo, light); else 
-	Output(fbo); // just output the latest buffer
+	if (useAntiAliasing) AntiAliasing(fbo, light, displayAfterAA); 
+	
+	/// store the current frame
+	if (saveFrame) SaveFrame(fbo);
+
+	// if it hasn't been done yet => just output the latest buffer
+	if (!useAntiAliasing || !displayAfterAA)
+		Output(fbo); 
 
 	glEnable(GL_LIGHTING);
@@ -795,5 +805,7 @@
 
 
-void DeferredRenderer::AntiAliasing(FrameBufferObject *fbo, DirectionalLight *light)
+void DeferredRenderer::AntiAliasing(FrameBufferObject *fbo, 
+									DirectionalLight *light, 
+									bool displayFrame)
 {
 	ColorBufferObject *colorBuffer = fbo->GetColorBuffer(colorBufferIdx);
@@ -802,7 +814,9 @@
 
 	// read the second buffer, write to the first buffer
-	//FlipFbos(fbo);
-	// end of the pipeline => just draw image to screen
-	FrameBufferObject::Release();
+	if (!displayFrame)
+		FlipFbos(fbo);
+	else
+		// end of the pipeline => just draw image to screen
+		FrameBufferObject::Release();
 
 	// the neighbouring texels
@@ -1292,4 +1306,53 @@
 
 
+void DeferredRenderer::SaveFrame(FrameBufferObject *fbo)
+{
+	ColorBufferObject *colorBuffer = fbo->GetColorBuffer(colorBufferIdx);
+	GLuint colorsTex = colorBuffer->GetTexture();
+
+	GLubyte *data = new GLubyte[mWidth * mHeight * 4];
+
+	// grab texture data
+	glEnable(GL_TEXTURE_2D);
+	glBindTexture(GL_TEXTURE_2D, colorsTex);
+	glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
+
+	glBindTexture(GL_TEXTURE_2D, 0);
+	glDisable(GL_TEXTURE_2D);
+
+	/////////////////
+
+	startil();
+
+	static char imageName[200];
+	sprintf(imageName, "myframe%05d.bmp", mSavedFrameNumber);
+
+	ILstring fileName = ILstring(imageName);
+	ilRegisterType(IL_FLOAT);
+
+	const int depth = 1;
+	const int bpp = 4;
+
+	if (!ilTexImage(mWidth, mHeight, depth, bpp, IL_RGBA, IL_UNSIGNED_BYTE, data))
+	{
+		cerr << "IL error " << ilGetError() << endl;
+		stopil();
+		return;
+	}
+
+	ilEnable(IL_FILE_OVERWRITE);
+
+	if (!ilSaveImage(fileName))
+	{
+		cerr << "TGA write error " << ilGetError() << endl;
+	}
+
+	delete [] data;
+
+	stopil();
+
+	PrintGLerror("Store frame");
+}
+
 
 void DeferredRenderer::SetUseTemporalCoherence(bool temporal)
@@ -1359,4 +1422,9 @@
 
 
+void DeferredRenderer::SetSaveFrame(int frameNumber)
+{
+	mSavedFrameNumber = frameNumber;
+}
+
 
 } // namespace
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/WalkThroughRecorder.h
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/WalkThroughRecorder.h	(revision 3210)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/WalkThroughRecorder.h	(revision 3219)
@@ -4,4 +4,6 @@
 #include "common.h"
 #include <fstream>
+#include "Vector3.h"
+
 
 namespace CHCDemoEngine
@@ -9,4 +11,37 @@
 
 class Camera;
+
+struct FrameInfo
+{
+	FrameInfo(const Vector3 &pos, const Vector3 &dir):
+	mPosition(pos), mDirection(dir)
+	{}
+
+	FrameInfo() {}
+
+
+	/////////////
+
+	Vector3 mPosition;
+	Vector3 mDirection;
+
+	friend std::ostream& operator<< (std::ostream &s, const FrameInfo &A);
+	friend std::istream& operator>> (std::istream &s, FrameInfo &A);
+};
+
+
+// Overload << operator for C++-style output
+inline std::ostream& operator<< (std::ostream &s, const FrameInfo &A)
+{
+	return s << A.mPosition << " " << A.mDirection;
+}
+
+
+// Overload >> operator for C++-style input
+inline std::istream& operator>> (std::istream &s, FrameInfo &A)
+{
+	return s >> A.mPosition >> A.mDirection;
+}
+
 
 
@@ -22,8 +57,5 @@
 	*/
 	void WriteFrame(Camera *cam);
-	/** Reads next frame
-	*/
-	void ReadNextFrame(Camera *cam);
-
+	
 protected:
 
@@ -39,11 +71,14 @@
 	*/
 	WalkThroughPlayer(const std::string &filename);
-	/** Reads next frame
+	/** Reads next frame. returns false if end of recorded frames is reached.
 	*/
-	void ReadNextFrame(Camera *cam);
+	bool ReadNextFrame(Camera *cam);
+
 
 protected:
 
-	std::ifstream mFile;
+	std::vector<FrameInfo> mFrameInfos;
+
+	int mFrame;
 };
 
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/toto.txt
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/toto.txt	(revision 3212)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/toto.txt	(revision 3219)
@@ -113,5 +113,5 @@
 adaptive number of samples instead of size?
 2) fix color bleeding
-3) fix ssao2 so that ssao contribution stays constant
+3) fix ssao2 so that ssao contribution stays constant for both methods
 4) find physical expressions for constants in ssao
 5) retry normal discontinuity for ssao filter
@@ -133,2 +133,16 @@
 sun disc
 environment lighting
+
+1) antialiasing very slow: try separable filter and one direction at a time
+2) try cross filter for ssao without tempcoh
+3) fix model directory => clean up structure (city/model => models ?)
+4) fix namespaces: one main namespace for core functions + math functions?
+   one util namespace
+
+5) clean up hacks: 
+
+normalmapping
+render target flipflopping for tone mapping
+scenequery
+
+fix walk speed
