diff --git a/assets/shaders/Image-Instanced-Fat.vert b/assets/shaders/Image-Instanced-Fat.vert
new file mode 100644
index 0000000000000000000000000000000000000000..5c700fb9fb03a19d4f2db893f107bf5c9ad3f7d9
--- /dev/null
+++ b/assets/shaders/Image-Instanced-Fat.vert
@@ -0,0 +1,16 @@
+#version 450 core
+layout (location = 0) in vec2 aPos;
+layout (location = 1) in vec2 aTex;
+
+uniform mat4 uProj;
+uniform mat4 uView;
+uniform mat4 uModel[128];
+
+out flat int Id;
+out vec2 Texture;
+
+void main() {
+    Texture = aTex;
+    Id = gl_InstanceID;
+    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/shaders/Texture-Fat.frag b/assets/shaders/Texture-Fat.frag
new file mode 100644
index 0000000000000000000000000000000000000000..37596cc07504422f6970ac898444549dda4b0577
--- /dev/null
+++ b/assets/shaders/Texture-Fat.frag
@@ -0,0 +1,12 @@
+#version 450 core
+out vec4 FragColor;
+
+in flat int Id;
+in vec2 Texture;
+
+uniform sampler2D uSampler[8];
+uniform int uTextures[128];
+
+void main() {
+    FragColor = texture(uSampler[uTextures[Id]], Texture);
+}
\ No newline at end of file
diff --git a/assets/textures/Cube_Blue_Outlined.png b/assets/textures/Cube_Blue_Outlined.png
new file mode 100644
index 0000000000000000000000000000000000000000..7b9880a482b09a1df76a7df636e288472e224130
Binary files /dev/null and b/assets/textures/Cube_Blue_Outlined.png differ
diff --git a/assets/textures/Cube_Test.png b/assets/textures/Cube_Test.png
new file mode 100644
index 0000000000000000000000000000000000000000..673ea5b784babacfdb93ea407c2db77aed95f6ac
Binary files /dev/null and b/assets/textures/Cube_Test.png differ
diff --git a/imgui.ini b/imgui.ini
index 6b73fe54ff07f17b07d20b210e2d40736cf7919f..ffc607e47918902a2e7f034df5eb6c6acb58de8b 100644
--- a/imgui.ini
+++ b/imgui.ini
@@ -3,6 +3,6 @@ Pos=60,60
 Size=400,400
 
 [Window][Isometric]
-Pos=138,21
+Pos=135,21
 Size=477,101
 
diff --git a/source/engine/graphics/back/shaders/Program.cpp b/source/engine/graphics/back/shaders/Program.cpp
index 9520109bcac16a39c81a1978afa2155874a85b6e..71a3e7702c01f97fc45d53c34d1e9307dc0eb494 100644
--- a/source/engine/graphics/back/shaders/Program.cpp
+++ b/source/engine/graphics/back/shaders/Program.cpp
@@ -154,6 +154,10 @@ namespace megu {
         glUniform1iv(this->_locations.at(name), static_cast<GLsizei>(value.size()), value.data());
     }
 
+    void Program::setUniform(const std::string & name, const std::vector<GLuint> & value) const {
+        glUniform1uiv(this->_locations.at(name), static_cast<GLsizei>(value.size()), value.data());
+    }
+
     void Program::setUniform(const std::string & name, const std::vector<GLfloat> & value) const {
         glUniform1fv(this->_locations.at(name), static_cast<GLsizei>(value.size()), value.data());
     }
diff --git a/source/engine/graphics/back/shaders/Program.hpp b/source/engine/graphics/back/shaders/Program.hpp
index 0b5df733d627649646e072c89772f3fe85dc49aa..cd005ddbf509596684218e527ac79e9ecd4c9542 100644
--- a/source/engine/graphics/back/shaders/Program.hpp
+++ b/source/engine/graphics/back/shaders/Program.hpp
@@ -63,6 +63,7 @@ namespace megu {
             void setUniform(const std::string &, const glm::mat4 &) const;
 
             void setUniform(const std::string &, const std::vector<GLint> &) const;
+            void setUniform(const std::string &, const std::vector<GLuint> &) const;
             void setUniform(const std::string &, const std::vector<GLfloat> &) const;
             void setUniform(const std::string &, const std::vector<glm::vec2> &) const;
             void setUniform(const std::string &, const std::vector<glm::vec4> &) const;
diff --git a/source/engine/graphics/back/textures/Texture.cpp b/source/engine/graphics/back/textures/Texture.cpp
index ccc5e95ed5dc8353a7c1e1e6acd6f4fb7ed317f3..4ff4eadaf57fc36c8a572269708803a3d9660f59 100644
--- a/source/engine/graphics/back/textures/Texture.cpp
+++ b/source/engine/graphics/back/textures/Texture.cpp
@@ -115,9 +115,9 @@ namespace megu {
         return this->_id == texture._id;
     }
 
-    bool Texture::operator!=(const Texture & texture) const {
+    /*bool Texture::operator!=(const Texture & texture) const {
         return this->_id != texture._id;
-    }
+    }*/
 
     bool Texture::operator>=(const Texture & texture) const {
         return this->_id >= texture._id;
diff --git a/source/engine/graphics/back/textures/Texture.hpp b/source/engine/graphics/back/textures/Texture.hpp
index 39345b128448bf12f63f637969b3b3cd207fe451..85ada6bb7585d955f89e85c0b4a3037f7394b1a6 100644
--- a/source/engine/graphics/back/textures/Texture.hpp
+++ b/source/engine/graphics/back/textures/Texture.hpp
@@ -55,7 +55,7 @@ namespace megu {
             bool valid() const;
 
             bool operator==(const Texture &) const;
-            bool operator!=(const Texture &) const;
+            //bool operator!=(const Texture &) const;
             bool operator>=(const Texture &) const;
             bool operator<=(const Texture &) const;
             bool operator>(const Texture &) const;
diff --git a/source/engine/graphics/front/Engine.cpp b/source/engine/graphics/front/Engine.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..2c81b69229305ebcc27ac15a55211ee7298dca44
--- /dev/null
+++ b/source/engine/graphics/front/Engine.cpp
@@ -0,0 +1,20 @@
+#include "Engine.hpp"
+
+namespace megu {
+    GraphicEngine::GraphicEngine(Window & window,float w, float h) 
+    : _renderer(w, h), _window(window) {
+        glViewport(0, 0, window.width(), window.height());
+        glClearColor(0.f, 0.f, 0.f, 1.f);
+        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+        glEnable(GL_BLEND);
+    } 
+
+    void GraphicEngine::step() {
+        if(this->_window.isOpen()) {
+            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+            this->_renderer.render(this->_window);
+            this->_window.swapBuffers();
+        }
+    }
+}
\ No newline at end of file
diff --git a/source/engine/graphics/front/Engine.hpp b/source/engine/graphics/front/Engine.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..9493020e963f97790b63077f812df0890b85e418
--- /dev/null
+++ b/source/engine/graphics/front/Engine.hpp
@@ -0,0 +1,22 @@
+#pragma once
+
+#include "Renderer.hpp"
+
+namespace megu {
+    class GraphicEngine {
+        public:
+            GraphicEngine() = delete;
+            GraphicEngine(Window &, float, float);
+           ~GraphicEngine() = default;
+
+            void step();
+            inline void setClearColor(float r, float g, float b, float a = 1.f) const {glClearColor(r, g, b, a);}
+
+            Renderer & tmp_getRenderer() {return this->_renderer;}
+
+        private:
+            Window & _window;
+            Renderer _renderer;
+
+    };
+}
\ No newline at end of file
diff --git a/source/engine/graphics/front/Renderer.cpp b/source/engine/graphics/front/Renderer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e1c8f589ff988fc7fef785facd1d0eef84a8c68c
--- /dev/null
+++ b/source/engine/graphics/front/Renderer.cpp
@@ -0,0 +1,18 @@
+#include "Renderer.hpp"
+
+namespace megu {
+    Renderer::Renderer(float x, float y)
+    : _view(0, 0, y, x) {
+
+    }
+
+    void Renderer::add(DrawGroup & group) {
+        this->_groups.insert(&group);
+    }
+
+    void Renderer::render(const Window & window) const {
+        for(auto & group : this->_groups) {
+            group->draw(window, this->_view);
+        }
+    }
+}
\ No newline at end of file
diff --git a/source/engine/graphics/front/Renderer.hpp b/source/engine/graphics/front/Renderer.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..517585960e964a001f29919925105112364ed86f
--- /dev/null
+++ b/source/engine/graphics/front/Renderer.hpp
@@ -0,0 +1,26 @@
+#pragma once
+
+#include <set>
+#include <any>
+
+#include <engine/graphics/utility/reference_sorter.hpp>
+#include <engine/graphics/back/cameras/View.hpp>
+#include <engine/graphics/front/group/DrawGroup.hpp> 
+
+namespace megu {
+    class Renderer {
+        public:
+            Renderer() = delete;
+            Renderer(float, float);
+           ~Renderer() = default;
+
+            void add(DrawGroup & group);
+            
+            virtual void render(const Window &) const;
+
+        private:
+            std::set<DrawGroup *> _groups;
+            View _view;
+
+    };
+}
\ No newline at end of file
diff --git a/source/engine/graphics/front/group/ImageGroup.cpp b/source/engine/graphics/front/group/ImageGroup.cpp
index d40ae5f39b8bd114b8f0b6b872ce4ccc8abb681f..0ecd104b0cc91354fe1247600d41adf13b251880 100644
--- a/source/engine/graphics/front/group/ImageGroup.cpp
+++ b/source/engine/graphics/front/group/ImageGroup.cpp
@@ -6,8 +6,8 @@ namespace megu {
     ImageGroup::ImageGroup() 
     : _vbo(this->_vao, Quads::Layout(), 400) {
         {
-            Source vert("assets/shaders/Image-Instanced.vert", Source::Categorie::VERTEX);
-            Source frag("assets/shaders/Image.frag", Source::Categorie::FRAGMENT);
+            Source vert("assets/shaders/Image-Instanced-Fat.vert", Source::Categorie::VERTEX);
+            Source frag("assets/shaders/Texture-Fat.frag", Source::Categorie::FRAGMENT);
 
             this->_program << vert;
             this->_program << frag;
@@ -36,21 +36,51 @@ namespace megu {
         this->_vao.bind();
         this->_program.use();
 
-        std::map<std::reference_wrapper<const Texture>, std::vector<glm::mat4>, std::greater<megu::Texture>> data;
-        
+        std::vector<std::reference_wrapper<const Texture>> textures;
+
+        std::vector<glm::mat4> uModels;
+        std::vector<GLint> uTextures;
+
         for(auto & image : this->_images) {
-            data[image.get().texture()].push_back(image.get().transformation().model());
+            
+            std::vector<std::reference_wrapper<const Texture>>::iterator it = std::find(textures.begin(), textures.end(), image.get().texture());
+            if(it != textures.end()) {
+                uModels.push_back(image.get().transformation().model());
+                uTextures.push_back(static_cast<GLint>(it - textures.begin()));
+            }
+            else {
+                if(textures.size() >= 8 || uModels.size() >= 124) {
+                    this->_program.setUniform("uProj", camera.projection());
+                    this->_program.setUniform("uView", camera.view());
+                    this->_program.setUniform("uSampler", std::vector<GLint>({0, 1, 2, 3, 4, 5, 6, 7}));
+                    this->_program.setUniform("uModel", uModels);
+                    this->_program.setUniform("uTextures", uTextures);
+
+                    glDrawArraysInstanced(Quads::Primitive(), 0, static_cast<GLsizei>(this->_vbo.size()), static_cast<GLsizei>(uModels.size()));
+
+                    textures.clear();
+                    uModels.clear();
+                    uTextures.clear();
+                }
+                
+                textures.push_back(image.get().texture());  
+                image.get().texture().bind(static_cast<GLint>(textures.size()-1));
+                uTextures.push_back(static_cast<GLint>(textures.size()-1)); 
+                uModels.push_back(image.get().transformation().model());
+            }
         }
 
-        for(auto &[texture, models] : data) {
-            texture.get().bind(0);
+        //std::cout << "---------------" << std::endl;
 
+        if(!textures.empty()) {
             this->_program.setUniform("uProj", camera.projection());
             this->_program.setUniform("uView", camera.view());
-            this->_program.setUniform("uSampler", 0);
-            this->_program.setUniform("uModel", models);
+            
+            this->_program.setUniform("uSampler", std::vector<GLint>({0, 1, 2, 3, 4, 5, 6, 7}));
+            this->_program.setUniform("uModel", uModels);
+            this->_program.setUniform("uTextures", uTextures);
 
-            glDrawArraysInstanced(Quads::Primitive(), 0, static_cast<GLsizei>(this->_vbo.size()), static_cast<GLsizei>(models.size()));
-        }    
+            glDrawArraysInstanced(Quads::Primitive(), 0, static_cast<GLsizei>(this->_vbo.size()), static_cast<GLsizei>(uModels.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 ed674ee1b0c496826ba2da7734a4eb16474ac16e..fbdbbd73e11c5633ba37076492bc7cc30b433c06 100644
--- a/source/engine/graphics/front/group/ImageGroup.hpp
+++ b/source/engine/graphics/front/group/ImageGroup.hpp
@@ -1,13 +1,14 @@
 #pragma once
 
 #include "DrawGroup.hpp"
-#include "reference_sorter.hpp"
-#include "isometric_sorter.hpp"
+
 
 #include <map>
 #include <list>
 #include <set>
 
+#include <engine/graphics/utility/isometric_sorter.hpp>
+
 #include <engine/graphics/back/buffers/VertexArray.hpp>
 #include <engine/graphics/back/buffers/VerticeBuffer.hpp>
 #include <engine/graphics/back/shaders/Program.hpp>
diff --git a/source/engine/graphics/front/group/isometric_sorter.cpp b/source/engine/graphics/utility/isometric_sorter.cpp
similarity index 100%
rename from source/engine/graphics/front/group/isometric_sorter.cpp
rename to source/engine/graphics/utility/isometric_sorter.cpp
diff --git a/source/engine/graphics/front/group/isometric_sorter.hpp b/source/engine/graphics/utility/isometric_sorter.hpp
similarity index 100%
rename from source/engine/graphics/front/group/isometric_sorter.hpp
rename to source/engine/graphics/utility/isometric_sorter.hpp
diff --git a/source/engine/graphics/front/group/reference_sorter.hpp b/source/engine/graphics/utility/reference_sorter.hpp
similarity index 86%
rename from source/engine/graphics/front/group/reference_sorter.hpp
rename to source/engine/graphics/utility/reference_sorter.hpp
index df5a8eab1f5dc1da160646482820fff6ecd467cb..54353b6e9beb6d079c5f7eb16f9384937c884298 100644
--- a/source/engine/graphics/front/group/reference_sorter.hpp
+++ b/source/engine/graphics/utility/reference_sorter.hpp
@@ -9,6 +9,7 @@ namespace megu {
             
             friend bool operator<(const T &, const T &);
             bool operator()(const T &, const T &) const;
+            bool operator()(const T *, const T *) const;
     };
 }
 
diff --git a/source/engine/graphics/front/group/reference_sorter.tpp b/source/engine/graphics/utility/reference_sorter.tpp
similarity index 68%
rename from source/engine/graphics/front/group/reference_sorter.tpp
rename to source/engine/graphics/utility/reference_sorter.tpp
index 320ee9f694d62abbc1cff1625298176fbce13595..c1226ad6e56d719f5592ee07ef9d18b352635a67 100644
--- a/source/engine/graphics/front/group/reference_sorter.tpp
+++ b/source/engine/graphics/utility/reference_sorter.tpp
@@ -10,4 +10,9 @@ namespace megu {
     bool reference_sorter<T>::operator()(const T & obj_1, const T & obj_2) const {
         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/main.cpp b/source/main.cpp
index ecd068c0726151c576b2802c2dc6caa12c514ac5..68133f00f0619342fc77e085a13fde9b59b3c920 100644
--- a/source/main.cpp
+++ b/source/main.cpp
@@ -7,13 +7,15 @@
 #include <imgui_impl_glfw.h>
 #include <imgui_impl_opengl3.h>
 
-#define WINDOW_WIDTH  1200
-#define WINDOW_HEIGHT 720
+#define WINDOW_WIDTH  640
+#define WINDOW_HEIGHT 640
 
 #include <engine/io/Window.hpp>
 #include <engine/graphics/back/cameras/View.hpp>
 #include <engine/graphics/front/object/Image.hpp>
 #include <engine/graphics/front/group/ImageGroup.hpp>
+#include <engine/graphics/front/Renderer.hpp>
+#include <engine/graphics/front/Engine.hpp>
 #include <engine/graphics/errors.hpp>
 
 #define NORMALIZE(X) X/255.f
@@ -39,10 +41,6 @@ int main(int argc, const char * argv[]) {
 
         std::cout << "Window Inited" << std::endl;
 
-        //? Camera
-        megu::View view(0, 0, 320, 240);
-        std::cout << "View Initied" << std::endl;
-
         //? Group
         megu::ImageGroup group;
 
@@ -50,16 +48,16 @@ int main(int argc, const char * argv[]) {
 
         //? Image
         std::vector<int> map = {
-            0, 0, 0, 0, 1, 2, 3, 0, 0, 3,
-            0, 0, 0, 2, 0, 3, 0, 0, 3, 1,
-            0, 0, 1, 3, 3, 0, 0, 0, 2, 2,
-            0, 2, 1, 0, 0, 1, 0, 2, 0, 0,
-            2, 1, 3, 1, 0, 0, 3, 0, 1, 0,
-            1, 3, 0, 2, 3, 0, 0, 1, 0, 0,
-            0, 1, 0, 0, 1, 2, 3, 1, 0, 0,
-            0, 0, 0, 0, 2, 0, 1, 0, 1, 0,
-            0, 0, 0, 2, 0, 0, 0, 1, 3, 0,
-            0, 0, 3, 1, 2, 0, 0, 0, 2, 3,
+            1, 1, 1, 1, 1, 1, 1, 1, 2, 2,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 2,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 2,
+            1, 1, 1, 1, 1, 1, 1, 1, 2, 2,
         };
 
         size_t x = 0;
@@ -67,8 +65,11 @@ int main(int argc, const char * argv[]) {
 
         std::vector<std::unique_ptr<megu::Image>> images;
 
-        megu::Texture texture;
-        texture.store(megu::TextureBuffer("assets/textures/Cube_Grass.png"));
+        megu::Texture texture_1;
+        texture_1.store(megu::TextureBuffer("assets/textures/Cube_Blue.png"));
+
+        megu::Texture texture_2;
+        texture_2.store(megu::TextureBuffer("assets/textures/Cube_Red.png"));
 
         for(auto id : map) {
             if(x == 10) {
@@ -76,16 +77,20 @@ int main(int argc, const char * argv[]) {
                 ++y;
             }
 
-            images.push_back(std::make_unique<megu::Image>(texture));
-            glm::vec2 pos = to_screen_coordinate({x, y}, 32.f, 32.f);
 
-            images.back()->setPosition(pos.x + 160, pos.y);
+            if(id != 0) {
+                images.push_back(std::make_unique<megu::Image>(id == 1 ? texture_1 : texture_2));
+                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);
+            i.get()->setSize(32.f, 32.f);
         }
 
         std::cout << "Image Inited" << std::endl;
@@ -95,88 +100,19 @@ int main(int argc, const char * argv[]) {
         ImGui_ImplOpenGL3_Init();
         ImGui_ImplGlfw_InitForOpenGL(window.ptr(), true);
 
-        //? Render Loop
-        glClearColor(1.f, 1.f, 1.f, 1.f);
-
-        double lastTime = glfwGetTime();
-        int nbFrames = 0;
+        //? Engines
+        megu::GraphicEngine engine(window, 320, 320);
+        engine.setClearColor(0.f, 0.f, 0.f);
 
+        //? Render Loop
         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;
-            }
+        engine.tmp_getRenderer().add(group);
 
-            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+        while(window.isOpen()) {
             window.pollEvents();
-            group.draw(window, view);
-
-            /*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();
+            engine.step();
         }
         std::cout << "Render Loop End !" << std::endl;
     }