Index: trunk/VUT/GtpVisibilityPreprocessor/scripts/default.env
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/scripts/default.env	(revision 508)
+++ trunk/VUT/GtpVisibilityPreprocessor/scripts/default.env	(revision 513)
@@ -180,5 +180,6 @@
 	height 5.0
 	maxViewCells 500
-	maxPvs 500
+	#percentage of total visible objects where pvs is considered invalid
+	maxPvsRatio 0.1
 		
 	PostProcess {
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Beam.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Beam.cpp	(revision 512)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Beam.cpp	(revision 513)
@@ -5,6 +5,5 @@
 
 void
-Beam::Construct(const  AxisAlignedBox3 &box,
-				const  AxisAlignedBox3 &dBox)
+Beam::Construct(const  AxisAlignedBox3 &box, const  AxisAlignedBox3 &dBox)
 {
   // the frustum is defined by set of negative halfspace described by mPlanes
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Beam.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Beam.h	(revision 512)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Beam.h	(revision 513)
@@ -18,6 +18,8 @@
   // list of nodes intersected by the frustum
   vector<KdNode *> mKdNodes;
-  // lits of objects intersected by the frustum
-  vector<Intersectable *> mObjects;
+  // list of objects intersected by the frustum
+  ObjectContainer mObjects;
+  // view cells intersected by frustum
+  ViewCellContainer mViewCells;
 
   // spatial box
Index: trunk/VUT/GtpVisibilityPreprocessor/src/GlRenderer.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/GlRenderer.h	(revision 512)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/GlRenderer.h	(revision 513)
@@ -172,4 +172,7 @@
 							   );
 
+private:
+	static void GenQueries(const int numQueries);
+
 };
 
Index: trunk/VUT/GtpVisibilityPreprocessor/src/GlRenderer.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/GlRenderer.cpp	(revision 512)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/GlRenderer.cpp	(revision 513)
@@ -6,4 +6,5 @@
 #include "Viewcell.h"
 #include "Beam.h"
+
 #include <GL/glext.h>
 #include <Cg/cg.h>
@@ -21,6 +22,8 @@
 GLuint depthMap;
 const int depthMapSize = 512;
+static vector<int> sQueries;
 
 GlRendererWidget *rendererWidget = NULL;
+
 
 #ifdef _WIN32
@@ -570,12 +573,11 @@
 											   BeamSampleStatistics &stat)
 {
-	// TODO: should be out of here
-	cgGLBindProgram(sCgFragmentProgram);
-	cgGLEnableProfile(sCgFragmentProfile);
+	// TODO: should not be done every time here
+	// only back faces are interesting for the depth pass
+	glShadeModel(GL_FLAT);
+	glDisable(GL_LIGHTING);
 
 	// assumes that the beam is constructed and contains kd-tree nodes
 	// and viewcells which it intersects
-	
-
   
   
@@ -618,6 +620,4 @@
 	// in order that thios scheme is working well the gpu render buffer should run in a separate
 	// thread than the cpu sampler, which would not be such a big problem....
-
-	cgGLDisableProfile(sCgFragmentProfile);
 }
 
@@ -631,35 +631,113 @@
 	// 2. setup the projection matrix and view matrix to match the viewpoint + beam.mDirBox
   
-	// 3. reset z-buffer to 0 and render the source object for the beam using
-	//    glDepthFunc(GL_GREATER)
-	//    and glCullFace(Enabled) and glFrontFace(GL_CW)
-	//    save result to depth buffer?
-	
-	// bind ray origin depth buffer
-	glClear(GL_DEPTH);
-	glBindTexture(GL_TEXTURE_2D, depthMap);
-    glEnable(GL_TEXTURE_2D);
-
-	// compare with second depth buffer: should be done in pixel shader
-	/*glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE);
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_GREATER);
-	glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE_ARB, GL_INTENSITY);
-	*/
-
+	// 3. reset z-buffer to 0 and render the source object for the beam
+	//    with glCullFace(Enabled) and glFrontFace(GL_CW)
+	//    save result to depth map
+	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+	glEnable(GL_CULL_FACE);
+	glEnable(GL_STENCIL_TEST);
+	glCullFace(GL_FRONT);
+	glColorMask(0, 0, 0, 0);
+	
+	// stencil is increased where the source object is located
+	glStencilFunc(GL_ALWAYS, 0x1, 0x1);
+	glStencilOp(GL_INCR, GL_INCR, GL_INCR);
+
+#if 0
+	static int glSourceObjList = -1;	 
+	if (glSourceObjList != -1) 
+	{
+		glSourceObjList = glGenLists(1);
+		glNewList(glSourceObjList, GL_COMPILE);
+
+		RenderIntersectable(sourceObject);
+	
+		glEndList();
+	}
+	glCallList(glSourceObjList);
+
+#else
+	RenderIntersectable(sourceObject);
+
+#endif	
 
 	// 4. set back to normal rendering and clear the ray termination depth buffer
+	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+	glColorMask(1, 1, 1, 1);
+	
 	// 5. render all objects inside the beam using id based false color
 	//    (objects can be compiled to a gl list now so that subsequent rendering for
 	//     this beam is fast - the same hold for step 3)
 
-
+	// list of objects intersected by the frustum
+#if 0
+	static int glObjList = -1; 
+	if (glObjList != -1) 
+	{
+		glObjList = glGenLists(1);
+		glNewList(glObjList, GL_COMPILE);
+	
+		ObjectContainer::const_iterator it, it_end = beam.mObjects.end();
+		for (it = beam.mObjects.begin(); it != it_end; ++ it)
+			RenderIntersectable(*it);
+		
+		glEndList();
+	}
+	glCallList(glObjList);
+#else
+	ObjectContainer::const_iterator it, it_end = beam.mObjects.end();
+		for (it = beam.mObjects.begin(); it != it_end; ++ it)
+			RenderIntersectable(*it);
+#endif
+
+	// bind ray origin depth buffer
+	glBindTexture(GL_TEXTURE_2D, depthMap);
+    glEnable(GL_TEXTURE_2D);
+	
+
+	//Read the depth buffer into the shadow map texture
+	glBindTexture(GL_TEXTURE_2D, depthMap);
+	glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, depthMapSize, depthMapSize);
+
+	
 	// 6. Now we have a two depth buffers defining the ray origin and termination
 	//    only rays which have non-zero entry in the origin buffer are valid since
 	//    they realy start on the object surface (this can also be tagged by setting a
 	//    stencil buffer bit at step 3)
+	glStencilFunc(GL_EQUAL, 0x1, 0x1);
+
+	// compare with second depth buffer: done in pixel shader
+	cgGLBindProgram(sCgFragmentProgram);
+	cgGLEnableProfile(sCgFragmentProfile);
 
 	// 7. Use occlusion queries for all viewcell meshes associated with the beam ->
 	// a fragment passes if the corresponding stencil fragment is set and its depth is
 	// between origin and termination buffer
+
+	// create new queries if necessary
+	GenQueries((int)beam.mViewCells.size());
+
+	// now check whether any backfacing polygon would pass the depth test
+	glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
+	glDepthMask(GL_FALSE);
+	glDisable(GL_CULL_FACE);
+  
+	ViewCellContainer::const_iterator vit, vit_end = beam.mViewCells.end();
+
+	int queryIdx = 0;
+
+	for (vit = beam.mViewCells.begin(); vit != vit_end; ++ vit)
+	{
+		glBeginOcclusionQueryNV(sQueries[queryIdx ++]);
+  
+		RenderIntersectable(*vit);
+  
+		glEndOcclusionQueryNV();
+	}
+
+	// at this point, if possible, go and do some other computation
+	glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+	glDepthMask(GL_TRUE);
+	glEnable(GL_CULL_FACE);
 
 	// 8. The number of visible pixels is the number of sample rays which see the source
@@ -675,3 +753,24 @@
 	// (new viewcell has been discovered) or relative contribution greater than a threashold ... 
 
-}
+	cgGLDisableProfile(sCgFragmentProfile);
+	glDisable(GL_TEXTURE_2D);
+}
+
+
+void GlRendererBuffer::GenQueries(const int numQueries)
+{
+	if ((int)sQueries.size() < numQueries)
+	{
+		const int n = numQueries - (int)sQueries.size();
+		int *newQueries = new int[n];
+
+		glGenOcclusionQueriesNV(n, (unsigned int *)&newQueries);
+
+		for (int i = 0; i < n; ++ i)
+		{
+			sQueries.push_back(newQueries[i]);
+		}
+
+		delete newQueries;
+	}
+}
