Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Material.h
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Material.h	(revision 3050)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Material.h	(revision 3054)
@@ -14,4 +14,5 @@
 class GPUProgramParameters;
 class ShaderProgram;
+struct RenderQueueBucket;
 
 
@@ -48,4 +49,5 @@
 {
 friend class ResourceManager;
+friend class RenderQueue;
 
 public:
@@ -55,5 +57,5 @@
 	Technique();
 
-	Technique(const Technique &tech);
+	//Technique(const Technique &tech);
 	/** Sets ambient and diffuse color to color
 	*/
@@ -134,4 +136,6 @@
 	/// if depth write is enabled
 	bool mDepthWriteEnabled;
+	/// pointer to the renderqueue bucket this entity belongs to
+	RenderQueueBucket *mRenderQueueBucket;
 };
 
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Shape.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Shape.cpp	(revision 2957)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Shape.cpp	(revision 3054)
@@ -13,6 +13,5 @@
 mGeometry(geometry), 
 mMaterial(mat), 
-mParent(parent), 
-mRenderQueueBucket(NULL)
+mParent(parent)
 {
 	mCenter = GetBoundingBox().Center();
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/RenderQueue.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/RenderQueue.cpp	(revision 3053)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/RenderQueue.cpp	(revision 3054)
@@ -6,5 +6,5 @@
 #include "Camera.h"
 #include "Shape.h"
-
+#include "RenderState.h"
 
 using namespace std;
@@ -51,28 +51,30 @@
 bool RenderQueue::FitsInBucket(Shape *shape, size_t idx) const
 {
-	Technique *tech = shape->GetMaterial()->GetDefaultTechnique();
+	Technique *tech = shape->GetMaterial()->GetTechnique(mState->GetRenderTechnique());
 
 	// test if entity belongs to this bucket
-	// note: rather slows down the application for some reason!!
-	if (tech->IsAlphaTestEnabled() != mBuckets[idx]->mAlphaTestEnabled) { cout << "a"; return false; }
-	if (tech->IsCullFaceEnabled() != mBuckets[idx]->mCullFaceEnabled) { cout << "b"; return false; }
-	if (tech->IsColorWriteEnabled() != mBuckets[idx]->mColorWriteEnabled) { cout << "c"; return false; }
-	if (tech->IsLightingEnabled() != mBuckets[idx]->mLightingEnabled) { cout << "d"; return false; }
-	if (tech->IsDepthWriteEnabled() != mBuckets[idx]->mDepthWriteEnabled) { cout << "e"; return false; }
+	if (tech->IsAlphaTestEnabled() != mBuckets[idx]->mAlphaTestEnabled) { return false; }
+	if (tech->IsCullFaceEnabled() != mBuckets[idx]->mCullFaceEnabled) { return false; }
+	if (tech->IsColorWriteEnabled() != mBuckets[idx]->mColorWriteEnabled) { return false; }
+	if (tech->IsLightingEnabled() != mBuckets[idx]->mLightingEnabled) { return false; }
+	if (tech->IsDepthWriteEnabled() != mBuckets[idx]->mDepthWriteEnabled) { return false; }
+
+	//if (tech->IsColorWriteEnabled()) cout << "x";
 
 	const bool hasTexture = (tech->GetTexture() != NULL);
 
-	if (hasTexture != mBuckets[idx]->mHasTexture) { cout << "f"; return false; }
+	if (hasTexture != mBuckets[idx]->mHasTexture) { return false; }
 
 	if (hasTexture)
 	{
-		if (tech->GetTexture()->GetWidth() != mBuckets[idx]->mTexWidth) { cout << "g"; return false; }
-		if (tech->GetTexture()->GetHeight() != mBuckets[idx]->mTexHeight) { cout << "h"; return false; }
-		if (tech->GetTexture()->GetFormat() != mBuckets[idx]->mTexFormat) { cout << "i"; return false; }
-	}
-
-	if (!tech->GetFragmentProgram() && mBuckets[idx]->mHasFragmentProgram) { cout << "j"; return false; }
-	if (!tech->GetVertexProgram() && mBuckets[idx]->mHasVertexProgram) { cout << "h"; return false; }
-
+		if (tech->GetTexture()->GetWidth() != mBuckets[idx]->mTexWidth) { return false; }
+		if (tech->GetTexture()->GetHeight() != mBuckets[idx]->mTexHeight) {return false; }
+		if (tech->GetTexture()->GetFormat() != mBuckets[idx]->mTexFormat) { return false; }
+	}
+
+	//if (!tech->GetFragmentProgram() && mBuckets[idx]->mHasFragmentProgram) { return false; }
+	//if (!tech->GetVertexProgram() && mBuckets[idx]->mHasVertexProgram) { return false; }
+	if (tech->GetFragmentProgram() != mBuckets[idx]->mFragmentProgram) { return false; }
+	if (tech->GetVertexProgram() != mBuckets[idx]->mVertexProgram) { return false; }
 
 	return true;
@@ -95,12 +97,10 @@
 void RenderQueue::Enqueue(Shape *shape)
 {
-	RenderQueueBucket *bucket;
+	Technique *tech = shape->GetMaterial()->GetTechnique(mState->GetRenderTechnique());
+	RenderQueueBucket *bucket = tech->mRenderQueueBucket;
+
 	++ mNumEntries;
 	
-	if (shape->mRenderQueueBucket)
-	{
-		bucket = shape->mRenderQueueBucket;
-	}
-	else
+	if (!bucket)
 	{
 		bool bucketFound = false;
@@ -119,6 +119,4 @@
 			RenderQueueBucket *bucket = new RenderQueueBucket();
 			bucket->mMinDistance = -1;
-
-			Technique *tech = shape->GetMaterial()->GetDefaultTechnique();
 
 			bucket->mAlphaTestEnabled = tech->IsAlphaTestEnabled();
@@ -150,14 +148,15 @@
 			}
 
-			bucket->mHasVertexProgram = tech->GetVertexProgram() != NULL;
-			bucket->mHasFragmentProgram = tech->GetFragmentProgram() != NULL;
+			//	bucket->mHasVertexProgram = (tech->GetVertexProgram() != NULL);
+			//	bucket->mHasFragmentProgram = (tech->GetFragmentProgram() != NULL);
+			bucket->mVertexProgram = tech->GetVertexProgram();
+			bucket->mFragmentProgram = tech->GetFragmentProgram();
 
 			mBuckets.push_back(bucket);
-
-			cout << "num buckets: " << (int)mBuckets.size() << endl;
+			//cout << "increased #buckets to " << (int)mBuckets.size() << endl;
 		}
 
 		bucket = mBuckets[i];
-		shape->mRenderQueueBucket = bucket;
+		tech->mRenderQueueBucket = bucket;
 	}
 
@@ -226,5 +225,5 @@
 			Shape *shape = *sit;
 			
-			Technique *tech = shape->GetMaterial()->GetDefaultTechnique();
+			Technique *tech = shape->GetMaterial()->GetTechnique(mState->GetRenderTechnique());
 			int tsize = tech->GetTexture() ? tech->GetTexture()->GetByteSize() : 0;
 			
@@ -239,5 +238,5 @@
 void RenderQueue::Sort()
 {
-	// sort buckets itself
+	// sort buckets itself by distance
 	sort(mBuckets.begin(), mBuckets.end(), CompDist);
 }
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SkyPreetham.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SkyPreetham.cpp	(revision 3048)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SkyPreetham.cpp	(revision 3054)
@@ -143,5 +143,5 @@
 	else
 	{
-		// no tone mapping => scale
+		// no tone mapping => scale to range
 		vtxParams->SetValue1f(8, 8e-5f);
 	}
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Shape.h
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Shape.h	(revision 3034)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Shape.h	(revision 3054)
@@ -68,7 +68,4 @@
 	Material *mMaterial;
 	SceneEntity *mParent;
-
-	/// pointer to the renderqueue bucket this entity belongs to
-	RenderQueueBucket *mRenderQueueBucket;
 };
 
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ResourceManager.h
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ResourceManager.h	(revision 3052)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ResourceManager.h	(revision 3054)
@@ -51,4 +51,10 @@
 	void DisableFragmentProfile();
 	void DisableVertexProfile();
+	/** Returns pointer to shape container.
+	*/
+	const ShapeContainer * const GetShapes() const { return &mShapes; }
+	/** Returns pointer to scene entity container.
+	*/
+	const SceneEntityContainer * const GetSceneEntities() const { return &mSceneEntities; }
 
 	/** Returns the resource manager as a singleton.
@@ -97,5 +103,4 @@
 	ShapeContainer mShapes;
 	LODContainer mLODs;
-
 	/// the scene entities
 	SceneEntityContainer mSceneEntities;
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/RenderQueue.h
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/RenderQueue.h	(revision 3051)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/RenderQueue.h	(revision 3054)
@@ -33,6 +33,8 @@
 	bool mCullFaceEnabled;
 
-	bool mHasVertexProgram;
-	bool mHasFragmentProgram;
+	//bool mHasVertexProgram;
+	//bool mHasFragmentProgram;
+	ShaderProgram *mVertexProgram;
+	ShaderProgram *mFragmentProgram;
 
 	/// minimal distance to the camera
@@ -65,4 +67,7 @@
 	*/
 	void Enqueue(SceneEntity *entity);
+	/** Enqueues a single shape.
+	*/
+	void Enqueue(Shape *shape);
 	/** Sets the current render state
 	*/
@@ -77,5 +82,7 @@
 	*/
 	void Apply();
-
+	/** Clears the render queue
+	*/
+	void Clear();
 
 protected:
@@ -83,10 +90,5 @@
 	void Sort();
 
-	void Enqueue(Shape *shape);
-
 	inline bool FitsInBucket(Shape *shape, size_t idx) const;
-	/** Clears the render queue
-	*/
-	void Clear();
 	/** Renders the contents of the render queue.
 	*/
@@ -104,5 +106,4 @@
 	//SceneEntityContainer mEntities;
 	int mMinSizeForSorting;
-
 	/// each bucket contains objects with similar materials that don't cause a hard state change
 	std::vector<RenderQueueBucket *> mBuckets;
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Material.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Material.cpp	(revision 3050)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Material.cpp	(revision 3054)
@@ -34,6 +34,8 @@
 	// if lighting is used
 	mLightingEnabled = true;
+	/// if depth write should be enabled
+	mDepthWriteEnabled = true;
 
-	mDepthWriteEnabled = true;
+	mRenderQueueBucket = NULL;
 }
 
@@ -58,5 +60,5 @@
 }
 
-
+/*
 Technique::Technique(const Technique &tech)
 {
@@ -80,5 +82,5 @@
 	mLightingEnabled = tech.mLightingEnabled;
 	mDepthWriteEnabled = tech.mDepthWriteEnabled;
-}
+}*/
 
 
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/chcdemo.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/chcdemo.cpp	(revision 3052)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/chcdemo.cpp	(revision 3054)
@@ -162,5 +162,4 @@
 int horizontalMotionBegin = 0;
 
-
 bool leftKeyPressed = false;
 bool rightKeyPressed = false;
@@ -170,4 +169,6 @@
 bool ascendKeyPressed = false;
 
+bool altKeyPressed = false;
+
 bool showHelp = false;
 bool showStatistics = false;
@@ -193,18 +194,16 @@
 bool showShadowMap = false;
 bool renderLightView = false;
-
-bool altKeyPressed = false;
-
 bool useHDR = true;
 
+PerfTimer frameTimer, algTimer;
+
+PerformanceGraph *perfGraph = NULL;
+
 static float ssaoTempCohFactor = 255.0;
-
-
-PerfTimer frameTimer, algTimer;
-
 static int sCurrentMrtSet = 0;
 
-PerformanceGraph *perfGraph = NULL;
-
+
+#define CAMERA_PASS 0
+#define LIGHT_PASS 1
 
 //DeferredRenderer::SAMPLING_METHOD samplingMethod = DeferredRenderer::SAMPLING_POISSON;
@@ -267,4 +266,5 @@
 void RenderShadowMap(float newfar);
 
+
 static Matrix4x4 viewProjMat = IdentityMatrix();
 static Matrix4x4 oldViewProjMat = IdentityMatrix();
@@ -356,5 +356,4 @@
 
 		//cout << "model path: " << model_path << endl;
-
 		cout << "**** end parameters ****" << endl << endl;
 	}
@@ -454,6 +453,4 @@
 	Matrix4x4 transl = TranslationMatrix(cubeCenter);
 
-	SceneEntityContainer dummy;
-	
 	string skyDomeStr(model_path + "sky.dem");
 
@@ -479,4 +476,21 @@
 	visualization = new Visualization(bvh, camera, NULL, &state);
 	
+	for (int i = 0; i < 3; ++ i)
+	{
+		state.SetRenderTechnique((RenderState::RenderTechnique)i);
+
+		// fill all shapes into the render queue	once so we can establish the buckets
+		ShapeContainer::const_iterator sit, sit_end = (*loader->GetShapes()).end();
+
+		for (sit = (*loader->GetShapes()).begin(); sit != sit_end; ++ sit)
+		{
+			renderQueue->Enqueue(*sit);
+		}
+	
+		//renderQueue->Apply();
+		// just clear queue again
+		renderQueue->Clear();
+	}
+
 	state.SetRenderTechnique(RenderState::FORWARD);
 
@@ -978,7 +992,7 @@
 		// change CHC++ set of state variables (must be done for each change of camera because
 		// otherwise the temporal coherency is broken
-		BvhNode::SetCurrentState(1);
+		BvhNode::SetCurrentState(LIGHT_PASS);
 		shadowMap->RenderShadowView(shadowTraverser, viewProjMat);
-		BvhNode::SetCurrentState(0);
+		BvhNode::SetCurrentState(CAMERA_PASS);
 	}
 	else
@@ -1013,7 +1027,4 @@
 	{
 		FrameBufferObject::Release();
-
-		//loader->DisableVertexProfile();
-		//loader->DisableFragmentProfile();
 
 		if (!ssaoShader) ssaoShader = 
@@ -1960,9 +1971,7 @@
 	// this must be done for each change of camera because
 	// otherwise the temporal coherency is broken
-	BvhNode::SetCurrentState(1);
-
+	BvhNode::SetCurrentState(LIGHT_PASS);
 	// hack: temporarily change camera far plane
 	camera->SetFar(newfar);
-
 	// the scene is rendered withouth any shading	
 	shadowMap->ComputeShadowMap(shadowTraverser, viewProjMat);
@@ -1977,4 +1986,4 @@
 
 	// change back state
-	BvhNode::SetCurrentState(0);
-}
+	BvhNode::SetCurrentState(CAMERA_PASS);
+}
