Преглед на файлове

Visibility determination

Panagiotis Christopoulos Charitos преди 15 години
родител
ревизия
d069475c81
променени са 10 файла, в които са добавени 150 реда и са изтрити 152 реда
  1. 0 1
      build/debug/Makefile
  2. 9 11
      src/Renderer/Is.cpp
  3. 2 2
      src/Renderer/Is.h
  4. 1 1
      src/Renderer/Ms.cpp
  5. 2 2
      src/Renderer/Sm.cpp
  6. 1 1
      src/Renderer/Sm.h
  7. 60 6
      src/Scene/Camera.h
  8. 1 1
      src/Scene/Scene.h
  9. 66 83
      src/Scene/VisibilityTester.cpp
  10. 8 44
      src/Scene/VisibilityTester.h

Файловите разлики са ограничени, защото са твърде много
+ 0 - 1
build/debug/Makefile


+ 9 - 11
src/Renderer/Is.cpp

@@ -203,10 +203,9 @@ void Is::ambientPass(const Vec3& color)
 //======================================================================================================================
 // pointLightPass                                                                                                      =
 //======================================================================================================================
-void Is::pointLightPass(const VisibilityTester::VisibleLight<PointLight>& vlight)
+void Is::pointLightPass(const PointLight& light)
 {
 	const Camera& cam = r.getCamera();
-	const PointLight& light = vlight.getLight();
 
 	// stencil optimization
 	smo.run(light);
@@ -234,15 +233,14 @@ void Is::pointLightPass(const VisibilityTester::VisibleLight<PointLight>& vlight
 //======================================================================================================================
 // spotLightPass                                                                                                       =
 //======================================================================================================================
-void Is::spotLightPass(const VisibilityTester::VisibleLight<SpotLight>& vlight)
+void Is::spotLightPass(const SpotLight& light)
 {
 	const Camera& cam = r.getCamera();
-	const SpotLight& light = vlight.getLight();
 
 	// shadow mapping
 	if(light.castsShadow() && sm.isEnabled())
 	{
-		sm.run(light.getCamera(), vlight.getRenderables());
+		sm.run(light.getCamera());
 
 		// restore the IS FBO
 		fbo.bind();
@@ -335,16 +333,16 @@ void Is::run()
 	calcPlanes();
 
 	// for all lights
-	BOOST_FOREACH(const VisibilityTester::VisibleLight<PointLight> light, 
-	              SceneSingleton::getInstance().getVisibilityTester().getPointLights())
+	BOOST_FOREACH(const PointLight* light,
+	              r.getCamera().getVisiblePointLights())
 	{
-		pointLightPass(light);
+		pointLightPass(*light);
 	}
 	
-	BOOST_FOREACH(const VisibilityTester::VisibleLight<SpotLight> light, 
-	              SceneSingleton::getInstance().getVisibilityTester().getSpotLights())
+	BOOST_FOREACH(const SpotLight* light,
+	              r.getCamera().getVisibleSpotLights())
 	{
-		spotLightPass(light);
+		spotLightPass(*light);
 	}
 	
 

+ 2 - 2
src/Renderer/Is.h

@@ -66,10 +66,10 @@ class Is: private RenderingPass
 		void ambientPass(const Vec3& color);
 
 		/// The point light pass
-		void pointLightPass(const VisibilityTester::VisibleLight<PointLight>& vlight);
+		void pointLightPass(const PointLight& plight);
 
 		/// The spot light pass
-		void spotLightPass(const VisibilityTester::VisibleLight<SpotLight>& vlight);
+		void spotLightPass(const SpotLight& slight);
 
 		/// Used in @ref init
 		void initFbo();

+ 1 - 1
src/Renderer/Ms.cpp

@@ -97,7 +97,7 @@ void Ms::run()
 	}
 
 	// render all
-	BOOST_FOREACH(const RenderableNode* node, SceneSingleton::getInstance().getVisibilityTester().getMsRenderables())
+	BOOST_FOREACH(const RenderableNode* node, r.getCamera().getVisibleMsRenderableNodes())
 	{
 		r.getSceneDrawer().renderRenderableNode(*node, r.getCamera(), SceneDrawer::RPT_COLOR);
 	}

+ 2 - 2
src/Renderer/Sm.cpp

@@ -69,7 +69,7 @@ void Sm::init(const RendererInitializer& initializer)
 //======================================================================================================================
 // run                                                                                                                 =
 //======================================================================================================================
-void Sm::run(const Camera& cam, const VisibilityTester::Types<const RenderableNode*>::Container renderables)
+void Sm::run(const Camera& cam)
 {
 	if(!enabled)
 	{
@@ -93,7 +93,7 @@ void Sm::run(const Camera& cam, const VisibilityTester::Types<const RenderableNo
 	glEnable(GL_POLYGON_OFFSET_FILL);
 
 	// render all
-	BOOST_FOREACH(const RenderableNode* node, renderables)
+	BOOST_FOREACH(const RenderableNode* node, cam.getVisibleMsRenderableNodes())
 	{
 		r.getSceneDrawer().renderRenderableNode(*node, cam, SceneDrawer::RPT_DEPTH);
 	}

+ 1 - 1
src/Renderer/Sm.h

@@ -28,7 +28,7 @@ class Sm: private RenderingPass
 
 		/// Render the scene only with depth and store the result in the shadowMap
 		/// @param[in] cam The light camera
-		void run(const Camera& cam, const VisibilityTester::Types<const RenderableNode*>::Container renderables);
+		void run(const Camera& cam);
 
 	private:
 		Fbo fbo; ///< Illumination stage shadowmapping FBO

+ 60 - 6
src/Scene/Camera.h

@@ -2,10 +2,17 @@
 #define CAMERA_H
 
 #include <boost/array.hpp>
+#include <deque>
+#include "Vec.h"
 #include "Collision.h"
 #include "SceneNode.h"
 
 
+class RenderableNode;
+class SpotLight;
+class PointLight;
+
+
 /// Camera SceneNode
 class Camera: public SceneNode
 {
@@ -25,18 +32,25 @@ class Camera: public SceneNode
 
 		/// @name Accessors
 		//// @{
-		void setFovX (float fovx_)  {fovX=fovx_; calcProjectionMatrix(); calcLSpaceFrustumPlanes();}
-		void setFovY (float fovy_)  {fovY=fovy_; calcProjectionMatrix(); calcLSpaceFrustumPlanes();}
-		void setZNear(float znear_) {zNear=znear_; calcProjectionMatrix(); calcLSpaceFrustumPlanes();}
-		void setZFar (float zfar_)  {zFar=zfar_; calcProjectionMatrix(); calcLSpaceFrustumPlanes();}
-		void setAll(float fovx_, float fovy_, float znear_, float zfar_);
+		void setFovX(float fovx);
+		void setFovY(float fovy);
+		void setZNear(float znear);
+		void setZFar(float zfar);
+		void setAll(float fovx, float fovy, float znear, float zfar);
 		float getFovX() const {return fovX;}
 		float getFovY() const {return fovY;}
 		float getZNear() const {return zNear;}
 		float getZFar() const {return zFar;}
 		const Mat4& getProjectionMatrix() const {return projectionMat;}
 		const Mat4& getViewMatrix() const {return viewMat;}
-		const Mat4& getInvProjectionMatrix() const {return invProjectionMat;} ///< See the declaration of invProjectionMat for info
+
+		/// See the declaration of invProjectionMat for info
+		const Mat4& getInvProjectionMatrix() const {return invProjectionMat;}
+
+		GETTER_RW(std::deque<const RenderableNode*>, msRenderableNodes, getVisibleMsRenderableNodes)
+		GETTER_RW(std::deque<const RenderableNode*>, bsRenderableNodes, getVisibleBsRenderableNodes)
+		GETTER_RW(Vec<const PointLight*>, pointLights, getVisiblePointLights)
+		GETTER_RW(Vec<SpotLight*>, spotLights, getVisibleSpotLights)
 		//// @}
 
 		void lookAtPoint(const Vec3& point);
@@ -88,6 +102,14 @@ class Camera: public SceneNode
 		Mat4 invProjectionMat;
 		/// @}
 
+		/// @name Visibility containers
+		/// @{
+		std::deque<const RenderableNode*> msRenderableNodes;
+		std::deque<const RenderableNode*> bsRenderableNodes;
+		Vec<const PointLight*> pointLights;
+		Vec<SpotLight*> spotLights;
+		/// @}
+
 		void calcProjectionMatrix();
 		void updateViewMatrix();
 		void calcLSpaceFrustumPlanes();
@@ -95,4 +117,36 @@ class Camera: public SceneNode
 };
 
 
+inline void Camera::setFovX(float fovx_)
+{
+	fovX = fovx_;
+	calcProjectionMatrix();
+	calcLSpaceFrustumPlanes();
+}
+
+
+inline void Camera::setFovY(float fovy_)
+{
+	fovY = fovy_;
+	calcProjectionMatrix();
+	calcLSpaceFrustumPlanes();
+}
+
+
+inline void Camera::setZNear(float znear_)
+{
+	zNear = znear_;
+	calcProjectionMatrix();
+	calcLSpaceFrustumPlanes();
+}
+
+
+inline void Camera::setZFar(float zfar_)
+{
+	zFar = zfar_;
+	calcProjectionMatrix();
+	calcLSpaceFrustumPlanes();
+}
+
+
 #endif

+ 1 - 1
src/Scene/Scene.h

@@ -42,7 +42,7 @@ class Scene
 
 		void updateAllWorldStuff();
 		void updateAllControllers();
-		void doVisibilityTests(const Camera& cam) {visibilityTester->test(cam);}
+		void doVisibilityTests(Camera& cam) {visibilityTester->test(cam);}
 
 		/// @name Accessors
 		/// @{

+ 66 - 83
src/Scene/VisibilityTester.cpp

@@ -22,7 +22,7 @@ bool VisibilityTester::CmpDistanceFromOrigin::operator()(const RenderableNode* a
 //======================================================================================================================
 // Constructor                                                                                                         =
 //======================================================================================================================
-VisibilityTester::VisibilityTester(const Scene& scene_):
+VisibilityTester::VisibilityTester(Scene& scene_):
 	scene(scene_)
 {}
 
@@ -30,80 +30,38 @@ VisibilityTester::VisibilityTester(const Scene& scene_):
 //======================================================================================================================
 // test                                                                                                                =
 //======================================================================================================================
-void VisibilityTester::test(const Camera& cam)
+void VisibilityTester::test(Camera& cam)
 {
 	//
-	// Clean
+	// Collect the lights for the main cam
 	//
-	msRenderables.clear();
-	bsRenderables.clear();
-	pointLights.clear();
-	spotLights.clear();
+	cam.getVisiblePointLights().clear();
+	cam.getVisibleSpotLights().clear();
 
-	//
-	// Collect the renderables
-	//
-	BOOST_FOREACH(const ModelNode* node, scene.getModelNodes())
-	{
-		// Skip if the ModeNode is not visible
-		if(!test(*node, cam))
-		{
-			continue;
-		}
-
-		// If not test every patch individually
-		BOOST_FOREACH(const ModelPatchNode* modelPatchNode, node->getModelPatchNodes())
-		{
-			// Test if visible by main camera
-			if(test(*modelPatchNode, cam))
-			{
-				if(modelPatchNode->getCpMtl().isBlendingEnabled())
-				{
-					bsRenderables.push_back(modelPatchNode);
-				}
-				else
-				{
-					msRenderables.push_back(modelPatchNode);
-				}
-			}
-		}
-	}
-
-	//
-	// Sort the renderables from closest to the camera to the farthest
-	//
-	std::sort(msRenderables.begin(), msRenderables.end(), CmpDistanceFromOrigin(cam.getWorldTransform().origin));
-	std::sort(bsRenderables.begin(), bsRenderables.end(), CmpDistanceFromOrigin(cam.getWorldTransform().origin));
-
-	//
-	// Collect the lights
-	//
-	BOOST_FOREACH(const Light* light, scene.getLights())
+	BOOST_FOREACH(Light* light, scene.getLights())
 	{
 		switch(light->getType())
 		{
 			// Point
 			case Light::LT_POINT:
 			{
-				const PointLight& pointl = static_cast<const PointLight&>(*light);
+				PointLight* pointl = static_cast<PointLight*>(light);
 
-				Sphere sphere(pointl.getWorldTransform().origin, pointl.getRadius());
+				Sphere sphere(pointl->getWorldTransform().origin, pointl->getRadius());
 				if(cam.insideFrustum(sphere))
 				{
-					pointLights.push_back(VisibleLight<PointLight>());
-					pointLights.back().light = &pointl;
+					cam.getVisiblePointLights().push_back(pointl);
 				}
 				break;
 			}
 			// Spot
 			case Light::LT_SPOT:
 			{
-				const SpotLight& spotl = static_cast<const SpotLight&>(*light);
+				SpotLight* spotl = static_cast<SpotLight*>(light);
 
-				if(cam.insideFrustum(spotl.getCamera()))
+				if(cam.insideFrustum(spotl->getCamera()))
 				{
-					spotLights.push_back(VisibleLight<SpotLight>());
-					spotLights.back().light = &spotl;
+					cam.getVisibleSpotLights().push_back(spotl);
 				}
 				break;
 			}
@@ -111,51 +69,76 @@ void VisibilityTester::test(const Camera& cam)
 	} // end for all lights
 
 	//
-	// For all the spot lights get the visible renderables
+	// Get the renderables for the main cam
+	//
+	getRenderableNodes(false, cam);
+
+	//
+	// For every spot light camera collect the renderable nodes
 	//
-	BOOST_FOREACH(VisibleLight<SpotLight>& sl, spotLights)
+	BOOST_FOREACH(SpotLight* spot, cam.getVisibleSpotLights())
 	{
-		// Skip if the light doesnt cast shadow
-		if(!sl.light->castsShadow())
+		getRenderableNodes(true, spot->getCamera());
+	}
+}
+
+
+//======================================================================================================================
+// test                                                                                                                =
+//======================================================================================================================
+template<typename Type>
+bool VisibilityTester::test(const Type& tested, const Camera& cam)
+{
+	return cam.insideFrustum(tested.getBoundingShapeWSpace());
+}
+
+
+//======================================================================================================================
+// getRenderableNodes                                                                                                  =
+//======================================================================================================================
+void VisibilityTester::getRenderableNodes(bool skipShadowless, Camera& cam)
+{
+	cam.getVisibleMsRenderableNodes().clear();
+	cam.getVisibleBsRenderableNodes().clear();
+
+	BOOST_FOREACH(const ModelNode* node, scene.getModelNodes())
+	{
+		// Skip if the ModeNode is not visible
+		if(!test(*node, cam))
 		{
 			continue;
 		}
 
-		BOOST_FOREACH(const ModelNode* node, scene.getModelNodes())
+		// If not test every patch individually
+		BOOST_FOREACH(const ModelPatchNode* modelPatchNode, node->getModelPatchNodes())
 		{
-			// Skip if the ModeNode is not visible
-			if(!test(*node, sl.light->getCamera()))
+			// Skip shadowless
+			if(skipShadowless && !modelPatchNode->getCpMtl().isShadowCaster())
 			{
 				continue;
 			}
 
-			// If not test every patch individually
-			BOOST_FOREACH(const ModelPatchNode* modelPatchNode, node->getModelPatchNodes())
+			// Test if visible by main camera
+			if(test(*modelPatchNode, cam))
 			{
-				// Skip if doesnt cast shadow
-				if(!modelPatchNode->getCpMtl().isShadowCaster())
+				if(modelPatchNode->getCpMtl().isBlendingEnabled())
 				{
-					continue;
+					cam.getVisibleBsRenderableNodes().push_back(modelPatchNode);
 				}
-
-				if(test(*modelPatchNode, sl.light->getCamera()))
+				else
 				{
-					sl.renderables.push_back(modelPatchNode);
+					cam.getVisibleMsRenderableNodes().push_back(modelPatchNode);
 				}
-			} // end for all patches
-		} // end for all model nodes
+			}
+		}
+	}
 
-		std::sort(sl.renderables.begin(), sl.renderables.end(),
-		          CmpDistanceFromOrigin(sl.light->getWorldTransform().origin));
-	} // end for all spot lights
+	//
+	// Sort the renderables from closest to the camera to the farthest
+	//
+	std::sort(cam.getVisibleMsRenderableNodes().begin(), cam.getVisibleMsRenderableNodes().end(),
+	          CmpDistanceFromOrigin(cam.getWorldTransform().origin));
+	std::sort(cam.getVisibleBsRenderableNodes().begin(), cam.getVisibleBsRenderableNodes().end(),
+	          CmpDistanceFromOrigin(cam.getWorldTransform().origin));
 }
 
-
-//======================================================================================================================
-// test                                                                                                                =
-//======================================================================================================================
-template<typename Type>
-bool VisibilityTester::test(const Type& tested, const Camera& cam)
-{
-	return cam.insideFrustum(tested.getBoundingShapeWSpace());
-}

+ 8 - 44
src/Scene/VisibilityTester.h

@@ -20,48 +20,15 @@ class VisibilityTester
 	// Public                                                                                                            =
 	//====================================================================================================================
 	public:
-		/// Types
-		template<typename Type>
-		class Types
-		{
-			public:
-				typedef std::deque<Type> Container;
-				typedef typename Container::iterator Iterator;
-				typedef typename Container::const_iterator ConstIterator;
-		};
-
-		/// The information about the visible lights
-		template<typename LightType>
-		class VisibleLight
-		{
-			friend class VisibilityTester;
-
-			public:
-				const LightType& getLight() const {return *light;}
-				GETTER_R(Types<const RenderableNode*>::Container, renderables, getRenderables)
-
-			private:
-				const LightType* light;
-				Types<const RenderableNode*>::Container renderables; ///< The visible nodes by that light
-		};
-
 		/// Constructor
-		VisibilityTester(const Scene& scene);
-
-		/// @name Accessors
-		/// @{
-		GETTER_R(Types<const RenderableNode*>::Container, msRenderables, getMsRenderables)
-		GETTER_R(Types<const RenderableNode*>::Container, bsRenderables, getBsRenderables)
-		GETTER_R(Types<VisibleLight<PointLight> >::Container, pointLights, getPointLights)
-		GETTER_R(Types<VisibleLight<SpotLight> >::Container, spotLights, getSpotLights)
-		/// @}
+		VisibilityTester(Scene& scene);
 
 		/// This method:
 		/// - Gets the visible renderable nodes
 		/// - Sort them from the closest to the farthest
 		/// - Get the visible lights
 		/// - For every spot light that casts shadow get the visible renderables
-		void test(const Camera& cam);
+		void test(Camera& cam);
 
 	//====================================================================================================================
 	// Private                                                                                                           =
@@ -75,19 +42,16 @@ class VisibilityTester
 			bool operator()(const RenderableNode* a, const RenderableNode* b) const;
 		};
 
-		const Scene& scene; ///< Know your father
-
-		/// @name Containers
-		/// @{
-		Types<const RenderableNode*>::Container msRenderables;
-		Types<const RenderableNode*>::Container bsRenderables;
-		Types<VisibleLight<PointLight> >::Container pointLights;
-		Types<VisibleLight<SpotLight> >::Container spotLights;
-		/// @}
+		Scene& scene; ///< Know your father
 
 		/// Test a node against the camera frustum
 		template<typename Type>
 		static bool test(const Type& tested, const Camera& cam);
+
+		/// Get renderable nodes for a given camera
+		/// @param skipShadowless Skip shadowless nodes. If the cam is a light cam
+		/// @param cam The camera to test and gather renderable nodes
+		void getRenderableNodes(bool skipShadowless, Camera& cam);
 };
 
 

Някои файлове не бяха показани, защото твърде много файлове са промени