Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/default.env
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/default.env	(revision 2828)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/default.env	(revision 2829)
@@ -9,5 +9,5 @@
 winWidth=1024
 winHeight=768
-position=483.398f 242.364f 186.078f
+camPosition=483.398f 242.364f 186.078f
 useFullScreen=false
 numSsaoSamples=8
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Camera.h
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Camera.h	(revision 2826)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Camera.h	(revision 2829)
@@ -78,4 +78,7 @@
 	float GetPitch() const { return mPitch; }
 	float GetYaw() const { return mYaw; }
+	/** Sets the camera direction.
+	*/
+	void SetDirection(const Vector3 &direction);
 
 
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/chcdemo.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/chcdemo.cpp	(revision 2828)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/chcdemo.cpp	(revision 2829)
@@ -298,5 +298,5 @@
 
 	env.GetFloatParam(string("keyForwardMotion"), keyForwardMotion);
-	env.GetFloatParam(string("keyForwardMotion"), keyRotation);
+	env.GetFloatParam(string("keyRotation"), keyRotation);
 
 	env.GetIntParam(string("winWidth"), winWidth);
@@ -305,4 +305,20 @@
 	env.GetBoolParam(string("useFullScreen"), useFullScreen);
 
+	//env.GetIntParam(string("numSssaoSamples"), numSsaoSamples);
+
+	Vector3 camPos;
+	env.GetVectorParam(string("camPosition"), camPos);
+
+	cout << "read values: " << endl;
+	cout << "assumedVisibleFrames: " << assumedVisibleFrames << endl; 
+	cout << "maxBatchSize: " << maxBatchSize << endl;
+	cout << "trianglesPerVirtualLeaf: " << trianglesPerVirtualLeaf << endl;
+
+	cout << "keyForwardMotion: " << keyForwardMotion << endl;
+	cout << "keyRotation: " << keyRotation << endl;
+	cout << "winWidth: " << winWidth << endl;
+	cout << "winHeight: " << winHeight << endl;
+	cout << "useFullScreen: " << useFullScreen << endl;
+	cout << "camPosition: " << camPos << endl;
 
 
@@ -312,4 +328,7 @@
 	camera->SetNear(nearDist);
 	
+	camera->Pitch(-M_PI * 0.5);
+	camera->SetPosition(camPos);
+
 	visCamera = new Camera(winWidth, winHeight, fov);
 
@@ -341,8 +360,9 @@
 	glutIgnoreKeyRepeat(true);
 
+	// initialise gl graphics
+
 	InitExtensions();
 	InitGLstate();
 	
-	//InitRenderTexture();
 	InitFBO();
 	
@@ -350,5 +370,5 @@
 	MiddleMotion(0, 0);
 
-	perfGraph = new PerformanceGraph(500);
+	perfGraph = new PerformanceGraph(1000);
 
 	loader = new ResourceManager();
@@ -382,7 +402,4 @@
 	BvhLoader bvhLoader;
 	bvh = bvhLoader.Load(bvh_filename, sceneEntities);
-	//bvh = bvhLoader.Load("data/city/model/city.bvh", sceneEntities);
-
-	myfar = 10.0f * Magnitude(bvh->GetBox().Diagonal());
 
 	if (!bvh)
@@ -393,4 +410,10 @@
 	}
 
+	// set far plane based on scene extent
+	myfar = 10.0f * Magnitude(bvh->GetBox().Diagonal());
+	bvh->SetVirtualLeaves(trianglesPerVirtualLeaf);
+
+	bvh->SetCamera(camera);
+	
 	InitCg();
 
@@ -398,11 +421,7 @@
 	CreateNoiseTex2D();
 
-	bvh->SetCamera(camera);
-
 	// init render traverser
 	ResetTraverser();
 
-	camera->Pitch(-M_PI * 0.5);
-	camera->SetPosition(Vector3(483.398f, 242.364f, 186.078f));
 
 	visualization = new Visualization(bvh, camera, NULL, &state);
@@ -692,5 +711,5 @@
 	glGenTextures(1, &fontTex);
 	glBindTexture(GL_TEXTURE_2D, fontTex);
-	if (!myfont.Create("data/fonts/myfont.glf", fontTex))
+	if (!myfont.Create("data/fonts/verdana.glf", fontTex))
 		return false;
 
@@ -790,4 +809,5 @@
 	glColor3f(1.0f, 1.0f, 1.0f);
 	
+	glEnable(GL_TEXTURE_2D);
 	myfont.Begin();
 
@@ -806,4 +826,5 @@
 		}
 	}
+	glDisable(GL_TEXTURE_2D);
 }
 
@@ -995,4 +1016,6 @@
 		glDrawBuffers(1, mrt);
 
+		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
 		break;
 
@@ -1006,4 +1029,8 @@
 		cgGLDisableProfile(RenderState::sCgVertexProfile);
 	
+		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+		glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
+
 		glDrawBuffers(1, mrt);
 
@@ -1026,8 +1053,9 @@
 		glDrawBuffers(3, mrt);
 
-		break;
-	}
-
-	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+		break;
+	}
+
 
 	glDepthFunc(GL_LESS);
@@ -1056,4 +1084,5 @@
 	if (renderType == RenderState::DEPTH_PASS) 
 	{
+		glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
 		RenderVisibleObjects();
 	}
@@ -1191,6 +1220,6 @@
 			upKeyPressed = true;
 		break;
-	case 'x':
-	case 'X':
+	case 's':
+	case 'S':
 			downKeyPressed = true;
 		break;
@@ -1266,6 +1295,6 @@
 		upKeyPressed = false;
 		break;
-	case 'X':
-	case 'x':
+	case 'S':
+	case 's':
 		downKeyPressed = false;
 		break;
@@ -1389,4 +1418,5 @@
 	else if ((button == GLUT_RIGHT_BUTTON) && (state == GLUT_DOWN))
 	{
+		xEyeBegin = x;
 		yEyeBegin = y;
 		yMotionBegin = y;
@@ -1436,9 +1466,13 @@
 void RightMotion(int x, int y) 
 {
+	float eyeXAngle = 0.2f *  M_PI * (xEyeBegin - x) / 180.0;
 	float eyeYAngle = -0.2f *  M_PI * (yEyeBegin - y) / 180.0;
 
 	camera->Yaw(eyeYAngle);
-
+	camera->Pitch(eyeXAngle);
+
+	xEyeBegin = x;
 	yEyeBegin = y;
+
 	glutPostRedisplay();
 }
@@ -1497,9 +1531,4 @@
 	glLoadIdentity();
 	gluOrtho2D(0, winWidth, 0, winHeight);
-
-	int w = winWidth / 2;
-	int h = winHeight / 2;
-	
-	//glOrtho(-w, w, -h, h, 0, 10);
 
 	glMatrixMode(GL_MODELVIEW);
@@ -1625,10 +1654,13 @@
 
 // this function inserts a dezimal point after each 1000
-void CalcDecimalPoint(string &str, int d)
+void CalcDecimalPoint(string &str, int d, int len)
 {
 	static vector<int> numbers;
 	numbers.clear();
 
-	char hstr[100];
+	static string shortStr;
+	shortStr.clear();
+
+	static char hstr[100];
 
 	while (d != 0)
@@ -1642,5 +1674,5 @@
 	{
 		sprintf(hstr, "%d", numbers.back());
-		str.append(hstr);
+		shortStr.append(hstr);
 	}
 	
@@ -1648,6 +1680,15 @@
 	{
 		sprintf(hstr, ",%03d", numbers[i]);
-		str.append(hstr);
-	}
+		shortStr.append(hstr);
+	}
+
+	int dif = len - (int)shortStr.size();
+
+	for (int i = 0; i < dif; ++ i)
+	{
+		str += " ";
+	}
+
+	str.append(shortStr);
 }
 
@@ -1696,13 +1737,7 @@
 	Begin2D();
 
-	float top_color[3] = {1.0F, 1.0F, 1.0F};
-	float bottom_color[3] = {0.0F, 0.0F, 1.0F};
-
-	glEnable(GL_TEXTURE_2D);
 	glEnable(GL_BLEND);
 	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 
-
-	//DrawFont();
 	if (showHelp)
 	{	
@@ -1711,10 +1746,24 @@
 	else
 	{
-		myfont.Begin();
-
-		glColor3f(0.0f, 1.0f, 0.0f);
-
 		if (showOptions)
 		{
+			glColor4f(0.0f, 0.0f, 0.0f, 0.5f);
+			glRecti(5, winHeight - 95, winWidth * 2 / 3 - 5, winHeight - 5);
+		}
+
+		if (showStatistics)
+		{
+			glColor4f(0.0f, 0.0f, 0.0f, 0.5f);
+			glRecti(5, winHeight - 165, winWidth * 2 / 3 - 5, winHeight - 100);
+		}
+
+		glEnable(GL_TEXTURE_2D);
+
+		myfont.Begin();
+
+		if (showOptions)
+		{
+			glColor3f(0.0f, 1.0f, 0.0f);
+
 			int i = 0;
 
@@ -1732,20 +1781,21 @@
 
 			for (int j = 0; j < 4; ++ j)
-				myfont.DrawString(msg[j], 20.0f, 760 - j * 30);
+				myfont.DrawString(msg[j], 10.0f, winHeight - 5 - j * 20);
 		}
-
-		glColor3f(0.0f, 1.0f, 1.0f);
 
 		if (showStatistics)
 		{
+			glColor3f(1.0f, 1.0f, 0.0f);
+
 			string str;
 			string str2;
 
-			CalcDecimalPoint(str, renderedTriangles);
-			CalcDecimalPoint(str2, bvh->GetBvhStats().mTriangles);
+			int len = 10;
+			CalcDecimalPoint(str, renderedTriangles, len);
+			CalcDecimalPoint(str2, bvh->GetBvhStats().mTriangles, len);
 
 			int i = 4;
 
-			sprintf(msg[i ++], "rendered: %6d nodes (of %6d), %s triangles (of %s)", 
+			sprintf(msg[i ++], "rendered: %6d of %6d nodes, %s of %s triangles", 
 				renderedNodes, bvh->GetNumVirtualNodes(), str.c_str(), str2.c_str()); 
 
@@ -1757,5 +1807,5 @@
 
 			for (int j = 4; j < 7; ++ j)
-				myfont.DrawString(msg[j], 20.0f, 760 - j * 30);
+				myfont.DrawString(msg[j], 10.0f, winHeight - (j + 1) * 20);
 		}
 
@@ -1772,5 +1822,5 @@
 		}
 
-		myfont.DrawString(msg[7], 720.0f, 760.0f);//, top_color, bottom_color);
+		myfont.DrawString(msg[7], 1.3f, 690.0f, 760.0f);//, top_color, bottom_color);
 		
 		//sprintf(msg[8], "algorithm time: %6.1f ms", rTime);
@@ -1832,6 +1882,6 @@
 void DisplayRenderTexture()
 {
+	glDisable(GL_ALPHA_TEST);
 	glDisable(GL_TEXTURE_2D);
-	
 	glDisable(GL_LIGHTING);
 	
@@ -1889,5 +1939,5 @@
 	glBegin(GL_QUADS);
 
-	// slightly larger than screen size in order to hide ambient occlusion errors
+	// note: slightly larger texture hides ambient occlusion error on border but costs resolution
 	//float offs2 = 0.55f;
 	float offs2 = 0.5f;
@@ -1900,19 +1950,10 @@
 	glEnd();
 
+	cgGLDisableTextureParameter(sColorsTexParamSsao);
+	cgGLDisableTextureParameter(sPositionsTexParamSsao);
+	cgGLDisableTextureParameter(sNormalsTexParamSsao);
+	
 	if (useSsao)
-	{
-		cgGLDisableTextureParameter(sColorsTexParamSsao);
-		cgGLDisableTextureParameter(sPositionsTexParamSsao);
-		cgGLDisableTextureParameter(sNormalsTexParamSsao);
-
 		cgGLDisableTextureParameter(sNoiseTexParamSsao);
-		//cgGLDisableTextureParameter(sSamplesParamSsao);
-	}
-	else
-	{
-		cgGLDisableTextureParameter(sColorsTexParam);
-		cgGLDisableTextureParameter(sPositionsTexParam);
-		cgGLDisableTextureParameter(sNormalsTexParam);
-	}
 
 	cgGLDisableProfile(RenderState::sCgFragmentProfile);
@@ -1932,10 +1973,11 @@
 
 
-
 void GenerateSamples()
 {
 	float scale = 1.0f / (float)NUM_SAMPLES;
 
-	// fill an array with uniformly distributed spherical samples
+	////////
+	//-- generate uniformly distributed spherical samples
+
 	for (int i = 0; i < NUM_SAMPLES; ++ i)
 	{
@@ -1949,34 +1991,17 @@
 		Vector3 unit = Vector3(sin(theta) * cos(phi), sin(theta) * sin(phi), cos(theta));
 
-		// project
+		//////
+		//-- we sample in texture space => store 2D component
+
+		// q: project to plane or just drop z?
 		Vector3 proj = unit / (1.0f + fabs(unit.z));
+		//Vector3 proj = unit;
 
 		samples[i + 0] = proj.x;
 		samples[i + 1] = proj.y;
-
-		cout << samples[i] << " " << samples[i + 1] << endl;
-	}
-}
-
-
-/*void GenerateSamples()
-{
-	float scale = 1.0f / (float)NUM_SAMPLES;
-
-	// fill an array with uniformly distributed spherical samples
-	for (int i = 0; i < NUM_SAMPLES; ++ i)
-	{
-		// create stratified samples over sphere
-		const float rx = ((float)i + RandomValue(0, 1)) * scale;
-
-		const float theta = 2.0f * acos(sqrt(1.0f - rx));
-		
-		samples[i + 0] = cos(theta);
-		samples[i + 1] = sin(theta);
-
-		cout << samples[i] << " " << samples[i + 1] << endl;
-	}
-}
-*/
+		//cout << samples[i] << " " << samples[i + 1] << endl;
+	}
+}
+
 
 void ComputeViewVectors(Vector3 &tl, Vector3 &tr, Vector3 &bl, Vector3 &br)
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Environment.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Environment.cpp	(revision 2828)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Environment.cpp	(revision 2829)
@@ -58,9 +58,10 @@
 		return false;
 	
+	// parse vector values
 	Tokenize((*it).second, tokens);
 
-	val.x = (float)atof(tokens[1].c_str());
-	val.y = (float)atof(tokens[2].c_str());
-	val.z = (float)atof(tokens[3].c_str());
+	val.x = (float)atof(tokens[0].c_str());
+	val.y = (float)atof(tokens[1].c_str());
+	val.z = (float)atof(tokens[2].c_str());
 
 	return true;
@@ -78,4 +79,8 @@
 	while (fgets(str, 256, file) != NULL)
 	{
+		// this line is empty or a comment
+		if ((strlen(str) <= 1) || (str[0] == '#'))
+			continue;
+
 		static vector<string> tokens;
 		tokens.clear();
@@ -83,8 +88,6 @@
 		Tokenize(str, tokens, "=");
 
-		// this line is a comment
-		if (tokens[0][0] == '#')
-			continue;
-
+		if (tokens.size() == 1)
+			cerr << "parsing failed at: " << tokens[0] << endl;
 		// store parameter
 		mParams[tokens[0]] = tokens[1];
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/deferred.cg
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/deferred.cg	(revision 2826)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/deferred.cg	(revision 2829)
@@ -1,2 +1,6 @@
+////////////////////
+// Screen Spaced Ambient Occlusion shader
+// mainly based on Kustls shader
+
 #define NUM_SAMPLES 8
 #define SAMPLE_INTENSITY 0.5f
@@ -180,8 +184,6 @@
   float ao = ssao(IN, positions, noiseTexture, samples, normal);
   
-  //OUT.color = tex2D(positions, IN.texCoord.xy);
-  //OUT.color = ao;
-  //OUT.color = col;
-  OUT.color = ao * col;
+   //OUT.color = ao;
+   OUT.color = ao * col; 
 
   return OUT;
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/PerformanceGraph.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/PerformanceGraph.cpp	(revision 2828)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/PerformanceGraph.cpp	(revision 2829)
@@ -67,6 +67,6 @@
 	glLoadIdentity();
 	
-	glTranslatef(0.68f, 0.68f, 0.0f);
-	glScalef(0.3f, 0.3f, 1.0f);
+	glTranslatef(0.668f, 0.668f, 0.0f);
+	glScalef(0.33f, 0.33f, 1.0f);
 
 	DrawBackGround();
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Camera.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Camera.cpp	(revision 2806)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Camera.cpp	(revision 2829)
@@ -182,5 +182,5 @@
 	const Vector3 fc = mPosition + view * z_far; 
 	
-	const Vector3 up = GetUpVector();
+	const Vector3 up = -GetUpVector();
 
 	const Vector3 right = GetRightVector();
@@ -218,13 +218,4 @@
 	mYaw += angle;
 	CalculateFromPitchAndYaw();
-	/*
-	Matrix4x4 viewOrientation(mRight, mUp, mDirection);
-	Matrix4x4 rot = RotationYMatrix(angle);
-
-	viewOrientation = viewOrientation * rot;
-
-	mDirection = Vector3(viewOrientation.x[2][0], viewOrientation.x[2][1], viewOrientation.x[2][2]);
-	mRight =     Vector3(viewOrientation.x[0][0], viewOrientation.x[0][1], viewOrientation.x[0][2]);
-	mUp =        Vector3(viewOrientation.x[1][0], viewOrientation.x[1][1], viewOrientation.x[1][2]);*/
 }
 
@@ -237,4 +228,16 @@
 
 
+void Camera::SetDirection(const Vector3 &direction)
+{
+	Vector3 h1 = direction; h1.z = 0; h1.Normalize();
+	Vector3 h2 = direction; h1.x = 0; h2.Normalize();
+
+	mYaw = acos(DotProd(h1, Vector3(0, 1, 0)));
+	mPitch = acos(DotProd(h2, Vector3(0, 1, 0)));
+
+	CalculateFromPitchAndYaw();
+}
+
+
 void Camera::CalculateFromPitchAndYaw()
 {
