Index: GTP/trunk/App/Demos/Vis/CHC_revisited/SceneEntity.h
===================================================================
--- GTP/trunk/App/Demos/Vis/CHC_revisited/SceneEntity.h	(revision 2764)
+++ GTP/trunk/App/Demos/Vis/CHC_revisited/SceneEntity.h	(revision 2767)
@@ -57,5 +57,6 @@
 	*/
 	int GetLastRendered() const;
-	
+
+	Material *GetMaterial() const  { return mMaterial; }
 
 protected:
Index: GTP/trunk/App/Demos/Vis/CHC_revisited/Texture.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/CHC_revisited/Texture.cpp	(revision 2764)
+++ GTP/trunk/App/Demos/Vis/CHC_revisited/Texture.cpp	(revision 2767)
@@ -61,4 +61,5 @@
 	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
 	//glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
+	//glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);
 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
 	//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
Index: GTP/trunk/App/Demos/Vis/CHC_revisited/Material.h
===================================================================
--- GTP/trunk/App/Demos/Vis/CHC_revisited/Material.h	(revision 2756)
+++ GTP/trunk/App/Demos/Vis/CHC_revisited/Material.h	(revision 2767)
@@ -15,21 +15,19 @@
   float r, g, b;
 
-  RgbColor():r(0.5f),g(0.5f),b(0.5f)
+  RgbColor(): r(0.5f), g(0.5f), b(0.5f)
   {
   }
 
-  RgbColor(const float _r,
-	   const float _g,
-	   const float _b):r(_r),g(_g),b(_b)
+  RgbColor(float _r, float _g, float _b): r(_r), g(_g), b(_b)
   {
   }
 
   friend RgbColor
-  RandomColor(const float a=0.0f, const float b=1.0f);
+  RandomColor(float a = 0.0f, float b = 1.0f);
 
   // Mapping from interval 0.0-1.0 to RGB using "rainbow" color map
   // (range of hue from 0-240)
 
-  friend RgbColor RainbowColorMapping(const float value);
+  friend RgbColor RainbowColorMapping(float value);
   
 };
Index: GTP/trunk/App/Demos/Vis/CHC_revisited/RenderTraverser.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/CHC_revisited/RenderTraverser.cpp	(revision 2765)
+++ GTP/trunk/App/Demos/Vis/CHC_revisited/RenderTraverser.cpp	(revision 2767)
@@ -46,16 +46,4 @@
 
 
-void RenderTraverser::InitFrame(Camera *camera, int currentFrameId)
-{
-	mFrameId = currentFrameId;
-	mBvh->InitFrame(camera, currentFrameId);
-
-	mStats.Reset();
-	mQueryHandler.ResetQueries();
-	mRenderState->mTexturesEnabled = false;
-	EnqueueNode(mBvh->GetRoot());
-}
-
-
 void RenderTraverser::EnqueueNode(BvhNode *node)
 {
@@ -71,6 +59,16 @@
 	if (node->IsVirtualLeaf())
 	{
-		//RenderBox(node->GetBox());
-		mStats.mNumRenderedGeometry +=	mBvh->Render(node, mRenderState);
+		if (mUseRenderQueue)
+		{
+			int geometrySize;
+			SceneEntity **geom = mBvh->GetGeometry(node, geometrySize);
+			mRenderQueue.Enqueue(geom, geometrySize);
+			mStats.mNumRenderedGeometry += geometrySize;
+		}
+		else
+		{
+			// RenderBox(node->GetBox());
+			mStats.mNumRenderedGeometry += mBvh->Render(node, mRenderState);
+		}		
 	}
 	else 
@@ -88,5 +86,4 @@
 {
 	mBvh = bvh;
-	//DelQueries();
 }
 
@@ -95,7 +92,6 @@
 {
 	mRenderState = state;
-	//DelQueries();
-}
-
+	mRenderQueue.SetRenderState(state);
+}
 
 
@@ -157,15 +153,4 @@
 
 
-
-void RenderTraverser::PullUpVisibility(BvhNode *node)
-{
-	while(node && ! node->IsVisible())
-	{
-		node->SetVisible(true);
-		node = node->GetParent();
-	}
-}
-
-
 void RenderTraverser::SetVisibilityThreshold(int threshold)
 {
@@ -180,141 +165,52 @@
 
 
-/*
-void RenderTraverser::RenderVisualization()
-{
-	mDistanceQueue.push(mHierarchyRoot);
-
-	while(!	mDistanceQueue.empty())
-	{
-		HierarchyNode *node = mDistanceQueue.top();
-		mDistanceQueue.pop();
-
-		// identify previously visible nodes
-		bool wasVisible = node->Visible() && (node->LastVisited() == mFrameID - 1);
-
-		if(wasVisible)
-			TraverseNode(node);
-		else
-		{
-			// also render culled nodes
-			glColor3f(1.0,0.0,0.0);
-			node->RenderBoundingVolumeForVisualization();		
-		}
-	}
-}*/
-
-
 void RenderTraverser::SetUseOptimization(bool useOptimization)
 {
 	mUseOptimization = useOptimization;
-	printf("using opt %d\n", mUseOptimization);
-}
-
-
-void RenderTraverser::RenderBox(const AxisAlignedBox3 &box)
-{
-	glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
-	glDisable(GL_CULL_FACE);
-	glColor3f(1.0f, 0.0f, 0.0f);
-
-	glBegin(GL_QUADS);
-	glVertex3f(box.Min().x, box.Max().y, box.Min().z);
-	glVertex3f(box.Max().x, box.Max().y, box.Min().z);
-	glVertex3f(box.Max().x, box.Min().y, box.Min().z);
-	glVertex3f(box.Min().x, box.Min().y, box.Min().z);
-	glEnd();
-
-	glBegin(GL_QUADS);
-	glVertex3f(box.Min().x, box.Min().y, box.Max().z);
-	glVertex3f(box.Max().x, box.Min().y, box.Max().z);
-	glVertex3f(box.Max().x, box.Max().y, box.Max().z);
-	glVertex3f(box.Min().x, box.Max().y, box.Max().z);
-	glEnd();
-
-	glBegin(GL_QUADS);
-	glVertex3f(box.Max().x, box.Min().y, box.Min().z);
-	glVertex3f(box.Max().x, box.Min().y, box.Max().z);
-	glVertex3f(box.Max().x, box.Max().y, box.Max().z);
-	glVertex3f(box.Max().x, box.Max().y, box.Min().z);
-	glEnd();
-
-	glBegin(GL_QUADS);
-	glVertex3f(box.Min().x, box.Min().y, box.Min().z);
-	glVertex3f(box.Min().x, box.Min().y, box.Max().z);
-	glVertex3f(box.Min().x, box.Max().y, box.Max().z);
-	glVertex3f(box.Min().x, box.Max().y, box.Min().z);
-	glEnd();
-
-	glBegin(GL_QUADS);
-	glVertex3f(box.Min().x, box.Min().y, box.Min().z);
-	glVertex3f(box.Max().x, box.Min().y, box.Min().z);
-	glVertex3f(box.Max().x, box.Min().y, box.Max().z);
-	glVertex3f(box.Min().x, box.Min().y, box.Max().z);
-	glEnd();
-
-	glBegin(GL_QUADS);
-	glVertex3f(box.Min().x, box.Max().y, box.Min().z);
-	glVertex3f(box.Max().x, box.Max().y, box.Min().z);
-	glVertex3f(box.Max().x, box.Max().y, box.Max().z);
-	glVertex3f(box.Min().x, box.Max().y, box.Max().z);
-	glEnd();
-
-	glEnable(GL_CULL_FACE);
-
-	glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
-}
-
-
-void RenderTraverser::RenderFrustum()
-{
-	Vector3 ftl, ftr, fbl, fbr, ntl, ntr, nbl, nbr;
-	mCamera->ComputePoints(ftl, ftr, fbl, fbr, ntl, ntr, nbl, nbr);
-
-	glLineWidth(2);
-
-	glBegin(GL_LINE_LOOP);
-	glVertex3d(fbl.x, fbl.y, fbl.z);
-	glVertex3d(fbr.x, fbr.y, fbr.z);
-	glVertex3d(ftr.x, ftr.y, ftr.z);
-	glVertex3d(ftl.x, ftl.y, ftl.z);
-	glEnd();
-
-	glBegin(GL_LINE_LOOP);
-	glVertex3d(nbl.x, nbl.y, nbl.z);
-	glVertex3d(nbr.x, nbr.y, nbr.z);
-	glVertex3d(ntr.x, ntr.y, ntr.z);
-	glVertex3d(ntl.x, ntl.y, ntl.z);
-	glEnd();
-
-	glBegin(GL_LINE_LOOP);
-	glVertex3d(fbl.x, fbl.y, fbl.z);
-	glVertex3d(ftl.x, ftl.y, ftl.z);
-	glVertex3d(ntl.x, ntl.y, ntl.z);
-	glVertex3d(nbl.x, nbl.y, nbl.z);
-	glEnd();
-
-	glBegin(GL_LINE_LOOP);
-	glVertex3d(fbr.x, fbr.y, fbr.z);
-	glVertex3d(ftr.x, ftr.y, ftr.z);
-	glVertex3d(ntr.x, ntr.y, ntr.z);
-	glVertex3d(nbr.x, nbr.y, nbr.z);
-	glEnd();
-
-	glBegin(GL_LINE_LOOP);
-	glVertex3d(fbr.x, fbr.y, fbr.z);
-	glVertex3d(fbl.x, fbl.y, fbl.z);
-	glVertex3d(nbl.x, nbl.y, nbl.z);
-	glVertex3d(nbr.x, nbr.y, nbr.z);
-	glEnd();
-
-	glBegin(GL_LINE_LOOP);
-	glVertex3d(ftr.x, ftr.y, ftr.z);
-	glVertex3d(ftl.x, ftl.y, ftl.z);
-	glVertex3d(ntl.x, ntl.y, ntl.z);
-	glVertex3d(ntr.x, ntr.y, ntr.z);
-	glEnd();
-}
-
-
-
-}
+}
+
+
+
+void RenderTraverser::RenderScene()
+{
+	InitTiming();
+	long t1, t2;
+
+	t1 = GetTime();
+
+	glEnableClientState(GL_VERTEX_ARRAY);
+	glEnableClientState(GL_NORMAL_ARRAY);
+
+	++ mFrameId;
+
+	mBvh->InitFrame(mCamera, mFrameId);
+
+	mStats.Reset();
+	mQueryHandler.ResetQueries();
+	mRenderState->mTexturesEnabled = false;
+	EnqueueNode(mBvh->GetRoot());
+
+
+	///////////
+	//-- the actual rendering algorithm
+
+	Traverse();
+
+	glDisableClientState(GL_VERTEX_ARRAY);
+	glDisableClientState(GL_NORMAL_ARRAY);
+
+	glDisable(GL_TEXTURE_2D);
+	glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+	
+	t2 = GetTime();
+	mStats.mRenderTime = TimeDiff(t1, t2);
+}
+
+
+void RenderTraverser::SetUseRenderQueue(bool useRenderQueue)
+{
+	mUseRenderQueue = useRenderQueue;
+	std::cout << "using render queue: " << mUseRenderQueue << std::endl;
+}
+
+}
Index: GTP/trunk/App/Demos/Vis/CHC_revisited/Visualization.h
===================================================================
--- GTP/trunk/App/Demos/Vis/CHC_revisited/Visualization.h	(revision 2767)
+++ GTP/trunk/App/Demos/Vis/CHC_revisited/Visualization.h	(revision 2767)
@@ -0,0 +1,71 @@
+#ifndef __VISUALIZATION_H
+#define __VISUALIZATION_H
+
+#include "common.h"
+
+
+namespace CHCDemo
+{
+
+class Bvh;
+class Camera;
+class RenderState;
+class AxisAlignedBox3;
+
+
+/** Abstract class implementing a scene traversal for rendering.
+*/
+class Visualization
+{
+public:
+	
+	Visualization(Bvh *bvh, Camera *camera, Camera *vizCamera, RenderState *renderState);
+
+	~Visualization() {}
+
+	/** Renders the visualizatioin
+	*/
+	void Render();
+	/** Sets the scene hierarchy.
+	*/
+	void SetHierarchy(Bvh *bvh);
+	/** Sets the visualization camera.
+	*/
+	void SetVizCamera(Camera *cam)  {mVizCamera = cam;}
+	/** Sets the currently used scene camera.
+	*/
+	void SetCamera(Camera *cam)  {mCamera = cam;}
+	/** Sets the current render state
+	*/
+	void SetRenderState(RenderState *state);
+	
+
+protected:
+
+	/** Renders a camera frustum.
+	*/
+	void RenderFrustum();
+	/** Renders a bounding box for visualization.
+	*/
+	void RenderBox(const AxisAlignedBox3 &box);
+
+
+
+	////////////
+	//-- members
+
+	/// the current camera
+	Camera *mCamera;
+	/// the visualization camera
+	Camera *mVizCamera;
+	/// the root of the scene hierarchy
+	Bvh *mBvh;
+	/// the current render state
+	RenderState *mRenderState;
+};
+
+}
+
+
+
+#endif // VISUALIZATION_H
Index: GTP/trunk/App/Demos/Vis/CHC_revisited/RenderQueue.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/CHC_revisited/RenderQueue.cpp	(revision 2767)
+++ GTP/trunk/App/Demos/Vis/CHC_revisited/RenderQueue.cpp	(revision 2767)
@@ -0,0 +1,85 @@
+#include "RenderQueue.h"
+#include "SceneEntity.h"
+#include "Geometry.h"
+#include "Texture.h"
+#include "Material.h"
+
+
+
+namespace CHCDemo
+{
+
+
+inline static bool IsLower(SceneEntity *ent1, SceneEntity *ent2)
+{
+	if (ent1->GetGeometry()->HasTexture() && ent2->GetGeometry()->HasTexture())
+	{
+		Texture *t1 = ent1->GetMaterial()->GetTexture();
+		Texture *t2 = ent1->GetMaterial()->GetTexture();
+
+		return t1->GetByteSize() < t2->GetByteSize();
+	}
+	else if (ent2->GetGeometry()->HasTexture())
+	{
+		return true;
+	}
+
+	return false;
+}
+
+
+
+RenderQueue::RenderQueue(): mState(NULL)
+{
+}
+
+
+RenderQueue::RenderQueue(RenderState *state):
+mState(state)
+{
+}
+
+
+void RenderQueue::Enqueue(SceneEntity **entities, int size)
+{
+	for (int i = 0; i < size; ++ i)
+		mEntities.push_back(entities[i]);
+
+}
+	
+
+void RenderQueue::Clear()
+{
+	mEntities.clear();
+
+}
+
+
+void RenderQueue::SetRenderState(RenderState *state)
+{
+	mState = state;
+}
+
+
+void RenderQueue::Render()
+{
+	Sort();
+
+	SceneEntityContainer::const_iterator sit, sit_end = mEntities.end();
+
+	for (sit = mEntities.begin(); sit != sit_end; ++ sit)
+	{
+		SceneEntity *ent = *sit;
+		ent->Render(mState);
+	}
+}
+
+	
+
+void RenderQueue::Sort()
+{
+	sort(mEntities.begin(), mEntities.end());
+}
+
+
+}
Index: GTP/trunk/App/Demos/Vis/CHC_revisited/Bvh.h
===================================================================
--- GTP/trunk/App/Demos/Vis/CHC_revisited/Bvh.h	(revision 2764)
+++ GTP/trunk/App/Demos/Vis/CHC_revisited/Bvh.h	(revision 2767)
@@ -27,5 +27,5 @@
 	friend class Bvh;
 	friend class BvhLoader;
-	friend class myless;
+	friend class mygreaterdistance;
 
 public:
@@ -393,5 +393,5 @@
 	a lower distance has a higher value in the queue
 */
-class myless
+class mygreaterdistance
 {
 public:
@@ -401,4 +401,6 @@
     }
 };
+
+typedef std::priority_queue<BvhNode *, std::vector<BvhNode *>, mygreaterdistance> TraversalQueue;
 
 
Index: GTP/trunk/App/Demos/Vis/CHC_revisited/StopAndWaitTraverser.h
===================================================================
--- GTP/trunk/App/Demos/Vis/CHC_revisited/StopAndWaitTraverser.h	(revision 2763)
+++ GTP/trunk/App/Demos/Vis/CHC_revisited/StopAndWaitTraverser.h	(revision 2767)
@@ -13,10 +13,14 @@
 {
 public:
+
 	StopAndWaitTraverser();
-	~StopAndWaitTraverser();
 
-	/** Renders the scene with the specified method
+	//~StopAndWaitTraverser();
+
+protected:
+	/** Traverses and renders the scene with the specified method
 	*/
-	virtual void Render();
+	virtual void Traverse();
+
 };
 
Index: GTP/trunk/App/Demos/Vis/CHC_revisited/CHCTraverser.h
===================================================================
--- GTP/trunk/App/Demos/Vis/CHC_revisited/CHCTraverser.h	(revision 2755)
+++ GTP/trunk/App/Demos/Vis/CHC_revisited/CHCTraverser.h	(revision 2767)
@@ -14,9 +14,11 @@
 public:
 	CHCTraverser();
-	~CHCTraverser();
+	//~CHCTraverser();
 
-	/** Renders the scene with the specified method
+	
+protected:
+	/** Traverses and renders the scene with the specified method
 	*/
-	virtual void Render();
+	virtual void Traverse();
 };
 
Index: GTP/trunk/App/Demos/Vis/CHC_revisited/Visualization.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/CHC_revisited/Visualization.cpp	(revision 2767)
+++ GTP/trunk/App/Demos/Vis/CHC_revisited/Visualization.cpp	(revision 2767)
@@ -0,0 +1,171 @@
+#include "Visualization.h"
+#include "glInterface.h"
+#include "Camera.h"
+#include "SceneEntity.h"
+#include "Bvh.h"
+#include <stack>
+
+
+using namespace std;
+
+
+namespace CHCDemo
+{
+
+/******************************************************/
+/*           Vizualization implementation           */
+/******************************************************/
+
+
+Visualization::Visualization(Bvh *bvh, 
+							 Camera *camera, 
+							 Camera *vizCamera, 
+							 RenderState *renderState): 
+mBvh(bvh), mCamera(camera), mVizCamera(vizCamera), mRenderState(renderState)
+{
+}
+
+
+void Visualization::SetHierarchy(Bvh *bvh)
+{
+	mBvh = bvh;
+}
+
+
+void Visualization::SetRenderState(RenderState *state)
+{
+	mRenderState = state;
+}
+
+
+void Visualization::Render()
+{
+	stack<BvhNode *> tStack;
+	tStack.push(mBvh->GetRoot());
+
+	while (!tStack.empty())
+	{
+		BvhNode *node = tStack.top();
+		tStack.pop();
+
+		if (!node->IsLeaf())
+		{
+			BvhInterior *interior = static_cast<BvhInterior *>(node);
+
+			tStack.push(interior->GetFront());
+			tStack.push(interior->GetBack());
+		}
+		else
+		{
+			//leaves.push_back(static_cast<BvhLeaf *>(node));
+		}
+	}
+}
+
+
+void Visualization::RenderBox(const AxisAlignedBox3 &box)
+{
+	glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+	glDisable(GL_CULL_FACE);
+	glColor3f(1.0f, 0.0f, 0.0f);
+
+	glBegin(GL_QUADS);
+	glVertex3f(box.Min().x, box.Max().y, box.Min().z);
+	glVertex3f(box.Max().x, box.Max().y, box.Min().z);
+	glVertex3f(box.Max().x, box.Min().y, box.Min().z);
+	glVertex3f(box.Min().x, box.Min().y, box.Min().z);
+	glEnd();
+
+	glBegin(GL_QUADS);
+	glVertex3f(box.Min().x, box.Min().y, box.Max().z);
+	glVertex3f(box.Max().x, box.Min().y, box.Max().z);
+	glVertex3f(box.Max().x, box.Max().y, box.Max().z);
+	glVertex3f(box.Min().x, box.Max().y, box.Max().z);
+	glEnd();
+
+	glBegin(GL_QUADS);
+	glVertex3f(box.Max().x, box.Min().y, box.Min().z);
+	glVertex3f(box.Max().x, box.Min().y, box.Max().z);
+	glVertex3f(box.Max().x, box.Max().y, box.Max().z);
+	glVertex3f(box.Max().x, box.Max().y, box.Min().z);
+	glEnd();
+
+	glBegin(GL_QUADS);
+	glVertex3f(box.Min().x, box.Min().y, box.Min().z);
+	glVertex3f(box.Min().x, box.Min().y, box.Max().z);
+	glVertex3f(box.Min().x, box.Max().y, box.Max().z);
+	glVertex3f(box.Min().x, box.Max().y, box.Min().z);
+	glEnd();
+
+	glBegin(GL_QUADS);
+	glVertex3f(box.Min().x, box.Min().y, box.Min().z);
+	glVertex3f(box.Max().x, box.Min().y, box.Min().z);
+	glVertex3f(box.Max().x, box.Min().y, box.Max().z);
+	glVertex3f(box.Min().x, box.Min().y, box.Max().z);
+	glEnd();
+
+	glBegin(GL_QUADS);
+	glVertex3f(box.Min().x, box.Max().y, box.Min().z);
+	glVertex3f(box.Max().x, box.Max().y, box.Min().z);
+	glVertex3f(box.Max().x, box.Max().y, box.Max().z);
+	glVertex3f(box.Min().x, box.Max().y, box.Max().z);
+	glEnd();
+
+	glEnable(GL_CULL_FACE);
+
+	glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+}
+
+
+void Visualization::RenderFrustum()
+{
+	Vector3 ftl, ftr, fbl, fbr, ntl, ntr, nbl, nbr;
+	mCamera->ComputePoints(ftl, ftr, fbl, fbr, ntl, ntr, nbl, nbr);
+
+	glLineWidth(2);
+
+	glBegin(GL_LINE_LOOP);
+	glVertex3d(fbl.x, fbl.y, fbl.z);
+	glVertex3d(fbr.x, fbr.y, fbr.z);
+	glVertex3d(ftr.x, ftr.y, ftr.z);
+	glVertex3d(ftl.x, ftl.y, ftl.z);
+	glEnd();
+
+	glBegin(GL_LINE_LOOP);
+	glVertex3d(nbl.x, nbl.y, nbl.z);
+	glVertex3d(nbr.x, nbr.y, nbr.z);
+	glVertex3d(ntr.x, ntr.y, ntr.z);
+	glVertex3d(ntl.x, ntl.y, ntl.z);
+	glEnd();
+
+	glBegin(GL_LINE_LOOP);
+	glVertex3d(fbl.x, fbl.y, fbl.z);
+	glVertex3d(ftl.x, ftl.y, ftl.z);
+	glVertex3d(ntl.x, ntl.y, ntl.z);
+	glVertex3d(nbl.x, nbl.y, nbl.z);
+	glEnd();
+
+	glBegin(GL_LINE_LOOP);
+	glVertex3d(fbr.x, fbr.y, fbr.z);
+	glVertex3d(ftr.x, ftr.y, ftr.z);
+	glVertex3d(ntr.x, ntr.y, ntr.z);
+	glVertex3d(nbr.x, nbr.y, nbr.z);
+	glEnd();
+
+	glBegin(GL_LINE_LOOP);
+	glVertex3d(fbr.x, fbr.y, fbr.z);
+	glVertex3d(fbl.x, fbl.y, fbl.z);
+	glVertex3d(nbl.x, nbl.y, nbl.z);
+	glVertex3d(nbr.x, nbr.y, nbr.z);
+	glEnd();
+
+	glBegin(GL_LINE_LOOP);
+	glVertex3d(ftr.x, ftr.y, ftr.z);
+	glVertex3d(ftl.x, ftl.y, ftl.z);
+	glVertex3d(ntl.x, ntl.y, ntl.z);
+	glVertex3d(ntr.x, ntr.y, ntr.z);
+	glEnd();
+}
+
+
+}
Index: GTP/trunk/App/Demos/Vis/CHC_revisited/CHCPlusPlusTraverser.h
===================================================================
--- GTP/trunk/App/Demos/Vis/CHC_revisited/CHCPlusPlusTraverser.h	(revision 2755)
+++ GTP/trunk/App/Demos/Vis/CHC_revisited/CHCPlusPlusTraverser.h	(revision 2767)
@@ -8,15 +8,17 @@
 {
 
-/** Class implementing traversal using the CHC algorithm.
+/** Class implementing traversal using the CHC++ algorithm.
 */
 class CHCPlusPlusTraverser: public RenderTraverser
 {
 public:
+	
 	CHCPlusPlusTraverser();
-	~CHCPlusPlusTraverser();
+	//~CHCPlusPlusTraverser();
 
-	/** Renders the scene with the specified method
+protected:
+	/** Traverses and renders the scene with the specified method
 	*/
-	virtual void Render();
+	virtual void Traverse();
 };
 
@@ -25,3 +27,3 @@
 
 
-#endif // __CHCTRAVERSER_H
+#endif // __CHCPLUSPLUSTRAVERSER_H
Index: GTP/trunk/App/Demos/Vis/CHC_revisited/FrustumCullingTraverser.h
===================================================================
--- GTP/trunk/App/Demos/Vis/CHC_revisited/FrustumCullingTraverser.h	(revision 2757)
+++ GTP/trunk/App/Demos/Vis/CHC_revisited/FrustumCullingTraverser.h	(revision 2767)
@@ -16,7 +16,8 @@
 	FrustumCullingTraverser();
 
-	/** Renders the scene with the specified method
+protected:
+	/** Traverses and renders the scene with the specified method
 	*/
-	virtual void Render();
+	virtual void Traverse();
 };
 
Index: GTP/trunk/App/Demos/Vis/CHC_revisited/RenderQueue.h
===================================================================
--- GTP/trunk/App/Demos/Vis/CHC_revisited/RenderQueue.h	(revision 2767)
+++ GTP/trunk/App/Demos/Vis/CHC_revisited/RenderQueue.h	(revision 2767)
@@ -0,0 +1,54 @@
+#ifndef __RENDERQUEUE_H
+#define __RENDERQUEUE_H
+
+#include "common.h"
+
+namespace CHCDemo 
+{
+
+class RenderState;
+
+
+/** This class implements a render queue that sorts entities according to
+	their materials.
+*/
+class RenderQueue
+{
+public:
+
+	/** Default constructor
+	*/
+	RenderQueue();
+	/** Constructor taking a render queue
+	*/
+	RenderQueue(RenderState *state);
+	/** Enqueues a number of entities
+	*/
+	void Enqueue(SceneEntity **entities, int size);
+	/** Renders the contents of the render queue.
+	*/
+	void Render();
+	/** Sets the current render state
+	*/
+	void SetRenderState(RenderState *state);
+	/** Clears the render queue
+	*/
+	void Clear();
+
+
+protected:
+
+	/** Sorts the render queue according to some parameters.
+	*/
+	void Sort();
+
+
+	///////////
+
+	RenderState *mState;
+	SceneEntityContainer mEntities;
+};
+
+}
+
+#endif
Index: GTP/trunk/App/Demos/Vis/CHC_revisited/CHCTraverser.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/CHC_revisited/CHCTraverser.cpp	(revision 2765)
+++ GTP/trunk/App/Demos/Vis/CHC_revisited/CHCTraverser.cpp	(revision 2767)
@@ -6,27 +6,18 @@
 {
 
-CHCTraverser::CHCTraverser(): RenderTraverser() 
-{
-}
+CHCTraverser::CHCTraverser() 
+{}
 
 
-CHCTraverser::~CHCTraverser()
+void CHCTraverser::Traverse()
 {
-	//DelQueries();
-}
-
-
-void CHCTraverser::Render()
-{
-	QueryQueue queryQueue;
-
 	//-- PART 1: process finished occlusion queries
-	while (!mDistanceQueue.empty() || !queryQueue.empty())
+	while (!mDistanceQueue.empty() || !mQueryQueue.empty())
 	{
-		while (!queryQueue.empty() && 
-			   (queryQueue.front()->ResultAvailable() || mDistanceQueue.empty()))
+		while (!mQueryQueue.empty() && 
+			   (mQueryQueue.front()->ResultAvailable() || mDistanceQueue.empty()))
 		{
-			OcclusionQuery *query = queryQueue.front();
-			queryQueue.pop();
+			OcclusionQuery *query = mQueryQueue.front();
+			mQueryQueue.pop();
 			
 			// wait until result available
@@ -84,5 +75,5 @@
 					{
 						OcclusionQuery *query = IssueOcclusionQuery(node, wasVisible);
-						queryQueue.push(query);
+						mQueryQueue.push(query);
 					}
 					
Index: GTP/trunk/App/Demos/Vis/CHC_revisited/StopAndWaitTraverser.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/CHC_revisited/StopAndWaitTraverser.cpp	(revision 2765)
+++ GTP/trunk/App/Demos/Vis/CHC_revisited/StopAndWaitTraverser.cpp	(revision 2767)
@@ -10,16 +10,10 @@
 
 
-StopAndWaitTraverser::StopAndWaitTraverser(): RenderTraverser() 
+StopAndWaitTraverser::StopAndWaitTraverser()
 {
 }
 
 
-StopAndWaitTraverser::~StopAndWaitTraverser()
-{
-	//DelQueries();
-}
-
-
-void StopAndWaitTraverser::Render()
+void StopAndWaitTraverser::Traverse()
 {
 	while (!mDistanceQueue.empty())
Index: GTP/trunk/App/Demos/Vis/CHC_revisited/chc_revisited.vcproj
===================================================================
--- GTP/trunk/App/Demos/Vis/CHC_revisited/chc_revisited.vcproj	(revision 2764)
+++ GTP/trunk/App/Demos/Vis/CHC_revisited/chc_revisited.vcproj	(revision 2767)
@@ -358,4 +358,8 @@
 				</File>
 				<File
+					RelativePath=".\RenderQueue.h"
+					>
+				</File>
+				<File
 					RelativePath=".\SceneEntity.h"
 					>
@@ -363,4 +367,8 @@
 				<File
 					RelativePath=".\Texture.h"
+					>
+				</File>
+				<File
+					RelativePath=".\Visualization.h"
 					>
 				</File>
@@ -396,4 +404,8 @@
 				</File>
 				<File
+					RelativePath=".\RenderQueue.cpp"
+					>
+				</File>
+				<File
 					RelativePath=".\SceneEntity.cpp"
 					>
@@ -401,4 +413,8 @@
 				<File
 					RelativePath=".\Texture.cpp"
+					>
+				</File>
+				<File
+					RelativePath=".\Visualization.cpp"
 					>
 				</File>
Index: GTP/trunk/App/Demos/Vis/CHC_revisited/Material.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/CHC_revisited/Material.cpp	(revision 2760)
+++ GTP/trunk/App/Demos/Vis/CHC_revisited/Material.cpp	(revision 2767)
@@ -18,8 +18,8 @@
 	mTexture = NULL;
 
-	mAmbientColor = RgbColor(0.2, 0.2, 0.2);
-	mDiffuseColor = RgbColor(1, 1, 1);
-	mSpecularColor = RgbColor(0.0, 0.0, 0.0);
-	//mSpecularColor = RgbColor(1, 1, 1);
+	mAmbientColor = RgbColor(.2f, .2f, .2f);
+	mDiffuseColor = RgbColor(1.0f, 1.0f, 1.0f);
+	mSpecularColor = RgbColor(0.0f, 0.0f, 0.0f);
+	mSpecularColor = RgbColor(1.0f, 1.0f, 1.0f);
 }
 
@@ -73,4 +73,12 @@
 		glBindTexture(GL_TEXTURE_2D, 0);
 
+/*	float amb[] = {0.2f, 0.2f, 0.2f, 1.0f};
+	float dif[] = {1.0f, 1.0f, 1.0f, 1.0f};
+	float spec[] = {1.0f, 1.0f, 1.0f, 1.0f};
+
+	glMaterialfv(GL_FRONT, GL_AMBIENT, (float *)&amb);
+	glMaterialfv(GL_FRONT, GL_DIFFUSE, (float *)&dif);
+	glMaterialfv(GL_FRONT, GL_SPECULAR, (float *)&spec);
+*/
 	glMaterialfv(GL_FRONT, GL_AMBIENT, (float *)&mAmbientColor.r);
 	glMaterialfv(GL_FRONT, GL_DIFFUSE, (float *)&mDiffuseColor.r);
Index: GTP/trunk/App/Demos/Vis/CHC_revisited/chcdemo.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/CHC_revisited/chcdemo.cpp	(revision 2765)
+++ GTP/trunk/App/Demos/Vis/CHC_revisited/chcdemo.cpp	(revision 2767)
@@ -17,4 +17,7 @@
 #include "StopAndWaitTraverser.h"
 #include "CHCTraverser.h"
+#include "CHCPlusPlusTraverser.h"
+#include "Visualization.h"
+
 
 
@@ -27,11 +30,11 @@
 SceneEntityContainer sceneEntities;
 // traverses and renders the hierarchy
-RenderTraverser *traverser;
+RenderTraverser *traverser = NULL;
 /// the hierarchy
-Bvh *bvh;
+Bvh *bvh = NULL;
 /// the scene camera
-Camera *camera;
-/// the scene bounding box
-AxisAlignedBox3 sceneBox;
+Camera *camera = NULL;
+/// the visualization
+Visualization *visualization = NULL;
 /// the current render state
 RenderState state;
@@ -43,4 +46,9 @@
 float nearDist = 0.1f; 
 
+const float keyForwardMotion = 1.0f;
+const float keyRotation = 0.2f;
+
+bool useRenderQueue = false;
+
 int winWidth = 1024;
 int winHeight = 768;
@@ -55,6 +63,4 @@
 
 
-int currentFrame = -1;
-
 // visualisation view matrix
 Matrix4x4 visView; 
@@ -63,15 +69,6 @@
 int xEyeBegin, yEyeBegin, yMotionBegin, verticalMotionBegin, horizontalMotionBegin = 0;
 
-const int renderTimeSize = 100;
-long renderTimes[renderTimeSize];
-int renderTimesIdx = 0;
-int renderTimesValid = 0;
-
 bool useOptimization = true;
 
-
-Vector3 amb[2];
-Vector3 dif[2];
-Vector3 spec[2];
 
 void InitExtensions();
@@ -100,5 +97,4 @@
 void setupVisView(void);
 long calcRenderTime(void);
-void resetTimer(void);
 void CalcDecimalPoint(std::string &str, int d);
 void ResetTraverser();
@@ -148,14 +144,11 @@
 	//bvh = bvhLoader.Load("house_test.bvh", sceneEntities);
 
-	sceneBox = bvh->GetBox();
-
 	ResetTraverser();
 
 	//camera->LookAtBox(sceneBox);
-	camera->LookInBox(sceneBox);
-
-	/// initialise rendertime array
-	for(int i=0; i<renderTimeSize; i++)
-		renderTimes[i] = 0;
+	//camera->LookInBox(bvh->GetBox());
+
+	camera->SetDirection(Vector3(0.961829f, 0.273652f, 0.0f));
+	camera->SetPosition(Vector3(483.398f, 242.364f, 186.078f));
 
 	glutMainLoop();
@@ -170,5 +163,5 @@
 void InitGLstate(void) 
 {
-	glClearColor(0.5f, 0.5f, 0.8f, 0.0);
+	glClearColor(0.5f, 0.5f, 0.8f, 0.0f);
 	
 	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
@@ -185,5 +178,10 @@
 	glMaterialf(GL_FRONT, GL_SHININESS, 64);
 	glEnable(GL_NORMALIZE);
-			
+		
+	//glEnable(GL_ALPHA_TEST);
+	//glAlphaFunc(GL_GEQUAL, 0.01);
+
+	glDisable(GL_ALPHA_TEST);
+
 	glFrontFace(GL_CCW);
 	glCullFace(GL_BACK);
@@ -288,8 +286,13 @@
 		traverser = new CHCTraverser();
 		break;
+	case RenderTraverser::CHCPLUSPLUS:
+		traverser = new CHCPlusPlusTraverser();
+		break;
+	
 	default:
 		traverser = new FrustumCullingTraverser();
 	}
 
+	traverser->SetCamera(camera);
 	traverser->SetHierarchy(bvh);
 	traverser->SetRenderState(&state);
@@ -302,4 +305,5 @@
 	glEnable(GL_LIGHT0);
 	glEnable(GL_LIGHT1);
+
 	//glDisable(GL_LIGHT1);
 	//glDisable(GL_LIGHTING);
@@ -349,5 +353,5 @@
 	glLoadIdentity();
 
-	gluPerspective(60.0f, 1.0f / winAspectRatio, nearDist, 2.0f * Magnitude(sceneBox.Diagonal()));
+	gluPerspective(60.0f, 1.0f / winAspectRatio, nearDist, 2.0f * Magnitude(bvh->GetBox().Diagonal()));
 
 	glMatrixMode(GL_MODELVIEW);
@@ -357,6 +361,5 @@
 	glLightfv(GL_LIGHT0, GL_POSITION, position);
 
-	GLfloat position1[] = {sceneBox.Center().x, sceneBox.Max().y, sceneBox.Center().z, 1.0f};
-	//GLfloat position1[] = {-2.0f, 1.0f, 0.0f, 0.0f};
+	GLfloat position1[] = {bvh->GetBox().Center().x, bvh->GetBox().Max().y, bvh->GetBox().Center().z, 1.0f};
 	glLightfv(GL_LIGHT1, GL_POSITION, position1);
 }
@@ -365,6 +368,4 @@
 void display(void) 
 {
-	++ currentFrame;
-
 	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
@@ -372,38 +373,12 @@
 	SetupEyeView();
 
-
-	traverser->InitFrame(camera, currentFrame);
-
-
-	InitTiming();
-	long t1, t2;
-
-	t1 = GetTime();
-
-	glEnableClientState(GL_VERTEX_ARRAY);
-	glEnableClientState(GL_NORMAL_ARRAY);
-
-	traverser->Render();
-
-	glDisableClientState(GL_VERTEX_ARRAY);
-	glDisableClientState(GL_NORMAL_ARRAY);
-
-	glDisable(GL_TEXTURE_2D);
-	glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-	
-
-	t2 = GetTime();
-	long loop_time = TimeDiff(t1, t2);
-	
-	// cycle through rendertime array
-	renderTimes[renderTimesIdx] = loop_time;// traverser.GetRenderTime();
-	renderTimesIdx = (renderTimesIdx + 1) % renderTimeSize;
-
-	if(renderTimesIdx  > renderTimesValid) 
-		renderTimesValid = renderTimesIdx;
-
+	//cout << camera->GetDirection() << " " << camera->GetPosition() << endl;
+	// actually render the scene geometry using one of the specified algorithms
+	traverser->RenderScene();
+	
 	//if(visMode) displayVisualization();
 	
 	DisplayStats();
+
 	glutSwapBuffers();
 }
@@ -413,4 +388,8 @@
 void keyboard(const unsigned char c, const int x, const int y) 
 {
+	// used to avoid vertical motion with the keys
+	Vector3 hvec = Vector3(camera->GetDirection()[0], camera->GetDirection()[1], 0.0f);
+	Vector3 uvec = Vector3(0, 0, 1);
+	
 	switch(c) 
 	{
@@ -420,5 +399,4 @@
 	case 32: //space
 		renderMode = (renderMode + 1) % RenderTraverser::NUM_RENDERMODES;
-		resetTimer();
 		ResetTraverser();
 		break;
@@ -432,6 +410,6 @@
 		//HierarchyNode::SetRenderBoundingVolume(showBoundingVolumes);
 		break;
-	case 's':
-	case 'S':
+	case 'O':
+	case 'o':
 		showStatistics = !showStatistics;
 		break;
@@ -449,5 +427,4 @@
 		visMode = !visMode;
 		break;
-	
 	case '2':
 		visZoomFactor += 0.1;	
@@ -460,8 +437,65 @@
 		setupVisView();
 		break;
+	case '8':
+		{
+			Vector3 pos = camera->GetPosition();
+			pos += uvec * keyForwardMotion;
+			camera->SetPosition(pos);
+			break;
+		}
+	case '9':
+		{
+			Vector3 pos = camera->GetPosition();
+			pos -= uvec * keyForwardMotion;
+			camera->SetPosition(pos);
+			break;
+		}	
 	case 'g':
 	case 'G':
 		useOptimization = !useOptimization;
 		traverser->SetUseOptimization(useOptimization);
+		break;
+	case 'a':
+	case 'A':
+		{
+			Vector3 viewDir = camera->GetDirection();
+			// rotate view vector
+			Matrix4x4 rot = RotationZMatrix(keyRotation);
+			viewDir = rot * viewDir;
+			camera->SetDirection(viewDir);
+		}
+		break;
+	case 'd':
+	case 'D':
+	{
+			Vector3 viewDir = camera->GetDirection();
+			// rotate view vector
+			Matrix4x4 rot = RotationZMatrix(-keyRotation);
+			viewDir = rot * viewDir;
+			camera->SetDirection(viewDir);
+		}
+		break;
+	case 'w':
+	case 'W':
+		{
+			Vector3 pos = camera->GetPosition();
+			pos += hvec * keyForwardMotion;
+			camera->SetPosition(pos);
+		}
+		break;
+	case 'x':
+	case 'X':
+		{
+			Vector3 pos = camera->GetPosition();
+			pos -= hvec * keyForwardMotion;
+			camera->SetPosition(pos);
+		}
+		break;
+	case 'r':
+	case 'R':
+		{
+			useRenderQueue = !useRenderQueue;
+			traverser->SetUseRenderQueue(useRenderQueue);
+		}
 	default:
 		return;
@@ -475,5 +509,5 @@
 {
 	// used to avoid vertical motion with the keys
-	//Vector3 hvec = Vector3(viewDir[0], 0, viewDir[2]);
+	Vector3 hvec = Vector3(camera->GetDirection()[0], camera->GetDirection()[1], 0.0f);
 	
 	switch(c) 
@@ -482,39 +516,35 @@
 		showHelp = !showHelp;
 		break;
-	case GLUT_KEY_F2:
-		//numNextObjects -= 100;
-		//if(numNextObjects < 100) numNextObjects = 100;
-		break;
-	case GLUT_KEY_F3:
-       // numNextObjects += 100;
-		break;
-	case GLUT_KEY_F4:
-		//zLength -= 1;
-		//if(zLength < 0) zLength = 0;
-		break;
-	case GLUT_KEY_F5:
-		//zLength += 1;
-		break;		
-	case GLUT_KEY_F6:
-		//objectSize -= 0.1;
-		//if(objectSize < 0.1) objectSize = 0.1;
-		break;
-	case GLUT_KEY_F7:
-		//objectSize += 0.1;
-		break;
-	case GLUT_KEY_F8:
-		//nextObjectType = (nextObjectType + 1) % Geometry::NUM_OBJECTS;
-		break;
 	case GLUT_KEY_LEFT:
-	//	rotateVectorY(viewDir, 0.2);
+		{
+			Vector3 viewDir = camera->GetDirection();
+			// rotate view vector
+			Matrix4x4 rot = RotationZMatrix(keyRotation);
+			viewDir = rot * viewDir;
+			camera->SetDirection(viewDir);
+		}
 		break;
 	case GLUT_KEY_RIGHT:
-		//rotateVectorY(viewDir, -0.2);
+		{
+			Vector3 viewDir = camera->GetDirection();
+			// rotate view vector
+			Matrix4x4 rot = RotationZMatrix(-keyRotation);
+			viewDir = rot * viewDir;
+			camera->SetDirection(viewDir);
+		}
 		break;
 	case GLUT_KEY_UP:
-	//	linCombVector3(eyePos, eyePos, hvec, 0.6);
+		{
+			Vector3 pos = camera->GetPosition();
+			pos += hvec * 0.6f;
+			camera->SetPosition(pos);
+		}
 		break;
 	case GLUT_KEY_DOWN:
-		//linCombVector3(eyePos, eyePos, hvec, -0.6);
+		{
+			Vector3 pos = camera->GetPosition();
+			pos -= hvec * 0.6f;
+			camera->SetPosition(pos);
+		}
 		break;
 	default:
@@ -525,4 +555,5 @@
 	glutPostRedisplay();
 }
+
 #pragma warning( default : 4100 )
 
@@ -542,5 +573,5 @@
 	glLoadIdentity();
 
-	gluPerspective(60.0f, 1.0f / winAspectRatio, nearDist, 2.0f * Magnitude(sceneBox.Diagonal()));
+	gluPerspective(60.0f, 1.0f / winAspectRatio, nearDist, 2.0f * Magnitude(bvh->GetBox().Diagonal()));
 	glMatrixMode(GL_MODELVIEW);
 
@@ -587,5 +618,4 @@
 
 	// don't move in the vertical direction
-	//Vector3 horView(viewDir[0], 0, viewDir[2]);
 	Vector3 horView(viewDir[0], viewDir[1], 0);
 	
@@ -593,5 +623,4 @@
 
 	// rotate view vector
-	//Matrix4x4 rot = RotationYMatrix(eyeXAngle);
 	Matrix4x4 rot = RotationZMatrix(eyeXAngle);
 	viewDir = rot * viewDir;
@@ -609,6 +638,6 @@
 
 
-/**	rotation for left/right mouse drag
-	motion for up/down mouse drag
+/**	rotation for left / right mouse drag
+	motion for up / down mouse drag
 */
 void rightMotion(int x, int y) 
@@ -707,11 +736,11 @@
 void output(const int x, const int y, const char *string) 
 {
-	if(string != 0) 
-	{
-		int len, i;
-		glRasterPos2f(x,y);
-		len = (int) strlen(string);
+	if (string != 0) 
+	{
+		size_t len, i;
+		glRasterPos2f(x, y);
+		len = strlen(string);
 		
-		for (i = 0; i < len; i++) 
+		for (i = 0; i < len; ++ i) 
 		{
 			glutBitmapCharacter(GLUT_BITMAP_8_BY_13, string[i]);
@@ -719,4 +748,5 @@
 	}
 }
+
 
 // displays the visualisation of the kd tree node culling
@@ -738,12 +768,13 @@
 	glClear(GL_DEPTH_BUFFER_BIT);
 
+	////////////
 	// --- visualization of the occlusion culling
-	/*HierarchyNode::SetRenderBoundingVolume(true);
-	traverser.RenderVisualization();
-	HierarchyNode::SetRenderBoundingVolume(showBoundingVolumes);
-*/
+	visualization->Render();
+	
 	glPopMatrix();
+	
 	glViewport(0, 0, winWidth, winHeight);
 }
+
 
 /** Sets up view matrix in order to get a good position 
@@ -752,5 +783,5 @@
 void setupVisView()
 {
-	const Vector3 up(0.0, 1.0, 0.0);
+	const Vector3 up(0.0, 0.0, 1.0);
 	
 	Vector3 visPos(24, 23, -6);
@@ -760,30 +791,5 @@
 	visPos[2] *= visZoomFactor;
 
-	Vector3 visDir = Vector3(-1.3, -1, -1);
-	
-	//normalize(visDir);
-	//look(visView, visPos, visDir, up);
-}
-
-// we take a couple of measurements and compute the average
-long calcRenderTime()
-{
-	long result = 0;
-
-	for(int i=0; i<renderTimesValid; i++)
-		result += renderTimes[i];
-    
-	if(renderTimesValid)
-		result /= renderTimesValid;
-
-	return result;
-}
-
-
-// reset the timer array for a new traversal method
-void resetTimer()
-{
-	renderTimesValid = 0;
-	renderTimesIdx = 0;
+	Vector3 visDir = Vector3(-1.3f, -1, -1);
 }
 
@@ -796,4 +802,5 @@
 
 	DEL_PTR(bvh);
+	DEL_PTR(visualization);
 }
 
@@ -829,5 +836,5 @@
 {
 	char *msg[] = {"Frustum Culling", "Stop and Wait",
-				    "Coherent Culling"};
+				    "CHC", "CHC ++"};
 
 	char msg2[200];
@@ -843,5 +850,10 @@
 	
 	float fps = 1e3f;
-	long renderTime = calcRenderTime();
+	static long renderTime = traverser->GetStats().mRenderTime;
+
+	const float expFactor = 0.9f;
+
+	renderTime = renderTime * expFactor + (1.0f - expFactor) * traverser->GetStats().mRenderTime;
+
 	if (renderTime) fps /= (float)renderTime;
 
@@ -868,6 +880,6 @@
 	else
 	{
-		glColor3f(1.0f ,1.0f ,1.0f );
-		output(20, winHeight - 10, msg[renderMode]);
+		glColor3f(1.0f, 1.0f , 1.0f);
+		output(10, winHeight - 10, msg[renderMode]);
 
 		if(showStatistics)
Index: GTP/trunk/App/Demos/Vis/CHC_revisited/CHCPlusPlusTraverser.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/CHC_revisited/CHCPlusPlusTraverser.cpp	(revision 2755)
+++ GTP/trunk/App/Demos/Vis/CHC_revisited/CHCPlusPlusTraverser.cpp	(revision 2767)
@@ -4,17 +4,89 @@
 {
 
-CHCPlusPlusTraverser::CHCPlusPlusTraverser(): RenderTraverser() 
+CHCPlusPlusTraverser::CHCPlusPlusTraverser() 
 {
 }
 
 
-CHCPlusPlusTraverser::~CHCPlusPlusTraverser()
+void CHCPlusPlusTraverser::Traverse()
 {
-	//DelQueries();
-}
+	//-- PART 1: process finished occlusion queries
+	while (!mDistanceQueue.empty() || !mQueryQueue.empty())
+	{
+		while (!mQueryQueue.empty() && 
+			   (mQueryQueue.front()->ResultAvailable() || mDistanceQueue.empty()))
+		{
+			OcclusionQuery *query = mQueryQueue.front();
+			mQueryQueue.pop();
+			
+			// wait until result available
+			int visiblePixels = query->GetQueryResult();
 
+			if (visiblePixels > mVisibilityThreshold)
+			{
+				BvhNode *node = query->GetFrontNode();
 
-void CHCPlusPlusTraverser::Render()
-{
+				mBvh->MakeParentsVisible(node);
+				TraverseNode(node);
+			}
+			else
+			{
+				++ mStats.mNumQueryCulledNodes;
+			}
+		}	
+
+		//-- PART 2: hierarchical traversal
+		if (!mDistanceQueue.empty())
+		{
+			BvhNode *node = mDistanceQueue.top();
+			mDistanceQueue.pop();
+	
+			if (mBvh->IsWithinViewFrustum(node))
+			{
+				// for near plane intersecting bounding box possible 
+				// wrong results => skip occlusion query
+				if (IntersectsNearPlane(node))
+				{
+					// update node's visited flag
+					node->SetLastVisitedFrame(mFrameId);
+					node->SetVisible(true);
+					mBvh->MakeParentsVisible(node);
+
+					TraverseNode(node);
+				}
+				else
+				{		
+					// identify previously visible nodes
+					const bool wasVisible = node->IsVisible() && (node->GetLastVisitedFrame() == mFrameId - 1);
+					
+					// identify nodes that we cannot skip queries for
+					const bool leafOrWasInvisible = 
+						(node->GetLastVisitedFrame() != mFrameId) && (!wasVisible || node->IsVirtualLeaf());
+
+					// reset node's visibility classification 
+					node->SetVisible(false);
+
+					// update node's visited flag
+					node->SetLastVisitedFrame(mFrameId);
+					
+					// skip testing previously visible interior nodes
+					if (leafOrWasInvisible)
+					{
+						OcclusionQuery *query = IssueOcclusionQuery(node, wasVisible);
+						mQueryQueue.push(query);
+					}
+					
+					// always traverse a node if it was visible
+					if (wasVisible)
+						TraverseNode(node);
+				}
+			}
+			else
+			{
+				// for stats
+				++ mStats.mNumFrustumCulledNodes;
+			}
+		}
+	}
 }
 
Index: GTP/trunk/App/Demos/Vis/CHC_revisited/FrustumCullingTraverser.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/CHC_revisited/FrustumCullingTraverser.cpp	(revision 2765)
+++ GTP/trunk/App/Demos/Vis/CHC_revisited/FrustumCullingTraverser.cpp	(revision 2767)
@@ -13,5 +13,5 @@
 
 
-void FrustumCullingTraverser::Render()
+void FrustumCullingTraverser::Traverse()
 {
 	while (!mDistanceQueue.empty())
@@ -36,5 +36,9 @@
 		}
 	}
+
+	mRenderQueue.Render();
+	mRenderQueue.Clear();
 }
 
+
 }
Index: GTP/trunk/App/Demos/Vis/CHC_revisited/RenderTraverser.h
===================================================================
--- GTP/trunk/App/Demos/Vis/CHC_revisited/RenderTraverser.h	(revision 2765)
+++ GTP/trunk/App/Demos/Vis/CHC_revisited/RenderTraverser.h	(revision 2767)
@@ -3,9 +3,10 @@
 
 #include <queue>
-#include <stack>
-#include "glInterface.h"
 #include "Bvh.h"
 #include "OcclusionQuery.h"
 #include "Camera.h"
+#include "RenderQueue.h"
+
+
 
 namespace CHCDemo
@@ -37,6 +38,4 @@
 
 
-//typedef std::priority_queue<BvhNode *, std::vector<BvhNode *>, myless<std::vector<BvhNode *>::value_type> > TraversalQueue;
-typedef std::priority_queue<BvhNode *, std::vector<BvhNode *>, myless> TraversalQueue;
 
 /** Abstract class implementing a scene traversal for rendering.
@@ -45,5 +44,6 @@
 {
 public:
-	enum {CULL_FRUSTUM, STOP_AND_WAIT, CHC, NUM_RENDERMODES};
+	
+	enum {CULL_FRUSTUM, STOP_AND_WAIT, CHC, CHCPLUSPLUS, NUM_RENDERMODES};
 
 	RenderTraverser();
@@ -52,10 +52,11 @@
 	//! Renders the scene with the specified method
 	/**
-		The mode is one of
-		RENDER_CULL_FRUSTUM: renders the scene with view frustum culling only
-		RENDER_STOP_AND_WAIT: renders the scene with the hierarchical stop and wait algorithm
-		RENDER_COHERENT: renders the scene with the coherent hierarchical algorithm
+		The method is one of
+		CULL_FRUSTUM: view frustum culling only
+		STOP_AND_WAIT: hierarchical stop and wait algorithm
+		CHC: coherent hierarchical algorithm
+		CHCPLUSPLUS: coherent hierarchical algorithm revisited
 	*/
-	virtual void Render() = 0;
+	void RenderScene();
 	/** Sets the scene hierarchy.
 	*/
@@ -79,31 +80,20 @@
 	*/
 	void SetRenderState(RenderState *state);
-	
-	void RenderFrustum();
 
+	void SetUseRenderQueue(bool useRenderQueue);
 	const TraversalStatistics &GetStats() const { return mStats; }
-
-	void InitFrame(Camera *camera, int currentFrameId);
 
 protected:
 
-	/** does some important initializations
+	/** This is the actual rendering algorithm. It must be implemented by all
+		the subclasses.
 	*/
-	void Preprocess();
+	virtual void Traverse() = 0;
 	/** Hierarchy traversal
 	*/
 	void TraverseNode(BvhNode *node);
-	/** Visibility is pulled up from visibility of children 
-	*/
-	void PullUpVisibility(BvhNode *node);
 	/** Issues occlusion query for specified node
 	*/
 	OcclusionQuery *IssueOcclusionQuery(BvhNode *node, bool wasVisible);
-	/** Resets occlusion queries after a traversal
-	*/
-	void DelQueries();
-	/** Does view frustum culling. returns intersect (if intersects view plane)
-	*/
-	bool InsideViewFrustum(BvhNode *node, bool &intersects);
 	/** switches to normal render mode
 	*/
@@ -112,10 +102,10 @@
 	*/
 	void Switch2GLQueryState();
-
-	inline bool IntersectsNearPlane(BvhNode *node) const {return mBvh->GetDistance(node) < mCamera->GetNear();}
-
+	/** Retunrs true if the current bvh node intersects the near plane.
+	*/
+	inline bool IntersectsNearPlane(BvhNode *node) const; 
+	/** Enqueues a bvh node.
+	*/
 	void EnqueueNode(BvhNode *node);
-
-	void RenderBox(const AxisAlignedBox3 &box);
 
 
@@ -128,14 +118,10 @@
 	/// the root of the scene hierarchy
 	Bvh *mBvh;
-	/// use a priority queue rather than a renderstack
+	/// the priority queue used for front to back traversal
 	TraversalQueue mDistanceQueue; 
-	
+	/// the current frame id
 	int mFrameId;
-	int mVisibilityThreshold;
 
 	bool mIsQueryMode;
-	
-	//bool mIntersects;
-	bool mUseOptimization;
 
 	RenderState *mRenderState;
@@ -144,5 +130,22 @@
 
 	TraversalStatistics mStats;
+
+	QueryQueue mQueryQueue;
+
+	int mVisibilityThreshold;
+	
+	bool mUseOptimization;
+
+	RenderQueue mRenderQueue;
+
+	bool mUseRenderQueue;
 };
+
+
+inline bool RenderTraverser::IntersectsNearPlane(BvhNode *node) const
+{ 
+	return mBvh->GetDistance(node) < mCamera->GetNear();
+}
+
 
 }
