diff --git a/demo/main.cpp b/demo/main.cpp
index e02b23fb279d77683751241ae19418eab9675d47..a5a456194edde6fd6b6b8997834dac5715f13145 100644
--- a/demo/main.cpp
+++ b/demo/main.cpp
@@ -64,16 +64,39 @@ int main(int argc, char* argv[]) {
 	// create ECS
 	fggl::ecs::ECS ecs;
 	ecs.registerComponent<fggl::gfx::MeshToken>();
+	ecs.registerComponent<fggl::math::Transform>();
 
-	// create an entity
-	auto entity = ecs.createEntity();
+	for (int i=0; i<3; i++) {
+		// create an entity
+		auto entity = ecs.createEntity();
 
-	// in a supprise to no one it's a triangle
-//	auto mesh = fggl::data::make_quad_xy();
-	auto mesh = fggl::data::make_point();
-	auto token = meshRenderer.upload(mesh);
-	token.pipeline = shader;
-	ecs.addComponent<fggl::gfx::MeshToken>(entity, token);
+		// set the position
+		auto result = ecs.addComponent<fggl::math::Transform>(entity);
+		result->origin( glm::vec3( 0.0f, 0.0f, i * -1.0f) );
+
+		// in a supprise to no one it's a triangle
+		auto mesh = fggl::data::make_cube();
+		auto token = meshRenderer.upload(mesh);
+		token.pipeline = shader;
+		ecs.addComponent<fggl::gfx::MeshToken>(entity, token);
+	}
+
+	constexpr float HALF_PI = M_PI / 2.0f;
+	for (int i=0; i<3; i++) {
+		// create an entity
+		auto entity = ecs.createEntity();
+
+		// set the position
+		auto result = ecs.addComponent<fggl::math::Transform>(entity);
+		result->origin( glm::vec3( 1.0f, 0.0f, i * -1.0f) );
+		result->euler( glm::vec3( 0.0f, HALF_PI, 0.0f) );
+
+		// in a supprise to no one it's a triangle
+		auto mesh = fggl::data::make_slope();
+		auto token = meshRenderer.upload(mesh);
+		token.pipeline = shader;
+		ecs.addComponent<fggl::gfx::MeshToken>(entity, token);
+	}
 
 	while( !win.closeRequested() ) {
 		ctx.pollEvents();
diff --git a/fggl/gfx/renderer.cpp b/fggl/gfx/renderer.cpp
index 635021ea1731d1b213707f3d40ef21a5c60066a5..fe3e9d07728ceb7bd3698d0599a5f7a8b6002f37 100644
--- a/fggl/gfx/renderer.cpp
+++ b/fggl/gfx/renderer.cpp
@@ -81,16 +81,16 @@ void MeshRenderer::render(const Window& window, const fggl::ecs::ECS& ecs, float
 
     glm::mat4 view = glm::lookAt( glm::vec3 ( 0.0f, 3.0f, 3.0f ), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f) );
     glm::mat4 proj = glm::perspective( glm::radians(45.0f), 1280.0f/720.0f, 0.1f, 100.0f);
-//    glm::mat4 proj = glm::mat4(1.0f);
 
 
     // TODO better performance if grouped by vao first
     // TODO the nvidia performance presentation said I shouldn't use uniforms for large data
     for ( auto& entity : entities ) {
+	    const auto& transform = ecs.getComponent<fggl::math::Transform>(entity);
 	    const auto& mesh = ecs.getComponent<GlRenderToken>(entity);
 
-    	    glm::mat4 model = glm::mat4(1.0f);
-	    model = glm::rotate(model, glm::radians(total/2048.0f * 360.0f), glm::vec3(0.0f,1.0f,0.0f));
+	    glm::mat4 model = transform->model();
+//	    model = glm::rotate(model, glm::radians(total/2048.0f * 360.0f), glm::vec3(0.0f,1.0f,0.0f));
 
 	    auto shader = mesh->pipeline;
 	    glUseProgram( shader );
diff --git a/fggl/math/types.hpp b/fggl/math/types.hpp
index d3c5b6e28192ebe02308fbd1c435d96af9d3eb8a..77373e6edb29610c97739fe26f9f46907eb06de7 100644
--- a/fggl/math/types.hpp
+++ b/fggl/math/types.hpp
@@ -1,6 +1,7 @@
 #ifndef FGGL_MATH_TYPES_H
 #define FGGL_MATH_TYPES_H
 
+#include <glm/ext/matrix_transform.hpp>
 #include <glm/glm.hpp>
 #include <glm/gtc/quaternion.hpp>
 #include <glm/gtx/quaternion.hpp>
@@ -21,7 +22,7 @@ namespace fggl::math {
 
 	struct Transform {
 
-		Transform() : m_local(1.0f), m_origin(0.0f), m_model(), m_rotation() {
+		Transform() : m_local(1.0f), m_origin(0.0f), m_model(1.0f), m_rotation() {
 		}
 
 		// local reference vectors
@@ -65,6 +66,14 @@ namespace fggl::math {
 			return glm::eulerAngles(m_rotation);
 		}
 
+		inline mat4 model() const {
+			mat4 tmp(1.0f);
+			tmp = glm::translate(tmp, m_origin);
+			tmp = tmp * glm::toMat4(m_rotation);
+
+			return tmp;
+		}
+
 		private:
 			mat4 m_local; // us -> parent
 			mat4 m_model; // us -> world