Selaa lähdekoodia

Adding tiler visibility tests. They work but need optimizations

Panagiotis Christopoulos Charitos 13 vuotta sitten
vanhempi
sitoutus
2220e8f7ea

+ 10 - 0
include/anki/renderer/Dbg.h

@@ -21,11 +21,21 @@ public:
 	void init(const RendererInitializer& initializer);
 	void run();
 
+	Bool getDepthTestEnabled() const
+	{
+		return depthTest;
+	}
+	void setDepthTestEnabled(Bool enable)
+	{
+		depthTest = enable;
+	}
+
 private:
 	Fbo fbo;
 	std::unique_ptr<DebugDrawer> drawer;
 	// Have it as ptr because the constructor calls opengl
 	std::unique_ptr<SceneDebugDrawer> sceneDrawer;
+	Bool depthTest = true;
 };
 
 } // end namespace

+ 2 - 2
include/anki/renderer/DebugDrawer.h

@@ -51,8 +51,8 @@ public:
 private:
 	struct Vertex
 	{
-		Vec3 position;
-		Vec3 color;
+		Vec4 position;
+		Vec4 color;
 		Mat4 matrix;
 	};
 

+ 3 - 0
include/anki/renderer/Renderer.h

@@ -272,6 +272,9 @@ public:
 		return distance / lodDistance;
 	}
 
+	/// Use the tiler to do visibility tests
+	Bool doVisibilityTests(const CollisionShape& cs) const;
+
 protected:
 	/// @name Rendering stages
 	/// @{

+ 1 - 5
include/anki/scene/Octree.h

@@ -66,11 +66,7 @@ public:
 		children[pos].reset(child);
 	}
 
-	void addSceneNode(SceneNode* sn)
-	{
-		ANKI_ASSERT(sn != nullptr);
-		sceneNodes.push_back(sn);
-	}
+	void addSceneNode(SceneNode* sn);
 
 	void removeSceneNode(SceneNode* sn);
 

+ 5 - 3
include/anki/scene/Scene.h

@@ -11,6 +11,8 @@
 
 namespace anki {
 
+class Renderer;
+
 /// @addtogroup Scene
 /// @{
 
@@ -92,9 +94,7 @@ public:
 	void registerNode(SceneNode* node);
 	void unregisterNode(SceneNode* node);
 
-	void update(float prevUpdateTime, float crntTime);
-
-	void doVisibilityTests(Camera& cam);
+	void update(float prevUpdateTime, float crntTime, Renderer& renderer);
 
 	SceneNode* findSceneNode(const char* name)
 	{
@@ -113,6 +113,8 @@ private:
 	U32 activeCameraChangeTimestamp = Timestamp::getTimestamp();
 	VisibilityTester vtester;
 
+	void doVisibilityTests(Camera& cam, Renderer& r);
+
 	/// Add to a container
 	template<typename T>
 	void addC(typename Types<T>::Container& c, T* ptr)

+ 2 - 13
include/anki/scene/Spatial.h

@@ -18,6 +18,8 @@ class SceneNode;
 /// tests
 class Spatial: public Flags<U32>
 {
+	friend class OctreeNode;
+
 public:
 	/// Spatial flags
 	enum SpatialFlag
@@ -50,19 +52,6 @@ public:
 	{
 		return timestamp;
 	}
-
-	OctreeNode* getOctreeNode()
-	{
-		return octreeNode;
-	}
-	const OctreeNode* getOctreeNode() const
-	{
-		return octreeNode;
-	}
-	void setOctreeNode(OctreeNode* x)
-	{
-		octreeNode = x;
-	}
 	/// @}
 
 	/// The derived class has to manually set when the collision shape got

+ 2 - 1
include/anki/scene/VisibilityTester.h

@@ -12,6 +12,7 @@ class SceneNode;
 class Frustumable;
 class Renderable;
 class Light;
+class Renderer;
 
 /// @addtogroup Scene
 /// @{
@@ -67,7 +68,7 @@ public:
 	/// This method:
 	/// - Gets the visible renderables and frustumables
 	/// - For every frustumable perform tests
-	static void test(Frustumable& ref, Scene& scene);
+	static void test(Frustumable& ref, Scene& scene, Renderer& r);
 
 private:
 	static void testLight(Light& light, Scene& scene);

+ 1 - 1
src/renderer/Dbg.cpp

@@ -54,7 +54,7 @@ void Dbg::run()
 	fbo.bind();
 
 	GlStateSingleton::get().disable(GL_BLEND);
-	GlStateSingleton::get().enable(GL_DEPTH_TEST);
+	GlStateSingleton::get().enable(GL_DEPTH_TEST, depthTest);
 
 	drawer->setViewProjectionMatrix(r->getViewProjectionMatrix());
 	drawer->setModelMatrix(Mat4::getIdentity());

+ 11 - 13
src/renderer/DebugDrawer.cpp

@@ -32,26 +32,28 @@ DebugDrawer::DebugDrawer()
 
 	vao.attachArrayBufferVbo(
 		&vbo, prog->findAttributeVariable("color"), 3, GL_FLOAT,
-		false, sizeof(Vertex), sizeof(Vec3));
+		false, sizeof(Vertex), sizeof(Vec4));
 
 	GLint loc =
 		prog->findAttributeVariable("modelViewProjectionMat").getLocation();
 
 	vao.attachArrayBufferVbo(
 		&vbo, loc, 4, GL_FLOAT, false, sizeof(Vertex), 
-		2 * sizeof(Vec3));
+		2 * sizeof(Vec4));
 	vao.attachArrayBufferVbo(
 		&vbo, loc + 1, 4, GL_FLOAT, false, sizeof(Vertex), 
-		2 * sizeof(Vec3) + sizeof(Vec4));
+		3 * sizeof(Vec4));
 	vao.attachArrayBufferVbo(
 		&vbo, loc + 2, 4, GL_FLOAT, false, sizeof(Vertex), 
-		2 * sizeof(Vec3) + sizeof(Vec4) * 2);
+		4 * sizeof(Vec4));
 	vao.attachArrayBufferVbo(
 		&vbo, loc + 3, 4, GL_FLOAT, false, sizeof(Vertex), 
-		2 * sizeof(Vec3) + sizeof(Vec4) * 3);
+		5 * sizeof(Vec4));
 
 	vertexPointer = 0;
 	mMat.setIdentity();
+	vpMat.setIdentity();
+	mvpMat.setIdentity();
 	crntCol = Vec3(1.0, 0.0, 0.0);
 }
 
@@ -62,8 +64,6 @@ DebugDrawer::~DebugDrawer()
 //==============================================================================
 void DebugDrawer::setModelMatrix(const Mat4& m)
 {
-	ANKI_ASSERT(vertexPointer == 0
-		&& "The func called after begin and before end");
 	mMat = m;
 	mvpMat = vpMat * mMat;
 }
@@ -71,8 +71,6 @@ void DebugDrawer::setModelMatrix(const Mat4& m)
 //==============================================================================
 void DebugDrawer::setViewProjectionMatrix(const Mat4& m)
 {
-	ANKI_ASSERT(vertexPointer == 0
-		&& "The func called after begin and before end");
 	vpMat = m;
 	mvpMat = vpMat * mMat;
 }
@@ -86,12 +84,10 @@ void DebugDrawer::begin()
 //==============================================================================
 void DebugDrawer::end()
 {
-	ANKI_ASSERT(vertexPointer != 0);
-
 	if(vertexPointer % 2 != 0)
 	{
 		// push back the previous vertex to close the loop
-		pushBackVertex(clientVerts[vertexPointer].position);
+		pushBackVertex(clientVerts[vertexPointer].position.xyz());
 	}
 }
 
@@ -115,7 +111,9 @@ void DebugDrawer::flush()
 //==============================================================================
 void DebugDrawer::pushBackVertex(const Vec3& pos)
 {
-	clientVerts[vertexPointer] = Vertex{pos, crntCol, mvpMat.getTransposed()};
+	clientVerts[vertexPointer].position = Vec4(pos, 1.0);
+	clientVerts[vertexPointer].color = Vec4(crntCol, 1.0);
+	clientVerts[vertexPointer].matrix = mvpMat.getTransposed();
 
 	++vertexPointer;
 

+ 8 - 7
src/renderer/Renderer.cpp

@@ -160,14 +160,15 @@ void Renderer::calcPlanes(const Vec2& cameraRange, Vec2& planes)
 void Renderer::calcLimitsOfNearPlane(const PerspectiveCamera& pcam,
 	Vec2& limitsOfNearPlane)
 {
-#if 0
-	limitsOfNearPlane.y() = pcam.getNear() * tan(0.5 * pcam.getFovY());
-	limitsOfNearPlane.x() = limitsOfNearPlane.y()
-		* (pcam.getFovX() / pcam.getFovY());
-#else
 	limitsOfNearPlane.y() = pcam.getNear() * tan(0.5 * pcam.getFovY());
 	limitsOfNearPlane.x() = pcam.getNear() * tan(0.5 * pcam.getFovX());
-#endif
 }
 
-} // end namespace
+
+//==============================================================================
+Bool Renderer::doVisibilityTests(const CollisionShape& cs) const
+{
+	return tiler.testAll(cs, true);
+}
+
+} // end namespace anki

+ 26 - 16
src/scene/Octree.cpp

@@ -12,13 +12,39 @@ namespace anki {
 // OctreeNode                                                                  =
 //==============================================================================
 
+//==============================================================================
+void OctreeNode::addSceneNode(SceneNode* sn)
+{
+	ANKI_ASSERT(sn != nullptr);
+
+	Spatial* sp = sn->getSpatial();
+	if(this == sp->octreeNode)
+	{
+		// early exit
+		return;
+	}
+
+	// Remove from current node ...
+	if(sp->octreeNode != nullptr)
+	{
+		sp->octreeNode->removeSceneNode(sn);
+	}
+
+	// ... and add to a new
+	sceneNodes.push_back(sn);
+	sp->octreeNode = this;
+}
+
 //==============================================================================
 void OctreeNode::removeSceneNode(SceneNode* sn)
 {
+	ANKI_ASSERT(sn != nullptr);
 	Vector<SceneNode*>::iterator it =
 		std::find(sceneNodes.begin(), sceneNodes.end(), sn);
 	ANKI_ASSERT(it != sceneNodes.end());
+
 	sceneNodes.erase(it);
+	sn->getSpatial()->octreeNode = nullptr;
 }
 
 //==============================================================================
@@ -44,23 +70,7 @@ void Octree::placeSceneNode(SceneNode* sn)
 		return;
 	}
 
-	OctreeNode* crntNode = sp->getOctreeNode();
-
-	if(crntNode == toBePlacedNode)
-	{
-		// Don't place in the same
-		return;
-	}
-
-	// Remove from current node ...
-	if(crntNode)
-	{
-		crntNode->removeSceneNode(sn);
-	}
-
-	// ... and add to a new
 	toBePlacedNode->addSceneNode(sn);
-	sp->setOctreeNode(toBePlacedNode);
 }
 
 //==============================================================================

+ 4 - 4
src/scene/Scene.cpp

@@ -30,7 +30,7 @@ void Scene::unregisterNode(SceneNode* node)
 }
 
 //==============================================================================
-void Scene::update(float prevUpdateTime, float crntTime)
+void Scene::update(float prevUpdateTime, float crntTime, Renderer& r)
 {
 	// First do the movable updates
 	for(SceneNode* n : nodes)
@@ -67,7 +67,7 @@ void Scene::update(float prevUpdateTime, float crntTime)
 		}
 	}
 
-	doVisibilityTests(*mainCam);
+	doVisibilityTests(*mainCam, r);
 
 #if 0
 	for(SceneNode* n : nodes)
@@ -97,11 +97,11 @@ void Scene::update(float prevUpdateTime, float crntTime)
 }
 
 //==============================================================================
-void Scene::doVisibilityTests(Camera& cam)
+void Scene::doVisibilityTests(Camera& cam, Renderer& r)
 {
 	Frustumable* f = cam.getFrustumable();
 	ANKI_ASSERT(f != nullptr);
-	vtester.test(*f, *this);
+	vtester.test(*f, *this, r);
 }
 
 } // end namespace anki

+ 7 - 1
src/scene/VisibilityTester.cpp

@@ -3,6 +3,7 @@
 #include "anki/scene/Camera.h"
 #include "anki/scene/Renderable.h"
 #include "anki/scene/Light.h"
+#include "anki/renderer/Renderer.h"
 
 namespace anki {
 
@@ -11,7 +12,7 @@ VisibilityTester::~VisibilityTester()
 {}
 
 //==============================================================================
-void VisibilityTester::test(Frustumable& ref, Scene& scene)
+void VisibilityTester::test(Frustumable& ref, Scene& scene, Renderer& r)
 {
 	VisibilityInfo& vinfo = ref.getVisibilityInfo();
 	vinfo.renderables.clear();
@@ -39,6 +40,11 @@ void VisibilityTester::test(Frustumable& ref, Scene& scene)
 			continue;
 		}
 
+		if(!r.doVisibilityTests(sp->getAabb()))
+		{
+			continue;
+		}
+
 		sp->enableFlag(Spatial::SF_VISIBLE);
 
 		Renderable* r = node->getRenderable();

+ 5 - 2
testapp/Main.cpp

@@ -231,7 +231,9 @@ void mainLoopExtra()
 	if(in.getKey(KC_P) == 1)
 	{
 		//MainRendererSingleton::get().getPps().getHdr().setExposure(20);
-		in.hideCursor(true);
+		//in.hideCursor(true);
+		MainRendererSingleton::get().getDbg().setDepthTestEnabled(
+			!MainRendererSingleton::get().getDbg().getDepthTestEnabled());
 	}
 
 	if(in.getKey(KC_UP)) mover->rotateLocalX(ang);
@@ -286,7 +288,8 @@ void mainLoop()
 		InputSingleton::get().handleEvents();
 		InputSingleton::get().moveMouse(Vec2(0.0));
 		mainLoopExtra();
-		SceneSingleton::get().update(prevUpdateTime, crntTime);
+		SceneSingleton::get().update(
+			prevUpdateTime, crntTime, MainRendererSingleton::get());
 		EventManagerSingleton::get().updateAllEvents(prevUpdateTime, crntTime);
 		MainRendererSingleton::get().render(SceneSingleton::get());