Panagiotis Christopoulos Charitos 13 lat temu
rodzic
commit
c9cc064b33

+ 191 - 0
include/anki/renderer/DebugDrawer.h

@@ -0,0 +1,191 @@
+#ifndef ANKI_RENDERER_DEBUG_DRAWER_H
+#define ANKI_RENDERER_DEBUG_DRAWER_H
+
+#include "anki/math/Math.h"
+#include "anki/gl/Vbo.h"
+#include "anki/gl/Vao.h"
+#include "anki/resource/Resource.h"
+#include "anki/collision/CollisionShape.h"
+#include "anki/scene/SceneNode.h"
+#include "anki/util/Flags.h"
+#include <array>
+#include <map>
+#include <LinearMath/btIDebugDraw.h>
+
+namespace anki {
+
+/// Draws simple primitives
+class DebugDrawer
+{
+public:
+	DebugDrawer();
+	~DebugDrawer();
+
+	void drawGrid();
+	void drawSphere(float radius, int complexity = 4);
+	void drawCube(float size = 1.0);
+	void drawLine(const Vec3& from, const Vec3& to, const Vec4& color);
+
+	/// @name Render functions. Imitate the GL 1.1 immediate mode
+	/// @{
+	void begin(); ///< Initiates the draw
+	void end(); ///< Draws
+	void pushBackVertex(const Vec3& pos); ///< Something like glVertex
+	/// Something like glColor
+	void setColor(const Vec3& col)
+	{
+		crntCol = col;
+	}
+	/// Something like glColor
+	void setColor(const Vec4& col)
+	{
+		crntCol = Vec3(col);
+	}
+	void setModelMatrix(const Mat4& modelMat);
+	void setViewProjectionMatrix(const Mat4& m)
+	{
+		vpMat = m;
+	}
+	/// @}
+
+private:
+	ShaderProgramResourcePointer sProg;
+	static const uint MAX_POINTS_PER_DRAW = 256;
+	std::array<Vec3, MAX_POINTS_PER_DRAW> positions;
+	std::array<Vec3, MAX_POINTS_PER_DRAW> colors;
+	Mat4 modelMat;
+	Mat4 vpMat;
+	uint pointIndex;
+	Vec3 crntCol;
+	Vbo positionsVbo;
+	Vbo colorsVbo;
+	Vao vao;
+
+	/// This is a container of some precalculated spheres. Its a map that
+	/// from sphere complexity it returns a vector of lines (Vec3s in
+	/// pairs)
+	std::map<uint, Vector<Vec3>> complexityToPreCalculatedSphere;
+};
+
+/// Contains methods to render the collision shapes
+class CollisionDebugDrawer: public CollisionShape::ConstVisitor
+{
+public:
+	/// Constructor
+	CollisionDebugDrawer(DebugDrawer* dbg_)
+		: dbg(dbg_)
+	{}
+
+	void visit(const LineSegment&)
+	{
+		/// XXX
+		ANKI_ASSERT(0 && "ToDo");
+	}
+
+	void visit(const Obb&);
+
+	void visit(const Frustum&);
+
+	void visit(const Plane&);
+
+	void visit(const Ray&)
+	{
+		ANKI_ASSERT(0 && "ToDo");
+	}
+
+	void visit(const Sphere&);
+
+	void visit(const Aabb&);
+
+private:
+	DebugDrawer* dbg; ///< The debug drawer
+};
+
+/// An implementation of btIDebugDraw used for debugging Bullet. See Bullet
+/// docs for details
+class PhysicsDebugDrawer: public btIDebugDraw
+{
+public:
+	PhysicsDebugDrawer(DebugDrawer* dbg_)
+		: dbg(dbg_)
+	{}
+
+	void drawLine(const btVector3& from, const btVector3& to,
+		const btVector3& color);
+
+	void drawContactPoint(const btVector3& pointOnB,
+		const btVector3& normalOnB, btScalar distance, int lifeTime,
+		const btVector3& color);
+
+	void drawSphere(btScalar radius, const btTransform& transform,
+		const btVector3& color);
+
+	void drawBox(const btVector3& bbMin, const btVector3& bbMax,
+		const btVector3& color);
+
+	void drawBox(const btVector3& bbMin, const btVector3& bbMax,
+		const btTransform& trans, const btVector3& color);
+
+	void reportErrorWarning(const char* warningString);
+	void draw3dText(const btVector3& location, const char* textString);
+	void setDebugMode(int debugMode_)
+	{
+		debugMode = debugMode_;
+	}
+	int getDebugMode() const
+	{
+		return debugMode;
+	}
+
+private:
+	int debugMode;
+	DebugDrawer* dbg;
+};
+
+// Forward
+class Octree;
+class OctreeNode;
+class Renderer;
+class Camera;
+
+/// This is a drawer for some scene nodes that need debug
+class SceneDebugDrawer: public Flags<U32>
+{
+public:
+	enum DebugFlag
+	{
+		DF_NONE = 0,
+		DF_SPATIAL = 1 << 0,
+		DF_FRUSTUMABLE = 1 << 1
+	};
+
+	SceneDebugDrawer(DebugDrawer* d)
+		: Flags<U32>(DF_SPATIAL | DF_FRUSTUMABLE), dbg(d)
+	{}
+
+	virtual ~SceneDebugDrawer()
+	{}
+
+	void draw(SceneNode& node);
+
+	virtual void draw(const Octree& octree) const;
+
+	void setViewProjectionMatrix(const Mat4& m)
+	{
+		dbg->setViewProjectionMatrix(m);
+	}
+
+private:
+	DebugDrawer* dbg;
+
+	virtual void draw(Frustumable& fr) const;
+
+	virtual void draw(Spatial& sp) const;
+
+	virtual void draw(const OctreeNode& octnode,
+		U32 depth, const Octree& octree) const;
+};
+
+} // end namespace anki
+
+#endif

+ 0 - 180
include/anki/renderer/Drawer.h

@@ -1,191 +1,11 @@
 #ifndef ANKI_RENDERER_DRAWER_H
 #ifndef ANKI_RENDERER_DRAWER_H
 #define ANKI_RENDERER_DRAWER_H
 #define ANKI_RENDERER_DRAWER_H
 
 
-#include "anki/math/Math.h"
-#include "anki/gl/Vbo.h"
-#include "anki/gl/Vao.h"
 #include "anki/resource/Resource.h"
 #include "anki/resource/Resource.h"
-#include "anki/collision/CollisionShape.h"
 #include "anki/scene/SceneNode.h"
 #include "anki/scene/SceneNode.h"
-#include "anki/util/Flags.h"
-#include <array>
-#include <map>
-#include <LinearMath/btIDebugDraw.h>
 
 
 namespace anki {
 namespace anki {
 
 
-/// Draws simple primitives
-class DebugDrawer
-{
-public:
-	DebugDrawer();
-	~DebugDrawer();
-
-	void drawGrid();
-	void drawSphere(float radius, int complexity = 4);
-	void drawCube(float size = 1.0);
-	void drawLine(const Vec3& from, const Vec3& to, const Vec4& color);
-
-	/// @name Render functions. Imitate the GL 1.1 immediate mode
-	/// @{
-	void begin(); ///< Initiates the draw
-	void end(); ///< Draws
-	void pushBackVertex(const Vec3& pos); ///< Something like glVertex
-	/// Something like glColor
-	void setColor(const Vec3& col)
-	{
-		crntCol = col;
-	}
-	/// Something like glColor
-	void setColor(const Vec4& col)
-	{
-		crntCol = Vec3(col);
-	}
-	void setModelMatrix(const Mat4& modelMat);
-	void setViewProjectionMatrix(const Mat4& m)
-	{
-		vpMat = m;
-	}
-	/// @}
-
-private:
-	ShaderProgramResourcePointer sProg;
-	static const uint MAX_POINTS_PER_DRAW = 256;
-	std::array<Vec3, MAX_POINTS_PER_DRAW> positions;
-	std::array<Vec3, MAX_POINTS_PER_DRAW> colors;
-	Mat4 modelMat;
-	Mat4 vpMat;
-	uint pointIndex;
-	Vec3 crntCol;
-	Vbo positionsVbo;
-	Vbo colorsVbo;
-	Vao vao;
-
-	/// This is a container of some precalculated spheres. Its a map that
-	/// from sphere complexity it returns a vector of lines (Vec3s in
-	/// pairs)
-	std::map<uint, Vector<Vec3>> complexityToPreCalculatedSphere;
-};
-
-
-/// Contains methods to render the collision shapes
-class CollisionDebugDrawer: public CollisionShape::ConstVisitor
-{
-public:
-	/// Constructor
-	CollisionDebugDrawer(DebugDrawer* dbg_)
-		: dbg(dbg_)
-	{}
-
-	void visit(const LineSegment&)
-	{
-		/// XXX
-		ANKI_ASSERT(0 && "ToDo");
-	}
-
-	void visit(const Obb&);
-
-	void visit(const Frustum&);
-
-	void visit(const Plane&);
-
-	void visit(const Ray&)
-	{
-		ANKI_ASSERT(0 && "ToDo");
-	}
-
-	void visit(const Sphere&);
-
-	void visit(const Aabb&);
-
-private:
-	DebugDrawer* dbg; ///< The debug drawer
-};
-
-/// An implementation of btIDebugDraw used for debugging Bullet. See Bullet
-/// docs for details
-class PhysicsDebugDrawer: public btIDebugDraw
-{
-public:
-	PhysicsDebugDrawer(DebugDrawer* dbg_)
-		: dbg(dbg_)
-	{}
-
-	void drawLine(const btVector3& from, const btVector3& to,
-		const btVector3& color);
-
-	void drawContactPoint(const btVector3& pointOnB,
-		const btVector3& normalOnB, btScalar distance, int lifeTime,
-		const btVector3& color);
-
-	void drawSphere(btScalar radius, const btTransform& transform,
-		const btVector3& color);
-
-	void drawBox(const btVector3& bbMin, const btVector3& bbMax,
-		const btVector3& color);
-
-	void drawBox(const btVector3& bbMin, const btVector3& bbMax,
-		const btTransform& trans, const btVector3& color);
-
-	void reportErrorWarning(const char* warningString);
-	void draw3dText(const btVector3& location, const char* textString);
-	void setDebugMode(int debugMode_)
-	{
-		debugMode = debugMode_;
-	}
-	int getDebugMode() const
-	{
-		return debugMode;
-	}
-
-private:
-	int debugMode;
-	DebugDrawer* dbg;
-};
-
-class Octree;
-class OctreeNode;
-class Renderer;
-class Camera;
-
-/// This is a drawer for some scene nodes that need debug
-class SceneDebugDrawer: public Flags<uint32_t>
-{
-public:
-	enum DebugFlag
-	{
-		DF_NONE = 0,
-		DF_SPATIAL = 1 << 0,
-		DF_FRUSTUMABLE = 1 << 1
-	};
-
-	SceneDebugDrawer(DebugDrawer* d)
-		: Flags<uint32_t>(DF_SPATIAL | DF_FRUSTUMABLE), dbg(d)
-	{}
-
-	virtual ~SceneDebugDrawer()
-	{}
-
-	void draw(SceneNode& node);
-
-	virtual void draw(const Octree& octree) const;
-
-	void setViewProjectionMatrix(const Mat4& m)
-	{
-		dbg->setViewProjectionMatrix(m);
-	}
-
-private:
-	DebugDrawer* dbg;
-
-	virtual void draw(Frustumable& fr) const;
-
-	virtual void draw(Spatial& sp) const;
-
-	virtual void draw(const OctreeNode& octnode,
-		uint32_t depth, const Octree& octree) const;
-};
-
 class PassLevelKey;
 class PassLevelKey;
 
 
 /// It includes all the functions to render a Renderable
 /// It includes all the functions to render a Renderable

+ 10 - 4
include/anki/scene/Renderable.h

@@ -3,13 +3,13 @@
 
 
 #include "anki/scene/Property.h"
 #include "anki/scene/Property.h"
 #include "anki/util/Vector.h"
 #include "anki/util/Vector.h"
+#include "anki/gl/Ubo.h"
 
 
 namespace anki {
 namespace anki {
 
 
 class ModelPatchBase;
 class ModelPatchBase;
 class Material;
 class Material;
 class MaterialVariable;
 class MaterialVariable;
-class Light;
 class Transform;
 class Transform;
 
 
 /// @addtogroup Scene
 /// @addtogroup Scene
@@ -33,11 +33,11 @@ public:
 
 
 	/// @name Accessors
 	/// @name Accessors
 	/// @{
 	/// @{
-	uint32_t getBuildinId() const
+	U32 getBuildinId() const
 	{
 	{
 		return buildinId;
 		return buildinId;
 	}
 	}
-	void setBuildinId(uint32_t id)
+	void setBuildinId(U32 id)
 	{
 	{
 		buildinId = id;
 		buildinId = id;
 	}
 	}
@@ -49,7 +49,7 @@ public:
 	/// @}
 	/// @}
 
 
 private:
 private:
-	uint32_t buildinId = 0; ///< The renderer sets it
+	U32 buildinId = 0; ///< The renderer sets it
 	const MaterialVariable* mvar = nullptr;
 	const MaterialVariable* mvar = nullptr;
 };
 };
 
 
@@ -86,6 +86,11 @@ public:
 	{
 	{
 		return props.end();
 		return props.end();
 	}
 	}
+
+	Ubo& getUbo()
+	{
+		return ubo;
+	}
 	/// @}
 	/// @}
 
 
 protected:
 protected:
@@ -93,6 +98,7 @@ protected:
 
 
 private:
 private:
 	MaterialVariableProperties props;
 	MaterialVariableProperties props;
+	Ubo ubo;
 };
 };
 /// @}
 /// @}
 
 

+ 505 - 0
src/renderer/DebugDrawer.cpp

@@ -0,0 +1,505 @@
+#include "anki/renderer/Drawer.h"
+#include "anki/resource/ShaderProgramResource.h"
+#include "anki/physics/Convertors.h"
+#include "anki/collision/Collision.h"
+#include "anki/scene/Frustumable.h"
+#include "anki/scene/Octree.h"
+#include "anki/resource/Material.h"
+#include "anki/scene/Renderable.h"
+#include "anki/scene/Camera.h"
+#include "anki/scene/ModelNode.h"
+#include "anki/resource/TextureResource.h"
+#include "anki/renderer/Renderer.h"
+
+namespace anki {
+
+//==============================================================================
+// DebugDrawer                                                                 =
+//==============================================================================
+
+//==============================================================================
+DebugDrawer::~DebugDrawer()
+{}
+
+//==============================================================================
+DebugDrawer::DebugDrawer()
+{
+	sProg.load("shaders/Dbg.glsl");
+
+	positionsVbo.create(GL_ARRAY_BUFFER, sizeof(positions), NULL,
+		GL_DYNAMIC_DRAW);
+	colorsVbo.create(GL_ARRAY_BUFFER, sizeof(colors), NULL, GL_DYNAMIC_DRAW);
+	vao.create();
+	const int positionAttribLoc = 0;
+	vao.attachArrayBufferVbo(positionsVbo, positionAttribLoc, 3, GL_FLOAT,
+		GL_FALSE, 0, NULL);
+	const int colorAttribLoc = 1;
+	vao.attachArrayBufferVbo(colorsVbo, colorAttribLoc, 3, GL_FLOAT, GL_FALSE,
+		0, NULL);
+
+	pointIndex = 0;
+	modelMat.setIdentity();
+	crntCol = Vec3(1.0, 0.0, 0.0);
+}
+
+//==============================================================================
+void DebugDrawer::drawLine(const Vec3& from, const Vec3& to, const Vec4& color)
+{
+	setColor(color);
+	begin();
+		pushBackVertex(from);
+		pushBackVertex(to);
+	end();
+}
+
+//==============================================================================
+void DebugDrawer::drawGrid()
+{
+	Vec4 col0(0.5, 0.5, 0.5, 1.0);
+	Vec4 col1(0.0, 0.0, 1.0, 1.0);
+	Vec4 col2(1.0, 0.0, 0.0, 1.0);
+
+	const float SPACE = 1.0; // space between lines
+	const int NUM = 57;  // lines number. must be odd
+
+	const float GRID_HALF_SIZE = ((NUM - 1) * SPACE / 2);
+
+	setColor(col0);
+
+	begin();
+
+	for(int x = - NUM / 2 * SPACE; x < NUM / 2 * SPACE; x += SPACE)
+	{
+		setColor(col0);
+
+		// if the middle line then change color
+		if(x == 0)
+		{
+			setColor(col1);
+		}
+
+		// line in z
+		pushBackVertex(Vec3(x, 0.0, -GRID_HALF_SIZE));
+		pushBackVertex(Vec3(x, 0.0, GRID_HALF_SIZE));
+
+		// if middle line change col so you can highlight the x-axis
+		if(x == 0)
+		{
+			setColor(col2);
+		}
+
+		// line in the x
+		pushBackVertex(Vec3(-GRID_HALF_SIZE, 0.0, x));
+		pushBackVertex(Vec3(GRID_HALF_SIZE, 0.0, x));
+	}
+
+	// render
+	end();
+}
+
+//==============================================================================
+void DebugDrawer::drawSphere(float radius, int complexity)
+{
+	Vector<Vec3>* sphereLines;
+
+	// Pre-calculate the sphere points5
+	//
+	std::map<uint, Vector<Vec3> >::iterator it =
+		complexityToPreCalculatedSphere.find(complexity);
+
+	if(it != complexityToPreCalculatedSphere.end()) // Found
+	{
+		sphereLines = &(it->second);
+	}
+	else // Not found
+	{
+		complexityToPreCalculatedSphere[complexity] = Vector<Vec3>();
+		sphereLines = &complexityToPreCalculatedSphere[complexity];
+
+		float fi = getPi<F32>() / complexity;
+
+		Vec3 prev(1.0, 0.0, 0.0);
+		for(float th = fi; th < getPi<F32>() * 2.0 + fi; th += fi)
+		{
+			Vec3 p = Mat3(Euler(0.0, th, 0.0)) * Vec3(1.0, 0.0, 0.0);
+
+			for(float th2 = 0.0; th2 < getPi<F32>(); th2 += fi)
+			{
+				Mat3 rot(Euler(th2, 0.0, 0.0));
+
+				Vec3 rotPrev = rot * prev;
+				Vec3 rotP = rot * p;
+
+				sphereLines->push_back(rotPrev);
+				sphereLines->push_back(rotP);
+
+				Mat3 rot2(Euler(0.0, 0.0, getPi<F32>() / 2));
+
+				sphereLines->push_back(rot2 * rotPrev);
+				sphereLines->push_back(rot2 * rotP);
+			}
+
+			prev = p;
+		}
+	}
+
+	// Render
+	//
+	modelMat = modelMat * Mat4(Vec3(0.0), Mat3::getIdentity(), radius);
+
+	begin();
+	for(const Vec3& p : *sphereLines)
+	{
+		if(pointIndex >= MAX_POINTS_PER_DRAW)
+		{
+			end();
+			begin();
+		}
+
+		pushBackVertex(p);
+	}
+	end();
+}
+
+//==============================================================================
+void DebugDrawer::drawCube(float size)
+{
+	Vec3 maxPos = Vec3(0.5 * size);
+	Vec3 minPos = Vec3(-0.5 * size);
+
+	std::array<Vec3, 8> points = {{
+		Vec3(maxPos.x(), maxPos.y(), maxPos.z()),  // right top front
+		Vec3(minPos.x(), maxPos.y(), maxPos.z()),  // left top front
+		Vec3(minPos.x(), minPos.y(), maxPos.z()),  // left bottom front
+		Vec3(maxPos.x(), minPos.y(), maxPos.z()),  // right bottom front
+		Vec3(maxPos.x(), maxPos.y(), minPos.z()),  // right top back
+		Vec3(minPos.x(), maxPos.y(), minPos.z()),  // left top back
+		Vec3(minPos.x(), minPos.y(), minPos.z()),  // left bottom back
+		Vec3(maxPos.x(), minPos.y(), minPos.z())   // right bottom back
+	}};
+
+	std::array<uint, 24> indeces = {{0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6,
+		7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7}};
+
+	begin();
+		for(uint id : indeces)
+		{
+			pushBackVertex(points[id]);
+		}
+	end();
+}
+
+//==============================================================================
+void DebugDrawer::setModelMatrix(const Mat4& modelMat_)
+{
+	ANKI_ASSERT(pointIndex == 0
+		&& "The func called after begin and before end");
+	modelMat = modelMat_;
+}
+
+//==============================================================================
+void DebugDrawer::begin()
+{
+	ANKI_ASSERT(pointIndex == 0);
+}
+
+//==============================================================================
+void DebugDrawer::end()
+{
+	ANKI_ASSERT(pointIndex != 0);
+
+	positionsVbo.write(&positions[0], 0, sizeof(Vec3) * pointIndex);
+	colorsVbo.write(&colors[0], 0, sizeof(Vec3) * pointIndex);
+
+	Mat4 pmv = vpMat * modelMat;
+	sProg->bind();
+	sProg->findUniformVariable("modelViewProjectionMat").set(pmv);
+
+	vao.bind();
+	glDrawArrays(GL_LINES, 0, pointIndex);
+	vao.unbind();
+
+	// Cleanup
+	pointIndex = 0;
+}
+
+//==============================================================================
+void DebugDrawer::pushBackVertex(const Vec3& pos)
+{
+	positions[pointIndex] = pos;
+	colors[pointIndex] = crntCol;
+	++pointIndex;
+}
+
+//==============================================================================
+// CollisionDebugDrawer                                                        =
+//==============================================================================
+
+//==============================================================================
+void CollisionDebugDrawer::visit(const Sphere& sphere)
+{
+	dbg->setModelMatrix(Mat4(sphere.getCenter(), Mat3::getIdentity(), 1.0));
+	dbg->drawSphere(sphere.getRadius());
+}
+
+//==============================================================================
+void CollisionDebugDrawer::visit(const Obb& obb)
+{
+	Mat4 scale(Mat4::getIdentity());
+	scale(0, 0) = obb.getExtend().x();
+	scale(1, 1) = obb.getExtend().y();
+	scale(2, 2) = obb.getExtend().z();
+
+	Mat4 rot(obb.getRotation());
+
+	Mat4 trs(obb.getCenter());
+
+	Mat4 tsl;
+	tsl = Mat4::combineTransformations(rot, scale);
+	tsl = Mat4::combineTransformations(trs, tsl);
+
+	dbg->setModelMatrix(tsl);
+	dbg->setColor(Vec3(1.0, 1.0, 0.0));
+	dbg->drawCube(2.0);
+}
+
+//==============================================================================
+void CollisionDebugDrawer::visit(const Plane& plane)
+{
+	const Vec3& n = plane.getNormal();
+	const float& o = plane.getOffset();
+	Quat q;
+	q.setFrom2Vec3(Vec3(0.0, 0.0, 1.0), n);
+	Mat3 rot(q);
+	rot.rotateXAxis(getPi<F32>() / 2.0);
+	Mat4 trf(n * o, rot);
+
+	dbg->setModelMatrix(trf);
+	dbg->drawGrid();
+}
+
+//==============================================================================
+void CollisionDebugDrawer::visit(const Aabb& aabb)
+{
+	const Vec3& min = aabb.getMin();
+	const Vec3& max = aabb.getMax();
+
+	Mat4 trf = Mat4::getIdentity();
+	// Scale
+	for(uint i = 0; i < 3; ++i)
+	{
+		trf(i, i) = max[i] - min[i];
+	}
+
+	// Translation
+	trf.setTranslationPart((max + min) / 2.0);
+
+	dbg->setModelMatrix(trf);
+	dbg->drawCube();
+}
+
+//==============================================================================
+void CollisionDebugDrawer::visit(const Frustum& f)
+{
+	switch(f.getFrustumType())
+	{
+	case Frustum::FT_ORTHOGRAPHIC:
+		visit(static_cast<const OrthographicFrustum&>(f).getObb());
+		break;
+	case Frustum::FT_PERSPECTIVE:
+	{
+		dbg->setColor(Vec4(0.5, 0.0, 0.5, 1.0));
+		const PerspectiveFrustum& pf =
+			static_cast<const PerspectiveFrustum&>(f);
+
+		float camLen = pf.getFar();
+		float tmp0 = camLen / tan((getPi<F32>() - pf.getFovX()) * 0.5) + 0.001;
+		float tmp1 = camLen * tan(pf.getFovY() * 0.5) + 0.001;
+
+		Vec3 points[] = {
+			Vec3(0.0, 0.0, 0.0), // 0: eye point
+			Vec3(-tmp0, tmp1, -camLen), // 1: top left
+			Vec3(-tmp0, -tmp1, -camLen), // 2: bottom left
+			Vec3(tmp0, -tmp1, -camLen), // 3: bottom right
+			Vec3(tmp0, tmp1, -camLen) // 4: top right
+		};
+
+		const uint indeces[] = {0, 1, 0, 2, 0, 3, 0, 4, 1, 2, 2,
+			3, 3, 4, 4, 1};
+
+		dbg->begin();
+		for(uint i = 0; i < sizeof(indeces) / sizeof(uint); i++)
+		{
+			dbg->pushBackVertex(points[indeces[i]]);
+		}
+		dbg->end();
+		break;
+	}
+	}
+}
+
+//==============================================================================
+// PhysicsDebugDrawer                                                          =
+//==============================================================================
+
+//==============================================================================
+void PhysicsDebugDrawer::drawLine(const btVector3& from, const btVector3& to,
+	const btVector3& color)
+{
+	dbg->drawLine(toAnki(from), toAnki(to), Vec4(toAnki(color), 1.0));
+}
+
+//==============================================================================
+void PhysicsDebugDrawer::drawSphere(btScalar radius,
+	const btTransform& transform,
+	const btVector3& color)
+{
+	dbg->setColor(toAnki(color));
+	dbg->setModelMatrix(Mat4(toAnki(transform)));
+	dbg->drawSphere(radius);
+}
+
+//==============================================================================
+void PhysicsDebugDrawer::drawBox(const btVector3& min, const btVector3& max,
+	const btVector3& color)
+{
+	Mat4 trf(Mat4::getIdentity());
+	trf(0, 0) = max.getX() - min.getX();
+	trf(1, 1) = max.getY() - min.getY();
+	trf(2, 2) = max.getZ() - min.getZ();
+	trf(0, 3) = (max.getX() + min.getX()) / 2.0;
+	trf(1, 3) = (max.getY() + min.getY()) / 2.0;
+	trf(2, 3) = (max.getZ() + min.getZ()) / 2.0;
+	dbg->setModelMatrix(trf);
+	dbg->setColor(toAnki(color));
+	dbg->drawCube(1.0);
+}
+
+//==============================================================================
+void PhysicsDebugDrawer::drawBox(const btVector3& min, const btVector3& max,
+	const btTransform& trans, const btVector3& color)
+{
+	Mat4 trf(Mat4::getIdentity());
+	trf(0, 0) = max.getX() - min.getX();
+	trf(1, 1) = max.getY() - min.getY();
+	trf(2, 2) = max.getZ() - min.getZ();
+	trf(0, 3) = (max.getX() + min.getX()) / 2.0;
+	trf(1, 3) = (max.getY() + min.getY()) / 2.0;
+	trf(2, 3) = (max.getZ() + min.getZ()) / 2.0;
+	trf = Mat4::combineTransformations(Mat4(toAnki(trans)), trf);
+	dbg->setModelMatrix(trf);
+	dbg->setColor(toAnki(color));
+	dbg->drawCube(1.0);
+}
+
+//==============================================================================
+void PhysicsDebugDrawer::drawContactPoint(const btVector3& /*pointOnB*/,
+	const btVector3& /*normalOnB*/,
+	btScalar /*distance*/, int /*lifeTime*/, const btVector3& /*color*/)
+{
+	//ANKI_LOGW("Unimplemented");
+}
+
+//==============================================================================
+void PhysicsDebugDrawer::reportErrorWarning(const char* warningString)
+{
+	throw ANKI_EXCEPTION(warningString);
+}
+
+//==============================================================================
+void PhysicsDebugDrawer::draw3dText(const btVector3& /*location*/,
+	const char* /*textString*/)
+{
+	//ANKI_LOGW("Unimplemented");
+}
+
+//==============================================================================
+// SceneDebugDrawer                                                            =
+//==============================================================================
+
+//==============================================================================
+void SceneDebugDrawer::draw(SceneNode& node)
+{
+	// Nothing to render?
+	if(getFlagsBitmask() == 0)
+	{
+		return;
+	}
+
+	Movable* mv = node.getMovable();
+	if(mv)
+	{
+		dbg->setModelMatrix(Mat4(mv->getWorldTransform()));
+	}
+	else
+	{
+		dbg->setModelMatrix(Mat4::getIdentity());
+	}
+
+	Frustumable* fr;
+	if(isFlagEnabled(DF_FRUSTUMABLE) && (fr = node.getFrustumable()))
+	{
+		draw(*fr);
+	}
+
+	Spatial* sp;
+	if(isFlagEnabled(DF_SPATIAL) && (sp = node.getSpatial())
+		&& sp->isFlagEnabled(Spatial::SF_VISIBLE))
+	{
+		draw(*sp);
+	}
+}
+
+//==============================================================================
+void SceneDebugDrawer::draw(Frustumable& fr) const
+{
+	const Frustum& fs = fr.getFrustum();
+
+	CollisionDebugDrawer coldraw(dbg);
+	fs.accept(coldraw);
+}
+
+//==============================================================================
+void SceneDebugDrawer::draw(Spatial& x) const
+{
+	/*const CollisionShape& cs = x.getSpatialCollisionShape();
+
+	CollisionDebugDrawer coldraw(dbg);
+	cs.accept(coldraw);*/
+	CollisionDebugDrawer coldraw(dbg);
+	x.getAabb().accept(coldraw);
+}
+
+//==============================================================================
+void SceneDebugDrawer::draw(const Octree& octree) const
+{
+	dbg->setColor(Vec3(1.0));
+	draw(octree.getRoot(), 0, octree);
+}
+
+//==============================================================================
+void SceneDebugDrawer::draw(const OctreeNode& octnode, U32 depth,
+	const Octree& octree) const
+{
+	// Draw if it has spatials
+	if(octnode.getSceneNodesCount() != 0)
+	{
+		//Vec3 color = Vec3(1.0 - float(depth) / float(octree.getMaxDepth()));
+		Vec3 color(1.0);
+		dbg->setColor(color);
+
+		CollisionDebugDrawer v(dbg);
+		octnode.getAabb().accept(v);
+	}
+
+	// Children
+	for(U32 i = 0; i < 8; ++i)
+	{
+		if(octnode.getChild(i) != nullptr)
+		{
+			draw(*octnode.getChild(i), depth + 1, octree);
+		}
+	}
+}
+
+}  // end namespace anki

+ 16 - 503
src/renderer/Drawer.cpp

@@ -1,9 +1,6 @@
 #include "anki/renderer/Drawer.h"
 #include "anki/renderer/Drawer.h"
 #include "anki/resource/ShaderProgramResource.h"
 #include "anki/resource/ShaderProgramResource.h"
-#include "anki/physics/Convertors.h"
-#include "anki/collision/Collision.h"
 #include "anki/scene/Frustumable.h"
 #include "anki/scene/Frustumable.h"
-#include "anki/scene/Octree.h"
 #include "anki/resource/Material.h"
 #include "anki/resource/Material.h"
 #include "anki/scene/Renderable.h"
 #include "anki/scene/Renderable.h"
 #include "anki/scene/Camera.h"
 #include "anki/scene/Camera.h"
@@ -13,499 +10,6 @@
 
 
 namespace anki {
 namespace anki {
 
 
-//==============================================================================
-// DebugDrawer                                                                 =
-//==============================================================================
-
-//==============================================================================
-DebugDrawer::~DebugDrawer()
-{}
-
-//==============================================================================
-DebugDrawer::DebugDrawer()
-{
-	sProg.load("shaders/Dbg.glsl");
-
-	positionsVbo.create(GL_ARRAY_BUFFER, sizeof(positions), NULL,
-		GL_DYNAMIC_DRAW);
-	colorsVbo.create(GL_ARRAY_BUFFER, sizeof(colors), NULL, GL_DYNAMIC_DRAW);
-	vao.create();
-	const int positionAttribLoc = 0;
-	vao.attachArrayBufferVbo(positionsVbo, positionAttribLoc, 3, GL_FLOAT,
-		GL_FALSE, 0, NULL);
-	const int colorAttribLoc = 1;
-	vao.attachArrayBufferVbo(colorsVbo, colorAttribLoc, 3, GL_FLOAT, GL_FALSE,
-		0, NULL);
-
-	pointIndex = 0;
-	modelMat.setIdentity();
-	crntCol = Vec3(1.0, 0.0, 0.0);
-}
-
-//==============================================================================
-void DebugDrawer::drawLine(const Vec3& from, const Vec3& to, const Vec4& color)
-{
-	setColor(color);
-	begin();
-		pushBackVertex(from);
-		pushBackVertex(to);
-	end();
-}
-
-//==============================================================================
-void DebugDrawer::drawGrid()
-{
-	Vec4 col0(0.5, 0.5, 0.5, 1.0);
-	Vec4 col1(0.0, 0.0, 1.0, 1.0);
-	Vec4 col2(1.0, 0.0, 0.0, 1.0);
-
-	const float SPACE = 1.0; // space between lines
-	const int NUM = 57;  // lines number. must be odd
-
-	const float GRID_HALF_SIZE = ((NUM - 1) * SPACE / 2);
-
-	setColor(col0);
-
-	begin();
-
-	for(int x = - NUM / 2 * SPACE; x < NUM / 2 * SPACE; x += SPACE)
-	{
-		setColor(col0);
-
-		// if the middle line then change color
-		if(x == 0)
-		{
-			setColor(col1);
-		}
-
-		// line in z
-		pushBackVertex(Vec3(x, 0.0, -GRID_HALF_SIZE));
-		pushBackVertex(Vec3(x, 0.0, GRID_HALF_SIZE));
-
-		// if middle line change col so you can highlight the x-axis
-		if(x == 0)
-		{
-			setColor(col2);
-		}
-
-		// line in the x
-		pushBackVertex(Vec3(-GRID_HALF_SIZE, 0.0, x));
-		pushBackVertex(Vec3(GRID_HALF_SIZE, 0.0, x));
-	}
-
-	// render
-	end();
-}
-
-//==============================================================================
-void DebugDrawer::drawSphere(float radius, int complexity)
-{
-	Vector<Vec3>* sphereLines;
-
-	// Pre-calculate the sphere points5
-	//
-	std::map<uint, Vector<Vec3> >::iterator it =
-		complexityToPreCalculatedSphere.find(complexity);
-
-	if(it != complexityToPreCalculatedSphere.end()) // Found
-	{
-		sphereLines = &(it->second);
-	}
-	else // Not found
-	{
-		complexityToPreCalculatedSphere[complexity] = Vector<Vec3>();
-		sphereLines = &complexityToPreCalculatedSphere[complexity];
-
-		float fi = getPi<F32>() / complexity;
-
-		Vec3 prev(1.0, 0.0, 0.0);
-		for(float th = fi; th < getPi<F32>() * 2.0 + fi; th += fi)
-		{
-			Vec3 p = Mat3(Euler(0.0, th, 0.0)) * Vec3(1.0, 0.0, 0.0);
-
-			for(float th2 = 0.0; th2 < getPi<F32>(); th2 += fi)
-			{
-				Mat3 rot(Euler(th2, 0.0, 0.0));
-
-				Vec3 rotPrev = rot * prev;
-				Vec3 rotP = rot * p;
-
-				sphereLines->push_back(rotPrev);
-				sphereLines->push_back(rotP);
-
-				Mat3 rot2(Euler(0.0, 0.0, getPi<F32>() / 2));
-
-				sphereLines->push_back(rot2 * rotPrev);
-				sphereLines->push_back(rot2 * rotP);
-			}
-
-			prev = p;
-		}
-	}
-
-	// Render
-	//
-	modelMat = modelMat * Mat4(Vec3(0.0), Mat3::getIdentity(), radius);
-
-	begin();
-	for(const Vec3& p : *sphereLines)
-	{
-		if(pointIndex >= MAX_POINTS_PER_DRAW)
-		{
-			end();
-			begin();
-		}
-
-		pushBackVertex(p);
-	}
-	end();
-}
-
-//==============================================================================
-void DebugDrawer::drawCube(float size)
-{
-	Vec3 maxPos = Vec3(0.5 * size);
-	Vec3 minPos = Vec3(-0.5 * size);
-
-	std::array<Vec3, 8> points = {{
-		Vec3(maxPos.x(), maxPos.y(), maxPos.z()),  // right top front
-		Vec3(minPos.x(), maxPos.y(), maxPos.z()),  // left top front
-		Vec3(minPos.x(), minPos.y(), maxPos.z()),  // left bottom front
-		Vec3(maxPos.x(), minPos.y(), maxPos.z()),  // right bottom front
-		Vec3(maxPos.x(), maxPos.y(), minPos.z()),  // right top back
-		Vec3(minPos.x(), maxPos.y(), minPos.z()),  // left top back
-		Vec3(minPos.x(), minPos.y(), minPos.z()),  // left bottom back
-		Vec3(maxPos.x(), minPos.y(), minPos.z())   // right bottom back
-	}};
-
-	std::array<uint, 24> indeces = {{0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6,
-		7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7}};
-
-	begin();
-		for(uint id : indeces)
-		{
-			pushBackVertex(points[id]);
-		}
-	end();
-}
-
-//==============================================================================
-void DebugDrawer::setModelMatrix(const Mat4& modelMat_)
-{
-	ANKI_ASSERT(pointIndex == 0
-		&& "The func called after begin and before end");
-	modelMat = modelMat_;
-}
-
-//==============================================================================
-void DebugDrawer::begin()
-{
-	ANKI_ASSERT(pointIndex == 0);
-}
-
-//==============================================================================
-void DebugDrawer::end()
-{
-	ANKI_ASSERT(pointIndex != 0);
-
-	positionsVbo.write(&positions[0], 0, sizeof(Vec3) * pointIndex);
-	colorsVbo.write(&colors[0], 0, sizeof(Vec3) * pointIndex);
-
-	Mat4 pmv = vpMat * modelMat;
-	sProg->bind();
-	sProg->findUniformVariable("modelViewProjectionMat").set(pmv);
-
-	vao.bind();
-	glDrawArrays(GL_LINES, 0, pointIndex);
-	vao.unbind();
-
-	// Cleanup
-	pointIndex = 0;
-}
-
-//==============================================================================
-void DebugDrawer::pushBackVertex(const Vec3& pos)
-{
-	positions[pointIndex] = pos;
-	colors[pointIndex] = crntCol;
-	++pointIndex;
-}
-
-//==============================================================================
-// CollisionDebugDrawer                                                        =
-//==============================================================================
-
-//==============================================================================
-void CollisionDebugDrawer::visit(const Sphere& sphere)
-{
-	dbg->setModelMatrix(Mat4(sphere.getCenter(), Mat3::getIdentity(), 1.0));
-	dbg->drawSphere(sphere.getRadius());
-}
-
-//==============================================================================
-void CollisionDebugDrawer::visit(const Obb& obb)
-{
-	Mat4 scale(Mat4::getIdentity());
-	scale(0, 0) = obb.getExtend().x();
-	scale(1, 1) = obb.getExtend().y();
-	scale(2, 2) = obb.getExtend().z();
-
-	Mat4 rot(obb.getRotation());
-
-	Mat4 trs(obb.getCenter());
-
-	Mat4 tsl;
-	tsl = Mat4::combineTransformations(rot, scale);
-	tsl = Mat4::combineTransformations(trs, tsl);
-
-	dbg->setModelMatrix(tsl);
-	dbg->setColor(Vec3(1.0, 1.0, 0.0));
-	dbg->drawCube(2.0);
-}
-
-//==============================================================================
-void CollisionDebugDrawer::visit(const Plane& plane)
-{
-	const Vec3& n = plane.getNormal();
-	const float& o = plane.getOffset();
-	Quat q;
-	q.setFrom2Vec3(Vec3(0.0, 0.0, 1.0), n);
-	Mat3 rot(q);
-	rot.rotateXAxis(getPi<F32>() / 2.0);
-	Mat4 trf(n * o, rot);
-
-	dbg->setModelMatrix(trf);
-	dbg->drawGrid();
-}
-
-//==============================================================================
-void CollisionDebugDrawer::visit(const Aabb& aabb)
-{
-	const Vec3& min = aabb.getMin();
-	const Vec3& max = aabb.getMax();
-
-	Mat4 trf = Mat4::getIdentity();
-	// Scale
-	for(uint i = 0; i < 3; ++i)
-	{
-		trf(i, i) = max[i] - min[i];
-	}
-
-	// Translation
-	trf.setTranslationPart((max + min) / 2.0);
-
-	dbg->setModelMatrix(trf);
-	dbg->drawCube();
-}
-
-//==============================================================================
-void CollisionDebugDrawer::visit(const Frustum& f)
-{
-	switch(f.getFrustumType())
-	{
-	case Frustum::FT_ORTHOGRAPHIC:
-		visit(static_cast<const OrthographicFrustum&>(f).getObb());
-		break;
-	case Frustum::FT_PERSPECTIVE:
-	{
-		dbg->setColor(Vec4(0.5, 0.0, 0.5, 1.0));
-		const PerspectiveFrustum& pf =
-			static_cast<const PerspectiveFrustum&>(f);
-
-		float camLen = pf.getFar();
-		float tmp0 = camLen / tan((getPi<F32>() - pf.getFovX()) * 0.5) + 0.001;
-		float tmp1 = camLen * tan(pf.getFovY() * 0.5) + 0.001;
-
-		Vec3 points[] = {
-			Vec3(0.0, 0.0, 0.0), // 0: eye point
-			Vec3(-tmp0, tmp1, -camLen), // 1: top left
-			Vec3(-tmp0, -tmp1, -camLen), // 2: bottom left
-			Vec3(tmp0, -tmp1, -camLen), // 3: bottom right
-			Vec3(tmp0, tmp1, -camLen) // 4: top right
-		};
-
-		const uint indeces[] = {0, 1, 0, 2, 0, 3, 0, 4, 1, 2, 2,
-			3, 3, 4, 4, 1};
-
-		dbg->begin();
-		for(uint i = 0; i < sizeof(indeces) / sizeof(uint); i++)
-		{
-			dbg->pushBackVertex(points[indeces[i]]);
-		}
-		dbg->end();
-		break;
-	}
-	}
-}
-
-//==============================================================================
-// PhysicsDebugDrawer                                                          =
-//==============================================================================
-
-//==============================================================================
-void PhysicsDebugDrawer::drawLine(const btVector3& from, const btVector3& to,
-	const btVector3& color)
-{
-	dbg->drawLine(toAnki(from), toAnki(to), Vec4(toAnki(color), 1.0));
-}
-
-//==============================================================================
-void PhysicsDebugDrawer::drawSphere(btScalar radius,
-	const btTransform& transform,
-	const btVector3& color)
-{
-	dbg->setColor(toAnki(color));
-	dbg->setModelMatrix(Mat4(toAnki(transform)));
-	dbg->drawSphere(radius);
-}
-
-//==============================================================================
-void PhysicsDebugDrawer::drawBox(const btVector3& min, const btVector3& max,
-	const btVector3& color)
-{
-	Mat4 trf(Mat4::getIdentity());
-	trf(0, 0) = max.getX() - min.getX();
-	trf(1, 1) = max.getY() - min.getY();
-	trf(2, 2) = max.getZ() - min.getZ();
-	trf(0, 3) = (max.getX() + min.getX()) / 2.0;
-	trf(1, 3) = (max.getY() + min.getY()) / 2.0;
-	trf(2, 3) = (max.getZ() + min.getZ()) / 2.0;
-	dbg->setModelMatrix(trf);
-	dbg->setColor(toAnki(color));
-	dbg->drawCube(1.0);
-}
-
-//==============================================================================
-void PhysicsDebugDrawer::drawBox(const btVector3& min, const btVector3& max,
-	const btTransform& trans, const btVector3& color)
-{
-	Mat4 trf(Mat4::getIdentity());
-	trf(0, 0) = max.getX() - min.getX();
-	trf(1, 1) = max.getY() - min.getY();
-	trf(2, 2) = max.getZ() - min.getZ();
-	trf(0, 3) = (max.getX() + min.getX()) / 2.0;
-	trf(1, 3) = (max.getY() + min.getY()) / 2.0;
-	trf(2, 3) = (max.getZ() + min.getZ()) / 2.0;
-	trf = Mat4::combineTransformations(Mat4(toAnki(trans)), trf);
-	dbg->setModelMatrix(trf);
-	dbg->setColor(toAnki(color));
-	dbg->drawCube(1.0);
-}
-
-//==============================================================================
-void PhysicsDebugDrawer::drawContactPoint(const btVector3& /*pointOnB*/,
-	const btVector3& /*normalOnB*/,
-	btScalar /*distance*/, int /*lifeTime*/, const btVector3& /*color*/)
-{
-	//ANKI_LOGW("Unimplemented");
-}
-
-//==============================================================================
-void PhysicsDebugDrawer::reportErrorWarning(const char* warningString)
-{
-	throw ANKI_EXCEPTION(warningString);
-}
-
-//==============================================================================
-void PhysicsDebugDrawer::draw3dText(const btVector3& /*location*/,
-	const char* /*textString*/)
-{
-	//ANKI_LOGW("Unimplemented");
-}
-
-//==============================================================================
-// SceneDebugDrawer                                                            =
-//==============================================================================
-
-//==============================================================================
-void SceneDebugDrawer::draw(SceneNode& node)
-{
-	// Nothing to render?
-	if(getFlagsBitmask() == 0)
-	{
-		return;
-	}
-
-	Movable* mv = node.getMovable();
-	if(mv)
-	{
-		dbg->setModelMatrix(Mat4(mv->getWorldTransform()));
-	}
-	else
-	{
-		dbg->setModelMatrix(Mat4::getIdentity());
-	}
-
-	Frustumable* fr;
-	if(isFlagEnabled(DF_FRUSTUMABLE) && (fr = node.getFrustumable()))
-	{
-		draw(*fr);
-	}
-
-	Spatial* sp;
-	if(isFlagEnabled(DF_SPATIAL) && (sp = node.getSpatial())
-		&& sp->isFlagEnabled(Spatial::SF_VISIBLE))
-	{
-		draw(*sp);
-	}
-}
-
-//==============================================================================
-void SceneDebugDrawer::draw(Frustumable& fr) const
-{
-	const Frustum& fs = fr.getFrustum();
-
-	CollisionDebugDrawer coldraw(dbg);
-	fs.accept(coldraw);
-}
-
-//==============================================================================
-void SceneDebugDrawer::draw(Spatial& x) const
-{
-	/*const CollisionShape& cs = x.getSpatialCollisionShape();
-
-	CollisionDebugDrawer coldraw(dbg);
-	cs.accept(coldraw);*/
-	CollisionDebugDrawer coldraw(dbg);
-	x.getAabb().accept(coldraw);
-}
-
-//==============================================================================
-void SceneDebugDrawer::draw(const Octree& octree) const
-{
-	dbg->setColor(Vec3(1.0));
-	draw(octree.getRoot(), 0, octree);
-}
-
-//==============================================================================
-void SceneDebugDrawer::draw(const OctreeNode& octnode, uint32_t depth,
-	const Octree& octree) const
-{
-	// Draw if it has spatials
-	if(octnode.getSceneNodesCount() != 0)
-	{
-		//Vec3 color = Vec3(1.0 - float(depth) / float(octree.getMaxDepth()));
-		Vec3 color(1.0);
-		dbg->setColor(color);
-
-		CollisionDebugDrawer v(dbg);
-		octnode.getAabb().accept(v);
-	}
-
-	// Children
-	for(uint32_t i = 0; i < 8; ++i)
-	{
-		if(octnode.getChild(i) != nullptr)
-		{
-			draw(*octnode.getChild(i), depth + 1, octree);
-		}
-	}
-}
-
-//==============================================================================
-// RenderableDrawer                                                            =
-//==============================================================================
-
 //==============================================================================
 //==============================================================================
 
 
 enum BuildinId
 enum BuildinId
@@ -519,13 +23,15 @@ enum BuildinId
 	BI_COUNT
 	BI_COUNT
 };
 };
 
 
-static std::array<const char*, BI_COUNT - 2> buildinNames = {{
+static Array<const char*, BI_COUNT - 2> buildinNames = {{
 	"modelViewProjectionMat",
 	"modelViewProjectionMat",
 	"modelViewMat",
 	"modelViewMat",
 	"normalMat",
 	"normalMat",
 	"blurring"
 	"blurring"
 }};
 }};
 
 
+static const UNIFORM_BLOCK_MAX_SIZE = 256;
+
 template<typename T>
 template<typename T>
 static void uniSet(const ShaderProgramUniformVariable& uni, const T& x)
 static void uniSet(const ShaderProgramUniformVariable& uni, const T& x)
 {
 {
@@ -565,6 +71,7 @@ struct SetupMaterialVariableVisitor
 	const Frustumable* fr = nullptr;
 	const Frustumable* fr = nullptr;
 	Renderer* r = nullptr;
 	Renderer* r = nullptr;
 	Renderable* renderable = nullptr;
 	Renderable* renderable = nullptr;
+	Array<U8, UNIFORM_BLOCK_MAX_SIZE> clientBlock;
 
 
 	template<typename TProp>
 	template<typename TProp>
 	void visit(TProp& x)
 	void visit(TProp& x)
@@ -628,7 +135,7 @@ struct SetupMaterialVariableVisitor
 			uniSet(*uni, mprop.getValue());
 			uniSet(*uni, mprop.getValue());
 			break;
 			break;
 		case BI_MODEL_VIEW_PROJECTION_MATRIX:
 		case BI_MODEL_VIEW_PROJECTION_MATRIX:
-			uni->set(mvpMat);
+			uniSet(*uni, mvpMat);
 			break;
 			break;
 		case BI_MODEL_VIEW_MATRIX:
 		case BI_MODEL_VIEW_MATRIX:
 			if(!mvMatCalculated)
 			if(!mvMatCalculated)
@@ -636,7 +143,7 @@ struct SetupMaterialVariableVisitor
 				mvMat = mMat * fr->getViewMatrix();
 				mvMat = mMat * fr->getViewMatrix();
 				mvMatCalculated = true;
 				mvMatCalculated = true;
 			}
 			}
-			uni->set(mvMat);
+			uniSet(*uni, mvMat);
 			break;
 			break;
 		case BI_NORMAL_MATRIX:
 		case BI_NORMAL_MATRIX:
 			if(!mvMatCalculated)
 			if(!mvMatCalculated)
@@ -644,10 +151,10 @@ struct SetupMaterialVariableVisitor
 				mvMat = mMat * fr->getViewMatrix();
 				mvMat = mMat * fr->getViewMatrix();
 				mvMatCalculated = true;
 				mvMatCalculated = true;
 			}
 			}
-			uni->set(mvMat.getRotationPart());
+			uniSet(*uni, mvMat.getRotationPart());
 			break;
 			break;
 		case BI_BLURRING:
 		case BI_BLURRING:
-			uni->set(0.0);
+			uniSet(*uni, 0.0);
 			break;
 			break;
 		}
 		}
 	}
 	}
@@ -661,6 +168,7 @@ void RenderableDrawer::setupShaderProg(
 {
 {
 	const Material& mtl = renderable.getMaterial();
 	const Material& mtl = renderable.getMaterial();
 	const ShaderProgram& sprog = mtl.findShaderProgram(key);
 	const ShaderProgram& sprog = mtl.findShaderProgram(key);
+	Array<U8, UNIFORM_BLOCK_MAX_SIZE> clientBlock;
 
 
 	/*if(mtl.getDepthTestingEnabled())
 	/*if(mtl.getDepthTestingEnabled())
 	{
 	{
@@ -679,6 +187,7 @@ void RenderableDrawer::setupShaderProg(
 	vis.key = key;
 	vis.key = key;
 	vis.renderable = &renderable;
 	vis.renderable = &renderable;
 	vis.r = r;
 	vis.r = r;
+	vis.clientBlock = &clientBlock;
 
 
 	for(auto it = renderable.getPropertiesBegin();
 	for(auto it = renderable.getPropertiesBegin();
 		it != renderable.getPropertiesEnd(); ++it)
 		it != renderable.getPropertiesEnd(); ++it)
@@ -686,6 +195,11 @@ void RenderableDrawer::setupShaderProg(
 		PropertyBase* pbase = *it;
 		PropertyBase* pbase = *it;
 		pbase->acceptVisitor(vis);
 		pbase->acceptVisitor(vis);
 	}
 	}
+
+	if(mtl->getUniformBlock())
+	{
+		renderable.getUbo().setBindingPoint(0);
+	}
 }
 }
 
 
 //==============================================================================
 //==============================================================================
@@ -702,8 +216,7 @@ void RenderableDrawer::render(const Frustumable& fr, uint pass,
 	setupShaderProg(key, fr, renderable);
 	setupShaderProg(key, fr, renderable);
 
 
 	// Render
 	// Render
-	uint32_t indecesNum =
-		renderable.getModelPatchBase().getIndecesNumber(0);
+	U32 indecesNum = renderable.getModelPatchBase().getIndecesNumber(0);
 
 
 	const Vao& vao = renderable.getModelPatchBase().getVao(key);
 	const Vao& vao = renderable.getModelPatchBase().getVao(key);
 	ANKI_ASSERT(vao.getAttachmentsCount() > 1);
 	ANKI_ASSERT(vao.getAttachmentsCount() > 1);

+ 16 - 4
src/scene/Renderable.cpp

@@ -11,9 +11,9 @@ namespace anki {
 /// Create a new property given a material variable
 /// Create a new property given a material variable
 struct CreateNewPropertyVisitor
 struct CreateNewPropertyVisitor
 {
 {
-	const MaterialVariable* mvar;
-	PropertyMap* pmap;
-	Renderable::MaterialVariableProperties* rprops;
+	const MaterialVariable* mvar = nullptr;
+	PropertyMap* pmap = nullptr;
+	Renderable::MaterialVariableProperties* rprops = nullptr;
 
 
 	template<typename T>
 	template<typename T>
 	void visit(const T&) const
 	void visit(const T&) const
@@ -50,6 +50,18 @@ void Renderable::init(PropertyMap& pmap)
 		vis.mvar = mv;
 		vis.mvar = mv;
 		mv->acceptVisitor(vis);
 		mv->acceptVisitor(vis);
 	}
 	}
+
+	// FUTURE if the material is simple (only viewprojection matrix and samlers)
+	// then use a common UBO. It will save the copying to the UBO and the 
+	// binding
+
+	// Init the UBO
+	const ShaderProgramUniformBlock* block = mtl.getUniformBlock();
+
+	if(block)
+	{
+		ubo.create(block->getSize());
+	}
 }
 }
 
 
-}  // namespace anki
+}  // end namespace anki