Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/chcdemo.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/chcdemo.cpp	(revision 2809)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/chcdemo.cpp	(revision 2810)
@@ -33,19 +33,17 @@
 
 GLuint fbo;
-GLuint depthbuffer;
-GLuint colorbuffer;
-GLuint colorbuffer2;
-GLuint depthTex;
-GLuint colorTex;
-GLuint colorTex2;
-
-GLuint normalTex;
-
-GLuint fbo2;
-GLuint occlusionbuffer;
-GLuint occlusionTex;
-
-int texWidth2 = 512;
-int texHeight2 = 512;
+
+GLuint depthBuffer;
+
+GLuint positionsBuffer;
+GLuint colorsBuffer;
+GLuint normalsBuffer;
+
+GLuint positionsTex;
+GLuint colorsTex;
+GLuint normalsTex;
+
+GLuint noiseTex;
+
 
 /// the renderable scene geometry
@@ -194,28 +192,33 @@
 void GenerateSamples();
 
+void CreateNoiseTex2D();
+
 void ComputeViewVectors(Vector3 &tl, Vector3 &tr, Vector3 &bl, Vector3 &br);
 
-GLenum mrt[] = {GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT};
-
-
-// cg stuff
+GLenum mrt[] = {GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_COLOR_ATTACHMENT2_EXT};
+
+
+/////////
+//-- cg stuff
+
 static CGcontext sCgContext = NULL;
-static CGprogram sCgLinearDepthProgram = NULL;
+static CGprogram sCgMrtVertexProgram = NULL;
 static CGprogram sCgSSAOProgram = NULL;
-static CGprogram sCgTestProgram = NULL;
+static CGprogram sCgMrtFragmentProgram = NULL;
 
 static CGprofile sCgFragmentProfile;
 static CGprofile sCgVertexProfile; 
 
-static CGparameter sTextureParam;
-static CGparameter sSceneTextureParam;
-static CGparameter sNormalTextureParam;
-
-static CGparameter sTexSizeParam; 
+static CGparameter sColorsTexParam;
+static CGparameter sPositionsTexParam;
+static CGparameter sNormalsTexParam;
+static CGparameter sNoiseTexParam;
+
+/*static CGparameter sTexSizeParam; 
 static CGparameter sSamplesParam; 
 static CGparameter sEyeVecParam; 
 static CGparameter sRadiusParam; 
-
-//static CGparameter sPositionParam;
+*/
+static CGparameter sProjectionMatrixParam;
 static CGparameter sModelViewMatrixParam;	
 static CGparameter sMaxDepthParam;
@@ -284,7 +287,8 @@
 	InitExtensions();
 	InitGLstate();
+	
 	//InitRenderTexture();
 	InitFBO();
-
+	
 	LeftMotion(0, 0);
 	MiddleMotion(0, 0);
@@ -317,4 +321,7 @@
 		exit(0);
 	}
+
+	// create noise texture for ssao
+	CreateNoiseTex2D();
 
 
@@ -374,32 +381,32 @@
 	cgGLSetOptimalOptions(sCgVertexProfile);
 
-	sCgLinearDepthProgram = 
+	sCgMrtVertexProgram = 
 		cgCreateProgramFromFile(sCgContext, 
 								CG_SOURCE,
-								"src/lineardepth.cg", 
+								"src/shaders/mrt.cg", 
 								sCgVertexProfile,
-								"main",
+								"vtx",
 								NULL);
 
-	if(sCgLinearDepthProgram != NULL)
-	{
-		cgGLLoadProgram(sCgLinearDepthProgram);
-	
-		sModelViewMatrixParam = cgGetNamedParameter(sCgLinearDepthProgram, "ModelViewProj");
-	}
-
-	sCgTestProgram = 
+	if(sCgMrtVertexProgram != NULL)
+	{
+		cgGLLoadProgram(sCgMrtVertexProgram);
+	
+		sModelViewMatrixParam = cgGetNamedParameter(sCgMrtVertexProgram, "ModelViewProj");
+	}
+
+	sCgMrtFragmentProgram = 
 		cgCreateProgramFromFile(sCgContext, 
 								CG_SOURCE,
-								"src/test2.cg", 
+								"src/shaders/mrt.cg", 
 								sCgFragmentProfile,
-								"main",
+								"frag",
 								NULL);
 
-	if(sCgTestProgram != NULL)
-	{
-		cgGLLoadProgram(sCgTestProgram);
-
-		sMaxDepthParam = cgGetNamedParameter(sCgTestProgram, "maxDepth");
+	if(sCgMrtFragmentProgram != NULL)
+	{
+		cgGLLoadProgram(sCgMrtFragmentProgram);
+
+		sMaxDepthParam = cgGetNamedParameter(sCgMrtFragmentProgram, "maxDepth");
 		cgGLSetParameter1f(sMaxDepthParam, 1.0f / myfar);
 	}
@@ -415,5 +422,5 @@
 		cgCreateProgramFromFile(sCgContext, 
 								CG_SOURCE,
-								"src/ssao.cg", 
+								"src/shaders/deferred.cg", 
 								//"src/test.cg", 
 								sCgFragmentProfile,
@@ -426,8 +433,12 @@
 
 		// we need size of texture for scaling
-		sTextureParam = cgGetNamedParameter(sCgSSAOProgram, "lindepth");  
-		sSceneTextureParam = cgGetNamedParameter(sCgSSAOProgram, "scene");  
-		sNormalTextureParam = cgGetNamedParameter(sCgSSAOProgram, "normal");  
-		sTexSizeParam = cgGetNamedParameter(sCgSSAOProgram, "invTexSize");
+		sPositionsTexParam = cgGetNamedParameter(sCgSSAOProgram, "positions");  
+		sColorsTexParam = cgGetNamedParameter(sCgSSAOProgram, "colors");  
+		sNormalsTexParam = cgGetNamedParameter(sCgSSAOProgram, "normals");  
+		sNoiseTexParam = cgGetNamedParameter(sCgSSAOProgram, "noiseTexture");  
+
+		sProjectionMatrixParam = cgGetNamedParameter(sCgSSAOProgram, "ProjTrafo");
+
+		/*sTexSizeParam = cgGetNamedParameter(sCgSSAOProgram, "invTexSize");
 		sRadiusParam = cgGetNamedParameter(sCgSSAOProgram, "radius");
 		sEyeVecParam = cgGetNamedParameter(sCgSSAOProgram, "eyevec");
@@ -436,5 +447,5 @@
 		cgGLSetParameter1f(sTexSizeParam, 1.0f / (float)texWidth);
 		cgGLSetParameter1f(sRadiusParam, radius);
-		cgGLSetParameterArray3f(sSamplesParam, 0, 32, (const float *)samples);
+		cgGLSetParameterArray3f(sSamplesParam, 0, 32, (const float *)samples);*/
 	}
 	else
@@ -480,22 +491,28 @@
 
 void InitFBO()
-{	
+{
 	glGenFramebuffersEXT(1, &fbo);
 	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
 
-	// create color buffer
+	//////////
+	//-- positions buffer
+
 	int samples = 8;
 
-	glGenRenderbuffersEXT(1, &colorbuffer);
-	//glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA16F_ARB, texWidth, texHeight);
-	glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, GL_FLOAT_RGBA_NV, texWidth, texHeight);
-	glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, colorbuffer);
-	glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, colorbuffer);
-
-	glGenTextures(1, &colorTex);
-	glBindTexture(GL_TEXTURE_2D, colorTex);
+	////////////
+	//-- colors buffer
+
+	glGenRenderbuffersEXT(1, &colorsBuffer);
+	glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, colorsBuffer);
+	glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA16F_ARB, texWidth, texHeight);
+	
+	glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, colorsBuffer);
+	
+	glGenTextures(1, &colorsTex);
+	glBindTexture(GL_TEXTURE_2D, colorsTex);
+
 	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F_ARB,  texWidth, texHeight, 0, GL_RGBA, GL_FLOAT, NULL);
 	glGenerateMipmapEXT(GL_TEXTURE_2D);
-	glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, colorTex, 0);
+	glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, colorsTex, 0);
 
 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
@@ -506,20 +523,44 @@
 
 	PrintFBOStatus(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
-
-
-	glGenRenderbuffersEXT(1, &colorbuffer2);
+	glGenRenderbuffersEXT(1, &positionsBuffer);
+	glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, positionsBuffer);
 	glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA16F_ARB, texWidth, texHeight);
-	glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, colorbuffer2);
-	glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_RENDERBUFFER_EXT, colorbuffer2);
-
-	glGenTextures(1, &colorTex2);
-	glBindTexture(GL_TEXTURE_2D, colorTex2);
+	//glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, GL_RGBA16F_ARB, texWidth, texHeight);
+	
+	glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_RENDERBUFFER_EXT, positionsBuffer);
+
+	glGenTextures(1, &positionsTex);
+	glBindTexture(GL_TEXTURE_2D, positionsTex);
 	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F_ARB,  texWidth, texHeight, 0, GL_RGBA, GL_FLOAT, NULL);
 	glGenerateMipmapEXT(GL_TEXTURE_2D);
-	glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D, colorTex2, 0);
+	glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D, positionsTex, 0);
 
 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
 
+	//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+	//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+	PrintFBOStatus(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
+	
+	
+	////////
+	//-- normals buffer
+
+	glGenRenderbuffersEXT(1, &normalsBuffer);
+	glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, normalsBuffer);
+	glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA8, texWidth, texHeight);
+	
+	glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT2_EXT, GL_RENDERBUFFER_EXT, normalsBuffer);
+
+	glGenTextures(1, &normalsTex);
+	glBindTexture(GL_TEXTURE_2D, normalsTex);
+	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8,  texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+	glGenerateMipmapEXT(GL_TEXTURE_2D);
+	glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT2_EXT, GL_TEXTURE_2D, normalsTex, 0);
+
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+
 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
@@ -527,11 +568,12 @@
 	PrintFBOStatus(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
 
+
 	///////////
-	// create depth buffer
-
-	glGenRenderbuffersEXT(1, &depthbuffer);	
-	glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depthbuffer);
+	//-- create depth buffer
+
+	glGenRenderbuffersEXT(1, &depthBuffer);	
+	glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depthBuffer);
 	glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, texWidth, texHeight);
-	glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depthbuffer);
+	glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depthBuffer);
 
 	
@@ -563,4 +605,5 @@
 
 	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);*/
+	PrintGLerror("fbo");
 }
 
@@ -838,10 +881,10 @@
 
 	cgGLEnableProfile(sCgFragmentProfile);
-	cgGLBindProgram(sCgTestProgram);
+	cgGLBindProgram(sCgMrtFragmentProgram);
 
 	cgGLEnableProfile(sCgVertexProfile);
-	cgGLBindProgram(sCgLinearDepthProgram);
-
-	glDrawBuffers(2, mrt);
+	cgGLBindProgram(sCgMrtVertexProgram);
+
+	glDrawBuffers(3, mrt);
 	
 	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
@@ -866,6 +909,6 @@
 	SetupEyeView();
 
-	Vector3 dir =  camera->GetDirection();
-	cgGLSetParameter3f(sEyeVecParam, dir.x, dir.y, dir.z);
+	Vector3 dir = camera->GetDirection();
+	//cgGLSetParameter3f(sEyeVecParam, dir.x, dir.y, dir.z);
 
 	// set modelview matrix for shaders
@@ -906,4 +949,6 @@
 
 	glPopAttrib();
+
+	cgGLSetStateMatrixParameter(sProjectionMatrixParam, CG_GL_PROJECTION_MATRIX, CG_GL_MATRIX_IDENTITY);
 	
 	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
@@ -1399,6 +1444,6 @@
 	DEL_PTR(renderQueue);
 
-	if (sCgLinearDepthProgram)
-		cgDestroyProgram(sCgLinearDepthProgram);
+	if (sCgMrtVertexProgram)
+		cgDestroyProgram(sCgMrtVertexProgram);
 	if (sCgSSAOProgram)
 		cgDestroyProgram(sCgSSAOProgram);
@@ -1568,11 +1613,10 @@
 
 
-void DisplayRenderTexture2()
-{
-	glEnable(GL_TEXTURE_2D);
-	glBindTexture(GL_TEXTURE_2D, occlusionTex);
-
+void DisplayRenderTexture()
+{
+	glDisable(GL_TEXTURE_2D);
+	//glEnable(GL_TEXTURE_2D);
 	glDisable(GL_LIGHTING);
-
+	//glBindTexture(GL_TEXTURE_2D, noiseTex);
 	glMatrixMode(GL_PROJECTION);
 	glPushMatrix();
@@ -1582,57 +1626,5 @@
 	glPushMatrix();
 	glLoadIdentity();
-	
-	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo2);
-	glPushAttrib(GL_VIEWPORT_BIT);
-	glViewport(0, 0, texWidth2, texHeight2);
-
-	glOrtho(-0.5f, 0.5f, -0.5f, 0.5f, 0, 1);
-
-	//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-	//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-	
-	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
-	glColor3f(1.0f, 1.0f, 1.0f);
-
-	glBegin(GL_QUADS);
-	glTexCoord2f(0, 0); glVertex3f(-1, -1, -0.5f);
-	glTexCoord2f(1, 0); glVertex3f( 1, -1, -0.5f);
-	glTexCoord2f(1, 1); glVertex3f( 1,  1, -0.5f);
-	glTexCoord2f(0, 1); glVertex3f(-1,  1, -0.5f);
-	glEnd();
-
-	glEnable(GL_LIGHTING);
-	glDisable(GL_TEXTURE_2D);
-	
-	glMatrixMode(GL_PROJECTION);
-	glPopMatrix();
-
-	glMatrixMode(GL_MODELVIEW);
-	glPopMatrix();
-
-	glPopAttrib();
-	glBindTexture(GL_TEXTURE_2D, 0);
-
-	PrintGLerror("displaytexture2");
-}
-
-void DisplayRenderTexture()
-{
-	glDisable(GL_TEXTURE_2D);
-	glDisable(GL_LIGHTING);
-
-	glMatrixMode(GL_PROJECTION);
-	glPushMatrix();
-	glLoadIdentity();
-
-	glMatrixMode(GL_MODELVIEW);
-	glPushMatrix();
-	glLoadIdentity();
-	
-	/*glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo2);
-	glPushAttrib(GL_VIEWPORT_BIT);
-	glViewport(0, 0, texWidth2, texHeight2);
-*/
+
 	glOrtho(-0.5f, 0.5f, -0.5f, 0.5f, 0, 1);
 	
@@ -1642,12 +1634,15 @@
 	cgGLBindProgram(sCgSSAOProgram);
 
-	cgGLEnableTextureParameter(sTextureParam);
-	cgGLSetTextureParameter(sTextureParam, colorTex2);
-	
-	cgGLEnableTextureParameter(sSceneTextureParam);
-	cgGLSetTextureParameter(sSceneTextureParam, colorTex);
-	
-	cgGLEnableTextureParameter(sNormalTextureParam);
-	cgGLSetTextureParameter(sNormalTextureParam, normalTex);
+	cgGLEnableTextureParameter(sPositionsTexParam);
+	cgGLSetTextureParameter(sPositionsTexParam, positionsTex);
+	
+	cgGLEnableTextureParameter(sColorsTexParam);
+	cgGLSetTextureParameter(sColorsTexParam, colorsTex);
+	
+	cgGLEnableTextureParameter(sNormalsTexParam);
+	cgGLSetTextureParameter(sNormalsTexParam, normalsTex);
+
+	cgGLEnableTextureParameter(sNoiseTexParam);
+	cgGLSetTextureParameter(sNoiseTexParam, noiseTex);
 
 	Vector3 tl, tr, bl, br;
@@ -1670,6 +1665,9 @@
 	glEnd();
 
-	cgGLDisableTextureParameter(sTextureParam);
-	cgGLDisableTextureParameter(sSceneTextureParam);
+	cgGLDisableTextureParameter(sColorsTexParam);
+	cgGLDisableTextureParameter(sPositionsTexParam);
+	cgGLDisableTextureParameter(sNormalsTexParam);
+	cgGLDisableTextureParameter(sNoiseTexParam);
+
 	cgGLDisableProfile(sCgFragmentProfile);
 	
@@ -1683,9 +1681,6 @@
 	glPopMatrix();
 
-	//glPopAttrib();
-	//glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo2);
-
+	
 	PrintGLerror("displaytexture");
-	//DisplayRenderTexture2();
 }
 
@@ -1735,9 +1730,10 @@
 	cout << "tr: " << tr << endl;
 	cout << "bl: " << bl << endl;
-	cout << "br: " << bl << endl << endl;*/
-}
-
-
-void CreateNormalMap()
+	cout << "br: " << bl << endl << endl;
+	*/
+}
+
+
+void CreateNoiseTex3D()
 {
 	Vector3 *data = new Vector3[texWidth * texHeight];
@@ -1753,10 +1749,92 @@
 
 		data[i] = Vector3(sin(theta) * cos(phi), sin(theta) * sin(phi), cos(theta));
-		data[i] += 1.0f;	
-		data[i] *= 0.5f;
-	}
-
-	glGenTextures(1, &normalTex);
-	glBindTexture(GL_TEXTURE_2D, normalTex);
+		// bring in 0 .. 1 so we can use unsigned byte
+		data[i] = data[i] * 0.5f + 0.5f;
+	}
+
+	glGenTextures(1, &noiseTex);
+	glBindTexture(GL_TEXTURE_2D, noiseTex);
 	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8,  texWidth, texHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
-}
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+
+	glBindTexture(GL_TEXTURE_2D, 0);
+
+	PrintGLerror("noisetexture");
+}
+
+#if 0
+void CreateNoiseTex2D()
+{
+	Vector3 *data = new Vector3[texWidth * texHeight];
+
+	for (int i = 0; i < texWidth * texHeight; ++ i)
+	{
+		// create random samples over sphere
+		const float rx = RandomValue(0, 1);
+		const float theta = 2.0f * acos(sqrt(1.0f - rx));
+
+		data[i] = Vector3(sin(theta), cos(theta), 0);
+
+		//if (i % 10000) cout << "vec: " << data[i] << endl;
+	
+		// bring in 0 .. 1 so we could use unsigned byte
+		data[i] = 1;//data[i] * 0.5f + 0.5f;
+	}
+
+	glGenTextures(1, &noiseTex);
+	glBindTexture(GL_TEXTURE_2D, noiseTex);
+	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F_ARB, texWidth, texHeight, 0, GL_RGB, GL_FLOAT, (float *)data);
+	
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+
+	glBindTexture(GL_TEXTURE_2D, 0);
+
+	PrintGLerror("noisetexture");
+}
+
+#else
+void CreateNoiseTex2D()
+{int w=256;
+int h=256;
+	GLubyte *data = new GLubyte[texWidth * texHeight * 4];
+
+	for (int i = 0; i < texWidth * texHeight * 4; i += 4)
+	{
+		// create random samples over sphere
+		const float rx = RandomValue(0, 1);
+		const float theta = 2.0f * acos(sqrt(1.0f - rx));
+
+		data[i + 0] = (GLubyte)((sin(theta) * 0.5f + 0.5f) * 255.0f);
+		data[i + 1] = (GLubyte)((cos(theta) * 0.5f + 0.5f) * 255.0f);
+		data[i + 2] = 0;
+		data[i + 3] = 255;
+
+		//if (i % 100000) cout << "vec: " << " " << (int)data[i] << " " << (int)data[i + 1] << endl;
+	}
+
+	glEnable(GL_TEXTURE_2D);
+	glGenTextures(1, &noiseTex);
+	glBindTexture(GL_TEXTURE_2D, noiseTex);
+	//glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
+
+	gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, texWidth, texHeight, GL_RGBA, GL_UNSIGNED_BYTE, data);
+	//glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+
+	glBindTexture(GL_TEXTURE_2D, 0);
+
+	glDisable(GL_TEXTURE_2D);
+
+	cout << "created noise texture" << endl;
+	PrintGLerror("noisetexture");
+}
+#endif
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/FragmentSsao.cg
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/FragmentSsao.cg	(revision 2810)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/FragmentSsao.cg	(revision 2810)
@@ -0,0 +1,105 @@
+struct INPUTDATA
+{
+	float2 diffuseTexCoords : TEXCOORD0;
+	
+};
+
+struct OUTPUTDATA
+{
+	float4 color			: COLOR0;
+
+};
+
+#define SAMPLES				24
+
+//kustls magic sample positions
+static const float2 samples[SAMPLES] =
+	{
+		{-0.326212f, -0.405805f},
+		{-0.840144f, -0.07358f},
+		{-0.695914f, 0.457137f},
+		{-0.203345f, 0.620716},
+		{0.96234f, -0.194983f},
+		{0.473434f, -0.480026f},
+		{0.519456, 0.767022f},
+		{0.185461f, -0.893124f},
+		{0.507431f, 0.064425f},
+		{0.89642f, 0.412458f},
+		{-0.32194f, -0.932615f},
+		{-0.791559f, -0.597705f},
+		{0.326212f, 0.405805f},
+		{0.840144f, 0.07358f},
+		{0.695914f, -0.457137f},
+		{0.203345f, -0.620716},
+		{-0.96234f, 0.194983f},
+		{-0.473434f, 0.480026f},
+		{-0.519456, -0.767022f},
+		{-0.185461f, 0.893124f},
+		{-0.507431f, -0.064425f},
+		{-0.89642f, -0.412458f},
+		{0.32194f, 0.932615f},
+		{0.791559f, 0.597705f}
+	};
+	
+//based on kustls shader	
+OUTPUTDATA main(INPUTDATA input,
+				uniform sampler2D positions,
+				uniform sampler2D colors,
+				uniform sampler2D normals,
+				const uniform float4x4 projectionTransformation,
+				uniform sampler2D noiseTexture				
+				)
+{
+			
+	OUTPUTDATA o;
+
+	float4 centerPositionW = tex2D(positions, input.diffuseTexCoords);
+	float3 centerPosition = centerPositionW.xyz;
+	float3 centerNormal = tex2D(normals, input.diffuseTexCoords).xyz;
+	float3 centerColor = tex2D(colors, input.diffuseTexCoords).xyz;
+
+	// Check in a circular area around the current position.
+	// Shoot vectors to the positions there, and check the angle to these positions.
+	// Summing up these angles gives an estimation of the occlusion at the current position.
+
+	float total_ao = 0.0;
+	const float areaSize = 4.0f;
+	const float sampleIntensity = 0.1;
+
+	for (int sample = 0; sample < SAMPLES; sample++)
+	{
+		float2 offset = samples[sample];
+		
+		//sample noisetex; r stores costheta, g stores sintheta
+		float3 randomRotation = tex2D(noiseTexture, input.diffuseTexCoords*10.0f).xyz;
+				
+		float2 offsetTransformed;
+		offsetTransformed.x = randomRotation.r*offset.x - randomRotation.g*offset.y;
+		offsetTransformed.y = randomRotation.g*offset.x + randomRotation.r*offset.y;
+		
+		
+		float2 texcoord = input.diffuseTexCoords + offsetTransformed * areaSize*(1.0f-centerPositionW.w);
+		
+		float3 sample_position = tex2D(positions, texcoord).xyz;
+		
+		float3 vector_to_sample = sample_position - centerPosition;
+		float length_to_sample = length(vector_to_sample);
+		float3 direction_to_sample = vector_to_sample / length_to_sample;
+		
+		// Angle between current normal and direction to sample controls AO intensity.
+		float angle = dot(direction_to_sample, centerNormal);
+		angle = max(angle, 0.0);
+		
+		// Distance between current position and sample position controls AO intensity.
+		float distance_intensity = 2.0 - 2.0f*length_to_sample;
+		distance_intensity = max(distance_intensity, 0.0);
+		
+		total_ao += angle * sampleIntensity * distance_intensity;
+	}
+	
+	
+	o.color.rgb = (1.0f-total_ao)*saturate(centerColor);
+	
+
+	return o;
+}
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/deferred.cg
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/deferred.cg	(revision 2810)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/deferred.cg	(revision 2810)
@@ -0,0 +1,138 @@
+#define SAMPLES	24
+
+// kustls magic sample positions
+static const float2 samples[SAMPLES] =
+{
+  {-0.326212f, -0.405805f},
+  {-0.840144f, -0.07358f},
+  {-0.695914f, 0.457137f},
+  {-0.203345f, 0.620716},
+  {0.96234f, -0.194983f},
+  {0.473434f, -0.480026f},
+  {0.519456, 0.767022f},
+  {0.185461f, -0.893124f},
+  {0.507431f, 0.064425f},
+  {0.89642f, 0.412458f},
+  {-0.32194f, -0.932615f},
+  {-0.791559f, -0.597705f},
+  {0.326212f, 0.405805f},
+  {0.840144f, 0.07358f},
+  {0.695914f, -0.457137f},
+  {0.203345f, -0.620716},
+  {-0.96234f, 0.194983f},
+  {-0.473434f, 0.480026f},
+  {-0.519456, -0.767022f},
+  {-0.185461f, 0.893124f},
+  {-0.507431f, -0.064425f},
+  {-0.89642f, -0.412458f},
+  {0.32194f, 0.932615f},
+  {0.791559f, 0.597705f}
+};
+
+
+struct fragment
+{
+  float4 pos: WPOS; // normalized screen position
+  float4 texCoord: TEXCOORD0; 
+};
+
+
+struct pixel
+{
+  float4 color: COLOR0;
+};
+
+
+//based on kustls shader	
+float ssao(fragment IN,
+	   uniform sampler2D positions,
+	   uniform sampler2D normals,
+	   const uniform float4x4 ProjTrafo,
+	   uniform sampler2D noiseTexture				
+	   )
+{
+  // the current world position
+  float4 centerPositionW = tex2D(positions, IN.texCoord.xy);
+  float3 centerPosition = centerPositionW.xyz;
+
+  // the normal on the current position
+  float3 centerNormal = tex2D(normals, IN.texCoord.xy).xyz * 2.0f - 1.0f;
+
+  // Check in a circular area around the current position.
+  // Shoot vectors to the positions there, and check the angle to these positions.
+  // Summing up these angles gives an estimation of the occlusion at the current position.
+  
+  float total_ao = 0.0;
+
+  //const float areaSize = 4.0f;  
+  const float areaSize = 5e-3f;
+  const float sampleIntensity = 0.1;
+  
+  for (int i = 0; i < SAMPLES; i ++) {
+    float2 offset = samples[i];
+    
+    //sample noisetex; r stores costheta, g stores sintheta
+    float3 noise = tex2D(noiseTexture, IN.texCoord.xy).xyz * 2.0f - 1.0f;
+
+    float2 offsetTransformed;
+    offsetTransformed.x = noise.r*offset.x - noise.g*offset.y;
+    offsetTransformed.y = noise.g*offset.x + noise.r*offset.y;
+		
+    float2 texcoord = IN.texCoord.xy + offsetTransformed * areaSize;// * (1.0f - centerPositionW.w);
+    
+    float3 sample_position = tex2D(positions, texcoord).xyz;
+    
+    float3 vector_to_sample = sample_position - centerPosition;
+    float length_to_sample = length(vector_to_sample);
+    float3 direction_to_sample = vector_to_sample / length_to_sample;
+    
+    // Angle between current normal and direction to sample controls AO intensity.
+    float cos_angle = dot(direction_to_sample, centerNormal);
+    cos_angle = max(cos_angle, 0.0f);
+    
+    // distance between current position and sample position controls AO intensity.
+    const float scale = 5e-1f;
+
+    float distance_intensity = scale * (1.0f - length_to_sample);
+    distance_intensity = max(distance_intensity, 0.0f);
+    
+    total_ao += cos_angle * sampleIntensity * distance_intensity;
+  }
+	
+  return (1.0f - total_ao);
+}
+
+
+pixel main(fragment IN, 
+	   uniform sampler2D colors,
+           uniform sampler2D positions,
+           uniform sampler2D normals,
+	   const uniform float4x4 ProjTrafo,
+	   uniform sampler2D noiseTexture)
+{
+  pixel OUT;
+  float4 lightDir = float4(1.0f, 1.0f, 1.0f, 0.0f);
+  
+  float4 color = tex2D(colors, IN.texCoord.xy);
+  float3 normal = tex2D(normals, IN.texCoord.xy).xyz;
+  // expand normal
+  normal = normal * 2.0f - 1.0f;
+
+  float4 position = tex2D(positions, IN.texCoord.xy);
+
+  float4 ambient = float4(0.3f);
+
+  // float3 L = normalize(lightPosition - position);
+  float3 light = normalize(lightDir.xyz);
+
+  float diffuseLight = max(dot(normal, light), 0.0f);
+  float diffuse = diffuseLight;
+
+  float ao = ssao(IN, positions, normals, ProjTrafo, noiseTexture);
+  OUT.color = ao; //(ambient + diffuse) * color;
+  //OUT.color = (ambient + diffuse) * color;
+  //float4 currentPos = tex2D(positions, IN.texCoord.xy);
+  //OUT.color = currentPos;
+  
+  return OUT;
+}
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/ambient_occlusion.fx
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/ambient_occlusion.fx	(revision 2810)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/ambient_occlusion.fx	(revision 2810)
@@ -0,0 +1,193 @@
+//=======================================================================================
+string description = "Screenspace Ambient Occlusion";
+//=======================================================================================
+
+
+//=======================================================================================
+
+
+#define SAMPLES				24
+
+static const float2 samples[SAMPLES] =
+	{
+		{-0.326212f, -0.405805f},
+		{-0.840144f, -0.07358f},
+		{-0.695914f, 0.457137f},
+		{-0.203345f, 0.620716},
+		{0.96234f, -0.194983f},
+		{0.473434f, -0.480026f},
+		{0.519456, 0.767022f},
+		{0.185461f, -0.893124f},
+		{0.507431f, 0.064425f},
+		{0.89642f, 0.412458f},
+		{-0.32194f, -0.932615f},
+		{-0.791559f, -0.597705f},
+		{0.326212f, 0.405805f},
+		{0.840144f, 0.07358f},
+		{0.695914f, -0.457137f},
+		{0.203345f, -0.620716},
+		{-0.96234f, 0.194983f},
+		{-0.473434f, 0.480026f},
+		{-0.519456, -0.767022f},
+		{-0.185461f, 0.893124f},
+		{-0.507431f, -0.064425f},
+		{-0.89642f, -0.412458f},
+		{0.32194f, 0.932615f},
+		{0.791559f, 0.597705f}
+	};
+	
+	
+//=======================================================================================
+
+
+float4x4 WorldViewProj			: WorldViewProjection;
+float4x4 WorldView				: WorldView;
+
+float4x4 CameraViewProjection;
+
+shared float3 WorldCenterPosition;		// Center positions around this point (usually eye point).
+shared float WorldScale;				// Scale positions to maintain precision.
+
+float AreaSize = 1.0;
+float SampleIntensity = 0.1;
+
+
+//=======================================================================================
+
+
+shared texture positions;
+shared texture diffuse;
+shared texture normals;
+
+sampler PositionsSampler = sampler_state 
+{
+    texture = <positions>;
+    AddressU  = CLAMP;        
+    AddressV  = CLAMP;
+    AddressW  = CLAMP;
+    MINFILTER = POINT;
+    MAGFILTER = POINT;
+    MIPFILTER = NONE;
+};
+
+sampler DiffuseSampler = sampler_state 
+{
+    texture = <diffuse>;
+    AddressU  = CLAMP;        
+    AddressV  = CLAMP;
+    AddressW  = CLAMP;
+    MINFILTER = POINT;
+    MAGFILTER = POINT;
+    MIPFILTER = NONE;
+};
+
+sampler NormalsSampler = sampler_state 
+{
+    texture = <normals>;
+    AddressU  = CLAMP;        
+    AddressV  = CLAMP;
+    AddressW  = CLAMP;
+    MINFILTER = POINT;
+    MAGFILTER = POINT;
+    MIPFILTER = NONE;
+};
+
+
+//=======================================================================================
+
+
+struct VertexInput {
+	float4 position			: POSITION;
+	float2 texcoord			: TEXCOORD0;
+};
+
+struct VertexOutput {
+	float4 position			: POSITION;
+	float2 texcoord			: TEXCOORD0;
+};
+
+struct PixelOutput {
+	float4 color			: COLOR0;
+};
+
+
+//=======================================================================================
+
+
+VertexOutput vs_render(VertexInput IN)
+{
+	VertexOutput OUT;
+
+	OUT.position = float4(IN.position.xyz, 1.0);
+	OUT.texcoord = IN.texcoord;
+	
+	return OUT;
+}
+
+
+//=======================================================================================
+
+
+PixelOutput ps_render(VertexOutput IN)
+{
+	PixelOutput OUT;
+
+	float4 positions = tex2D(PositionsSampler, IN.texcoord);
+	float4 normals = tex2D(NormalsSampler, IN.texcoord);
+	
+	float3 current_position = positions.xyz;
+	float3 current_normal = normals.xyz * 2.0 - 1.0;
+	
+	// Get postprojection Z value to adjust AO area size.
+	float3 worldposition = (positions.xyz / WorldScale) + WorldCenterPosition;
+	float4 projected_position = mul(float4(worldposition.xyz, 1.0), CameraViewProjection);
+	projected_position.xyz /= projected_position.w;
+	
+
+	// Check in a circular area around the current position.
+	// Shoot vectors to the positions there, and check the angle to these positions.
+	// Summing up these angles gives an estimation of the occlusion at the current position.
+
+	float total_ao = 0.0;
+
+	for (float sample = 0.0; sample < SAMPLES; sample++)
+	{
+		float2 offset = samples[sample];
+		float2 texcoord = IN.texcoord + offset * AreaSize * (1.0 - projected_position.z);
+		
+		float3 sample_position = tex2D(PositionsSampler, texcoord).xyz;
+		
+		float3 vector_to_sample = sample_position - current_position;
+		float length_to_sample = length(vector_to_sample);
+		float3 direction_to_sample = vector_to_sample / length_to_sample;
+		length_to_sample /= WorldScale;
+		
+		// Angle between current normal and direction to sample controls AO intensity.
+		float angle = dot(direction_to_sample, current_normal);
+		angle = max(angle, 0.0);
+		
+		// Distance between current position and sample position controls AO intensity.
+		float distance_intensity = 1.0 - length_to_sample * 2.0;
+		distance_intensity = max(distance_intensity, 0.0);
+		
+		total_ao += angle * SampleIntensity * distance_intensity;
+	}
+	
+	
+	OUT.color = float4(0.0, 0.0, 0.0, total_ao);
+	
+	return OUT;
+}
+
+
+//=======================================================================================
+
+
+technique render
+{
+	pass p0
+	{
+		VertexShader = compile vs_3_0 vs_render();
+		PixelShader = compile ps_3_0 ps_render();	
+	}
+}
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/mrt.cg
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/mrt.cg	(revision 2810)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/mrt.cg	(revision 2810)
@@ -0,0 +1,71 @@
+// input
+struct vtxin 
+{
+  float4 position: POSITION;
+  float3 normal: NORMAL;
+  float4 color: COLOR0;
+  float4 texCoord: TEXCOORD0;
+};
+
+// vtx output
+struct vtxout
+{
+  float4 position: POSITION; // eye space
+  float4 texCoord: TEXCOORD0;    
+
+  float4 color: COLOR0;  
+  float4 worldPos: TEXCOORD1; // world position
+  float3 norm: TEXCOORD2;
+};
+
+
+// fragment input
+struct fragin
+{
+  float4 position: POSITION; // eye space
+  float4 texCoord: TEXCOORD0;    
+
+  float4 dummy: WPOS;
+  float4 color: COLOR0;  
+  float4 worldPos: TEXCOORD1; // world position
+  float3 norm: TEXCOORD2;
+};
+
+
+struct pixel
+{
+  float4 col: COLOR0;
+  float4 pos: COLOR1;
+  float3 norm: COLOR2;
+};
+
+
+vtxout vtx(vtxin IN, uniform float4x4 ModelViewProj)
+{
+   vtxout OUT;
+  
+   // transform the vertex position into eye space
+   OUT.position = mul(ModelViewProj, IN.position);
+
+   OUT.color = IN.color;
+
+   OUT.texCoord = IN.texCoord;
+   OUT.worldPos = IN.position;
+   // eye pos with linear depth
+   //OUT.worldPos = OUT.position;
+   OUT.norm = IN.normal;
+
+   return OUT;
+}
+
+
+pixel frag(fragin IN, uniform sampler2D tex, uniform float maxDepth)
+{
+  pixel pix;
+      
+  pix.col = tex2D(tex, IN.texCoord.xy);
+  pix.pos = IN.worldPos * maxDepth;
+  pix.norm = IN.norm * 0.5f + 0.5f;
+
+  return pix;
+}
