Panagiotis Christopoulos Charitos 12 years ago
parent
commit
db1830b9c8

+ 13 - 8
include/anki/renderer/Tiler.h

@@ -6,6 +6,7 @@
 #include "anki/gl/Gl.h"
 #include "anki/gl/Gl.h"
 #include "anki/resource/Resource.h"
 #include "anki/resource/Resource.h"
 #include "anki/core/Timestamp.h"
 #include "anki/core/Timestamp.h"
+#include <bitset>
 
 
 namespace anki {
 namespace anki {
 
 
@@ -25,6 +26,9 @@ public:
 	// mind that there are size limitations in uniform blocks.
 	// mind that there are size limitations in uniform blocks.
 	static const U TILES_X_COUNT = 16;
 	static const U TILES_X_COUNT = 16;
 	static const U TILES_Y_COUNT = 16;
 	static const U TILES_Y_COUNT = 16;
+	static const U TILES_COUNT = TILES_X_COUNT * TILES_X_COUNT;
+
+	typedef std::bitset<TILES_X_COUNT * TILES_X_COUNT> Bitset;
 
 
 	Tiler();
 	Tiler();
 	~Tiler();
 	~Tiler();
@@ -54,7 +58,7 @@ public:
 		const CollisionShape& cs, 
 		const CollisionShape& cs, 
 		const Aabb& aabb, 
 		const Aabb& aabb, 
 		Bool skipNearPlane,
 		Bool skipNearPlane,
-		Array<U32, 2>* mask) const;
+		Bitset* mask) const;
 
 
 private:
 private:
 	/// A screen tile
 	/// A screen tile
@@ -86,7 +90,7 @@ private:
 	};
 	};
 
 
 	Vector<Tile_> tiles_;
 	Vector<Tile_> tiles_;
-	Tile_* tiles0; ///< Tiles last level
+	Tile_* tiles0 = nullptr; ///< Tiles last level
 
 
 	/// The timestamp of the 4 planes update
 	/// The timestamp of the 4 planes update
 	U32 planes4UpdateTimestamp = Timestamp::getTimestamp();
 	U32 planes4UpdateTimestamp = Timestamp::getTimestamp();
@@ -104,10 +108,10 @@ private:
 	/// Main shader program
 	/// Main shader program
 	ShaderProgramResourcePointer prog;
 	ShaderProgramResourcePointer prog;
 
 
-	const ShaderProgramUniformVariable* depthMapUniform; ///< Cache it
+	const ShaderProgramUniformVariable* depthMapUniform = nullptr; ///< Cache it
 
 
-	Renderer* r;
-	const Camera* prevCam;
+	Renderer* r = nullptr;
+	const Camera* prevCam = nullptr;
 
 
 	void initInternal(Renderer* r);
 	void initInternal(Renderer* r);
 	Tile_* initTilesInDepth(Tile_* tiles, U depth);
 	Tile_* initTilesInDepth(Tile_* tiles, U depth);
@@ -119,9 +123,10 @@ private:
 	Bool testInternal(const CollisionShape& cs, const Tile& tile, 
 	Bool testInternal(const CollisionShape& cs, const Tile& tile, 
 		const U startPlane) const;
 		const U startPlane) const;
 
 
-	void testTile(const Tile_& tile, const Vec2& a, const Vec2& b, 
-		const Array<Vec3, 2>& objMinMax,
-		Array<U32, 2>& mask) const;
+	void testTile(const Tile_& tile, const Vec2& a, const Vec2& b,
+		const Array<Vec3, 2>& objMinMax, Bitset &bitset) const;
+
+	void updateBitset(const Tile_& tile, Bitset &bitset) const;
 };
 };
 
 
 } // end namespace anki
 } // end namespace anki

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

@@ -5,6 +5,7 @@
 #include "anki/collision/Collision.h"
 #include "anki/collision/Collision.h"
 #include "anki/util/Bitset.h"
 #include "anki/util/Bitset.h"
 #include "anki/core/Timestamp.h"
 #include "anki/core/Timestamp.h"
+#include <bitset>
 
 
 namespace anki {
 namespace anki {
 
 
@@ -83,6 +84,15 @@ public:
 		return timestamp;
 		return timestamp;
 	}
 	}
 
 
+	const std::bitset<256>& getTilerBitset() const
+	{
+		return tilerBitset;
+	}
+	void setTilerBitset(const std::bitset<256>& bitset)
+	{
+		tilerBitset = bitset;
+	}
+
 	/// Used for sorting spatials. In most object the origin is the center of
 	/// Used for sorting spatials. In most object the origin is the center of
 	/// the bounding volume but for cameras the origin is the eye point
 	/// the bounding volume but for cameras the origin is the eye point
 	virtual const Vec3& getSpatialOrigin() const
 	virtual const Vec3& getSpatialOrigin() const
@@ -152,6 +162,8 @@ public:
 		{
 		{
 			subsp->disableBits(SF_VISIBLE_ANY);
 			subsp->disableBits(SF_VISIBLE_ANY);
 		}
 		}
+
+		tilerBitset.reset();
 	}
 	}
 
 
 protected:
 protected:
@@ -171,6 +183,7 @@ private:
 	OctreeNode* octreeNode = nullptr; ///< What octree node includes this
 	OctreeNode* octreeNode = nullptr; ///< What octree node includes this
 	Aabb aabb; ///< A faster shape
 	Aabb aabb; ///< A faster shape
 	Vec3 origin; ///< Cached value
 	Vec3 origin; ///< Cached value
+	std::bitset<256> tilerBitset;
 };
 };
 /// @}
 /// @}
 
 

+ 3 - 3
shaders/IsLpGeneric.glsl

@@ -291,9 +291,9 @@ void main()
 #endif
 #endif
 
 
 #if 1
 #if 1
-	if(tiles[vInstanceId].lightsCount[3] == 333)
+	if(tiles[vInstanceId].lightsCount[3] > 0)
 	{
 	{
-		fColor *= vec3(1.5);
+		fColor += vec3(0.1);
 	}
 	}
 #endif
 #endif
 
 
@@ -323,7 +323,7 @@ void main()
 	}
 	}
 #endif
 #endif
 
 
-#if 0
+#if 1
 	vec3 tmpc = vec3((vInstanceId % 4) / 3.0, (vInstanceId % 3) / 2.0, 
 	vec3 tmpc = vec3((vInstanceId % 4) / 3.0, (vInstanceId % 3) / 2.0, 
 		(vInstanceId % 2));
 		(vInstanceId % 2));
 	fColor += tmpc / 40.0;
 	fColor += tmpc / 40.0;

+ 21 - 0
src/core/App.cpp

@@ -7,9 +7,27 @@
 #include <sstream>
 #include <sstream>
 #include <iostream>
 #include <iostream>
 #include <iomanip>
 #include <iomanip>
+#include <execinfo.h>
+#include <signal.h>
 
 
 namespace anki {
 namespace anki {
 
 
+//==============================================================================
+/// Segfault signal handler
+void handler(int sig)
+{
+	void *array[10];
+	size_t size;
+
+	// get void*'s for all entries on the stack
+	size = backtrace(array, 10);
+
+	// print out all the frames to stderr
+	fprintf(stderr, "Error: signal %d:\n", sig);
+	backtrace_symbols_fd(array, size, 2);
+	exit(1);
+}
+
 //==============================================================================
 //==============================================================================
 void App::handleLoggerMessages(const Logger::Info& info)
 void App::handleLoggerMessages(const Logger::Info& info)
 {
 {
@@ -68,6 +86,9 @@ void App::parseCommandLineArgs(int argc, char* argv[])
 //==============================================================================
 //==============================================================================
 void App::init(int argc, char* argv[])
 void App::init(int argc, char* argv[])
 {
 {
+	// Install signal handler
+	signal(SIGSEGV, handler);
+
 	// send output to handleMessageHanlderMsgs
 	// send output to handleMessageHanlderMsgs
 	ANKI_CONNECT(&LoggerSingleton::get(), messageRecieved, 
 	ANKI_CONNECT(&LoggerSingleton::get(), messageRecieved, 
 		this, handleLoggerMessages);
 		this, handleLoggerMessages);

+ 6 - 5
src/renderer/Dbg.cpp

@@ -161,7 +161,7 @@ void Dbg::run()
 	drawer->setModelMatrix(Mat4::getIdentity());
 	drawer->setModelMatrix(Mat4::getIdentity());
 	//drawer->drawGrid();
 	//drawer->drawGrid();
 
 
-#if 0
+#if 1
 	SceneGraph& scene = r->getSceneGraph();
 	SceneGraph& scene = r->getSceneGraph();
 
 
 	for(auto it = scene.getSceneNodesBegin();
 	for(auto it = scene.getSceneNodesBegin();
@@ -169,7 +169,7 @@ void Dbg::run()
 	{
 	{
 		SceneNode* node = *it;
 		SceneNode* node = *it;
 		Spatial* sp = node->getSpatial();
 		Spatial* sp = node->getSpatial();
-		if(flagsEnabled(DF_SPATIAL) && sp)
+		if(bitsEnabled(DF_SPATIAL) && sp)
 		{
 		{
 			sceneDrawer->draw(*node);
 			sceneDrawer->draw(*node);
 		}
 		}
@@ -180,12 +180,12 @@ void Dbg::run()
 	{
 	{
 		//if(sector->isVisible())
 		//if(sector->isVisible())
 		{
 		{
-			if(flagsEnabled(DF_SECTOR))
+			if(bitsEnabled(DF_SECTOR))
 			{
 			{
 				sceneDrawer->draw(*sector);
 				sceneDrawer->draw(*sector);
 			}
 			}
 
 
-			if(flagsEnabled(DF_OCTREE))
+			if(bitsEnabled(DF_OCTREE))
 			{
 			{
 				sceneDrawer->draw(sector->getOctree());
 				sceneDrawer->draw(sector->getOctree());
 			}
 			}
@@ -193,12 +193,13 @@ void Dbg::run()
 	}
 	}
 
 
 	// Physics
 	// Physics
-	if(flagsEnabled(DF_PHYSICS))
+	if(bitsEnabled(DF_PHYSICS))
 	{
 	{
 		scene.getPhysics().debugDraw();
 		scene.getPhysics().debugDraw();
 	}
 	}
 #endif
 #endif
 
 
+	if(0)
 	{
 	{
 		drawer->setColor(Vec3(0.1, 0.1, 0.1));
 		drawer->setColor(Vec3(0.1, 0.1, 0.1));
 		Aabb box(Vec3(-1.0, 1.0, -1.0), Vec3(1.5, 2.0, 1.5));
 		Aabb box(Vec3(-1.0, 1.0, -1.0), Vec3(1.5, 2.0, 1.5));

+ 19 - 0
src/renderer/Is.cpp

@@ -4,6 +4,7 @@
 #include "anki/scene/Camera.h"
 #include "anki/scene/Camera.h"
 #include "anki/scene/Light.h"
 #include "anki/scene/Light.h"
 #include "anki/core/ThreadPool.h"
 #include "anki/core/ThreadPool.h"
+#include <bitset> // XXX remove it
 
 
 namespace anki {
 namespace anki {
 
 
@@ -200,6 +201,8 @@ struct WriteTilesUboJob: ThreadJob
 		// Point lights
 		// Point lights
 		//
 		//
 
 
+		stile.lightsCount[3] = 0;
+
 		U pointLightsInTileCount = 0;
 		U pointLightsInTileCount = 0;
 		for(U i = 0; i < visiblePointLightsCount; i++)
 		for(U i = 0; i < visiblePointLightsCount; i++)
 		{
 		{
@@ -212,6 +215,22 @@ struct WriteTilesUboJob: ThreadJob
 				lightIndices[id] = i;
 				lightIndices[id] = i;
 				++pointLightsInTileCount;
 				++pointLightsInTileCount;
 			}
 			}
+
+			// XXX
+				{
+					const Tiler::Bitset& bitset = light.getTilerBitset();
+
+					//std::cout << std::bitset<32>(mask[0]) << std::endl;
+
+					if(bitset.test(tileId))
+					{
+						stile.lightsCount[3] = 333;
+					}
+					else
+					{
+						stile.lightsCount[3] = 0;
+					}
+				}
 		}
 		}
 
 
 		stile.lightsCount[0] = pointLightsInTileCount;
 		stile.lightsCount[0] = pointLightsInTileCount;

+ 0 - 5
src/renderer/Renderer.cpp

@@ -85,10 +85,7 @@ void Renderer::render(SceneGraph& scene_)
 #if ANKI_CFG_RENDERER_PROFILE
 #if ANKI_CFG_RENDERER_PROFILE
 	HighRezTimer::Scalar timea, timeb;
 	HighRezTimer::Scalar timea, timeb;
 
 
-	timea = HighRezTimer::getCurrentTime();
-	tiler.updateTiles(scene->getActiveCamera());
 	timeb = HighRezTimer::getCurrentTime();
 	timeb = HighRezTimer::getCurrentTime();
-	tilerTime += timeb - timea;
 
 
 	ms.run();
 	ms.run();
 	timea = HighRezTimer::getCurrentTime();
 	timea = HighRezTimer::getCurrentTime();
@@ -109,8 +106,6 @@ void Renderer::render(SceneGraph& scene_)
 	timea = HighRezTimer::getCurrentTime();
 	timea = HighRezTimer::getCurrentTime();
 	ppsTime += timea - timeb;
 	ppsTime += timea - timeb;
 #else
 #else
-	// Wrong time to update the tiler
-	tiler.updateTiles(scene->getActiveCamera());
 	ms.run();
 	ms.run();
 	tiler.runMinMax(ms.getDepthFai());
 	tiler.runMinMax(ms.getDepthFai());
 	is.run();
 	is.run();

+ 101 - 58
src/renderer/Tiler.cpp

@@ -278,6 +278,7 @@ void Tiler::initTiles()
 		tiles0 = tmpTiles;
 		tiles0 = tmpTiles;
 		tmpTiles = initTilesInDepth(tmpTiles, d);
 		tmpTiles = initTilesInDepth(tmpTiles, d);
 	}
 	}
+	ANKI_ASSERT(tiles_.size() - (tiles0 - &tiles_[0]) == TILES_COUNT);
 
 
 	// Init hierarchy
 	// Init hierarchy
 	U offset = 0;
 	U offset = 0;
@@ -347,11 +348,14 @@ Tiler::Tile_* Tiler::initTilesInDepth(Tile_* tiles, U depth)
 //==============================================================================
 //==============================================================================
 void Tiler::runMinMax(const Texture& depthMap)
 void Tiler::runMinMax(const Texture& depthMap)
 {
 {
+	ANKI_ASSERT(depthMap.getFiltering() == Texture::TFT_NEAREST);
+
 	// Issue the min/max job
 	// Issue the min/max job
 	fbo.bind();
 	fbo.bind();
 	GlStateSingleton::get().setViewport(0, 0, TILES_X_COUNT, TILES_Y_COUNT);
 	GlStateSingleton::get().setViewport(0, 0, TILES_X_COUNT, TILES_Y_COUNT);
 	r->clearAfterBindingFbo(GL_COLOR_BUFFER_BIT);
 	r->clearAfterBindingFbo(GL_COLOR_BUFFER_BIT);
 	prog->bind();
 	prog->bind();
+	ANKI_ASSERT(depthMapUniform);
 	depthMapUniform->set(depthMap);
 	depthMapUniform->set(depthMap);
 
 
 	r->drawQuad();
 	r->drawQuad();
@@ -375,10 +379,17 @@ void Tiler::updateTilesInternal()
 	//
 	//
 	// Set the Z of the level 0 tiles
 	// Set the Z of the level 0 tiles
 	//
 	//
-	for(U i = 0; i < TILES_X_COUNT * TILES_X_COUNT; i++)
+	ANKI_ASSERT(tiles0);
+	Tile_* tile = tiles0;
+	Tile_* tileEnd = tile + TILES_COUNT;
+	F32* pixel = &pixels[0];
+	for(; tile != tileEnd; ++tile)
 	{
 	{
-		tiles0[i].min.z() = pixels[i * 2 + 0];
-		tiles0[i].max.z() = pixels[i * 2 + 1];
+		tile->min.z() = pixel[0];
+		tile->max.z() = pixel[1];
+		ANKI_ASSERT(tile->max.z() >= tile->min.z());
+
+		pixel += 2;
 	}
 	}
 
 
 	//
 	//
@@ -533,7 +544,7 @@ Bool Tiler::test(
 	const CollisionShape& cs, 
 	const CollisionShape& cs, 
 	const Aabb& aabb, 
 	const Aabb& aabb, 
 	Bool skipNearPlane,
 	Bool skipNearPlane,
-	Array<U32, 2>* outMask) const
+	Bitset* outBitset) const
 {
 {
 	//
 	//
 	// Get points from sp
 	// Get points from sp
@@ -566,13 +577,14 @@ Bool Tiler::test(
 	// Transform those shapes
 	// Transform those shapes
 	//
 	//
 	Array<Vec2, 8> points2D;
 	Array<Vec2, 8> points2D;
+	ANKI_ASSERT(prevCam);
 	const Mat4& projection = prevCam->getViewProjectionMatrix();
 	const Mat4& projection = prevCam->getViewProjectionMatrix();
-	Array<Vec3, 2> minMax = {{Vec3(10.0), Vec3(-1.0)}};
+	Array<Vec3, 2> minMax = {{Vec3(10.0), Vec3(-10.0)}};
 
 
 	for(U i = 0; i < pointsCount; i++)
 	for(U i = 0; i < pointsCount; i++)
 	{
 	{
 		Vec4 point = projection * points[i];
 		Vec4 point = projection * points[i];
-		Vec3 v3 = point.xyz() / point.w();
+		Vec3 v3 = point.xyz() / fabs(point.w());
 		points2D[i] = v3.xy();
 		points2D[i] = v3.xy();
 
 
 		// Min z
 		// Min z
@@ -604,38 +616,55 @@ Bool Tiler::test(
 	//
 	//
 	// Run the algorithm for every edge
 	// Run the algorithm for every edge
 	//
 	//
-	Array<U32, 2> mask = {{0, 0}};
+	Bitset bitset;
 	for(U i = 0; i < convPointsCount - 1; i++)
 	for(U i = 0; i < convPointsCount - 1; i++)
 	{
 	{
-		Array<U32, 2> edgemask = {{0, 0}};
-		testTile(tiles_[0], convPoints[i], convPoints[i + 1], minMax, edgemask);
-
-		std::cout << "-- " << edgemask[1] << std::endl;
+		Bitset edgebitset;
+		testTile(tiles_[0], convPoints[i], convPoints[i + 1],
+			minMax, edgebitset);
 
 
 		if(i != 0)
 		if(i != 0)
 		{
 		{
-			mask[0] &= edgemask[0];
-			mask[1] &= edgemask[1];
+			bitset &= edgebitset;
 		}
 		}
 		else
 		else
 		{
 		{
-			mask[0] = edgemask[0];
-			mask[1] = edgemask[1];
+			bitset = edgebitset;
 		}
 		}
 
 
 	}
 	}
 
 
-	if(outMask)
+	//
+	// XXX
+	//
+	for(U i = 0; i < TILES_COUNT; i++)
+	{
+		if(bitset.test(i))
+		{
+			ANKI_ASSERT(i < tiles_.size());
+
+			if(tiles0[i].max.z() > minMax[0].z())
+			{
+				// Keep it
+			}
+			else
+			{
+				bitset.set(i, false);
+			}
+		}
+	}
+
+	if(outBitset)
 	{
 	{
-		*outMask = mask;
+		*outBitset = bitset;
 	}
 	}
 
 
-	return mask[0] != 0 && mask[1] != 0;
+	return bitset.any();
 }
 }
 
 
 //==============================================================================
 //==============================================================================
 void Tiler::testTile(const Tile_& tile, const Vec2& a, const Vec2& b, 
 void Tiler::testTile(const Tile_& tile, const Vec2& a, const Vec2& b, 
-	const Array<Vec3, 2>& objMinMax, Array<U32, 2>& mask) const
+	const Array<Vec3, 2>& objMinMax, Bitset& bitset) const
 {
 {
 	// If edge not inside return
 	// If edge not inside return
 	for(U i = 0; i < 2; i++)
 	for(U i = 0; i < 2; i++)
@@ -652,68 +681,82 @@ void Tiler::testTile(const Tile_& tile, const Vec2& a, const Vec2& b,
 	// Continue
 	// Continue
 	Bool final = tile.children[0] == -1;
 	Bool final = tile.children[0] == -1;
 
 
-	U inside = 0;
-
-	if(isLeft(a, b, tile.max.xy()))
+	if(!final)
 	{
 	{
-		if(final)
+		U inside = 0;
+
+		if(isLeft(a, b, tile.max.xy()))
 		{
 		{
-			goto allIn;
+			inside |= 1;
 		}
 		}
-		inside |= 1;
-	}
 
 
-	if(isLeft(a, b, Vec2(tile.min.x(), tile.max.y())))
-	{
-		if(final)
+		if(isLeft(a, b, Vec2(tile.min.x(), tile.max.y())))
 		{
 		{
-			goto allIn;
+			inside |= 2;
 		}
 		}
-		inside |= 2;
-	}
 
 
-	if(isLeft(a, b, tile.min.xy()))
-	{
-		if(final)
+		if(isLeft(a, b, tile.min.xy()))
 		{
 		{
-			goto allIn;
+			inside |= 4;
 		}
 		}
-		inside |= 4;
-	}
 
 
-	if(isLeft(a, b, Vec2(tile.max.x(), tile.min.y())))
-	{
-		if(final)
+		if(isLeft(a, b, Vec2(tile.max.x(), tile.min.y())))
+		{
+			inside |= 8;
+		}
+
+		// None inside
+		if(inside == 0)
+		{
+			return;
+		}
+		else if(inside == 0xF) // All inside
 		{
 		{
 			goto allIn;
 			goto allIn;
 		}
 		}
-		inside |= 8;
-	}
+		else // Some inside
+		{
+			ANKI_ASSERT(!final);
 
 
-	// None inside
-	if(inside == 0)
-	{
-		return;
-	}
-	else if(inside == 0xF) // All inside
-	{
-		goto allIn;
+			for(U i = 0; i < 4; i++)
+			{
+				testTile(tiles_[tile.children[i]], a, b, objMinMax, bitset);
+			}
+		}
 	}
 	}
-	else // Some inside
+	else
 	{
 	{
-		ANKI_ASSERT(!final);
-
-		for(U i = 0; i < 4; i++)
+		if(isLeft(a, b, tile.max.xy())
+			|| isLeft(a, b, Vec2(tile.min.x(), tile.max.y()))
+			|| isLeft(a, b, tile.min.xy())
+			|| isLeft(a, b, Vec2(tile.max.x(), tile.min.y())))
 		{
 		{
-			testTile(tiles_[tile.children[i]], a, b, objMinMax, mask);
+			goto allIn;
 		}
 		}
 	}
 	}
 
 
 	return;
 	return;
 
 
 allIn:
 allIn:
-	mask[0] |= tile.mask[0];
-	mask[1] |= tile.mask[1];
+	updateBitset(tile, bitset);
+}
+
+//==============================================================================
+void Tiler::updateBitset(const Tile_& tile, Bitset &bitset) const
+{
+	if(tile.children[0] != -1)
+	{
+		for(U i = 0; i < 4; i++)
+		{
+			updateBitset(tiles_[tile.children[i]], bitset);
+		}
+	}
+	else
+	{
+		U tileId = &tile - tiles0;
+		ANKI_ASSERT(tileId < TILES_COUNT);
+		bitset.set(tileId);
+	}
 }
 }
 
 
 } // end namespace anki
 } // end namespace anki

+ 3 - 0
src/scene/SceneGraph.cpp

@@ -2,6 +2,7 @@
 #include "anki/scene/Camera.h"
 #include "anki/scene/Camera.h"
 #include "anki/util/Exception.h"
 #include "anki/util/Exception.h"
 #include "anki/core/ThreadPool.h"
 #include "anki/core/ThreadPool.h"
+#include "anki/renderer/Renderer.h"
 
 
 namespace anki {
 namespace anki {
 
 
@@ -131,7 +132,9 @@ void SceneGraph::update(F32 prevUpdateTime, F32 crntTime, Renderer& renderer)
 
 
 	frameAlloc.reset();
 	frameAlloc.reset();
 
 
+	// XXX Do that in parallel
 	physics.update(prevUpdateTime, crntTime);
 	physics.update(prevUpdateTime, crntTime);
+	renderer.getTiler().updateTiles(*mainCam);
 
 
 #if 0
 #if 0
 	// First do the movable updates
 	// First do the movable updates

+ 12 - 7
src/scene/Visibility.cpp

@@ -13,7 +13,7 @@ struct VisibilityTestJob: ThreadJob
 	U nodesCount = 0;
 	U nodesCount = 0;
 	SceneGraph::Types<SceneNode>::Container::iterator nodes;
 	SceneGraph::Types<SceneNode>::Container::iterator nodes;
 	SceneNode* frustumableSn = nullptr;
 	SceneNode* frustumableSn = nullptr;
-	Renderer* renderer = nullptr;
+	Tiler* tiler = nullptr;
 	SceneAllocator<U8> frameAlloc;
 	SceneAllocator<U8> frameAlloc;
 
 
 	VisibilityTestResults* visible;
 	VisibilityTestResults* visible;
@@ -60,8 +60,8 @@ struct VisibilityTestJob: ThreadJob
 				Spatial* subsp = *it;
 				Spatial* subsp = *it;
 	
 	
 				if(frustumable->insideFrustum(*subsp)
 				if(frustumable->insideFrustum(*subsp)
-					&& renderer->doVisibilityTests(
-					subsp->getOptimalCollisionShape()))
+					/*&& renderer->doVisibilityTests(
+					subsp->getOptimalCollisionShape())*/)
 				{
 				{
 					subSpatialsMask |= 1 << i;
 					subSpatialsMask |= 1 << i;
 					subsp->enableBits(Spatial::SF_VISIBLE_CAMERA);
 					subsp->enableBits(Spatial::SF_VISIBLE_CAMERA);
@@ -78,11 +78,11 @@ struct VisibilityTestJob: ThreadJob
 			Renderable* r = node->getRenderable();
 			Renderable* r = node->getRenderable();
 			if(r)
 			if(r)
 			{
 			{
-				if(!renderer->doVisibilityTests(
+				/*if(!renderer->doVisibilityTests(
 					sp->getOptimalCollisionShape()))
 					sp->getOptimalCollisionShape()))
 				{
 				{
 					continue;
 					continue;
-				}
+				}*/
 				visible->renderables.push_back(node);
 				visible->renderables.push_back(node);
 
 
 				// Inform the renderable for the mask
 				// Inform the renderable for the mask
@@ -95,10 +95,15 @@ struct VisibilityTestJob: ThreadJob
 			else
 			else
 			{
 			{
 				Light* l = node->getLight();
 				Light* l = node->getLight();
-				if(l)
+				Tiler::Bitset tilerBitset;
+				if(l
+					&& tiler->test(sp->getSpatialCollisionShape(),
+					sp->getAabb(), false, &tilerBitset))
 				{
 				{
 					visible->lights.push_back(node);
 					visible->lights.push_back(node);
 
 
+					sp->setTilerBitset(tilerBitset);
+
 					if(l->getShadowEnabled() && fr)
 					if(l->getShadowEnabled() && fr)
 					{
 					{
 						testLight(*node);
 						testLight(*node);
@@ -200,7 +205,7 @@ void doVisibilityTests(SceneNode& fsn, SceneGraph& scene,
 		jobs[i].nodesCount = scene.getSceneNodesCount();
 		jobs[i].nodesCount = scene.getSceneNodesCount();
 		jobs[i].nodes = scene.getSceneNodesBegin();
 		jobs[i].nodes = scene.getSceneNodesBegin();
 		jobs[i].frustumableSn = &fsn;
 		jobs[i].frustumableSn = &fsn;
-		jobs[i].renderer = &r;
+		jobs[i].tiler = &r.getTiler();
 		jobs[i].frameAlloc = scene.getFrameAllocator();
 		jobs[i].frameAlloc = scene.getFrameAllocator();
 
 
 		threadPool.assignNewJob(i, &jobs[i]);
 		threadPool.assignNewJob(i, &jobs[i]);

+ 1 - 1
testapp/Main.cpp

@@ -240,7 +240,7 @@ void init()
 		0.7));
 		0.7));
 #endif
 #endif
 
 
-#if 0
+#if 1
 	StaticGeometryNode* sponzaModel = new StaticGeometryNode(
 	StaticGeometryNode* sponzaModel = new StaticGeometryNode(
 		//"data/maps/sponza/sponza_no_bmeshes.mdl",
 		//"data/maps/sponza/sponza_no_bmeshes.mdl",
 		"data/maps/sponza/sponza.mdl",
 		"data/maps/sponza/sponza.mdl",