diff --git a/assets/shaders/Image-Instanced.vert b/assets/shaders/Image-Instanced.vert
new file mode 100644
index 0000000000000000000000000000000000000000..e2cad8b2f9c134ba947503e8221b01ae4ac7b610
--- /dev/null
+++ b/assets/shaders/Image-Instanced.vert
@@ -0,0 +1,14 @@
+#version 330 core
+layout (location = 0) in vec2 aPos;
+layout (location = 1) in vec2 aTex;
+
+uniform mat4 uProj;
+uniform mat4 uView;
+uniform mat4 uModel[128];
+
+out vec2 Texture;
+
+void main() {
+    Texture = aTex;
+    gl_Position = uProj * uView * uModel[gl_InstanceID] * vec4(aPos.x, aPos.y, 0.0, 1.0);
+}
\ No newline at end of file
diff --git a/assets/textures/Armored.png b/assets/textures/Armored.png
new file mode 100644
index 0000000000000000000000000000000000000000..b39470eae7d9c3b30ab47fae1f4a8e5f204d6b7b
Binary files /dev/null and b/assets/textures/Armored.png differ
diff --git a/assets/textures/Neera.png b/assets/textures/Neera.png
new file mode 100644
index 0000000000000000000000000000000000000000..01d777dca4146f5ff1d41da072aa59c744c5cc5b
Binary files /dev/null and b/assets/textures/Neera.png differ
diff --git a/imgui.ini b/imgui.ini
new file mode 100644
index 0000000000000000000000000000000000000000..6b73fe54ff07f17b07d20b210e2d40736cf7919f
--- /dev/null
+++ b/imgui.ini
@@ -0,0 +1,8 @@
+[Window][Debug##Default]
+Pos=60,60
+Size=400,400
+
+[Window][Isometric]
+Pos=138,21
+Size=477,101
+
diff --git a/source/engine/graphics/back/buffers/ShaderStorageBuffer.hpp b/source/engine/graphics/back/buffers/ShaderStorageBuffer.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..778b059821779a7019c1bcfd120d45698989631f
--- /dev/null
+++ b/source/engine/graphics/back/buffers/ShaderStorageBuffer.hpp
@@ -0,0 +1,30 @@
+#pragma once
+
+#include "Buffer.hpp"
+
+#include <map>
+
+#include "../shaders/Program.hpp"
+
+namespace megu {
+    template <class T>
+    class ShaderStorageBuffer : public Buffer {
+        public:
+            ShaderStorageBuffer(T * = nullptr);
+   virtual ~ShaderStorageBuffer();
+
+            void setData(T *);
+            void attach(const std::string &, const Program &);
+
+            void bind() const override;
+            void unbind() const override;
+            inline GLuint identifier() const override {return this->_id;}
+
+        private:
+            T * _data;
+            GLuint _id;
+            std::map<const Program *, GLuint> _programs;
+    };
+}
+
+#include "ShaderStorageBuffer.tpp"
\ No newline at end of file
diff --git a/source/engine/graphics/back/buffers/ShaderStorageBuffer.tpp b/source/engine/graphics/back/buffers/ShaderStorageBuffer.tpp
new file mode 100644
index 0000000000000000000000000000000000000000..163159e9109136e13e21299e73a6696965cfc381
--- /dev/null
+++ b/source/engine/graphics/back/buffers/ShaderStorageBuffer.tpp
@@ -0,0 +1,45 @@
+#include "ShaderStorageBuffer.hpp"
+
+namespace megu {
+    template <class T>
+    ShaderStorageBuffer<T>::ShaderStorageBuffer(T * data) 
+    : _data(data), _id(0) {
+        glCreateBuffers(1, &this->_id);
+        glBindBuffer(GL_SHADER_STORAGE_BUFFER, this->_id);
+        glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(T), data, GL_DYNAMIC_DRAW);
+    }
+
+    template <class T>
+    ShaderStorageBuffer<T>::~ShaderStorageBuffer() {
+        glDeleteBuffers(1, &this->_id);
+    }
+
+    template <class T>
+    void ShaderStorageBuffer<T>::setData(T * data) {
+        this->_data = data;
+        glBindBuffer(GL_SHADER_STORAGE_BUFFER, this->_id);
+        glBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, sizeof(T), data);
+    }
+
+    template <class T>
+    void ShaderStorageBuffer<T>::attach(const std::string & name, const Program & program) {
+        this->_programs.insert(std::pair<const Program *, GLuint>(&program, 0));
+        glBindBuffer(GL_SHADER_STORAGE_BUFFER, this->_id);
+        this->_programs[&program] = glGetProgramResourceIndex(program.id(), GL_SHADER_STORAGE_BLOCK, name.c_str());
+        glBindBufferBase(GL_SHADER_STORAGE_BUFFER, this->_programs[&program], this->_id);
+    }
+
+    template <class T>
+    void ShaderStorageBuffer<T>::bind() const {
+        glBindBuffer(GL_SHADER_STORAGE_BUFFER, this->_id);
+    }
+
+    template <class T>
+    void ShaderStorageBuffer<T>::unbind() const {
+        GLint binded = 0;
+        glGetIntegerv(GL_SHADER_STORAGE_BUFFER, &binded);
+        if(static_cast<GLuint>(binded) == this->_id) {
+            glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
+        }
+    }
+}
\ No newline at end of file
diff --git a/source/engine/graphics/back/geometry/Counter.hpp b/source/engine/graphics/back/geometry/Counter.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..84de6dc30ece6b926562d7469d2b9e647fb3c465
--- /dev/null
+++ b/source/engine/graphics/back/geometry/Counter.hpp
@@ -0,0 +1,93 @@
+#pragma once
+
+#include <list>
+#include <typeindex>
+
+namespace megu {
+    template <typename T>
+    class Counter {
+        public:
+            template <T U>
+            static std::list<T> Count() {
+                std::list<T> list;
+                list.push_back(U);
+                return list;
+            }
+
+            template <T U>
+            static std::list<T> Count(std::list<T> & list) {
+                list.push_back(U);
+                return list;
+            }
+
+            template <T U, T V, T ... L>
+            static std::list<T> Count() {
+                std::list<T> list;
+                list.push_back(U);
+                return Counter<T>::Count<V, L...>(list);
+            }
+
+            template <T U, T V, T ... L>
+            static std::list<T> Count(std::list<T> & list) {
+                list.push_back(U);
+                return Counter<T>::Count<V, L...>(list);
+            }
+    };
+
+    class Type_Counter {
+        public:
+            template <class T>
+            static std::list<std::type_index> Count() {
+                std::list<std::type_index> list;
+                list.push_back(typeid(T));
+                return list;
+            }
+
+            template <class T>
+            static std::list<std::type_index> Count(std::list<std::type_index> & list) {
+                list.push_back(typeid(T));
+                return list;
+            }
+
+            template <class T, class U, class ... V>
+            static std::list<std::type_index> Count() {
+                std::list<std::type_index> list;
+                list.push_back(typeid(T));
+                return Type_Counter::Count<U, V...>(list);
+            }
+
+            template <class T, class U, class ... V>
+            static std::list<std::type_index> Count(std::list<std::type_index> & list) {
+                list.push_back(typeid(T));
+                return Type_Counter::Count<U, V...>(list);
+            }
+    };
+
+    template <typename T>
+    class Sum {
+        public:
+            template <T U>
+            static constexpr size_t sum() {
+                size_t sum = U;
+                return sum;
+            }   
+
+            template <T U>
+            static constexpr size_t sum(size_t & sum) {
+                sum += U;
+                return sum;
+            }
+
+            template <T U, T V, T ... S>
+            static constexpr size_t sum() {
+                size_t sum = U;
+                return Sum::sum<V, S...>(sum);
+            }
+
+            template <T U, T V, T ... S>
+            static constexpr size_t sum(size_t & sum) {
+                sum += U;
+                return Sum::sum<V, S...>(sum);
+            }
+    };
+}
\ No newline at end of file
diff --git a/source/engine/graphics/back/geometry/Geometry.hpp b/source/engine/graphics/back/geometry/Geometry.hpp
index 7b34f29090660d2aac1b896631091be7a995f7b2..ca78b648733fb414082ae95c5e52ec519f930514 100644
--- a/source/engine/graphics/back/geometry/Geometry.hpp
+++ b/source/engine/graphics/back/geometry/Geometry.hpp
@@ -8,6 +8,7 @@
 #include <GL/glew.h>
 
 #include "../buffers/Layout.hpp"
+#include "Counter.hpp"
 
 namespace megu {
     using Vertices_t = std::vector<float>;
@@ -19,7 +20,13 @@ namespace megu {
     };
 
     template <Primitive_t P>
-    class Geometry {
+    class Primitived {
+        public: 
+            inline static Primitive_t Primitive() {return P;}
+    };
+
+    template <Primitive_t P>
+    class Geometry : public Primitived<P> {
         public: 
             Geometry() = delete;
             Geometry(const Layout &);
@@ -27,8 +34,8 @@ namespace megu {
 
             virtual const Vertices_t & vertices() const = 0;
 
-            inline static Primitive_t Primitive() {return P;}
-
+            inline const Layout & layout() const {return this->_layout;}
+            
         private:
             Layout _layout;
     };
@@ -43,22 +50,22 @@ namespace megu {
             virtual const Elements_t & elements() const = 0;
     };
 
-    template <class T, Primitive_t P>
-    class Static_Geometry : public Geometry<P> {
+    template <class T, Primitive_t P, layout::Value ... L>
+    class Static_Geometry : public Primitived<P> {
         public:
-            Static_Geometry() = delete;
-            Static_Geometry(const Layout &);
+            Static_Geometry() = default;
            ~Static_Geometry() = default;
 
-            const Vertices_t & vertices() const final override {return Static_Geometry<T, P>::Vertices();}
+            const Vertices_t & vertices() const {return Static_Geometry<T, P>::Vertices();}
+
+            static Layout Layout() {return Counter<megu::layout::Value>::Count<L...>();}
             static const Vertices_t & Vertices() {return T::Vertices();}
     };
 
-    template <class T, Primitive_t P>
-    class Static_Geometry_Indiced : public Geometry_Indiced<P>, public Static_Geometry<T, P> {
+    template <class T, Primitive_t P, layout::Value ... L>
+    class Static_Geometry_Indiced : public Geometry_Indiced<P>, public Static_Geometry<T, P, L> {
         public:
-            Static_Geometry_Indiced() = delete;
-            Static_Geometry_Indiced(const Layout &);
+            Static_Geometry_Indiced() = default;
            ~Static_Geometry_Indiced() = default;
 
             const Elements_t  & elements() const final override {return Static_Geometry_Indiced<T, P>::Elements();}
diff --git a/source/engine/graphics/back/geometry/Geometry.tpp b/source/engine/graphics/back/geometry/Geometry.tpp
index c8cdbdcb2ac16a8dfbc2aa511f76a82eb78961ab..6bb031da821637d77e7a51cbddfe49c3a7de7c13 100644
--- a/source/engine/graphics/back/geometry/Geometry.tpp
+++ b/source/engine/graphics/back/geometry/Geometry.tpp
@@ -8,12 +8,4 @@ namespace megu {
     template <Primitive_t P>
     Geometry_Indiced<P>::Geometry_Indiced(const Layout & layout)
     : Geometry<P>(layout) {}
-
-    template <class T, Primitive_t P>
-    Static_Geometry<T,P>::Static_Geometry(const Layout & layout)
-    : Geometry<P>(layout) {}
-
-    template <class T, Primitive_t P>
-    Static_Geometry_Indiced<T, P>:: Static_Geometry_Indiced(const Layout & layout)
-    : Geometry<P>(layout) {}
 }
\ No newline at end of file
diff --git a/source/engine/graphics/back/geometry/Transformable.cpp b/source/engine/graphics/back/geometry/Transformable.cpp
index 482a57ef6108f35281fcafc70eed8366e504ab7c..e553b6b3bdc12ec52d2d85a1ef5a37936e06784d 100644
--- a/source/engine/graphics/back/geometry/Transformable.cpp
+++ b/source/engine/graphics/back/geometry/Transformable.cpp
@@ -42,6 +42,21 @@ namespace megu {
         this->_updated = true;
     }
 
+    void Transformable::setX(float x) {
+        this->_position.x = x;
+        this->_updated = true;
+    }
+
+    void Transformable::setY(float y) {
+        this->_position.y = y;
+        this->_updated = true;
+    }
+
+    void Transformable::setZ(float z) {
+        this->_position.z = z;
+        this->_updated = true;
+    }
+
     void Transformable::setRotation(float angle, Axis axis) {
         if((Axis::X & axis) != 0) {
             this->_rotation.x = angle; 
@@ -108,4 +123,28 @@ namespace megu {
         }
         return this->_model;
     }
+
+    bool Transformable::operator==(const Transformable & t) const {
+        return this->_position == t._position;
+    }
+
+    bool Transformable::operator!=(const Transformable & t) const {
+        return this->_position != t._position;
+    }
+
+    bool Transformable::operator>=(const Transformable & t) const {
+        return this->_position.x <= t._position.x &&  this->_position.y <= t._position.y;
+    }
+
+    bool Transformable::operator<=(const Transformable & t) const {
+        return this->_position.x >= t._position.x && this->_position.y >= t._position.y;
+    }
+
+    bool Transformable::operator>(const Transformable & t) const {
+        return this->_position.x < t._position.x &&  this->_position.y < t._position.y;
+    }
+
+    bool Transformable::operator<(const Transformable & t) const {
+        return this->_position.x > t._position.x && this->_position.y > t._position.y;
+    }
 }
\ No newline at end of file
diff --git a/source/engine/graphics/back/geometry/Transformable.hpp b/source/engine/graphics/back/geometry/Transformable.hpp
index ce39c3be765e3cd50960b1d48e5e0743703fefb0..c8582090e36a6a4f774493cbd49d4cf0215961ce 100644
--- a/source/engine/graphics/back/geometry/Transformable.hpp
+++ b/source/engine/graphics/back/geometry/Transformable.hpp
@@ -43,11 +43,15 @@ namespace megu {
             void setPosition(const glm::vec3 &);
             void setRotation(float, Axis);
             void setScaling(const glm::vec3 &);
+            void setX(float);
+            void setY(float);
+            void setZ(float);
 
             inline void setMatrix(const glm::mat4 & matrix) {this->_model = matrix;}
+            inline void setOrigine(const glm::vec3 & position) {this->_origine = position;}
             inline void setPosition(float x, float y, float z = 0.f) {this->setPosition({x, y, z});}
             inline void setScaling(float x, float y, float z = 0.f) {this->setScaling({x, y, z});}
-            inline void setOrigine(const glm::vec3 & position) {this->_origine = position;}
+            inline void setOrigine(float x, float y, float z = 0.f) {this->setOrigine({x, y, z});}
 
             void move(const glm::vec3 &);
             void rotate(float, Axis);
@@ -56,6 +60,13 @@ namespace megu {
             inline void translate(const glm::vec3 & translation) {this->move(translation);}
             inline void move(float x, float y, float z = 0.f) {this->move({x, y, z});}
             inline void scale(float x, float y, float z = 0.f) {this->scale({x, y, z});}
+
+            bool operator==(const Transformable &) const;
+            bool operator!=(const Transformable &) const;
+            bool operator>=(const Transformable &) const;
+            bool operator<=(const Transformable &) const;
+            bool operator>(const Transformable &) const;
+            bool operator<(const Transformable &) const;
             
             virtual const glm::mat4x4 & model() const;
 
diff --git a/source/engine/graphics/back/shaders/Program.cpp b/source/engine/graphics/back/shaders/Program.cpp
index f4f9860b4f24ffc369e34d283e7e098a7f3ae892..9520109bcac16a39c81a1978afa2155874a85b6e 100644
--- a/source/engine/graphics/back/shaders/Program.cpp
+++ b/source/engine/graphics/back/shaders/Program.cpp
@@ -6,6 +6,7 @@
 #include "../../errors/Shader_Error.hpp"
 
 #include <iostream>
+#include <list>
 
 namespace megu {
     Program::Program() 
@@ -169,4 +170,11 @@ namespace megu {
         glUniformMatrix4fv(this->_locations.at(name), static_cast<GLsizei>(value.size()), GL_FALSE, glm::value_ptr(value[0]));
     }
 
+    void Program::setUniform(const std::string & name, const std::vector<std::reference_wrapper<const glm::mat4>> & value) const {
+        glUniformMatrix4fv(this->_locations.at(name), static_cast<GLsizei>(value.size()), GL_FALSE, glm::value_ptr(value[0].get()));
+    }
+
+    void Program::setUniform(const std::string & name, const std::set<std::reference_wrapper<const glm::mat4>> & value) const {
+        glUniformMatrix4fv(this->_locations.at(name), static_cast<GLsizei>(value.size()), GL_FALSE, glm::value_ptr(value.begin()->get()));
+    }
 }
\ No newline at end of file
diff --git a/source/engine/graphics/back/shaders/Program.hpp b/source/engine/graphics/back/shaders/Program.hpp
index 5e4b08d0d2d2833296a0487c5cdbecab6d5931ba..0b5df733d627649646e072c89772f3fe85dc49aa 100644
--- a/source/engine/graphics/back/shaders/Program.hpp
+++ b/source/engine/graphics/back/shaders/Program.hpp
@@ -3,6 +3,7 @@
 #include <GL/glew.h>
 #include <glm/glm.hpp>
 #include <vector>
+#include <set>
 #include <unordered_map>
 
 #include "Source.hpp"
@@ -66,5 +67,8 @@ namespace megu {
             void setUniform(const std::string &, const std::vector<glm::vec2> &) const;
             void setUniform(const std::string &, const std::vector<glm::vec4> &) const;
             void setUniform(const std::string &, const std::vector<glm::mat4> &) const;
+
+            void setUniform(const std::string &, const std::vector<std::reference_wrapper<const glm::mat4>> &) const;
+            void setUniform(const std::string &, const std::set<std::reference_wrapper<const glm::mat4>> &) const;
     };
 }
\ No newline at end of file
diff --git a/source/engine/graphics/back/textures/Texture.cpp b/source/engine/graphics/back/textures/Texture.cpp
index e47163a402c3bdfd815e8ce830234b613f67baed..e913a049b849777323b098d501b06af5070c13d8 100644
--- a/source/engine/graphics/back/textures/Texture.cpp
+++ b/source/engine/graphics/back/textures/Texture.cpp
@@ -9,6 +9,14 @@ namespace megu {
         glGenTextures(1, &this->_id);
     }
 
+    Texture::Texture(const std::filesystem::path & path, GLuint slot)
+    : _id(0), _type(GL_RED), _slot(slot) {
+        this->store(TextureBuffer(path));
+    }
+
+    Texture::Texture(const Texture & texture) 
+    : _id(texture._id), _type(texture._type), _slot(texture._slot) {}
+
     Texture::~Texture() {
         glDeleteTextures(1, &this->_id);
     }
diff --git a/source/engine/graphics/back/textures/Texture.hpp b/source/engine/graphics/back/textures/Texture.hpp
index 55f70524c6e2c60784ee174e6e0a8f02fc6bda27..aeb75f89bb5035327c64ceec1708fa0d16fc002c 100644
--- a/source/engine/graphics/back/textures/Texture.hpp
+++ b/source/engine/graphics/back/textures/Texture.hpp
@@ -9,7 +9,8 @@ namespace megu {
     class Texture {
         public:
             Texture(GLuint = 0, GLuint = GL_TEXTURE_2D);
-            Texture(const Texture &) = delete;
+            Texture(const std::filesystem::path &, GLuint = 0);
+            Texture(const Texture &);
             Texture & operator=(const Texture &) = delete;
            ~Texture();
 
diff --git a/source/engine/graphics/back/textures/TextureBuffer.cpp b/source/engine/graphics/back/textures/TextureBuffer.cpp
index 67013aa8b08ab818a5d8fdb8079a8eca7aa00ec2..52f13a891aac71fcebaae923b311a8189165409f 100644
--- a/source/engine/graphics/back/textures/TextureBuffer.cpp
+++ b/source/engine/graphics/back/textures/TextureBuffer.cpp
@@ -12,6 +12,11 @@ namespace megu {
     TextureBuffer::TextureBuffer(GLuint width, GLuint height, GLubyte * data, GLenum format) 
     : _data(data, data + (width * height)), _width(width), _height(height), _format(format) {}
 
+    TextureBuffer::TextureBuffer(const std::filesystem::path & path, bool flip) 
+    : _data(), _width(0), _height(0), _format(GL_RED) {
+        this->load(path, flip);
+    }
+
     TextureBuffer::TextureBuffer(const TextureBuffer & src)
     : _data(src._data), _width(src._width), _height(src._height) {}
 
diff --git a/source/engine/graphics/back/textures/TextureBuffer.hpp b/source/engine/graphics/back/textures/TextureBuffer.hpp
index 584ed8c28e467091c69ff141755f953dc625c91e..489e72e48042aeab55e49f180f662f76bcddd312 100644
--- a/source/engine/graphics/back/textures/TextureBuffer.hpp
+++ b/source/engine/graphics/back/textures/TextureBuffer.hpp
@@ -9,6 +9,7 @@ namespace megu {
         public:
             TextureBuffer();
             TextureBuffer(GLuint, GLuint, GLubyte *, GLenum);
+            TextureBuffer(const std::filesystem::path &, bool = false);
             TextureBuffer(const TextureBuffer &);
             TextureBuffer & operator=(const TextureBuffer & src);
            ~TextureBuffer() = default;
@@ -24,7 +25,7 @@ namespace megu {
             void flipVerticaly();
 
             void load(const GLubyte *, size_t);
-            void load(const std::filesystem::path &, bool = true);
+            void load(const std::filesystem::path &, bool = false);
             void free();
 
             static int BytePerPixel(GLenum);
diff --git a/source/engine/graphics/front/geometry/FlatGeometry.cpp b/source/engine/graphics/front/geometry/FlatGeometry.cpp
deleted file mode 100644
index e6e0de17daf4a8e06e0814b8c18f96367a8767fb..0000000000000000000000000000000000000000
--- a/source/engine/graphics/front/geometry/FlatGeometry.cpp
+++ /dev/null
@@ -1,21 +0,0 @@
-#include "FlatGeometry.hpp"
-
-namespace megu {
-    Flat_Geometry::Flat_Geometry()
-    : Geometry({layout::FLAT, layout::COLOR}) {}
-    
-    Vertices_t Static_Flat_Geometry::_Vertices = {
-        0.f,  0.f,    0.f, 0.f,
-        1.f,  0.f,    1.f, 0.f,
-        1.f,  1.f,    1.f, 1.f,
-        0.f,  1.f,    0.f, 1.f
-    };
-
-    Static_Flat_Geometry::Static_Flat_Geometry()
-    : Static_Geometry<Static_Flat_Geometry, QUADS>(Static_Flat_Geometry::GetLayout()) {}
-
-    const Vertices_t & Static_Flat_Geometry::Vertices() {
-        return Static_Flat_Geometry::_Vertices;
-    }
-    
-}
\ No newline at end of file
diff --git a/source/engine/graphics/front/geometry/FlatGeometry.hpp b/source/engine/graphics/front/geometry/FlatGeometry.hpp
deleted file mode 100644
index 7f56662bcaa71c655fd5d924ad14bd4173eb3976..0000000000000000000000000000000000000000
--- a/source/engine/graphics/front/geometry/FlatGeometry.hpp
+++ /dev/null
@@ -1,24 +0,0 @@
-#pragma once
-
-#include <engine/graphics/back/geometry/Geometry.hpp>
-
-namespace megu {
-    class Flat_Geometry : public Geometry<QUADS> {
-        public:
-            Flat_Geometry();
-           ~Flat_Geometry() = default;
-    }; 
-
-    class Static_Flat_Geometry : public Static_Geometry<Static_Flat_Geometry, QUADS> {
-        public:
-            Static_Flat_Geometry();
-           ~Static_Flat_Geometry() = default;
-
-            inline static Layout GetLayout() {return {layout::FLAT, layout::TEXTURE};}
-
-            static const Vertices_t & Vertices();
-            
-        private:
-            static Vertices_t _Vertices;
-    };
-}
diff --git a/source/engine/graphics/front/geometry/Quads.cpp b/source/engine/graphics/front/geometry/Quads.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..fccb8871cb6f30fb070e1fc8b834732c6ccb5547
--- /dev/null
+++ b/source/engine/graphics/front/geometry/Quads.cpp
@@ -0,0 +1,10 @@
+#include "Quads.hpp"
+
+namespace megu {
+    Vertices_t Quads::_Vertices = {
+        0.f,  0.f,    0.f, 0.f,
+        1.f,  0.f,    1.f, 0.f,
+        1.f,  1.f,    1.f, 1.f,
+        0.f,  1.f,    0.f, 1.f
+    };    
+}
\ No newline at end of file
diff --git a/source/engine/graphics/front/geometry/Quads.hpp b/source/engine/graphics/front/geometry/Quads.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..2e70bc67aef40de435784c07c6bc3d1ef07852e1
--- /dev/null
+++ b/source/engine/graphics/front/geometry/Quads.hpp
@@ -0,0 +1,13 @@
+#pragma once
+
+#include <engine/graphics/back/geometry/Geometry.hpp>
+
+namespace megu {
+    class Quads : public Static_Geometry<Quads, QUADS, layout::FLAT, layout::TEXTURE> {
+        public:
+            inline static const Vertices_t & Vertices() {return Quads::_Vertices;}
+            
+        private:
+            static Vertices_t _Vertices;
+    };
+}
diff --git a/source/engine/graphics/front/group/ImageGroup.cpp b/source/engine/graphics/front/group/ImageGroup.cpp
index 47fe30a4360cb91119c2ec3b765b8f0f93aeaa8f..5239d8e8c0eb10b79fbf2929e614d8c466a96678 100644
--- a/source/engine/graphics/front/group/ImageGroup.cpp
+++ b/source/engine/graphics/front/group/ImageGroup.cpp
@@ -1,10 +1,12 @@
 #include "ImageGroup.hpp"
 
+#include <tuple>
+
 namespace megu {
     ImageGroup::ImageGroup() 
-    : _images(nullptr), _vbo(this->_vao, Static_Flat_Geometry::GetLayout(), 400) {
+    : _vbo(this->_vao, Quads::Layout(), 400) {
         {
-            Source vert("assets/shaders/Image.vert", Source::Categorie::VERTEX);
+            Source vert("assets/shaders/Image-Instanced.vert", Source::Categorie::VERTEX);
             Source frag("assets/shaders/Image.frag", Source::Categorie::FRAGMENT);
 
             this->_program << vert;
@@ -15,20 +17,40 @@ namespace megu {
             frag.release();
         }
 
-        this->_vbo << Static_Flat_Geometry::Vertices();
+        this->_vbo << Quads::Vertices();
+    }
+
+    void ImageGroup::add(const Image & image) {
+        this->_images.insert(image);
+    }
+
+    void ImageGroup::update() {
+        std::set<std::reference_wrapper<const Image>, isometric_sorter> source = this->_images;
+        this->_images.clear();
+        for(auto & i : source) {
+            this->_images.insert(i);
+        }
     }
 
     void ImageGroup::draw(const Camera & camera) const {
         this->_vao.bind();
         this->_program.use();
 
-        this->_images->texture().bind(0);
+        std::map<std::reference_wrapper<const Texture>, std::vector<std::reference_wrapper<const glm::mat4>>> data;
+        
+        for(auto & image : this->_images) {
+            data[image.get().texture()].push_back(image.get().transformation().model());
+        }
+        
+        for(auto &[texture, models] : data) {
+            texture.get().bind();
 
-        this->_program.setUniform("uProj", camera.projection());
-        this->_program.setUniform("uView", camera.view());
-        this->_program.setUniform("uModel", this->_images->transformation().model());
-        this->_program.setUniform("uSampler", 0);
+            this->_program.setUniform("uProj", camera.projection());
+            this->_program.setUniform("uView", camera.view());
+            this->_program.setUniform("uSampler", 0);
+            this->_program.setUniform("uModel", models);
 
-        glDrawArrays(Static_Flat_Geometry::Primitive(), 0, static_cast<GLsizei>(this->_vbo.size()));
+            glDrawArraysInstanced(Quads::Primitive(), 0, static_cast<GLsizei>(this->_vbo.size()), static_cast<GLsizei>(models.size()));
+        }    
     }
 }
\ No newline at end of file
diff --git a/source/engine/graphics/front/group/ImageGroup.hpp b/source/engine/graphics/front/group/ImageGroup.hpp
index 465609efcd3788c70bc94344e10991511e7e96b1..8bad28b9b4526814241590b4149ac26d6f46920d 100644
--- a/source/engine/graphics/front/group/ImageGroup.hpp
+++ b/source/engine/graphics/front/group/ImageGroup.hpp
@@ -1,6 +1,12 @@
 #pragma once
 
 #include "DrawGroup.hpp"
+#include "reference_sorter.hpp"
+#include "isometric_sorter.hpp"
+
+#include <map>
+#include <list>
+#include <set>
 
 #include <engine/graphics/back/buffers/VertexArray.hpp>
 #include <engine/graphics/back/buffers/VerticeBuffer.hpp>
@@ -16,11 +22,12 @@ namespace megu {
 
             void draw(const Camera & camera) const override;
 
-            inline void temp_set(Image & image) {this->_images = &image;}
+            void add(const Image &);
+            void update();
 
         private:
-            Image * _images;
-
+            std::set<std::reference_wrapper<const Image>, isometric_sorter> _images;
+            
             VertexArray _vao;
             VerticeBuffer _vbo;
             Program _program;
diff --git a/source/engine/graphics/front/group/isometric_sorter.cpp b/source/engine/graphics/front/group/isometric_sorter.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b1eb9261b340f9b3c602c7c764ff2054263f031c
--- /dev/null
+++ b/source/engine/graphics/front/group/isometric_sorter.cpp
@@ -0,0 +1,21 @@
+#include "isometric_sorter.hpp"
+
+#include <engine/graphics/front/object/Image.hpp>
+
+namespace megu {
+    bool isometric_sorter::operator()(const Image & img1, const Image & img2) const {
+        if(img1.transformation().z() != img2.transformation().z()) {
+            return img1.transformation().z() > img2.transformation().z();
+        }
+
+        if(img1.transformation().y() != img2.transformation().y()) {
+            return img1.transformation().y() < img2.transformation().y();
+        }
+
+        if(img1.transformation().x() != img2.transformation().x()) {
+            return img1.transformation().x() > img2.transformation().x();
+        }
+
+        return &img1 > &img2;
+    }
+}
\ No newline at end of file
diff --git a/source/engine/graphics/front/group/isometric_sorter.hpp b/source/engine/graphics/front/group/isometric_sorter.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..6c840065780ce622b62c10abf40565dd6b80c841
--- /dev/null
+++ b/source/engine/graphics/front/group/isometric_sorter.hpp
@@ -0,0 +1,10 @@
+#pragma once
+
+namespace megu {
+    class Image;
+
+    class isometric_sorter {
+        public:
+            bool operator()(const Image & img1, const Image & img2) const;
+    };
+}
\ No newline at end of file
diff --git a/source/engine/graphics/front/group/reference_sorter.hpp b/source/engine/graphics/front/group/reference_sorter.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..df5a8eab1f5dc1da160646482820fff6ecd467cb
--- /dev/null
+++ b/source/engine/graphics/front/group/reference_sorter.hpp
@@ -0,0 +1,15 @@
+#pragma once
+
+namespace megu {
+    template <class T>
+    class reference_sorter {
+        public:
+            reference_sorter() = default;
+           ~reference_sorter() = default;
+            
+            friend bool operator<(const T &, const T &);
+            bool operator()(const T &, const T &) const;
+    };
+}
+
+#include "reference_sorter.tpp"
\ No newline at end of file
diff --git a/source/engine/graphics/front/group/reference_sorter.tpp b/source/engine/graphics/front/group/reference_sorter.tpp
new file mode 100644
index 0000000000000000000000000000000000000000..320ee9f694d62abbc1cff1625298176fbce13595
--- /dev/null
+++ b/source/engine/graphics/front/group/reference_sorter.tpp
@@ -0,0 +1,13 @@
+#include "reference_sorter.hpp"
+
+namespace megu {
+    template <class T>
+    bool operator<(const T & obj_1, const T & obj_2) {
+        return &obj_1 < &obj_2;
+    }
+
+    template <class T>
+    bool reference_sorter<T>::operator()(const T & obj_1, const T & obj_2) const {
+        return &obj_1 < &obj_2;
+    }
+}
\ No newline at end of file
diff --git a/source/engine/graphics/front/object/Image.cpp b/source/engine/graphics/front/object/Image.cpp
index 42ac510d4d50153fea150b9c9d797e30260d7f1d..dce4a4269d6ffcbb1d3e667dcc10dd4dd08f05d0 100644
--- a/source/engine/graphics/front/object/Image.cpp
+++ b/source/engine/graphics/front/object/Image.cpp
@@ -3,8 +3,26 @@
 namespace megu {
     Image::Image() 
     : _texture(), 
-      _transformation(), 
-      _geometry() {}
+      _geometry(),
+      _transformation() {}
+
+    Image::Image(const std::filesystem::path & path) 
+    : _texture(), 
+      _geometry(),
+      _transformation() {
+        this->load(path);
+    }
+
+    Image::Image(const Texture & texture) 
+    : _texture(texture),
+      _geometry(),
+      _transformation() {}
+
+    Image::Image(const Image & src) 
+    : _texture(src._texture), 
+      _geometry(src._geometry),
+      _transformation(src._transformation) {
+    }
 
     void Image::load(const std::filesystem::path & path, bool flip) {
         TextureBuffer buffer;
diff --git a/source/engine/graphics/front/object/Image.hpp b/source/engine/graphics/front/object/Image.hpp
index 0392e9411f0a2068338a2d76664cf29d321633d7..485d7036da82d3fb7a7f399a7bdd9cf3332b174a 100644
--- a/source/engine/graphics/front/object/Image.hpp
+++ b/source/engine/graphics/front/object/Image.hpp
@@ -6,30 +6,36 @@
 #include <engine/graphics/back/geometry/Transformable.hpp>
 #include <engine/graphics/back/textures/Texture.hpp> 
 
-#include <engine/graphics/front/geometry/FlatGeometry.hpp>
+#include <engine/graphics/front/geometry/Quads.hpp>
 
 namespace megu {
     class Image {
         public:
             Image();
+            Image(const std::filesystem::path &);
+            Image(const Texture &);
+            Image(const Image &);
            ~Image() = default;
 
             inline glm::vec2 getPosition() const {return glm::vec2(this->_transformation.x(), this->_transformation.y());}
             inline glm::vec2 getSize() const {return glm::vec2(this->_transformation.scaling().x, this->_transformation.scaling().y);}
            
-
             inline void setPosition(float x, float y) {this->_transformation.setPosition(x, y);}
+            inline void setOrigine(float x, float y) {this->_transformation.setOrigine(x, y);}
             inline void setSize(float x, float y) {this->_transformation.setScaling(x, y);}
+            inline void setRotation(float a) {this->_transformation.setRotation(a, Transformable::Axis::Z);}
+            inline void setLayer(float l) {this->_transformation.setZ(l);}
 
             void load(const std::filesystem::path &, bool = true);
             void load(const TextureBuffer &);
 
             inline const Texture & texture() const {return this->_texture;}
-            inline const Transformable & transformation() const {return this->_transformation;}
+            inline const Quads & geometry() const {return this->_geometry;}
+            inline const Transformable & transformation() const {return this->_transformation;}   
 
         private:
             Texture _texture;
+            Quads _geometry;
             Transformable _transformation;
-            Static_Flat_Geometry _geometry;
     };
 }
\ No newline at end of file
diff --git a/source/engine/io/Window.cpp b/source/engine/io/Window.cpp
index fdc462a7bb2e986c42518b7948065180f25e6675..e73e875ca8453030fbbd0c8d4e33417d57fdfa26 100644
--- a/source/engine/io/Window.cpp
+++ b/source/engine/io/Window.cpp
@@ -38,6 +38,12 @@ namespace megu {
         }
     }
 
+    void Window::setTitle(const std::string & title) {
+        if(this->_pointer != nullptr) {
+            glfwSetWindowTitle(this->_pointer, title.c_str());
+        }
+    }
+
     void Window::open(const std::string & title, uint16_t width, uint16_t height) {
         if(this->_pointer == nullptr) {
             this->_pointer = glfwCreateWindow(width, height, title.c_str(), NULL, NULL);
diff --git a/source/engine/io/Window.hpp b/source/engine/io/Window.hpp
index b541bf866d0ad45074692b8701231cf5e0345deb..b4412d3dd96b38016b0eff90960b8764a722d659 100644
--- a/source/engine/io/Window.hpp
+++ b/source/engine/io/Window.hpp
@@ -17,12 +17,15 @@ namespace megu {
             bool isOpen() const;
 
             void resize(uint16_t, uint16_t);
+            void setTitle(const std::string &);
             void open(const std::string &, uint16_t, uint16_t);
             void close();
 
             void pollEvents();
             void swapBuffers();
 
+            inline GLFWwindow * ptr() const {return this->_pointer;}
+
             inline static double Time() {return glfwGetTime();}
 
         private:
diff --git a/source/main.cpp b/source/main.cpp
index 7b6a23deed8bb2680d0b18276470c08012337f54..853f72d3bd17605040b345d57348ea059d7e93e3 100644
--- a/source/main.cpp
+++ b/source/main.cpp
@@ -3,6 +3,10 @@
 #include <GL/glew.h>
 #include <GLFW/glfw3.h>
 
+#include <imgui.h>
+#include <imgui_impl_glfw.h>
+#include <imgui_impl_opengl3.h>
+
 #define WINDOW_WIDTH  1200
 #define WINDOW_HEIGHT 720
 
@@ -12,42 +16,22 @@
 #include <engine/graphics/front/group/ImageGroup.hpp>
 #include <engine/graphics/errors.hpp>
 
-int main(int argc, const char * argv[]) {
-    try {
-        /*//? GLFW
-        if(glfwInit() == GLFW_FALSE) {
-            std::cerr << "GLFW : GLFW Init Error" << std::endl;
-            return EXIT_FAILURE;
-        }
-
-        GLFWmonitor * monitore = glfwGetPrimaryMonitor();
-        const GLFWvidmode * videoMode = glfwGetVideoMode(monitore);
+#define NORMALIZE(X) X/255.f
 
-        glfwWindowHint(GLFW_RED_BITS, videoMode->redBits);
-        glfwWindowHint(GLFW_GREEN_BITS, videoMode->greenBits);
-        glfwWindowHint(GLFW_BLUE_BITS, videoMode->blueBits);
-        glfwWindowHint(GLFW_REFRESH_RATE, videoMode->refreshRate);
+const float i_x =  1.f;
+const float i_y =  0.5f;
+const float j_x = -1.f;
+const float j_y =  0.5f;
 
-        glfwWindowHint(GLFW_RESIZABLE, true);
-        glfwWindowHint(GLFW_DECORATED, true);
-        glfwWindowHint(GLFW_VISIBLE, true);
-        glfwWindowHint(GLFW_DOUBLEBUFFER, true);
+glm::vec2 to_screen_coordinate(const glm::vec2 & tile, float w, float h, float layer = 0.0f) {
+    return {
+        (tile.x + layer) * i_x * 0.5f * w + (tile.y + layer) * j_x * 0.5f * w,
+        (tile.x + layer) * i_y * 0.5f * h + (tile.y + layer) * j_y * 0.5f * h
+    };
+}
 
-        GLFWwindow * window = glfwCreateWindow(WINDOW_WIDTH, WINDOW_HEIGHT, "Scene", NULL, NULL);
-        if(window == NULL) {
-            std::cerr << "GLFW : Window Init Error" << std::endl;
-            return EXIT_FAILURE;
-        }
-
-        glfwMakeContextCurrent(window);
-        glfwSwapInterval(0);
-        std::cout << "GLFW Inited" << std::endl;
-
-        //? Glew
-        if(glewInit()) {
-            std::cerr << "Failed to initialize GLAD" << std::endl;
-            return EXIT_FAILURE;
-        }*/
+int main(int argc, const char * argv[]) {
+    try {
         //? Window
         megu::Window window;
         window.open("Window", WINDOW_WIDTH, WINDOW_HEIGHT);
@@ -56,31 +40,151 @@ int main(int argc, const char * argv[]) {
         std::cout << "Window Inited" << std::endl;
 
         //? Camera
-        megu::View view(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
+        megu::View view(0, 0, 320, 240);
         std::cout << "View Initied" << std::endl;
 
-        //? Image
-        megu::Image image;
-        image.load("assets/textures/Cube_Red.png");
-
-        std::cout << "Image Inited" << std::endl;
-
         //? Group
         megu::ImageGroup group;
-        group.temp_set(image);
 
         std::cout << "Group Inited" << std::endl;
 
+        //? Image
+        std::vector<int> map = {
+            1, 0, 0, 0, 1, 1, 0, 0, 0, 1,
+            0, 1, 0, 1, 0, 0, 1, 0, 1, 0,
+            0, 0, 1, 0, 0, 0, 0, 1, 0, 0,
+            0, 1, 0, 1, 0, 0, 1, 0, 1, 0,
+            1, 0, 0, 0, 1, 1, 0, 0, 0, 1,
+            1, 0, 0, 0, 1, 1, 0, 0, 0, 1,
+            0, 1, 0, 1, 0, 0, 1, 0, 1, 0,
+            0, 0, 1, 0, 0, 0, 0, 1, 0, 0,
+            0, 1, 0, 1, 0, 0, 1, 0, 1, 0,
+            1, 0, 0, 0, 1, 1, 0, 0, 0, 1,
+        };
+
+        std::vector<std::string> textures = {
+            "assets/textures/Cube_Red.png",
+            "assets/textures/Cube_Blue.png",
+            "assets/textures/Cube_Green.png",
+            "assets/textures/Cube_Cyan.png",
+            "assets/textures/Cube_Pink.png",
+            "assets/textures/Cube_Yellow.png",
+            "assets/textures/Cube_Magenta.png",
+            "assets/textures/Cube_Purple.png",
+            "assets/textures/Cube_Gray.png",
+            "assets/textures/Cube_Orange.png"
+        };
+
+        size_t x = 0;
+        size_t y = 0;
+
+        std::vector<std::unique_ptr<megu::Image>> images;
+
+        for(auto id : map) {
+            if(x == 10) {
+                x = 0;
+                ++y;
+            }
+
+            images.push_back(std::make_unique<megu::Image>(textures.at(3)));
+            glm::vec2 pos = to_screen_coordinate({x, y}, 32.f, 32.f);
+
+            images.back()->setPosition(pos.x + 160, pos.y);
+            
+            ++x;
+        }
+
+        for(auto & i : images) {
+            group.add(*i);
+        }
+
+        std::cout << "Image Inited" << std::endl;
+
+        //? ImGui
+        ImGui::CreateContext();
+        ImGui_ImplOpenGL3_Init();
+        ImGui_ImplGlfw_InitForOpenGL(window.ptr(), true);
+
         //? Render Loop
-        glClearColor(0.0f, 0.0f, 0.0f, 0.f);
+        glClearColor(NORMALIZE(110), NORMALIZE(110), NORMALIZE(255), 0.f);
+
+        double lastTime = glfwGetTime();
+        int nbFrames = 0;
 
         std::cout << "Render Loop Begin !" << std::endl;
+
+        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+        glEnable(GL_BLEND);
+
+        glm::vec2 xy = {0, 0};
+
         while(window.isOpen()) {
+            double currentTime = glfwGetTime();
+            nbFrames++;
+            if ( currentTime - lastTime >= 1.0 ){ // If last prinf() was more than 1 sec ago
+                // printf and reset timer
+                window.setTitle(std::to_string(nbFrames));
+                nbFrames = 0;
+                lastTime += 1.0;
+            }
+
             glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
             window.pollEvents();
             group.draw(view);
 
-            image.setPosition(static_cast<float>(sin(glfwGetTime()) * WINDOW_WIDTH/2), static_cast<float>(cos(glfwGetTime()) * WINDOW_HEIGHT/2));
+            ImGui_ImplOpenGL3_NewFrame();
+            ImGui_ImplGlfw_NewFrame();
+            ImGui::NewFrame();
+
+            if(ImGui::Begin("Isometric")) {
+                ImGui::Text("Position : %i / %i", static_cast<int>(xy.x), static_cast<int>(xy.y));
+
+                ImGui::Text("x : ");
+                ImGui::SameLine();
+                if(ImGui::Button("+")) {
+                    ++xy.x;
+                    glm::vec2 pos = to_screen_coordinate(xy, 32, 32, 0.f);
+                    images[1]->setPosition(pos.x, pos.y);
+                    group.update();
+
+                }
+
+                ImGui::SameLine();
+                if(ImGui::Button("-")) {
+                    --xy.x;
+                    glm::vec2 pos = to_screen_coordinate(xy, 32, 32, 0.f);
+                    images[1]->setPosition(pos.x, pos.y);
+                    group.update();
+
+                }
+
+                ImGui::PushID(1);
+
+                ImGui::Text("y : ");
+                ImGui::SameLine();
+                if(ImGui::Button("+")) {
+                    ++xy.y;
+                    glm::vec2 pos = to_screen_coordinate(xy, 32, 32, 0.f);
+                    images[1]->setPosition(pos.x, pos.y);
+                    group.update();
+
+                }
+
+                ImGui::SameLine();
+                if(ImGui::Button("-")) {
+                    --xy.y;
+                    glm::vec2 pos = to_screen_coordinate(xy, 32, 32, 0.f);
+                    images[1]->setPosition(pos.x, pos.y);
+                    group.update();
+
+                }
+
+                ImGui::PopID();
+            }   
+            ImGui::End();
+
+            ImGui::Render();
+            ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
             
             window.swapBuffers();
         }