Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/FrameBufferObject.cpp
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/FrameBufferObject.cpp	(revision 2859)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/FrameBufferObject.cpp	(revision 2861)
@@ -9,4 +9,5 @@
 {
 
+GLenum color_attachment[] = {GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_COLOR_ATTACHMENT2_EXT, GL_COLOR_ATTACHMENT3_EXT};
 
 void PrintFBOStatus(GLenum status)
@@ -15,5 +16,5 @@
 	{
 	case GL_FRAMEBUFFER_COMPLETE_EXT:
-		cout << "frame buffer object created successfully" << endl;
+		cout << "frame buffer object complete" << endl;
 		break;
 	case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
@@ -45,20 +46,38 @@
 
 ColorBufferObject::ColorBufferObject(int w, int h, 
-									 FORMAT c, 
+									 FORMAT format, 
 									 WRAP_TYPE wrapType, 
 									 FILTER_TYPE filterType, 
 									 bool useMipMap, 
-									 bool useMultiSampling)
+									 bool useMultiSampling,
+									 int attachment_idx)
 {
+	GLuint glformat, internalFormat;
+
+
+	switch (format)
+	{
+	case BUFFER_UBYTE:
+		glformat = GL_UNSIGNED_BYTE; internalFormat = GL_RGBA8; break;
+	case BUFFER_FLOAT_16:
+		glformat = GL_FLOAT; internalFormat = GL_RGBA16F_ARB; break;
+	case BUFFER_FLOAT_32: 
+		glformat = GL_FLOAT; internalFormat = GL_RGBA32F_ARB; break;
+	default:
+		glformat = GL_UNSIGNED_BYTE; internalFormat = GL_RGBA8;
+		cerr << "should not come here" << endl;
+	}
+
 	glGenRenderbuffersEXT(1, &mId);
 	glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, mId);
-	glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA8, w, h);
+	glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, internalFormat, w, h);
 	
-	glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT2_EXT, GL_RENDERBUFFER_EXT, mId);
+	glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, color_attachment[attachment_idx], GL_RENDERBUFFER_EXT, mId);
 
 	glGenTextures(1, &mTexId);
 	glBindTexture(GL_TEXTURE_2D, mTexId);
-	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
-	glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT2_EXT, GL_TEXTURE_2D, mTexId, 0);
+	//glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, w, h, 0, GL_RGBA, glformat, NULL);
+	glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, w, h, 0, GL_RGBA, glformat, NULL);
+	glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, color_attachment[attachment_idx], GL_TEXTURE_2D, mTexId, 0);
 
 	GLuint filterParam;
@@ -72,4 +91,7 @@
 	case FILTER_MIPMAP_LINEAR: 
 		filterParam = GL_LINEAR_MIPMAP_LINEAR; break;
+	default:
+		filterParam = GL_NEAREST;
+		cerr << "should not come here" << endl;
 	}
 
@@ -96,5 +118,5 @@
 
 
-FrameBufferObject::FrameBufferObject(int w, int h, bool useDepth, DEPTH_FORMAT d)
+FrameBufferObject::FrameBufferObject(int w, int h, DEPTH_FORMAT d)
 : mWidth(w), mHeight(h)
 {
@@ -102,12 +124,15 @@
 	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mId);
 
-	
+	cout << "creating fbo" << endl;
+
 	///////////
 	//-- create depth buffer
 
-	if (useDepth)
+	if (d != DEPTH_NONE)
 	{
 		glGenRenderbuffersEXT(1, &mDepthId);	
 		glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, mDepthId);
+
+		cout << "adding depth buffer" << endl;
 
 		GLuint depthFormat;
@@ -121,4 +146,6 @@
 		case DEPTH_32: 
 			depthFormat = GL_DEPTH_COMPONENT32; break;
+		default:	
+			cerr << "should not come here" << endl;
 		}
 
@@ -126,7 +153,4 @@
 		glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, mDepthId);
 	}
-
-	// print status
-	PrintFBOStatus(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
 }
 
@@ -138,9 +162,29 @@
 									  bool useMultiSampling)
 {
+	cout << "adding color buffer" << endl;
+
+	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mId);
+
+	int idx = (int)mColorBuffers.size();
 	ColorBufferObject *colorBuf = 
-		new ColorBufferObject(mWidth, mHeight, col, wrapType, filterType, useMipMap, useMultiSampling);
+		new ColorBufferObject(mWidth, mHeight, col, wrapType, filterType, useMipMap, useMultiSampling, idx);
+
 	mColorBuffers.push_back(colorBuf);
 
-	return (int)mColorBuffers.size() - 1;
+	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+
+	return idx;
+}
+
+
+void FrameBufferObject::Bind() const
+{
+	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mId);
+}
+
+
+void FrameBufferObject::Release()
+{
+	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
 }
 
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/deferred.cg
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/deferred.cg	(revision 2854)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/deferred.cg	(revision 2861)
@@ -289,4 +289,5 @@
 
 	float4 col = shade(IN, colors, positions, normal.xyz, amb);
+	
 	OUT.color = col;
 
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/RenderState.cpp
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/RenderState.cpp	(revision 2851)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/RenderState.cpp	(revision 2861)
@@ -3,4 +3,5 @@
 #include "Material.h"
 
+using namespace std;
 
 namespace CHCDemoEngine 
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ResourceManager.cpp
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ResourceManager.cpp	(revision 2853)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ResourceManager.cpp	(revision 2861)
@@ -69,4 +69,5 @@
 		str.read(reinterpret_cast<char *>(&dist), sizeof(float));
 
+		if (i>=3) dist=2e20;
 		int numShapes;
 		str.read(reinterpret_cast<char *>(&numShapes), sizeof(int));
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SsaoShader.cpp
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SsaoShader.cpp	(revision 2860)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SsaoShader.cpp	(revision 2861)
@@ -61,17 +61,42 @@
 SsaoShader::SsaoShader(int w, int h, 
 					   Camera *cam,
-					   float expFactor, 
 					   float scaleFactor
 					   ):
 mWidth(w), mHeight(h), 
 mCamera(cam),
-mExpFactor(expFactor), 
 mScaleFactor(scaleFactor)
-{}
+{
+	
+	///////////
+	//-- the flip-flop fbos
+
+	mNewFbo = new FrameBufferObject(w, h, FrameBufferObject::DEPTH_NONE);
+	// the diffuse color buffer
+	mNewFbo->AddColorBuffer(ColorBufferObject::BUFFER_FLOAT_32, ColorBufferObject::WRAP_CLAMP_TO_EDGE, ColorBufferObject::FILTER_LINEAR, false, false);
+	
+	mOldFbo = new FrameBufferObject(w, h, FrameBufferObject::DEPTH_NONE);
+	// the diffuse color buffer
+	mOldFbo->AddColorBuffer(ColorBufferObject::BUFFER_FLOAT_32, ColorBufferObject::WRAP_CLAMP_TO_EDGE, ColorBufferObject::FILTER_LINEAR, false, false);
+	
+
+	// create noise texture for ssao
+	CreateNoiseTex2D();
+}
+
+
+SsaoShader::~SsaoShader() 
+{
+	if (sCgSsaoProgram)
+		cgDestroyProgram(sCgSsaoProgram);
+
+	DEL_PTR(mNewFbo);
+	DEL_PTR(mOldFbo);
+
+	glDeleteTextures(1, &noiseTex);
+}
 
 
 void SsaoShader::Init(CGcontext context)
-{
-	
+{	
 	///////////////
 
@@ -112,18 +137,31 @@
 
 
-void SsaoShader::Render(FrameBufferObject *fbo, FrameBufferObject *fbo2)
-{
-	FirstPass(fbo, fbo2);
-	SecondPass(fbo, fbo2);
-}
-
-
-void SsaoShader::FirstPass(FrameBufferObject *fbo, FrameBufferObject *fbo2)
-{
-	GLuint positionsTex = fbo->GetColorBuffer(0)->GetTexture();
+void SsaoShader::Render(FrameBufferObject *fbo, 
+						const Matrix4x4 &oldProjViewMatrix,
+						float expFactor)
+{
+	cgGLSetMatrixParameterfc(sOldModelViewProjMatrixParam, (const float *)oldProjViewMatrix.x);
+
+	// switch roles of old and new fbo
+	// the algorihm uses two input fbos, where the one
+	// contais the color buffer from the last frame, 
+	// the other one will be written
+	swap(mNewFbo, mOldFbo);	
+
+	FirstPass(fbo, expFactor);
+	// the second pass just renders the combined solution
+	SecondPass(fbo);
+}
+
+
+void SsaoShader::FirstPass(FrameBufferObject *fbo, float expFactor)
+{
 	GLuint colorsTex = fbo->GetColorBuffer(0)->GetTexture();
-	GLuint normalsTex = fbo->GetColorBuffer(0)->GetTexture();
-
-	GLuint oldTex = fbo2->GetColorBuffer(0)->GetTexture();
+	GLuint positionsTex = fbo->GetColorBuffer(1)->GetTexture();
+	GLuint normalsTex = fbo->GetColorBuffer(2)->GetTexture();
+
+	// read the second buffer, write to the first buffer
+	mNewFbo->Bind();
+	GLuint oldTex = mOldFbo->GetColorBuffer(0)->GetTexture();
 
 	glPushAttrib(GL_VIEWPORT_BIT);
@@ -172,5 +210,5 @@
 	
 	cgGLSetParameter1f(sMaxDepthParam, mScaleFactor);
-	cgGLSetParameter1f(sExpFactorParam, mExpFactor);
+	cgGLSetParameter1f(sExpFactorParam, expFactor);
 
 
@@ -215,8 +253,5 @@
 	glPopAttrib();
 
-	PrintGLerror("displaytexture");
-
-	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
-
+	FrameBufferObject::Release();
 
 	PrintGLerror("ssao first pass");
@@ -224,9 +259,9 @@
 
 
-void SsaoShader::SecondPass(FrameBufferObject *fbo, FrameBufferObject *fbo2)
+void SsaoShader::SecondPass(FrameBufferObject *fbo)
 {
 	glEnable(GL_TEXTURE_2D);
 
-	glBindTexture(GL_TEXTURE_2D, fbo2->GetColorBuffer(0)->GetTexture());
+	glBindTexture(GL_TEXTURE_2D, mNewFbo->GetColorBuffer(0)->GetTexture());
 
 	glDisable(GL_LIGHTING);
@@ -274,5 +309,5 @@
 	mCamera->ComputePoints(ftl, ftr, fbl, fbr, ntl, ntr, nbl, nbr);
 
-#if 1 // matT: debug this!!
+#if 0 // matT: debug this!!
 	
 	bl = Normalize(nbl - fbl);
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/DeferredShader.h
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/DeferredShader.h	(revision 2859)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/DeferredShader.h	(revision 2861)
@@ -24,4 +24,5 @@
 	DeferredShader(int w, int h);
 
+	~DeferredShader();
 	/** The algorithm renders the scene given an fbo.
 		The fbo must have color buffer, position buffer, normal buffer.
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SsaoShader.h
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SsaoShader.h	(revision 2860)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SsaoShader.h	(revision 2861)
@@ -14,5 +14,5 @@
 class Vector3;
 class Camera;
-
+class Matrix4x4;
 
 /** This class implements a deferred shading algorithm that takes
@@ -23,6 +23,5 @@
 public:
 	/** constructor for a deferred shader taking the requested output image size,
-		the current camera, the exponential smoothing factor for temporal reprojection, 
-		and a scaling factor.
+		the current camera,	and a scaling factor.
 			
 		The parameter scaleFactor must be reciprocal value of the 
@@ -30,9 +29,13 @@
 		exact scene size that was scaled in order to improve floating point precision.
 	*/
-	SsaoShader(int w, int h, Camera *cam, float expFactor, float scaleFactor);
-	/** The algorithm renders the scene given an fbo.
-		The fbo must have color buffer, position buffer, normal buffer.
+	SsaoShader(int w, int h, Camera *cam, float scaleFactor);
+	/** 
+	
+		The algorithm renders the scene given an fbo consists of 1 color buffer, 
+		1 position buffer, and 1 normal buffer.
+		We also need the  projection view matrix of the last frame for reprojection, and
+		a smoothing factor for temporal coherence
 	*/
-	void Render(FrameBufferObject *fbo, FrameBufferObject *fbo2);
+	void Render(FrameBufferObject *fbo, const Matrix4x4 &oldProjViewMatrix, float expFactor);
 
 	/** Initialises the deferred shader and loads the required shaders:
@@ -41,10 +44,14 @@
 	static void Init(CGcontext context);
 
+	~SsaoShader();
 
 protected:
 
-	void FirstPass(FrameBufferObject *fbo, FrameBufferObject *fbo2);
+	void FirstPass(FrameBufferObject *fbo, float expFactor);
 
-	void SecondPass(FrameBufferObject *fbo, FrameBufferObject *fbo2);
+	void SecondPass(FrameBufferObject *fbo);
+
+	void CreateNoiseTex2D();
+	void ComputeViewVectors(Vector3 &tl, Vector3 &tr, Vector3 &bl, Vector3 &br);
 
 
@@ -54,6 +61,4 @@
 	int mHeight;
 
-	/// the temporal smoothing factor
-	float mExpFactor;
 	/// this is just a scale factor for the scene depth in order to get better float precision in the shader
 	float mScaleFactor;
@@ -61,10 +66,6 @@
 	Camera *mCamera;
 
-
-private:
-
-	void CreateNoiseTex2D();
-	void ComputeViewVectors(Vector3 &tl, Vector3 &tr, Vector3 &bl, Vector3 &br);
-
+	FrameBufferObject *mOldFbo;
+	FrameBufferObject *mNewFbo;
 };
 
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/chcdemo.cpp
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/chcdemo.cpp	(revision 2860)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/chcdemo.cpp	(revision 2861)
@@ -33,4 +33,6 @@
 #include "SampleGenerator.h"
 #include "FrameBufferObject.h"
+#include "SsaoShader.h"
+#include "DeferredShader.h"
 
 
@@ -45,35 +47,7 @@
 //-- fbos
 
-GLuint fbo;
-GLuint fbo1;
-GLuint fbo2;
+FrameBufferObject *fbo;
 
 bool isFirstTexture = true;
-
-/////////////
-//-- renderbuffers
-
-
-GLuint depthBuffer;
-
-GLuint positionsBuffer;
-GLuint colorsBuffer;
-GLuint colorsBuffer1;
-GLuint colorsBuffer2;
-GLuint normalsBuffer;
-
-
-/////////////
-//-- textures
-
-
-GLuint positionsTex;
-GLuint colorsTex;
-GLuint colorsTex1;
-GLuint colorsTex2;
-
-GLuint normalsTex;
-
-GLuint noiseTex;
 
 GLuint fontTex;
@@ -177,4 +151,5 @@
 
 bool useSsao = false;
+static float ssaoExpFactor = 0.1f;
 
 bool showAlgorithmTime = false;
@@ -190,17 +165,6 @@
 bool useFullScreen = false;
 
-// exp factor for ssao
-float expFactor = 0.05f;
-
-// ssao number of samples
-//#define NUM_SAMPLES 8
-#define NUM_SAMPLES 16
-
-// ssao random spherical samples
-static float samples[NUM_SAMPLES * 2];
-
 static Matrix4x4 matProjectionView = IdentityMatrix();
 
-FrameBufferObject *myfbo = NULL;
 
 
@@ -241,5 +205,4 @@
 
 void PlaceViewer(const Vector3 &oldPos);
-void DisplayRenderTexture();
 
 
@@ -249,10 +212,6 @@
 void InitFBO();
 
-void CreateNoiseTex2D();
-
-void ComputeViewVectors(Vector3 &tl, Vector3 &tr, Vector3 &bl, Vector3 &br);
-
-void GenerateSamples();
-
+SsaoShader *ssaoShader = NULL;
+DeferredShader *deferredShader = NULL;
 
 GLenum mrt[] = {GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_COLOR_ATTACHMENT2_EXT};
@@ -264,26 +223,10 @@
 static CGcontext sCgContext = NULL;
 static CGprogram sCgMrtVertexProgram = NULL;
-static CGprogram sCgSsaoProgram = NULL;
-static CGprogram sCgDeferredProgram = NULL;
-
-static CGparameter sColorsTexParam;
-static CGparameter sPositionsTexParam;
-static CGparameter sNormalsTexParam;
-
-static CGparameter sColorsTexParamSsao;
-static CGparameter sPositionsTexParamSsao;
-static CGparameter sNormalsTexParamSsao;
-static CGparameter sNoiseTexParamSsao;
 
 static CGparameter sModelViewProjMatrixParam;
-static CGparameter sOldModelViewProjMatrixParam;
 static CGparameter sMaxDepthParam;
-static CGparameter sMaxDepthParamSsao;
 static CGparameter sMaxDepthParamTex;
 
-static CGparameter sSamplesParamSsao; 
-static CGparameter sOldTexParamSsao;
-static CGparameter sNoiseMultiplierParam;
-static CGparameter sExpFactorParamSsao;
+static Matrix4x4 oldViewProjMatrix;
 
 
@@ -296,4 +239,5 @@
 		printf("%s\n\n", cgGetErrorString(lastError));
 		printf("%s\n", cgGetLastListing(sCgContext));
+		
 		printf("Cg error, exiting...\n");
 
@@ -343,5 +287,5 @@
 
 		env.GetBoolParam(string("useFullScreen"), useFullScreen);
-		env.GetFloatParam(string("expFactor"), expFactor);
+		env.GetFloatParam(string("expFactor"), ssaoExpFactor);
 		env.GetVectorParam(string("camPosition"), camPos);
 		env.GetVectorParam(string("camDirection"), camDir);
@@ -360,5 +304,5 @@
 		cout << "useFullScreen: " << useFullScreen << endl;
 		cout << "camPosition: " << camPos << endl;
-		cout << "expFactor: " << expFactor << endl;
+		cout << "expFactor: " << ssaoExpFactor << endl;
 		//cout << "model path: " << model_path << endl;
 	}
@@ -466,6 +410,9 @@
 	InitCg();
 
-	// create noise texture for ssao
-	CreateNoiseTex2D();
+	SsaoShader::Init(sCgContext);
+	DeferredShader::Init(sCgContext);
+
+	ssaoShader = new SsaoShader(texWidth, texHeight, camera, myfar / 10.0f);
+	deferredShader = new DeferredShader(texWidth, texHeight);
 
 	// initialize the render traverser
@@ -499,5 +446,4 @@
 	// get the best profile for this hardware
 	RenderState::sCgFragmentProfile = cgGLGetLatestProfile(CG_GL_FRAGMENT);
-	//assert(sCgFragmentProfile != CG_PROFILE_UNKNOWN);
 	cgGLSetOptimalOptions(RenderState::sCgFragmentProfile);
 
@@ -564,101 +510,7 @@
 		cerr << "fragment program failed to load" << endl;
 
-	PrintGLerror("test");
-
-
-	///////////////
-
-	sCgSsaoProgram = 
-		cgCreateProgramFromFile(sCgContext, 
-								CG_SOURCE,
-								"src/shaders/deferred.cg", 
-								RenderState::sCgFragmentProfile,
-								"main_ssao",
-								NULL);
-
-	if (sCgSsaoProgram != NULL)
-	{
-		cgGLLoadProgram(sCgSsaoProgram);
-
-		// we need size of texture for scaling
-		sPositionsTexParamSsao = cgGetNamedParameter(sCgSsaoProgram, "positions");  
-		sColorsTexParamSsao = cgGetNamedParameter(sCgSsaoProgram, "colors");  
-		sNormalsTexParamSsao = cgGetNamedParameter(sCgSsaoProgram, "normals");  
-		sNoiseTexParamSsao = cgGetNamedParameter(sCgSsaoProgram, "noiseTexture");
-		sNoiseMultiplierParam = cgGetNamedParameter(sCgSsaoProgram, "noiseMultiplier");
-		sOldModelViewProjMatrixParam = cgGetNamedParameter(sCgSsaoProgram, "oldModelViewProj");
-		sMaxDepthParamSsao = cgGetNamedParameter(sCgSsaoProgram, "maxDepth");
-		sExpFactorParamSsao = cgGetNamedParameter(sCgSsaoProgram, "expFactor");
-
-		cgGLSetParameter1f(sMaxDepthParamSsao, myfar / 10.0f);
-		cgGLSetParameter1f(sExpFactorParamSsao, expFactor);
-
-		sSamplesParamSsao = cgGetNamedParameter(sCgSsaoProgram, "samples");
-		sOldTexParamSsao = cgGetNamedParameter(sCgSsaoProgram, "oldTex");  
-
-		GenerateSamples(); cgGLSetParameterArray2f(sSamplesParamSsao, 0, NUM_SAMPLES, (const float *)samples);
-	}
-	else
-		cerr << "ssao program failed to load" << endl;
-
-	
-	sCgDeferredProgram = 
-		cgCreateProgramFromFile(sCgContext, 
-								CG_SOURCE,
-								"src/shaders/deferred.cg", 
-								RenderState::sCgFragmentProfile,
-								"main",
-								NULL);
-
-	if (sCgDeferredProgram != NULL)
-	{
-		cgGLLoadProgram(sCgDeferredProgram);
-
-		// we need size of texture for scaling
-		sPositionsTexParam = cgGetNamedParameter(sCgDeferredProgram, "positions");  
-		sColorsTexParam = cgGetNamedParameter(sCgDeferredProgram, "colors");  
-		sNormalsTexParam = cgGetNamedParameter(sCgDeferredProgram, "normals"); 
-	}
-	else
-		cerr << "deferred program failed to load" << endl;
-
-
 	PrintGLerror("init");
 
 	cout << "cg initialization successful" << endl;
-}
-
-
-void PrintFBOStatus(GLenum status)
-{
-	switch(status)
-	{
-	case GL_FRAMEBUFFER_COMPLETE_EXT:
-		cout << "frame buffer object created successfully" << endl;
-		break;
-	case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
-		cerr << "incomplete attachment" << endl;
-		break;
-	case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
-		cerr << "missing attachment" << endl;
-		break;
-	case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
-		cerr << "incomplete dimensions" << endl;
-		break;
-	case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
-		cerr << "incomplete formats" << endl;
-		break;
-	case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
-		cerr << "incomplete draw buffer" << endl;
-		break;
-	case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
-		cerr << "incomplete read buffer" << endl;
-		break;
-	case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
-		cerr << "framebuffer unsupported" << endl;
-		break;
-	default:
-		cerr << "unknown status code " << status << endl;
-	}
 }
 
@@ -668,189 +520,12 @@
 	// this fbo basicly stores the scene information we get from standard rendering of a frame
 	// we store colors, normals, positions (for the ssao)
-	fbo = new FrameBufferObject(texWidth, texHeight, true, FrameBufferObject::DEPTH_24);
-
+	fbo = new FrameBufferObject(texWidth, texHeight, FrameBufferObject::DEPTH_24);
 
 	// the diffuse color buffer
 	fbo->AddColorBuffer(ColorBufferObject::BUFFER_FLOAT_32, ColorBufferObject::WRAP_CLAMP_TO_EDGE, ColorBufferObject::FILTER_LINEAR, false, false);
-
 	// the positions buffer
 	fbo->AddColorBuffer(ColorBufferObject::BUFFER_FLOAT_32, ColorBufferObject::WRAP_CLAMP_TO_EDGE, ColorBufferObject::FILTER_NEAREST, false, false);
-
 	// the normals buffer
 	fbo->AddColorBuffer(ColorBufferObject::BUFFER_UBYTE, ColorBufferObject::WRAP_CLAMP_TO_EDGE, ColorBufferObject::FILTER_NEAREST, false, false);
-
-
-
-	////////////////////////
-
-	glGenFramebuffersEXT(1, &fbo);
-	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
-
-	
-	////////////
-	//-- colors buffer
-
-	glGenRenderbuffersEXT(1, &colorsBuffer);
-	glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, colorsBuffer);
-	
-#if 1
-	glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA32F_ARB, texWidth, texHeight);
-#else
-	int samples = 8;
-	glEnable(GL_MULTISAMPLE_ARB);
-	glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, GL_RGBA8, texWidth, texHeight);
-#endif
-
-	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_RGBA32F_ARB, texWidth, texHeight, 0, GL_RGBA, GL_FLOAT, NULL);
-	//glGenerateMipmapEXT(GL_TEXTURE_2D);
-	glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, colorsTex, 0);
-
-	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_CLAMP_TO_EDGE);
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-
-
-	//////////
-	//-- positions buffer
-
-	PrintFBOStatus(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
-	glGenRenderbuffersEXT(1, &positionsBuffer);
-	glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, positionsBuffer);
-	glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA32F_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_RGBA32F_ARB, texWidth, texHeight, 0, GL_RGBA, GL_FLOAT, NULL);
-	//glGenerateMipmapEXT(GL_TEXTURE_2D);
-	glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D, positionsTex, 0);
-
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-
-	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);
-	glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT2_EXT, GL_TEXTURE_2D, normalsTex, 0);
-
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-
-	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));
-
-
-	///////////
-	//-- create depth buffer
-
-	glGenRenderbuffersEXT(1, &depthBuffer);	
-	glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depthBuffer);
-	glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, texWidth, texHeight);
-	glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depthBuffer);
-
-	
-	PrintFBOStatus(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
-	
-	
-
-	//////////////////////////////////
-
-
-
-	glGenFramebuffersEXT(1, &fbo1);
-	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo1);
-
-	
-	////////////
-	//-- colors buffer
-
-	glGenRenderbuffersEXT(1, &colorsBuffer1);
-	glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, colorsBuffer1);
-	
-	glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA32F_ARB, texWidth, texHeight);
-	glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, colorsBuffer1);
-	
-	glGenTextures(1, &colorsTex1);
-	glBindTexture(GL_TEXTURE_2D, colorsTex1);
-
-	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F_ARB, texWidth, texHeight, 0, GL_RGBA, GL_FLOAT, NULL);
-	//glGenerateMipmapEXT(GL_TEXTURE_2D);
-	glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, colorsTex1, 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);
-
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-
-	PrintFBOStatus(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
-
-
-
-	/////////////////////////
-
-	glGenFramebuffersEXT(1, &fbo2);
-	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo2);
-
-	
-	////////////
-	//-- colors buffer
-
-	glGenRenderbuffersEXT(1, &colorsBuffer2);
-	glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, colorsBuffer2);
-	
-	glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA32F_ARB, texWidth, texHeight);
-	glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, colorsBuffer2);
-	
-	glGenTextures(1, &colorsTex2);
-	glBindTexture(GL_TEXTURE_2D, colorsTex2);
-
-	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F_ARB, texWidth, texHeight, 0, GL_RGBA, GL_FLOAT, NULL);
-	//glGenerateMipmapEXT(GL_TEXTURE_2D);
-	glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, colorsTex2, 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_MAG_FILTER, GL_NEAREST);
-	//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-
-	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_CLAMP_TO_EDGE);
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-
-	PrintFBOStatus(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
-
-	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
 
 	PrintGLerror("fbo");
@@ -1073,8 +748,6 @@
 	Matrix4x4 matViewing, matProjection;
 
-	if (renderType == RenderState::DEFERRED)
-	{
-		cgGLSetMatrixParameterfc(sOldModelViewProjMatrixParam, (const float *)matProjectionView.x);
-	}
+	// store matrix of last frame
+	oldViewProjMatrix = matProjectionView;
 
 	glMatrixMode(GL_PROJECTION);
@@ -1170,5 +843,5 @@
 		//glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE_ARB);
 
-		glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+		fbo->Release();
 
 		state.SetRenderType(RenderState::FIXED);
@@ -1189,5 +862,5 @@
 		//glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE_ARB);
 
-		glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+		fbo->Release();
 
 		cgGLDisableProfile(RenderState::sCgFragmentProfile);
@@ -1215,5 +888,5 @@
 		state.SetRenderType(RenderState::DEFERRED);
 
-		glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
+		fbo->Bind();
 	
 		glPushAttrib(GL_VIEWPORT_BIT);
@@ -1226,4 +899,5 @@
 		cgGLBindProgram(sCgMrtVertexProgram);
 
+		/// draw to 3 color buffers
 		glDrawBuffers(3, mrt);
 
@@ -1240,4 +914,5 @@
 		
 
+	// reset lod levels for current frame
 	LODLevel::InitFrame(camera->GetPosition());
 
@@ -1279,6 +954,5 @@
 	if (renderType == RenderState::DEFERRED) 
 	{
-		//glPopAttrib();
-		glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+		fbo->Release();
 
 		cgGLDisableProfile(RenderState::sCgVertexProfile);
@@ -1287,7 +961,9 @@
 		glDrawBuffers(1, mrt);
 
-		DisplayRenderTexture();
-	}
-
+		if (useSsao)
+			ssaoShader->Render(fbo, oldViewProjMatrix, ssaoExpFactor);
+		else
+			deferredShader->Render(fbo);
+	}
 	
 	///////////
@@ -1379,9 +1055,9 @@
 		break;
 	case '7':
-		expFactor *= 0.5f;
+		ssaoExpFactor *= 0.5f;
 		break;
 	case '8':
-		expFactor *= 2.0f;
-		if (expFactor > 1.0f) expFactor = 1.0f;
+		ssaoExpFactor *= 2.0f;
+		if (ssaoExpFactor > 1.0f) ssaoExpFactor = 1.0f;
 		break;
 	case 'o':
@@ -1819,22 +1495,7 @@
 	if (RenderState::sCgMrtFragmentTexProgram)
 		cgDestroyProgram(RenderState::sCgMrtFragmentTexProgram);
-	if (sCgSsaoProgram)
-		cgDestroyProgram(sCgSsaoProgram);
-	if (sCgDeferredProgram)
-		cgDestroyProgram(sCgDeferredProgram);
+	
 	if (sCgContext)
 		cgDestroyContext(sCgContext);
-
-	glDeleteFramebuffersEXT(1, &fbo);
-	glDeleteRenderbuffersEXT(1, &depthBuffer);
-	glDeleteRenderbuffersEXT(1, &colorsBuffer);
-	glDeleteRenderbuffersEXT(1, &normalsBuffer);
-	glDeleteRenderbuffersEXT(1, &positionsBuffer);
-
-	glDeleteTextures(1, &colorsTex);
-	glDeleteTextures(1, &normalsTex);
-	glDeleteTextures(1, &positionsTex);
-	glDeleteTextures(1, &noiseTex);
-	glDeleteTextures(1, &fontTex);
 }
 
@@ -2065,358 +1726,2 @@
 	}
 }
-
-
-void DisplayRenderTexture3()
-{
-	glEnable(GL_TEXTURE_2D);
-
-	if (isFirstTexture)
-		glBindTexture(GL_TEXTURE_2D, colorsTex1);
-	else
-		glBindTexture(GL_TEXTURE_2D, colorsTex2);
-
-	glDisable(GL_LIGHTING);
-	
-	glMatrixMode(GL_PROJECTION);
-	glPushMatrix();
-	glLoadIdentity();
-
-	glMatrixMode(GL_MODELVIEW);
-	glPushMatrix();
-	glLoadIdentity();
-
-	const float offs = 0.5f;
-	glOrtho(-offs, offs, -offs, offs, 0, 1);
-	
-	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
-	glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
-	glBegin(GL_QUADS);
-
-	glTexCoord2f(0, 0); glVertex3f(-offs, -offs, -0.5f);
-	glTexCoord2f(1, 0); glVertex3f( offs, -offs, -0.5f);
-	glTexCoord2f(1, 1); glVertex3f( offs,  offs, -0.5f);
-	glTexCoord2f(0, 1); glVertex3f(-offs,  offs, -0.5f);
-
-	glEnd();
-
-	glEnable(GL_LIGHTING);
-	glDisable(GL_TEXTURE_2D);
-	
-	glMatrixMode(GL_PROJECTION);
-	glPopMatrix();
-
-	glMatrixMode(GL_MODELVIEW);
-	glPopMatrix();
-
-	PrintGLerror("displaytexture3");
-}
-
-
-void DisplayRenderTexture()
-{
-	GLuint oldTex;
-
-	if (isFirstTexture)
-	{
-		glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo1);
-		oldTex = colorsTex2;
-	}
-	else 
-	{
-		glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo2);
-		oldTex = colorsTex1;
-	}
-
-	glPushAttrib(GL_VIEWPORT_BIT);
-	glViewport(0, 0, texWidth, texHeight);
-
-	glDrawBuffers(1, mrt);
-
-	glDisable(GL_ALPHA_TEST);
-	glDisable(GL_TEXTURE_2D);
-	glDisable(GL_LIGHTING);
-	
-	glMatrixMode(GL_PROJECTION);
-	glPushMatrix();
-	glLoadIdentity();
-
-	glMatrixMode(GL_MODELVIEW);
-	glPushMatrix();
-	glLoadIdentity();
-
-	const float offs = 0.5f;
-	
-	glOrtho(-offs, offs, -offs, offs, 0, 1);
-	
-	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
-	cgGLEnableProfile(RenderState::sCgFragmentProfile);
-
-	if (useSsao)
-	{
-		cgGLBindProgram(sCgSsaoProgram);
-		
-		cgGLSetTextureParameter(sPositionsTexParamSsao, positionsTex);
-		cgGLEnableTextureParameter(sPositionsTexParamSsao);
-
-		cgGLSetTextureParameter(sColorsTexParamSsao, colorsTex);
-		cgGLEnableTextureParameter(sColorsTexParamSsao);
-
-		cgGLSetTextureParameter(sNormalsTexParamSsao, normalsTex);
-		cgGLEnableTextureParameter(sNormalsTexParamSsao);
-
-		cgGLSetTextureParameter(sNoiseTexParamSsao, noiseTex);
-		cgGLEnableTextureParameter(sNoiseTexParamSsao);
-
-		cgGLSetTextureParameter(sOldTexParamSsao, oldTex);
-		cgGLEnableTextureParameter(sOldTexParamSsao);
-
-		cgGLSetParameter1f(sNoiseMultiplierParam, RandomValue(3.0f, 17.0f));
-		cgGLSetParameter1f(sExpFactorParamSsao, expFactor);
-
-		GenerateSamples(); cgGLSetParameterArray2f(sSamplesParamSsao, 0, NUM_SAMPLES, (const float *)samples);
-	}
-	else
-	{
-		cgGLBindProgram(sCgDeferredProgram);
-
-		cgGLSetTextureParameter(sPositionsTexParam, positionsTex);
-		cgGLEnableTextureParameter(sPositionsTexParam);
-
-		cgGLSetTextureParameter(sColorsTexParam, colorsTex);
-		cgGLEnableTextureParameter(sColorsTexParam);
-
-		cgGLSetTextureParameter(sNormalsTexParam, normalsTex);
-		cgGLEnableTextureParameter(sNormalsTexParam);
-	}
-
-	Vector3 tl, tr, bl, br;
-	ComputeViewVectors(tl, tr, bl, br);
-
-	glColor3f(1.0f, 1.0f, 1.0f);
-
-	glBegin(GL_QUADS);
-
-	// note: slightly larger texture hides ambient occlusion error on border but costs resolution
-	//float offs2 = 0.55f;
-	float offs2 = 0.5f;
-
-	glColor3f(bl.x, bl.y, bl.z); glTexCoord2f(0, 0); glVertex3f(-offs2, -offs2, -0.5f);
-	glColor3f(br.x, br.y, br.z); glTexCoord2f(1, 0); glVertex3f( offs2, -offs2, -0.5f);
-	glColor3f(tr.x, tr.y, tr.z); glTexCoord2f(1, 1); glVertex3f( offs2,  offs2, -0.5f);
-	glColor3f(tl.x, tl.y, tl.z); glTexCoord2f(0, 1); glVertex3f(-offs2,  offs2, -0.5f);
-
-	glEnd();
-
-	
-	if (useSsao)
-	{
-		cgGLDisableTextureParameter(sColorsTexParamSsao);
-		cgGLDisableTextureParameter(sPositionsTexParamSsao);
-		cgGLDisableTextureParameter(sNormalsTexParamSsao);
-		cgGLDisableTextureParameter(sNoiseTexParamSsao);
-		cgGLDisableTextureParameter(sOldTexParamSsao);
-	}
-	else
-	{
-		cgGLDisableTextureParameter(sColorsTexParam);
-		cgGLDisableTextureParameter(sPositionsTexParam);
-		cgGLDisableTextureParameter(sNormalsTexParam);
-	}
-
-	cgGLDisableProfile(RenderState::sCgFragmentProfile);
-	
-	glEnable(GL_LIGHTING);
-	glDisable(GL_TEXTURE_2D);
-	
-	glMatrixMode(GL_PROJECTION);
-	glPopMatrix();
-
-	glMatrixMode(GL_MODELVIEW);
-	glPopMatrix();
-
-	glPopAttrib();
-
-	PrintGLerror("displaytexture");
-
-	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
-
-	DisplayRenderTexture3();
-}
-
-#if 0
-// kustls magic sample positions
-void GenerateSamples()
-{
-	static const float mysamples[] =
-	{ 
-		-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
-	};
-
-	for (int i = 0; i < NUM_SAMPLES; ++ i)
-	{
-		samples[i] = mysamples[i];
-	}
-}
-
-#else
-
-
-void GenerateSamples()
-{
-	/*static HaltonSequence halton;
-
-	float r[2];
-
-	// generates poisson distribution on disc
-	float minDist = 2.0f / sqrt((float)NUM_SAMPLES);
-
-	//cout << "minDist before= " << minDist << endl;
-
-	for (int i = 0; i < NUM_SAMPLES * 2; i += 2)
-	{
-		int tries = 0, totalTries = 0;
-
-		// repeat until valid sample was found
-		while (1)
-		{
-			++ tries;
-			++ totalTries;
-
-			halton.GetNext(2, r);
-
-			//const float rx = RandomValue(-1, 1);
-			//const float ry = RandomValue(-1, 1);
-
-			const float rx = r[0] * 2.0f - 1.0f;
-			const float ry = r[1] * 2.0f - 1.0f;
-
-			// check if in disk, else exit early
-			if (rx * rx + ry * ry > 1)
-				continue;
-
-			bool sampleValid = true;
-
-			// check poisson property
-			for (int j = 0; ((j < i) && sampleValid); j += 2)
-			{
-				const float dist = 
-					sqrt((samples[j] - rx) * (samples[j] - rx) +
-					     (samples[j + 1] - ry) * (samples[j + 1] - ry));
-			
-				if (dist < minDist)
-					sampleValid = false;
-			}
-
-			if (sampleValid)
-			{
-				samples[i] = rx;
-				samples[i + 1]= ry;
-				break;
-			}
-
-			if (tries > 2000)
-			{
-				minDist *= 0.9f;
-				tries = 0;
-			}
-		}
-	}
-*/
-
-	static PoissonDiscSampleGenerator poisson(NUM_SAMPLES, 1.0f);
-	poisson.Generate((Sample2 *)samples);
-}
-
-
-#endif
-
-
-void ComputeViewVectors(Vector3 &tl, Vector3 &tr, Vector3 &bl, Vector3 &br)
-{
-	float myfov = fov * M_PI / 180.0f;
-
-	const float w_far = 2.0f * tan(myfov / 2.0f);
-	const float aspect = texWidth / texHeight;
-
-	const float h_far = w_far / aspect;
-
-	float t1 = h_far * 0.5f;
-	float t2 = w_far * 0.5f;
-
-#if 0
-	bl = Normalize(-Vector3(-t1, -t2, 1.0f));
-	br = Normalize(-Vector3( t1, -t2, 1.0f));
-	tl = Normalize(-Vector3(-t1,  t2, 1.0f));
-	tr = Normalize(-Vector3( t1,  t2, 1.0f));
-#else
-	bl = -Normalize(camera->GetDirection());
-	br = -Normalize(camera->GetDirection());
-	tl = -Normalize(camera->GetDirection());
-	tr = -Normalize(camera->GetDirection());
-#endif
-	// normalize to 0 .. 1
-	bl = bl * 0.5f + 0.5f;
-	br = br * 0.5f + 0.5f;
-	tl = tl * 0.5f + 0.5f;
-	tr = tr * 0.5f + 0.5f;
-}
-
-
-void CreateNoiseTex2D()
-{
-	randomNormals = new GLubyte[texWidth * texHeight * 3];
-
-	for (int i = 0; i < texWidth * texHeight * 3; i += 3)
-	{
-		// create random samples over sphere
-		const float rx = RandomValue(0, 1);
-		const float theta = 2.0f * acos(sqrt(1.0f - rx));
-
-		randomNormals[i + 0] = (GLubyte)((cos(theta) * 0.5f + 0.5f) * 255.0f);
-		randomNormals[i + 1] = (GLubyte)((sin(theta) * 0.5f + 0.5f) * 255.0f);
-		randomNormals[i + 2] = 0;
-	}
-
-	glEnable(GL_TEXTURE_2D);
-	glGenTextures(1, &noiseTex);
-	glBindTexture(GL_TEXTURE_2D, noiseTex);
-		
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
-
-	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, texWidth, texHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, randomNormals);
-	//gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, texWidth, texHeight, GL_RGB, GL_UNSIGNED_BYTE, randomNormals);
-
-	glBindTexture(GL_TEXTURE_2D, 0);
-	glDisable(GL_TEXTURE_2D);
-
-	cout << "created noise texture" << endl;
-	PrintGLerror("noisetexture");
-}
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/DeferredShader.cpp
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/DeferredShader.cpp	(revision 2859)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/DeferredShader.cpp	(revision 2861)
@@ -35,4 +35,11 @@
 
 
+DeferredShader::~DeferredShader()
+{
+	if (sCgDeferredProgram)
+		cgDestroyProgram(sCgDeferredProgram);
+}
+
+
 void DeferredShader::Init(CGcontext context)
 {
@@ -65,7 +72,9 @@
 void DeferredShader::Render(FrameBufferObject *fbo)
 {
-	GLuint positionsTex = fbo->GetColorBuffer(0)->GetTexture();
+	FrameBufferObject::Release();
+
 	GLuint colorsTex = fbo->GetColorBuffer(0)->GetTexture();
-	GLuint normalsTex = fbo->GetColorBuffer(0)->GetTexture();
+	GLuint positionsTex = fbo->GetColorBuffer(1)->GetTexture();
+	GLuint normalsTex = fbo->GetColorBuffer(2)->GetTexture();
 
 	glPushAttrib(GL_VIEWPORT_BIT);
@@ -103,5 +112,5 @@
 	
 	glColor3f(1.0f, 1.0f, 1.0f);
-
+	
 	glBegin(GL_QUADS);
 
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/FrameBufferObject.h
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/FrameBufferObject.h	(revision 2859)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/FrameBufferObject.h	(revision 2861)
@@ -25,5 +25,6 @@
 					  FILTER_TYPE filterType, 
 					  bool useMipMap, 
-					  bool useMultiSampling);
+					  bool useMultiSampling,
+					  int attachment_idx);
 
 	unsigned int GetTexture() const {return mTexId;}
@@ -42,9 +43,9 @@
 public:
 
-	enum DEPTH_FORMAT { DEPTH_16, DEPTH_24, DEPTH_32 };
+	enum DEPTH_FORMAT { DEPTH_NONE, DEPTH_16, DEPTH_24, DEPTH_32 };
 
 	/** constructor requesting an opengl occlusion query.
 	*/
-	FrameBufferObject(int w, int h, bool useDepth, DEPTH_FORMAT d);
+	FrameBufferObject(int w, int h, DEPTH_FORMAT d);
 	/** Creates and adds a color buffer to the current frame buffer object.
 		Returns the index that allows to retrieve the color buffer object.
@@ -59,5 +60,10 @@
 	*/
 	ColorBufferObject *GetColorBuffer(int i) const { return mColorBuffers[i]; }
-
+	/** Binds this frame buffer object.
+	*/
+	void Bind() const;
+	/** Releases any bound frame buffer object.
+	*/
+	static void Release();
 
 protected:
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/default.env
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/default.env	(revision 2846)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/default.env	(revision 2861)
@@ -18,4 +18,5 @@
 # shader stuff
 
+# ssao exponential smoothing factor
 expFactor=0.1f
 #numSsaoSamples=8
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/FriendlyCulling.vcproj
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/FriendlyCulling.vcproj	(revision 2859)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/FriendlyCulling.vcproj	(revision 2861)
@@ -793,4 +793,8 @@
 		</Filter>
 		<File
+			RelativePath=".\default.env"
+			>
+		</File>
+		<File
 			RelativePath=".\ReadMe.txt"
 			>
