Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Texture.cpp
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Texture.cpp	(revision 2865)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Texture.cpp	(revision 3214)
@@ -64,4 +64,18 @@
 
 
+static int GetGlWrapMode(int mode)
+{
+	switch (mode)
+	{
+	case Texture::REPEAT: return GL_REPEAT;
+	case Texture::CLAMP: return GL_CLAMP_TO_EDGE;
+	case Texture::BORDER: return GL_CLAMP_TO_BORDER;
+	default: return GL_CLAMP_TO_EDGE;
+	}
+
+	return GL_CLAMP_TO_EDGE;
+}
+
+
 void Texture::Create()
 {
@@ -75,9 +89,6 @@
 	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 4);
 
-	int glWrapModeS = (mBoundaryModeS == REPEAT) ?  GL_REPEAT : GL_CLAMP_TO_EDGE;
-	int glWrapModeT = (mBoundaryModeT == REPEAT) ?  GL_REPEAT : GL_CLAMP_TO_EDGE;
-
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, glWrapModeS);
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, glWrapModeT);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GetGlWrapMode(mBoundaryModeS));
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GetGlWrapMode(mBoundaryModeT));
 
 	if (mUseMipMap)
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaderenv.h
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaderenv.h	(revision 3212)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaderenv.h	(revision 3214)
@@ -52,4 +52,6 @@
 #define WHITE_LUMINANCE 3e4f
 
+#define TONE_MAPPING_EXPONENTIAL_FACTOR 1e-1f
+
 
 ///////////////////
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Texture.h
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Texture.h	(revision 3212)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Texture.h	(revision 3214)
@@ -19,5 +19,5 @@
 	enum {FORMAT_INVALID, FORMAT_RGB, FORMAT_RGBA};
 	// texture uv modes
-	enum {CLAMP, REPEAT};
+	enum {CLAMP, REPEAT, BORDER};
 
 
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/tonemap.cg
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/tonemap.cg	(revision 3198)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/tonemap.cg	(revision 3214)
@@ -139,8 +139,6 @@
 	//-- exponential smoothing of the tone mapping over time
 
-	const float expFactor = 1e-2f;
-	
 	if (oldLogLum > 1e-3f) // check if loglum from last frame too small (=> tm too bright)
-		OUT.col.w = lerp(oldLogLum, logLumScaled, expFactor);
+		OUT.col.w = lerp(oldLogLum, logLumScaled, TONE_MAPPING_EXPONENTIAL_FACTOR);
 	else
 		OUT.col.w = logLumScaled;
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/lenseFlare.cg
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/lenseFlare.cg	(revision 3213)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/lenseFlare.cg	(revision 3214)
@@ -7,4 +7,22 @@
 
 
+inline float2 ComputeTexCoords(float2 tex, float2 v, float dist, float scale, float distScale)
+{
+	const float2 center = float2(.5f, .5f);
+	const float2 newPos = -v * dist * distScale;
+	//const float2 newPos = v * dist * distScale;
+
+	//return (tex - center - newPos) / scale + newPos + center;
+	return (tex - center) / scale + center + newPos / scale;
+	//return tex / scale - center;// + center + newPos;
+}
+
+
+inline float4 ComputeColor(sampler2D tex, float2 texCoords, float2 v, float dist, float scale, float distScale)
+{
+	const float2 newTexCoords = ComputeTexCoords(texCoords, v, dist, scale, distScale);
+	return tex2Dlod(tex, float4(newTexCoords, 0, 0));
+}
+
 
 float4 LenseFlare(fragment IN, 
@@ -14,4 +32,5 @@
 				  uniform sampler2D flareTex3,
 				  uniform sampler2D flareTex4,
+				  uniform sampler2D flareTex5,
 				  uniform float2 vectorToLight, // vector to current light position
 				  uniform float distanceToLight // distance to current light position
@@ -21,20 +40,24 @@
 	const float4 color = tex2Dlod(colorsTex, float4(IN.texCoords, 0, 0));
 	
-	const float scale = 0.5f;
-	const float center = float2(.5f, .5f);
-	const float2 newPos = vectorToLight * distanceToLight;
+	const float scale = 0.3f;
 
-	const float2 newTexCoords = (IN.texCoords - center) / scale + center - newPos;
+	float4 flare[8];
 
-	const float4 flare1 = tex2Dlod(flareTex1, float4(newTexCoords, 0, 0));
+	flare[0] = ComputeColor(flareTex1, IN.texCoords, vectorToLight, distanceToLight, 1.0f * scale, 1.0f);
+	flare[1] = ComputeColor(flareTex2, IN.texCoords, vectorToLight, distanceToLight, 0.7f * scale, 1.0f / 3.0f);
+	flare[2] = ComputeColor(flareTex3, IN.texCoords, vectorToLight, distanceToLight, 0.25f * scale, 0.7f);
+	flare[3] = ComputeColor(flareTex4, IN.texCoords, vectorToLight, distanceToLight, .7f * scale, -1.0f / 2.0f);
+	flare[4] = ComputeColor(flareTex3, IN.texCoords, vectorToLight, distanceToLight, .4f * scale, -1.0f / 6.0f);
 
-	float4 result;
+	flare[5] = ComputeColor(flareTex5, IN.texCoords, vectorToLight, distanceToLight, .1f * scale, 0.5f);
+	flare[6] = ComputeColor(flareTex5, IN.texCoords, vectorToLight, distanceToLight, .2f * scale, -0.25f);
 
-	result.w = color.w;
+	flare[7] = ComputeColor(flareTex2, IN.texCoords, vectorToLight, distanceToLight, 1.0f * scale, -1.0f);
 
-	//const float factor = 0.9f;
-	//result.xyz = lerp(color.xyz, flare1.xyz, factor);
-	//result.xyz = color.xyz * (1.0f - flare1.w) + flare1.xyz * flare1.w;
-	result.xyz = color.xyz + flare1.xyz;
+	float4 result = color;
+
+	//result.xyz = float3(0);
+	for (int i = 0; i < 8; ++ i)
+		result.xyz += flare[i].xyz;
 
 	return result;
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/RenderState.cpp
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/RenderState.cpp	(revision 3153)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/RenderState.cpp	(revision 3214)
@@ -86,17 +86,4 @@
 
 
-static Technique GetDummyTechnique()
-{
-	Technique tech;
-	tech.Init();
-
-	tech.SetColorWriteEnabled(true);
-	tech.SetLightingEnabled(true);
-	tech.SetDepthWriteEnabled(false);
-	//tech.SetCullFaceEnabled(false);
-
-	return tech;
-}
-
 /** A special technique for occlusion queries. This material
 	has color write, depth write, and lighting turned off
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Polyhedron.cpp
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Polyhedron.cpp	(revision 3021)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Polyhedron.cpp	(revision 3214)
@@ -242,7 +242,6 @@
 
 		float dist = plane.Distance(center);
-		//cout << "dist: " << dist<< endl;
-		if (dist > 0) 
-			return false;
+		
+		if (dist > 0) return false;
 	}
 	return true;
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/DeferredRenderer.h
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/DeferredRenderer.h	(revision 3213)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/DeferredRenderer.h	(revision 3214)
@@ -42,4 +42,5 @@
 				bool useToneMapping,
 				bool useAntiAliasing,
+				bool isLightSourceVisible,
 				ShadowMap *shadowMap = NULL
 				);
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Bvh.cpp
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Bvh.cpp	(revision 3203)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Bvh.cpp	(revision 3214)
@@ -260,6 +260,4 @@
 	// nodes are tested using the subnodes from 3 levels below
 	mMaxDepthForTestingChildren = 3;
-	//mMaxDepthForTestingChildren = 4;
-
 	// the ratio of area between node and subnodes where 
 	// testing the subnodes as proxy is still considered feasable
@@ -268,5 +266,5 @@
 
 	mVboId = -1;
-
+	// bound the maximal depth of the dynamic branch
 	mMaxDepthForDynamicBranch = 10;
 }
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/chcdemo.cpp
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/chcdemo.cpp	(revision 3212)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/chcdemo.cpp	(revision 3214)
@@ -71,4 +71,5 @@
 /// the renderable scene geometry
 SceneEntityContainer sceneEntities;
+/// the dynamic objects in the scene
 SceneEntityContainer dynamicObjects;
 // traverses and renders the hierarchy
@@ -251,4 +252,7 @@
 SceneEntity *buddha = NULL;
 SceneEntity *skyDome = NULL;
+SceneEntity *sunBox = NULL;
+
+GLuint sunQuery = 0;
 
 
@@ -271,4 +275,6 @@
 /// render the objects found visible in the depth pass
 void RenderVisibleObjects();
+
+bool TestSunVisible();
 
 void Begin2D();
@@ -565,4 +571,25 @@
 
 	CreateAnimation();
+
+	//////////////////////////
+	//-- a bounding box representing the sun position
+	//-- in order to test sun visibility
+	Transform3 *trafo = resourceManager->CreateTransform(IdentityMatrix());
+
+	// make it slightly bigger to simulate sun diameter
+	const float size = 25.0f;
+	AxisAlignedBox3 sbox(Vector3(-size), Vector3(size));
+
+	SceneEntityConverter conv;
+
+	// toto clean up material
+	Material *mat = new Material();
+
+	mat->GetTechnique(0)->SetDepthWriteEnabled(false);
+	mat->GetTechnique(0)->SetColorWriteEnabled(false);
+
+	sunBox = conv.ConvertBox(sbox, mat, trafo);
+	
+	glGenQueriesARB(1, &sunQuery);
 
 
@@ -1133,4 +1160,7 @@
 	
 
+	bool sunVisible = TestSunVisible();
+
+
 	///////////////
 	//-- render sky
@@ -1170,5 +1200,5 @@
 
 		ShadowMap *sm = showShadowMap ? shadowMap : NULL;
-		deferredShader->Render(fbo, ssaoTempCohFactor, light, useHDR, useAntiAliasing, sm);
+		deferredShader->Render(fbo, ssaoTempCohFactor, light, useHDR, useAntiAliasing, sunVisible, sm);
 	}
 
@@ -2217,2 +2247,24 @@
 	motionPath = new MotionPath(vertices);
 }
+
+
+bool TestSunVisible()
+{
+	// assume sun is at a far away point along the light vector
+	Vector3 sunPos = light->GetDirection() * -1e3f;
+	sunPos += camera->GetPosition();
+
+	sunBox->GetTransform()->SetMatrix(TranslationMatrix(sunPos));
+
+	glBeginQueryARB(GL_SAMPLES_PASSED_ARB, sunQuery);
+
+	sunBox->Render(&renderState);
+
+	glEndQueryARB(GL_SAMPLES_PASSED_ARB);
+
+	GLuint sampleCount;
+
+	glGetQueryObjectuivARB(sunQuery, GL_QUERY_RESULT_ARB, &sampleCount);
+
+	return (sampleCount > 0);
+}
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/DeferredRenderer.cpp
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/DeferredRenderer.cpp	(revision 3213)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/DeferredRenderer.cpp	(revision 3214)
@@ -79,5 +79,5 @@
 static float ssaoFilterWeights[NUM_SSAO_FILTER_SAMPLES];
 
-static Texture *sHaloTex[4];
+static Texture *sHaloTex[5];
 
 int DeferredRenderer::colorBufferIdx = 0;
@@ -300,12 +300,12 @@
 static void PrepareLenseFlare()
 {
-	string textures[] = {"lens1.jpg", "lens2.jpg", "lens3.jpg", "lens4.jpg"};
-
-	for (int i = 0; i < 4; ++ i)
+	string textures[] = {"flare4.tga", "lens2.jpg", "lens3.jpg", "lens4.jpg", "lens1.jpg"};
+
+	for (int i = 0; i < 5; ++ i)
 	{
 		sHaloTex[i] = new Texture(model_path + textures[i]);
 
-		sHaloTex[i]->SetBoundaryModeS(Texture::CLAMP);
-		sHaloTex[i]->SetBoundaryModeT(Texture::CLAMP);
+		sHaloTex[i]->SetBoundaryModeS(Texture::BORDER);
+		sHaloTex[i]->SetBoundaryModeT(Texture::BORDER);
 
 		sHaloTex[i]->Create();
@@ -501,7 +501,7 @@
 	string lenseFlareParams[] = 
 		{"colorsTex", "flareTex1", "flareTex2", "flareTex3", "flareTex4", 
-		 "vectorToLight", "distanceToLight"};
-
-	sCgLenseFlareProgram->AddParameters(lenseFlareParams, 0, 7);
+		 "flareTex5", "vectorToLight", "distanceToLight"};
+
+	sCgLenseFlareProgram->AddParameters(lenseFlareParams, 0, 8);
 
 
@@ -555,4 +555,5 @@
 							  bool useToneMapping,
 							  bool useAntiAliasing,
+							  bool lightSourceVisible,
 							  ShadowMap *shadowMap
 							  )
@@ -567,6 +568,5 @@
 	if (mShadingMethod != 0)
 	{
-		// downsample fbo buffers
-		PrepareSsao(fbo);
+		PrepareSsao(fbo); // downsample fbo buffers
 	}
 
@@ -584,5 +584,5 @@
 		CombineIllum(fbo);
 		break;
-	default: // DEFAULT
+	default:
 		// do nothing: standard deferred shading
 		break;
@@ -598,5 +598,6 @@
 
 
-	LenseFlare(fbo, light);
+	if (lightSourceVisible)
+		LenseFlare(fbo, light);
 
 	// multisampling is difficult / costly with deferred shading
@@ -1277,15 +1278,19 @@
 	// the sun is a large distance in the reverse light direction
 	// => extrapolate light pos
-	
 	const Vector3 lightPos = light->GetDirection() * -1e3f;
 
-	Vector3 projLightPos = mProjViewMatrix * lightPos * 0.5f + Vector3(0.5f);
-	cout << "lightPos " << projLightPos << endl;
-
-	// check if light is visible in the image
-	if ((projLightPos.x < -0.2f) || (projLightPos.y < -0.2f) ||
-		(projLightPos.x >= 1.2f) || (projLightPos.y >= 1.2f))
+	float w;
+	Vector3 projLightPos = mProjViewMatrix.Transform(w, lightPos, 1.0f);
+	projLightPos /= w;
+	projLightPos = projLightPos * 0.5f + Vector3(0.5f);
+
+	//Vector3 dummy = mProjViewMatrix * lightPos;
+
+	// check if light out of image range
+	/*if ((projLightPos.x < -0.2f) || (projLightPos.y < -0.2f) ||
+		(projLightPos.x >= 1.2f) || (projLightPos.y >= 1.2f) || 
+		(w < .0f))
 		return;
-
+*/
 	// vector to light from screen center in texture space
 	Vector3 vectorToLight = projLightPos - Vector3(0.5f);
@@ -1295,5 +1300,5 @@
 	vectorToLight /= distanceToLight;
 
-	cout << "dist " << distanceToLight << " v " << vectorToLight << endl;
+	//cout << "dist " << distanceToLight << " v " << vectorToLight << endl;
 
 
@@ -1310,4 +1315,5 @@
 	sCgLenseFlareProgram->SetTexture(i ++, sHaloTex[2]->GetId());
 	sCgLenseFlareProgram->SetTexture(i ++, sHaloTex[3]->GetId());
+	sCgLenseFlareProgram->SetTexture(i ++, sHaloTex[4]->GetId());
 	sCgLenseFlareProgram->SetValue2f(i ++, vectorToLight.x, vectorToLight.y);
 	sCgLenseFlareProgram->SetValue1f(i ++, distanceToLight);
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Camera.cpp
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Camera.cpp	(revision 3213)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Camera.cpp	(revision 3214)
@@ -59,5 +59,5 @@
 			if (dist < minDist)
 			{
-				cout << "minDist: " << dist << endl;
+				//cout << "minDist: " << dist << endl;
 				minDist = dist;
 			}
