diff --git a/.gitignore b/.gitignore
index e2a14a608ced625ac1a1bcd11c3e85b904f63ba7..6013f5a905d5f985f97d9fd4f73d133d4b43e34d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -16,4 +16,6 @@ build/*
 include/*
 library/*
 vcpkg_installed/*
-old/*
\ No newline at end of file
+old/*
+
+assets/textures/*
\ No newline at end of file
diff --git a/source/engine/graphics/back.hpp b/source/engine/graphics/back.hpp
index d04d031424ab0d33ac0f044542d0372b57cc6f4f..d56b9d070e92a6b2d833a34d51d7997b79128606 100644
--- a/source/engine/graphics/back.hpp
+++ b/source/engine/graphics/back.hpp
@@ -10,7 +10,6 @@
 #include "back/cameras/View.hpp"
 #include "back/cameras/Walkaround.hpp"
 
-#include "back/geometry/Geometry.hpp"
 #include "back/geometry/Transform.hpp"
 
 #include "back/shaders/Program.hpp"
diff --git a/source/engine/graphics/back/buffers/Buffer.hpp b/source/engine/graphics/back/buffers/Buffer.hpp
index f2577d116a20c3d54c5901ca35e152d9ba92fda3..0aba4b3c20a45c7a40b14fde49ece037f7d626e5 100644
--- a/source/engine/graphics/back/buffers/Buffer.hpp
+++ b/source/engine/graphics/back/buffers/Buffer.hpp
@@ -7,6 +7,6 @@ namespace megu {
         public:
             virtual void bind() const = 0;
             virtual void unbind() const = 0;
-            virtual GLuint identifier() const = 0;
+            virtual GLuint identifier() const noexcept = 0;
     };
 }
\ No newline at end of file
diff --git a/source/engine/graphics/back/buffers/DynamicBuffer-impl.cpp b/source/engine/graphics/back/buffers/DynamicBuffer-impl.cpp
deleted file mode 100644
index 53e0cf00fa09463e50c15dca75049f22b450219b..0000000000000000000000000000000000000000
--- a/source/engine/graphics/back/buffers/DynamicBuffer-impl.cpp
+++ /dev/null
@@ -1,6 +0,0 @@
-#include "DynamicBuffer.cpp"
-
-namespace megu {
-    template class DynamicBuffer<float, GL_ARRAY_BUFFER>;
-    template class DynamicBuffer<unsigned int, GL_ELEMENT_ARRAY_BUFFER>;
-}
\ No newline at end of file
diff --git a/source/engine/graphics/back/buffers/DynamicBuffer.hpp b/source/engine/graphics/back/buffers/DynamicBuffer.hpp
index c09a61006e90497bec4572b4545dfa0a97d4bc23..1cf3573b719ae75776f8dda6fd7f4b2818f00b0b 100644
--- a/source/engine/graphics/back/buffers/DynamicBuffer.hpp
+++ b/source/engine/graphics/back/buffers/DynamicBuffer.hpp
@@ -2,18 +2,13 @@
 
 #include "Buffer.hpp"
 
-#include <stdint.h>
 #include <vector>
-#include <list>
 #include <functional>
+#include <stdint.h>
 
 namespace megu {
     template <typename T, uint32_t Y>
     class DynamicBuffer : public Buffer {
-        private:
-            size_t _max_size;
-            size_t _size;
-
         public:
             DynamicBuffer() = delete;
             DynamicBuffer(size_t, size_t=0);
@@ -63,5 +58,11 @@ namespace megu {
             void operator()(std::function<void(void *)>);
 
             void operator<<(const DynamicBuffer<T,Y> &);
+
+        private:
+            size_t _max_size;
+            size_t _size;
     };
-}
\ No newline at end of file
+}
+
+#include "DynamicBuffer.tpp"
\ No newline at end of file
diff --git a/source/engine/graphics/back/buffers/DynamicBuffer.cpp b/source/engine/graphics/back/buffers/DynamicBuffer.tpp
similarity index 99%
rename from source/engine/graphics/back/buffers/DynamicBuffer.cpp
rename to source/engine/graphics/back/buffers/DynamicBuffer.tpp
index e9da1b1c1711f4e37c6772fe947a926e2e5baa4c..80c3a40c5e98b8af5beaa46645fd8a7dd040741e 100644
--- a/source/engine/graphics/back/buffers/DynamicBuffer.cpp
+++ b/source/engine/graphics/back/buffers/DynamicBuffer.tpp
@@ -9,9 +9,7 @@
 namespace megu {
     template <typename T, uint32_t Y>
     DynamicBuffer<T,Y>::DynamicBuffer(size_t size, size_t array_size)
-    : _max_size(size),_size(array_size) {
-
-    }
+    : _max_size(size), _size(array_size) {}
 
     template <typename T, uint32_t Y>
     size_t DynamicBuffer<T,Y>::size() const {
diff --git a/source/engine/graphics/back/buffers/EditMode.hpp b/source/engine/graphics/back/buffers/EditMode.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..fc7100a464a50346668ca31bc381e4829bfebf68
--- /dev/null
+++ b/source/engine/graphics/back/buffers/EditMode.hpp
@@ -0,0 +1,11 @@
+#pragma once
+
+#include <GL/glew.h>
+#include <stdint.h>
+
+namespace megu {
+    enum EditMode {
+        DYNAMIC = GL_DYNAMIC_DRAW,
+        STATIC  = GL_STATIC_DRAW
+    };
+}
\ No newline at end of file
diff --git a/source/engine/graphics/back/buffers/ElementBuffer.cpp b/source/engine/graphics/back/buffers/ElementBuffer.cpp
index b316b7790fd80d03d143ce13807c66b5863a684e..07b4e4ec5e2a6bb4ce30cd61be99c24cd7d2b39f 100644
--- a/source/engine/graphics/back/buffers/ElementBuffer.cpp
+++ b/source/engine/graphics/back/buffers/ElementBuffer.cpp
@@ -1,13 +1,13 @@
 #include "ElementBuffer.hpp"
 
 namespace megu {
-    ElementBuffer::ElementBuffer(const VertexArray & vao,size_t size,uint32_t mode)
-    : DynamicBuffer(size),_vao(&vao),_id(0),_mode(mode) {
+    ElementBuffer::ElementBuffer(const VertexArray & vao, size_t size, EditMode mode)
+    : DynamicBuffer(size), _vao(&vao), _id(0), _mode(mode) {
         this->generate({});
     }
 
-    ElementBuffer::ElementBuffer(const VertexArray & vao,const std::vector<unsigned int> & indices,uint32_t mode)
-    : DynamicBuffer(indices.size(),indices.size()),_vao(&vao),_id(0),_mode(mode) {
+    ElementBuffer::ElementBuffer(const VertexArray & vao, const std::vector<unsigned int> & indices, EditMode mode)
+    : DynamicBuffer(indices.size(), indices.size()), _vao(&vao), _id(0), _mode(mode) {
         this->generate(indices);
     }
 
@@ -16,10 +16,6 @@ namespace megu {
         glDeleteBuffers(1,&this->_id);
     }
 
-    GLuint ElementBuffer::identifier() const {
-        return this->_id;
-    } 
-
     void ElementBuffer::bind() const {
         if(this->_id != 0) {
             this->_vao->bind();
@@ -46,7 +42,7 @@ namespace megu {
 
         glGenBuffers(1,&this->_id);
         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,this->_id);
-        glBufferData(GL_ELEMENT_ARRAY_BUFFER,this->max_size()*sizeof(unsigned int),vertices.size() == 0 ? NULL : std::vector<unsigned int>(vertices).data(),this->_mode);
+        glBufferData(GL_ELEMENT_ARRAY_BUFFER,this->max_size()*sizeof(unsigned int),vertices.size() == 0 ? NULL : vertices.data(), this->_mode);
 
     }
 
diff --git a/source/engine/graphics/back/buffers/ElementBuffer.hpp b/source/engine/graphics/back/buffers/ElementBuffer.hpp
index 43b693553ea4c20443c41c8d62835102a3708df4..cff85434716f41eddbe850b66bf7eb0b4b2f3252 100644
--- a/source/engine/graphics/back/buffers/ElementBuffer.hpp
+++ b/source/engine/graphics/back/buffers/ElementBuffer.hpp
@@ -1,25 +1,21 @@
 #pragma once
 
-#include <compare>
-
 #include "DynamicBuffer.hpp"
+
+#include <compare>
 #include "VertexArray.hpp"
+#include "EditMode.hpp"
 
 namespace megu {
     class ElementBuffer : public DynamicBuffer<unsigned int, GL_ELEMENT_ARRAY_BUFFER> {
-        private:
-            const VertexArray * _vao;
-            GLuint _id;
-            GLuint _mode;
-
         public:
             ElementBuffer() = delete;
-            ElementBuffer(const VertexArray & vao,size_t size=1024,uint32_t mode=GL_DYNAMIC_DRAW);
-            ElementBuffer(const VertexArray & vao,const std::vector<unsigned int> & indice,uint32_t mode=GL_DYNAMIC_DRAW);
+            ElementBuffer(const VertexArray & vao, size_t size, EditMode mode = EditMode::DYNAMIC);
+            ElementBuffer(const VertexArray & vao, const std::vector<unsigned int> & indice, EditMode mode = EditMode::DYNAMIC);
             ElementBuffer(const ElementBuffer &) = delete;
    virtual ~ElementBuffer();
 
-            virtual inline GLuint identifier() const;
+            virtual inline GLuint identifier() const noexcept {return this->_id;}
 
             virtual void bind() const;
             virtual void unbind() const;
@@ -38,5 +34,10 @@ namespace megu {
 
             friend ElementBuffer & operator<<(ElementBuffer &, const std::initializer_list<unsigned int> &);
             friend ElementBuffer & operator<<(ElementBuffer &, const std::vector<unsigned int> &);
+
+        private:
+            const VertexArray * _vao;
+            GLuint _id;
+            GLuint _mode;
     };
 }
\ No newline at end of file
diff --git a/source/engine/graphics/back/buffers/FrameBuffer.cpp b/source/engine/graphics/back/buffers/FrameBuffer.cpp
index 6be8653c4e36b8c32d6e43a21f1cf7639b72e1b6..72a54b983eab238ac786f7020aa7145c82f0404e 100644
--- a/source/engine/graphics/back/buffers/FrameBuffer.cpp
+++ b/source/engine/graphics/back/buffers/FrameBuffer.cpp
@@ -1,7 +1,6 @@
 #include "FrameBuffer.hpp"
 
-#include <iostream>
-#include "../../errors/OpenGL_Error.hpp"
+#include <stdexcept>
 
 namespace megu {
     FrameBuffer::FrameBuffer(GLuint width, GLuint height) 
@@ -19,11 +18,12 @@ namespace megu {
         glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height);
         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, this->_rbo_id);
 
+        glBindFramebuffer(GL_FRAMEBUFFER, 0);
+
         if(!this->usable()) {
-            std::cerr << "Incomplete FrameBuffer." << std::endl;
+            throw std::runtime_error("Incomplete FrameBuffer.");
         }
 
-        glBindFramebuffer(GL_FRAMEBUFFER, 0);
     }
 
     FrameBuffer::~FrameBuffer() {
diff --git a/source/engine/graphics/back/buffers/FrameBuffer.hpp b/source/engine/graphics/back/buffers/FrameBuffer.hpp
index 782ef844720d653a3dc7cec20c4c1e6da95fee3b..7620b06c8ef5aec69bc8a2cffe011c50139332f4 100644
--- a/source/engine/graphics/back/buffers/FrameBuffer.hpp
+++ b/source/engine/graphics/back/buffers/FrameBuffer.hpp
@@ -5,11 +5,6 @@
 
 namespace megu {
     class FrameBuffer : public Buffer {
-        private:
-            GLuint _id;
-            GLuint _rbo_id;
-            Texture _texture;
-
         public:
             FrameBuffer() = delete;
             FrameBuffer(GLuint width, GLuint height);
@@ -18,7 +13,7 @@ namespace megu {
             inline const Texture & texture() const {return this->_texture;}
             GLuint rbo_identifier() const {return this->_rbo_id;}
 
-            inline virtual GLuint identifier() const {return this->_id;}
+            inline virtual GLuint identifier() const noexcept {return this->_id;}
 
             bool usable() const;
 
@@ -26,5 +21,10 @@ namespace megu {
             virtual void unbind() const;
 
             static void BindDefaultFrameBuffer();
+
+        private:
+            GLuint _id;
+            GLuint _rbo_id;
+            Texture _texture;
     }; 
 }
\ No newline at end of file
diff --git a/source/engine/graphics/back/buffers/Layout.hpp b/source/engine/graphics/back/buffers/Layout.hpp
index faab8e0d01d0b0519c3aee305dea954a26bbd7e7..994e24cb9b0401a22aec5af426bbd9fee2e37ca4 100644
--- a/source/engine/graphics/back/buffers/Layout.hpp
+++ b/source/engine/graphics/back/buffers/Layout.hpp
@@ -2,18 +2,21 @@
 
 #include <list>
 #include <numeric>
-#include <stdint.h>
 
 namespace megu {
-    using Layout = std::list<uint8_t>;
-    using Layout_Initializer = std::initializer_list<uint8_t>;
+    namespace layout {
+        enum Value;
+    }
+
+    using Layout = std::list<layout::Value>;
+    using Layout_Initializer = std::initializer_list<layout::Value>;
 
     namespace layout {
         inline size_t weight(const Layout & layout) {
             return std::accumulate(layout.begin(), layout.end(), 0);
         }
 
-        enum Value : unsigned char {
+        enum Value : uint8_t {
             POSITION            = 3,
             FLAT                = 2,
             COLOR               = 3,
diff --git a/source/engine/graphics/back/buffers/UniformeBuffer.hpp b/source/engine/graphics/back/buffers/UniformeBuffer.hpp
index e1474ae3aaa32144894645b4e3de2efb4f95c1d3..fafdb5f4b0473e62e3d8eb64f174cebfc44995c7 100644
--- a/source/engine/graphics/back/buffers/UniformeBuffer.hpp
+++ b/source/engine/graphics/back/buffers/UniformeBuffer.hpp
@@ -11,11 +11,6 @@
 namespace megu {
     template <class T>
     class UniformeBuffer : public Buffer {
-        private:
-            T * _data;
-            GLuint _id;
-            std::map<const Program *, GLuint> _programs;
-
         public:
             UniformeBuffer(T * = nullptr);
    virtual ~UniformeBuffer();
@@ -26,10 +21,16 @@ namespace megu {
             void setData(T *);
             void attach(const std::string &, const Program &);
 
-            inline virtual GLuint identifier() const {return this->_id;}
+            inline virtual GLuint identifier() const noexcept {return this->_id;}
 
             virtual void bind() const;
             virtual void unbind() const;
+    
+        private:
+            T * _data;
+            GLuint _id;
+            std::map<const Program *, GLuint> _programs;
+
     }; 
 }
 
diff --git a/source/engine/graphics/back/buffers/VertexArray.hpp b/source/engine/graphics/back/buffers/VertexArray.hpp
index 200a3eb6cf5eb96ab77bfcce74201ba415054c59..8e5ee67f1a4d9d43649695760f3c778270db0830 100644
--- a/source/engine/graphics/back/buffers/VertexArray.hpp
+++ b/source/engine/graphics/back/buffers/VertexArray.hpp
@@ -7,15 +7,12 @@
 
 namespace megu {
     class VertexArray : public Buffer {
-        private:
-            GLuint _vao;
-
         public:
             VertexArray(bool binded=false);
             VertexArray(const VertexArray &) = delete;
    virtual ~VertexArray();
 
-            virtual GLuint identifier() const {return this->_vao;}
+            virtual GLuint identifier() const noexcept {return this->_vao;}
 
             virtual void bind() const;
             virtual void unbind() const;
@@ -29,5 +26,8 @@ namespace megu {
             bool operator>(const VertexArray &) const;
 
             std::strong_ordering operator<=>(const VertexArray &) const;
+
+        private:
+            GLuint _vao;
     };
 }
\ No newline at end of file
diff --git a/source/engine/graphics/back/buffers/VerticeBuffer.cpp b/source/engine/graphics/back/buffers/VerticeBuffer.cpp
index 1a883d5ae2ef0f4087ad422903ae3686db7bb5cd..98e2c4d06c568802d40f8df5cc432d4b6980a2d2 100644
--- a/source/engine/graphics/back/buffers/VerticeBuffer.cpp
+++ b/source/engine/graphics/back/buffers/VerticeBuffer.cpp
@@ -3,12 +3,12 @@
 #include <list>
 
 namespace megu {
-    VerticeBuffer::VerticeBuffer(const VertexArray & vao,const Layout_Initializer & attributes,size_t size,uint32_t mode)
+    VerticeBuffer::VerticeBuffer(const VertexArray & vao, const Layout & attributes, size_t size, EditMode mode)
     : DynamicBuffer(size), _vao(&vao), _id(0), _mode(mode), _layout(attributes) {
         this->generate({});
     } 
 
-    VerticeBuffer::VerticeBuffer(const VertexArray & vao,const std::vector<float> & vertices, const Layout & attributes,uint32_t mode)
+    VerticeBuffer::VerticeBuffer(const VertexArray & vao, const Layout & attributes, const std::vector<float> & vertices, EditMode mode)
     : DynamicBuffer(vertices.size(), vertices.size()), _vao(&vao), _id(0), _mode(mode), _layout(attributes) {
         this->generate(vertices);
     }
@@ -18,10 +18,6 @@ namespace megu {
         glDeleteBuffers(1, &this->_id);
     }
 
-    GLuint VerticeBuffer::identifier() const {
-        return this->_id;
-    }  
-
     size_t VerticeBuffer::weight() const {
         return layout::weight(this->_layout);
     }
diff --git a/source/engine/graphics/back/buffers/VerticeBuffer.hpp b/source/engine/graphics/back/buffers/VerticeBuffer.hpp
index 215341125ea34c775ff394ffdd62a2247f3a6789..7c440037ff2514d44bebd2ed54e89f7e87c8056f 100644
--- a/source/engine/graphics/back/buffers/VerticeBuffer.hpp
+++ b/source/engine/graphics/back/buffers/VerticeBuffer.hpp
@@ -6,20 +6,14 @@
 
 #include "VertexArray.hpp"
 #include "Layout.hpp"
+#include "EditMode.hpp"
 
 namespace megu {
     class VerticeBuffer : public DynamicBuffer<float, GL_ARRAY_BUFFER> {
-        private:
-            const VertexArray * _vao;
-            GLuint _id;
-            GLuint _mode;
-            
-            Layout _layout;
-
         public:
             VerticeBuffer() = delete;
-            VerticeBuffer(const VertexArray & vao, const Layout_Initializer &, size_t=2048, uint32_t=GL_DYNAMIC_DRAW);
-            VerticeBuffer(const VertexArray & vao, const std::vector<float> &, const Layout &, uint32_t=GL_DYNAMIC_DRAW);
+            VerticeBuffer(const VertexArray & vao, const Layout &, size_t, EditMode=EditMode::DYNAMIC);
+            VerticeBuffer(const VertexArray & vao, const Layout &, const std::vector<float> &, EditMode=EditMode::DYNAMIC);
             VerticeBuffer(const VerticeBuffer &) = delete;
    virtual ~VerticeBuffer();
 
@@ -28,7 +22,7 @@ namespace megu {
             size_t weight() const;
             size_t vertices() const;
 
-            virtual GLuint identifier() const;
+            virtual GLuint identifier() const noexcept {return this->_id;}
            
             virtual void bind() const;
             virtual void unbind() const;
@@ -49,6 +43,12 @@ namespace megu {
 
             friend VerticeBuffer & operator<<(VerticeBuffer &, const std::initializer_list<float> &);
             friend VerticeBuffer & operator<<(VerticeBuffer &, const std::vector<float> &);
+
+        private:
+            const VertexArray * _vao;
+            GLuint _id;
+            EditMode _mode;
+            Layout _layout;
     };
 
     
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
new file mode 100644
index 0000000000000000000000000000000000000000..c80bef27800212ddca6a97dba9b6f6c8c03c3fb5
--- /dev/null
+++ b/source/engine/graphics/back/geometry/Geometry.hpp
@@ -0,0 +1,64 @@
+#pragma once
+
+#include <stdint.h>
+#include <vector>
+#include <array>
+#include <thread>
+
+#include "Counter.hpp"
+#include "../buffers/Layout.hpp"
+
+namespace megu {
+    using Primitive = uint32_t;
+
+    using tVertices = std::vector<float>;
+    using tIndices = std::vector<unsigned int>;
+
+    class LayoutStorage {
+        public:
+            LayoutStorage() = delete;
+            LayoutStorage(const Layout & layout) : _layout(layout) {}
+           ~LayoutStorage() = default;
+
+            inline const Layout & layout() const {return this->_layout;}
+
+        private:
+            const Layout _layout;
+    };   
+    
+    template <Primitive P>
+    class Geometry : public LayoutStorage {
+        public:
+            Geometry() = delete;
+            Geometry(const Layout & layout) : LayoutStorage(layout) {}
+           ~Geometry() = default;
+
+            inline static Primitive Primitive() {return P;}
+
+            virtual void retrieve(tVertices &, tIndices &) const = 0;
+    };
+
+    template <class T, Primitive P>
+    class Static_Geometry : public Geometry<P> {
+        public:
+            Static_Geometry() = delete;
+            Static_Geometry(const Layout & layout) : Geometry<P>(layout) {}
+           ~Static_Geometry() = default;
+
+            virtual void retrieve(tVertices & vertices, tIndices & indices) const final {
+                std::thread tVertices([&vertices]() {
+                    vertices = Static_Geometry<T, P>::Vertices();
+                });
+
+                std::thread tIndices([&indices]() {
+                    indices = Static_Geometry<T, P>::Indices();
+                });
+
+                tVertices.join();
+                tIndices.join();
+            }
+
+            inline static tVertices Vertices() {return T::Vertices();}
+            inline static tIndices Indices() {return T::Indices();}
+    };
+}
\ No newline at end of file
diff --git a/source/engine/graphics/back/geometry/Transform.cpp b/source/engine/graphics/back/geometry/Transform.cpp
index 1b931b5b59e2e6b651afe8743004f75f7122bd3b..b54248611b1b348844f0b16e45d8b107caed3596 100644
--- a/source/engine/graphics/back/geometry/Transform.cpp
+++ b/source/engine/graphics/back/geometry/Transform.cpp
@@ -6,28 +6,52 @@
 
 namespace megu {
     Transform::Transform(const glm::mat4x4 & matrix)
-    : _model(matrix), _position(0.f, 0.f, 0.f), _rotation(0.f, 0.f, 0.f), _scaling(1.f, 1.f, 1.f), _origine(0.f, 0.f, 0.f), _updated(true) {}
-
-    Transform::Transform(const glm::vec3 & position, float angle, uint8_t axis, const glm::vec3 & scaling)
-    : _model(1.0f), _position(position), _rotation(0, 0, 0), _scaling(scaling), _updated(true) {
-        this->setRotation(angle, axis);
-    }
+    : _model(matrix), 
+      _position(0.f), 
+      _rotation(0.f), 
+      _scaling(1.f), 
+      _origine(0.f), 
+      _updated(true) {}
+
+    Transform::Transform(const glm::vec3 & position, const glm::vec3 & origine)
+    : _model(1.0f), 
+      _position(position), 
+      _rotation(0.f), 
+      _scaling(1.f), 
+      _origine(origine), 
+      _updated(false) {}
+
+    Transform::Transform(const Transform & src)
+    : _model(src._model), 
+      _position(src._position), 
+      _rotation(src._rotation), 
+      _scaling(src._scaling), 
+      _origine(src._origine), 
+      _updated(false) {}
+
+    Transform::Transform(const Transform && src)
+    : _model(std::move(src._model)), 
+      _position(std::move(src._position)), 
+      _rotation(std::move(src._rotation)), 
+      _scaling(std::move(src._scaling)), 
+      _origine(std::move(src._origine)), 
+      _updated(false) {}
 
     void Transform::setPosition(const glm::vec3 & position) {
         this->_position = position;
         this->_updated = true;
     }
 
-    void Transform::setRotation(float angle, uint8_t axis) {
-        if((axis & Axis::X) != 0) {
+    void Transform::setRotation(float angle, Axis axis) {
+        if((Axis::X & axis) != 0) {
             this->_rotation.x = angle; 
         }
 
-        if((axis & Axis::Y) != 0) {
+        if((Axis::Y & axis) != 0) {
             this->_rotation.y = angle; 
         }
 
-        if((axis & Axis::Z) != 0) {
+        if((Axis::Z & axis) != 0) {
             this->_rotation.z = angle; 
         }
 
@@ -44,16 +68,16 @@ namespace megu {
         this->_updated = true;
     }
 
-    void Transform::rotate(float angle, uint8_t axis) {
-        if((axis & Axis::X) != 0) {
+    void Transform::rotate(float angle, Axis axis) {
+        if((Axis::X & axis) != 0) {
             this->_rotation.x += angle; 
         }
 
-        if((axis & Axis::Y) != 0) {
+        if((Axis::Y & axis) != 0) {
             this->_rotation.y += angle; 
         }
 
-        if((axis & Axis::Z) != 0) {
+        if((Axis::Z & axis) != 0) {
             this->_rotation.z += angle; 
         }
 
diff --git a/source/engine/graphics/back/geometry/Transform.hpp b/source/engine/graphics/back/geometry/Transform.hpp
index 0f1ec2be7da951ead7e9d3e0e95b2f8ec25abed4..899871c599fd1e83a26341e53a4e6b88eb2667da 100644
--- a/source/engine/graphics/back/geometry/Transform.hpp
+++ b/source/engine/graphics/back/geometry/Transform.hpp
@@ -3,67 +3,70 @@
 #include <glm/vec3.hpp>
 #include <glm/mat4x4.hpp>
 
-namespace megu {
-    class Transform {
-        private:
-            mutable glm::mat4 _model;
-            glm::vec3 _position;
-            glm::vec3 _rotation;
-            glm::vec3 _scaling;
-            glm::vec3 _origine;
-            mutable bool _updated;
+#include "Transformable.hpp"
 
+namespace megu {
+    class Transform : public Transformable {
         public:
-            enum Axis : unsigned char {
+            enum class Axis : uint8_t {
                 X = 1,
                 Y = 2, 
                 Z = 4
             };
 
+            inline friend uint8_t operator&(Axis a, Axis b) {return static_cast<uint8_t>(a) & static_cast<uint8_t>(b);}
+            inline friend uint8_t operator|(Axis a, Axis b) {return static_cast<uint8_t>(a) | static_cast<uint8_t>(b);}
+            inline friend uint8_t operator^(Axis a, Axis b) {return static_cast<uint8_t>(a) ^ static_cast<uint8_t>(b);}
+
             Transform(const glm::mat4 & = glm::mat4(1.f));
-            Transform(const glm::vec3 &, float, uint8_t, const glm::vec3 & = {1.f, 1.f, 1.f});
+            Transform(const glm::vec3 &, const glm::vec3 & = glm::vec3(0.f));
+            Transform(const Transform &);
+            Transform(const Transform &&);
+           ~Transform() = default;
 
             inline const glm::vec3 & position() const {return this->_position;}
+            inline const glm::vec3 & rotation() const {return this->_rotation;}
+            inline const glm::vec3 & scaling() const {return this->_scaling;}
+            inline const glm::vec3 & origine() const {return this->_origine;}
+
             inline glm::vec3 & position() {return this->_position;}
+            inline glm::vec3 & rotation() {return this->_rotation;}
+            inline glm::vec3 & scaling() {return this->_scaling;}
+            inline glm::vec3 & origine() {return this->_origine;}
 
             inline float x() const {return this->_position.x;}
             inline float y() const {return this->_position.y;}
             inline float z() const {return this->_position.z;}
 
-            inline const glm::vec3 & rotation() const {return this->_rotation;}
-            inline glm::vec3 & rotation() {return this->_rotation;}
-
             inline float pitch() const {return this->_rotation.x;}
             inline float yaw()   const {return this->_rotation.y;}
             inline float roll()  const {return this->_rotation.z;}
 
-            inline const glm::vec3 & scaling() const {return this->_scaling;}
-            inline glm::vec3 & scaling() {return this->_scaling;}
-
-            inline const glm::vec3 & origine() const {return this->_origine;}
-            inline glm::vec3 & origine() {return this->_origine;}
-
-            void setRotation(float, uint8_t);
-
             void setPosition(const glm::vec3 &);
-            inline void setPosition(float x, float y, float z = 0.0) {this->setPosition({x, y, z});}
-
+            void setRotation(float, Axis);
             void setScaling(const glm::vec3 &);
-            inline void setScaling(float x, float y, float z = 0.0) {this->setScaling({x, y, z});}
 
             inline void setMatrix(const glm::mat4 & matrix) {this->_model = matrix;}
+            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;}
 
-            void rotate(float, uint8_t);
-            
             void move(const glm::vec3 &);
-            inline void move(float x, float y, float z = 0.0f) {this->move({x, y, z});}
-
+            void rotate(float, Axis);
             void scale(const glm::vec3 &);
-            inline void scale(float x, float y, float z = 0.0f) {this->scale({x, y, z});}
+
+            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});}
             
             virtual const glm::mat4x4 & model() const;
 
-            inline void translate(const glm::vec3 & translation) {this->move(translation);}
+        private:
+            mutable glm::mat4 _model;
+            glm::vec3 _position;
+            glm::vec3 _rotation;
+            glm::vec3 _scaling;
+            glm::vec3 _origine;
+            mutable bool _updated;
     };
 }
\ No newline at end of file
diff --git a/source/engine/graphics/back/geometry/Transformable.hpp b/source/engine/graphics/back/geometry/Transformable.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..8855ccf992b9880eb091afb70ae1d637dc2cc603
--- /dev/null
+++ b/source/engine/graphics/back/geometry/Transformable.hpp
@@ -0,0 +1,10 @@
+#pragma once
+
+#include <glm/mat4x4.hpp>
+
+namespace megu {
+    class Transformable {
+        public: 
+            virtual const glm::mat4x4 & model() const = 0;
+    };
+}
\ No newline at end of file
diff --git a/source/engine/graphics/back/shaders/Program.cpp b/source/engine/graphics/back/shaders/Program.cpp
index aa7f73d2b881f7c21e7801207bb84f39022594ba..5a915e1aa7e6dc48613a2ce2f86105eb3d834ca1 100644
--- a/source/engine/graphics/back/shaders/Program.cpp
+++ b/source/engine/graphics/back/shaders/Program.cpp
@@ -1,6 +1,8 @@
 #include "Program.hpp"
 
-#include <GLM/gtc/type_ptr.hpp>
+#include <glm/gtc/type_ptr.hpp>
+#include <glm/mat4x4.hpp>
+
 #include "../../errors/Shader_Error.hpp"
 
 namespace megu {
@@ -64,6 +66,17 @@ namespace megu {
                 this->_usable = false;
                 glGetProgramInfoLog(this->_id, 512, NULL, infoLog);
                 throw error::shader_error(infoLog);
+            }   
+
+            GLint count;
+            glGetProgramiv(this->_id, GL_ACTIVE_UNIFORMS, &count);
+
+            for(size_t i = 0; i < count; ++i) {
+                GLint length, size;
+                GLenum type;
+                GLchar* name;
+                glGetActiveUniform(this->_id, static_cast<GLuint>(i), 32, &length, &size, &type, name);
+                this->_locations[name] = glGetUniformLocation(this->_id, name);
             }
         }
         else {
@@ -89,67 +102,67 @@ namespace megu {
     }
 
     void Program::setUniform(const std::string & name, GLint value) const {
-        glUniform1i(glGetUniformLocation(this->_id, name.c_str()), value);
+        glUniform1i(this->_locations.at(name), value);
     }
 
     void Program::setUniform(const std::string & name, GLuint value) const {
-        glUniform1ui(glGetUniformLocation(this->_id, name.c_str()), value);
+        glUniform1ui(this->_locations.at(name), value);
     }
 
     void Program::setUniform(const std::string & name, GLfloat value) const {
-        glUniform1f(glGetUniformLocation(this->_id, name.c_str()), value);
+        glUniform1f(this->_locations.at(name), value);
     }
 
     void Program::setUniform(const std::string & name, GLdouble value) const {
-        glUniform1d(glGetUniformLocation(this->_id, name.c_str()), value);
+        glUniform1d(this->_locations.at(name), value);
     }
 
     void Program::setUniform(const std::string & name, GLchar value) const {
-        this->setUniform(name,(GLint) value);
+        this->setUniform(name, static_cast<GLint>(value));
     }
 
     void Program::setUniform(const std::string & name, const glm::mat4 & value) const {
-        glUniformMatrix4fv(glGetUniformLocation(this->_id, name.c_str()), 1, GL_FALSE, &value[0][0]);
+        glUniformMatrix4fv(this->_locations.at(name), 1, GL_FALSE, &value[0][0]);
     }
 
     void Program::setUniform(const std::string & name, const glm::vec2 & value) const {
-        glUniform2f(glGetUniformLocation(this->_id, name.c_str()), value.x, value.y);
+        glUniform2f(this->_locations.at(name), value.x, value.y);
     }
 
     void Program::setUniform(const std::string & name, const glm::vec3 & value) const {
-        glUniform3f(glGetUniformLocation(this->_id, name.c_str()), value.x, value.y, value.z);
+        glUniform3f(this->_locations.at(name), value.x, value.y, value.z);
     }
 
     void Program::setUniform(const std::string & name, const glm::vec<3, uint32_t> & value) const {
-        glUniform3ui(glGetUniformLocation(this->_id, name.c_str()), value.x, value.y, value.z);
+        glUniform3ui(this->_locations.at(name), value.x, value.y, value.z);
     }
 
     void Program::setUniform(const std::string & name, const glm::vec<3, int32_t> & value) const {
-        glUniform3i(glGetUniformLocation(this->_id, name.c_str()), value.x, value.y, value.z);
+        glUniform3i(this->_locations.at(name), value.x, value.y, value.z);
     }
 
     void Program::setUniform(const std::string & name, const glm::vec4 & value) const {
-        glUniform4f(glGetUniformLocation(this->_id, name.c_str()), value.x, value.y, value.z, value.w);
+        glUniform4f(this->_locations.at(name), value.x, value.y, value.z, value.w);
     }
 
     void Program::setUniform(const std::string & name, const std::vector<GLint> & value) const {
-        glUniform1iv(glGetUniformLocation(this->_id, name.c_str()), static_cast<GLsizei>(value.size()), value.data());
+        glUniform1iv(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(glGetUniformLocation(this->_id, name.c_str()), static_cast<GLsizei>(value.size()), value.data());
+        glUniform1fv(this->_locations.at(name), static_cast<GLsizei>(value.size()), value.data());
     }
 
     void Program::setUniform(const std::string & name, const std::vector<glm::vec2> & value) const {
-        glUniform2fv(glGetUniformLocation(this->_id, name.c_str()),  static_cast<GLsizei>(value.size()), (float *)value.data());
+        glUniform2fv(this->_locations.at(name), static_cast<GLsizei>(value.size()), (float *)value.data());
     }
 
     void Program::setUniform(const std::string & name, const std::vector<glm::vec4> & value) const {
-        glUniform4fv(glGetUniformLocation(this->_id, name.c_str()),  static_cast<GLsizei>(value.size()), (float *)value.data());
+        glUniform4fv(this->_locations.at(name), static_cast<GLsizei>(value.size()), (float *)value.data());
     }
 
     void Program::setUniform(const std::string & name, const std::vector<glm::mat4> & value) const {
-        glUniformMatrix4fv(glGetUniformLocation(this->_id, name.c_str()),  static_cast<GLsizei>(value.size()), GL_FALSE, glm::value_ptr(value[0]));
+        glUniformMatrix4fv(this->_locations.at(name), static_cast<GLsizei>(value.size()), GL_FALSE, glm::value_ptr(value[0]));
     }
 
 }
\ 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 a1b356262f3c1a9f015269da878cb980f8e646f3..ab545d3992a90eed6722b438d7cbd3f6955ea85e 100644
--- a/source/engine/graphics/back/shaders/Program.hpp
+++ b/source/engine/graphics/back/shaders/Program.hpp
@@ -1,8 +1,9 @@
 #pragma once
 
 #include <GL/glew.h>
-#include <glm/mat4x4.hpp>
+#include <glm/glm.hpp>
 #include <vector>
+#include <map>
 
 #include "Source.hpp"
 
@@ -12,6 +13,7 @@ namespace megu {
             GLuint _id;
             bool _usable;
             uint8_t _attached;
+            std::map<std::string, GLuint> _locations;
 
         protected:
             enum Bit_Categorie {
diff --git a/source/engine/graphics/back/textures/Material.cpp b/source/engine/graphics/back/textures/Material.cpp
index ee4b81bf7a6b3ae68e2f0f0357c9f518908ea611..962db762f60a6b44823ec543bef7fe109357056b 100644
--- a/source/engine/graphics/back/textures/Material.cpp
+++ b/source/engine/graphics/back/textures/Material.cpp
@@ -11,37 +11,38 @@ namespace megu {
 
     }
 
-    Material::Material(const std::string & path, bool invert, Texture::Format format)
+    Material::Material(const std::string & path, bool invert)
     : Texture(), _ressource() {
-        this->load(path, format, invert);
+        this->load(path, invert);
     }
 
-    void Material::load(const std::string & path, Texture::Format format, bool invert) {
+    void Material::load(const std::string & path, bool invert) {
         this->_ressource = std::filesystem::canonical(path);
         if(std::filesystem::is_directory(this->_ressource) || !std::filesystem::exists(this->_ressource)) {
             throw std::runtime_error("Cannot load ressource !");
         }
 
-        int width, height, nrChannels;
+        int width = 0, height = 0, nrChannels = 0;
         stbi_set_flip_vertically_on_load(invert);
         unsigned char * data = stbi_load(path.c_str(), &width, &height, &nrChannels, 0);
-        if(format == Texture::AUTO) {
-            switch (nrChannels) {
-                case  3:
-                    format = Texture::RGB;
-                    break;
-            
-                case 4:
-                    format = Texture::RGBA;
-                    break;
-
-                default:
-                    format = Texture::RGBA;
-                    break;
-            }
+
+        Texture::Format format = Texture::RGB;
+        switch (nrChannels) {
+            case 4:
+                format = Texture::RGBA;
+                break;
+
+            case 3:
+                format = Texture::RGB;
+                break;
+
+            default:
+                format = Texture::RGB;
+                break;
         }
 
         this->store(width, height, data, format);
         stbi_image_free(data);
+        stbi_set_flip_vertically_on_load(false);
     }
 }
\ No newline at end of file
diff --git a/source/engine/graphics/back/textures/Material.hpp b/source/engine/graphics/back/textures/Material.hpp
index 04074a23937001cb17e51745ab1a5171a35eb5dc..37fd87267d9acc1f9cce0251820d8b2718a663f8 100644
--- a/source/engine/graphics/back/textures/Material.hpp
+++ b/source/engine/graphics/back/textures/Material.hpp
@@ -6,18 +6,18 @@
 #include "Texture.hpp"
 
 namespace megu {
-    class Material : public Texture {
-        private:
-            std::filesystem::path _ressource;
-        
+    class Material : public Texture { 
         public:
             Material();
             Material(const Material &) = delete;
-            Material(const std::string &, bool = false, Texture::Format = Texture::RGBA);
+            Material(const std::string &, bool = false);
             Material operator=(const Material &) = delete;
 
             inline const std::filesystem::path & ressource() const {return this->_ressource;} 
 
-            void load(const std::string &, Texture::Format = AUTO, bool = false);
+            void load(const std::string &, bool = false);
+
+        private:
+            std::filesystem::path _ressource;
     };
 }
\ No newline at end of file
diff --git a/source/engine/graphics/back/textures/Shared_Material.cpp b/source/engine/graphics/back/textures/Shared_Material.cpp
index 2320d7cb267274b790fc8b782aefbb1156a4fa23..6b89740c30c3ef7b0f4c0e04d1437b9d21fca3af 100644
--- a/source/engine/graphics/back/textures/Shared_Material.cpp
+++ b/source/engine/graphics/back/textures/Shared_Material.cpp
@@ -2,47 +2,47 @@
 
 namespace megu {
 
-    std::map<std::filesystem::path,std::set<const Shared_Material *>> Shared_Material::_shared = std::map<std::filesystem::path,std::set<const Shared_Material *>>();
+    std::map<std::filesystem::path, std::set<std::reference_wrapper<Shared_Material>, std::less<Shared_Material>>> Shared_Material::_shared = std::map<std::filesystem::path, std::set<std::reference_wrapper<Shared_Material>, std::less<Shared_Material>>>();
 
     Shared_Material::Shared_Material() 
-    : _material(std::make_shared<Material>()) {
+    : _material(nullptr) {
 
     }
 
-    Shared_Material::Shared_Material(const std::string & path, bool invert, Texture::Format format)
+    Shared_Material::Shared_Material(const std::string & path, bool invert)
     : _material(nullptr) {
         if(!path.empty() && Shared_Material::_shared.contains(path)) {
-            this->_material = Shared_Material::_shared.at(path).begin().operator*()->_material;
-            Shared_Material::_shared.at(path).insert(this);
+            this->_material = Shared_Material::_shared.at(path).begin()->get()._material;
+            Shared_Material::_shared.at(path).insert(*this);
         }
         else {
-            this->_material = std::make_shared<Material>(path, invert, format);
-            Shared_Material::_shared.insert(std::pair<std::filesystem::path, std::set<const Shared_Material *>>(path, {this}));
+            this->_material = std::make_shared<Material>(path, invert);
+            Shared_Material::_shared.insert(std::pair<std::filesystem::path, std::set<std::reference_wrapper<Shared_Material>, std::less<Shared_Material>>>(path, {*this}));
         }
     }
 
     Shared_Material::Shared_Material(Material & material) 
     : _material(nullptr) {
         if(!material.ressource().empty() && Shared_Material::_shared.contains(material.ressource())) {
-            this->_material = Shared_Material::_shared.at(material.ressource()).begin().operator*()->_material;
-            Shared_Material::_shared.at(material.ressource()).insert(this);
+            this->_material = Shared_Material::_shared.at(material.ressource()).begin()->get()._material;
+            Shared_Material::_shared.at(material.ressource()).insert(*this);
         }
         else {
             this->_material = std::shared_ptr<Material>(&material);
-            Shared_Material::_shared.insert(std::pair<std::filesystem::path,std::set<const Shared_Material *>>(material.ressource(),{this}));
+            Shared_Material::_shared.insert(std::pair<std::filesystem::path, std::set<std::reference_wrapper<Shared_Material>, std::less<Shared_Material>>>(material.ressource(), {*this}));
         }
     }
 
     Shared_Material::~Shared_Material() {
         if(Shared_Material::_shared.contains(this->_material->ressource())) {
-            Shared_Material::_shared.at(this->_material->ressource()).erase(this);
+            Shared_Material::_shared.at(this->_material->ressource()).erase(*this);
             if(Shared_Material::_shared.at(this->_material->ressource()).empty()) {
                 Shared_Material::_shared.erase(this->_material->ressource());
             }
         }
     }
 
-    const Material & Shared_Material::material() const {
+    const Material & Shared_Material::get() const {
         return *this->_material.get();
     }
 
@@ -74,67 +74,75 @@ namespace megu {
         this->_material->bind(slot);
     }
 
-    void Shared_Material::load(const std::string & path, Texture::Format format, bool flip_y) {
+    void Shared_Material::load(const std::string & path, bool flip_y) {
         if(!this->_material->ressource().empty()) {
-            Shared_Material::_shared.at(this->_material->ressource()).erase(this);
+            Shared_Material::_shared.at(this->_material->ressource()).erase(*this);
             if(Shared_Material::_shared.at(this->_material->ressource()).empty()) {
                 Shared_Material::_shared.erase(this->_material->ressource());
             }
         }
 
         if(Shared_Material::_shared.contains(path)) {
-            this->_material = Shared_Material::_shared.at(path).begin().operator*()->_material;
-            Shared_Material::_shared.at(path).insert(this);
+            this->_material = Shared_Material::_shared.at(path).begin()->get()._material;
+            Shared_Material::_shared.at(path).insert(*this);
         }
         else {
-            this->_material->load(path, format, flip_y);
-            Shared_Material::_shared.insert(std::pair<std::filesystem::path,std::set<const Shared_Material *>>(path,{this}));
+            this->_material->load(path, flip_y);
+            Shared_Material::_shared.insert(std::pair<std::filesystem::path, std::set<std::reference_wrapper<Shared_Material>, std::less<Shared_Material>>>(path, {*this}));
         }
     }
 
     void Shared_Material::load(Material & material) {
         if(!material.ressource().empty() && Shared_Material::_shared.contains(material.ressource())) {
-            this->_material = Shared_Material::_shared.at(material.ressource()).begin().operator*()->_material;
-            Shared_Material::_shared.at(material.ressource()).insert(this);
+            this->_material = Shared_Material::_shared.at(material.ressource()).begin()->get()._material;
+            Shared_Material::_shared.at(material.ressource()).insert(*this);
         }
         else {
             this->_material = std::shared_ptr<Material>(&material);
         }
     }
 
-    bool Shared_Material::valide() const {
-        return this->_material->valide();
+    bool Shared_Material::valid() const {
+        return this->empty() ? false : this->_material->valid();
     }
 
     bool Shared_Material::operator==(const Shared_Material & material) const {
-        return this->material() == material.material();
+        return this->get() == material.get();
     }
 
     bool Shared_Material::operator!=(const Shared_Material & material) const {
-        return this->material() != material.material();
+        return this->get() != material.get();
     }
 
     bool Shared_Material::operator>=(const Shared_Material & material) const {
-        return this->material() >= material.material();
+        return this->get() >= material.get();
     }
 
     bool Shared_Material::operator<=(const Shared_Material & material) const {
-        return this->material() <= material.material();
+        return this->get() <= material.get();
     }
 
     bool Shared_Material::operator>(const Shared_Material & material) const {
-        return this->material() > material.material();
+        return this->get() > material.get();
     }
 
     bool Shared_Material::operator<(const Shared_Material & material) const {
-        return this->material() < material.material();
+        return this->get() < material.get();
     }
 
     Material * Shared_Material::operator->() const {
         return this->_material.get();
     }
 
+    Material & Shared_Material::operator*() const {
+        return *this->_material.get();
+    }
+
     std::strong_ordering Shared_Material::operator<=>(const Shared_Material & material) const {
-        return this->material() <=> material.material();
+        return this->get() <=> material.get();
+    }
+
+    size_t Shared_Material::Total() {
+        return Shared_Material::_shared.size();
     }
 }
\ No newline at end of file
diff --git a/source/engine/graphics/back/textures/Shared_Material.hpp b/source/engine/graphics/back/textures/Shared_Material.hpp
index 9247bdf1c5913a8a4bfd39536d914be988fda28a..7c85f670174b6ed3599577044a7f45279c29905a 100644
--- a/source/engine/graphics/back/textures/Shared_Material.hpp
+++ b/source/engine/graphics/back/textures/Shared_Material.hpp
@@ -3,24 +3,20 @@
 #include <memory>
 #include <map>
 #include <set>
+#include <unordered_set>
 #include <filesystem>
-#include <optional>
 
 #include "Material.hpp"
 
 namespace megu {
     class Shared_Material {
-        private:
-            std::shared_ptr<Material> _material;
-            static std::map<std::filesystem::path,std::set<const Shared_Material *>> _shared;
-
         public:
             Shared_Material();
-            Shared_Material(const std::string &, bool = false, Texture::Format = Texture::AUTO);
+            Shared_Material(const std::string &, bool = false);
             Shared_Material(Material &);
    virtual ~Shared_Material();
 
-            const Material & material() const;
+            const Material & get() const;
 
             GLuint identifier() const;
             GLuint format() const;
@@ -33,10 +29,11 @@ namespace megu {
             void bind() const;
             void bind(uint32_t slot) const;
 
-            void load(const std::string &, Texture::Format=Texture::RGB, bool=true);
+            void load(const std::string &, bool=false);
             void load(Material &);
 
-            bool valide() const;
+            bool valid() const;
+            inline bool empty() const {return this->_material.get() != nullptr;}
 
             bool operator==(const Shared_Material &) const;
             bool operator!=(const Shared_Material &) const;
@@ -46,8 +43,15 @@ namespace megu {
             bool operator<(const Shared_Material &) const;
 
             Material * operator->() const;
+            Material & operator*() const;
 
             std::strong_ordering operator<=>(const Shared_Material &) const;
 
+            static size_t Total();
+
+        private:
+            std::shared_ptr<Material> _material;
+            static std::map<std::filesystem::path, std::set<std::reference_wrapper<Shared_Material>, std::less<Shared_Material>>> _shared;
+
     };
 }
\ 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 0db023fa5bbcd9535ec222bdd644b4c6f6789bde..d1b0a30287fb0aac7259aa1adf22c7e035217298 100644
--- a/source/engine/graphics/back/textures/Texture.cpp
+++ b/source/engine/graphics/back/textures/Texture.cpp
@@ -7,7 +7,6 @@ namespace megu {
     Texture::Texture(GLuint slot, GLuint type) 
     : _id(0), _type(type), _slot(slot) {
         glGenTextures(1, &this->_id);
-        
     }
 
     Texture::~Texture() {
@@ -26,7 +25,7 @@ namespace megu {
 
     GLint Texture::width() const {
         if(this->_id == 0) {
-            throw std::runtime_error("Void texture.");
+            return 0;
         }
 
         GLint width;
@@ -36,7 +35,7 @@ namespace megu {
 
     GLint Texture::height() const {
         if(this->_id == 0) {
-            throw std::runtime_error("Void texture.");
+            return 0;
         }
 
         GLint height;
@@ -72,7 +71,7 @@ namespace megu {
     }
 
     void Texture::store(GLsizei width, GLsizei height, const void * data, GLuint format) {
-        if(this->valide()) {
+        if(this->valid()) {
             glDeleteTextures(1, &this->_id);
             glGenTextures(1, &this->_id);
         }
@@ -84,7 +83,7 @@ namespace megu {
         this->setSmoothing(false);
     }
 
-    bool Texture::valide() const {
+    bool Texture::valid() const {
         return this->_id != 0;
     }
 
diff --git a/source/engine/graphics/back/textures/Texture.hpp b/source/engine/graphics/back/textures/Texture.hpp
index 4eabc13b9944ecd2c949b23b8f27e18b67e7f5eb..80e8b1b0c56762a54cd038065ef2d351ef43894e 100644
--- a/source/engine/graphics/back/textures/Texture.hpp
+++ b/source/engine/graphics/back/textures/Texture.hpp
@@ -5,11 +5,6 @@
 
 namespace megu {
     class Texture {
-        private:
-            GLuint _id;
-            GLuint _type;
-            mutable GLuint _slot;
-
         public:
             Texture(GLuint = 0, GLuint = GL_TEXTURE_2D);
             Texture(const Texture &) = delete;
@@ -30,7 +25,6 @@ namespace megu {
             };
 
             enum Format {
-                AUTO,
                 RGB     = GL_RGB,
                 BGR     = GL_BGR,
                 RGBA    = GL_RGBA,
@@ -54,7 +48,7 @@ namespace megu {
             void setSmoothing(bool);
 
             void store(GLsizei, GLsizei, const void *, GLuint = RGBA);
-            bool valide() const;
+            bool valid() const;
 
             bool operator==(const Texture &) const;
             bool operator!=(const Texture &) const;
@@ -67,6 +61,9 @@ namespace megu {
 
             static void Unbind(GLuint = GL_TEXTURE_2D);
 
-            
+        private:
+            GLuint _id;
+            GLuint _type;
+            mutable GLuint _slot;    
     };
 }
\ No newline at end of file
diff --git a/source/main.cpp b/source/main.cpp
index 65dc652fb31193956f9ca609f5cc0ee16aa8e746..9f510b97bce2164b08a3946fc5725c9f5a55fc0b 100644
--- a/source/main.cpp
+++ b/source/main.cpp
@@ -1,6 +1,179 @@
 #include <iostream>
 
-int main(int argc, const char * argv[]) {
-    std::cout << "Hello World !" << std::endl;
+#include <GL/glew.h>
+#include <GLFW/glfw3.h>
+
+#include <engine/graphics/errors.hpp>
+#include <engine/graphics/back.hpp>
+
+#define NORMALIZE(X) X/255.f
+
+#define WINDOW_WIDTH  1200
+#define WINDOW_HEIGHT 720
+
+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);
+
+        glfwWindowHint(GLFW_RED_BITS, videoMode->redBits);
+        glfwWindowHint(GLFW_GREEN_BITS, videoMode->greenBits);
+        glfwWindowHint(GLFW_BLUE_BITS, videoMode->blueBits);
+        glfwWindowHint(GLFW_REFRESH_RATE, videoMode->refreshRate);
+
+        glfwWindowHint(GLFW_RESIZABLE, true);
+        glfwWindowHint(GLFW_DECORATED, true);
+        glfwWindowHint(GLFW_VISIBLE, true);
+        glfwWindowHint(GLFW_DOUBLEBUFFER, true);
+
+        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;
+        }
+
+        std::cout << "Glew Inited" << std::endl;
+
+        //? Viewport
+        glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
+
+        megu::error::opengl_error::check();
+        std::cout <<  "Viewport" << std::endl;
+
+        //? Buffers
+        megu::VertexArray vao;
+        megu::VerticeBuffer vbo(vao, {megu::layout::POSITION, megu::layout::COLOR}, 128, megu::EditMode::STATIC);
+
+        std::vector<float> vertices = {
+            -1.f, -1.f,  0.f,   NORMALIZE(33),  NORMALIZE(114), NORMALIZE(255), 
+             1.f, -1.f,  0.f,   NORMALIZE(33),  NORMALIZE(114), NORMALIZE(255),
+             1.f,  0.0f, 0.f,   NORMALIZE(217), NORMALIZE(63),  NORMALIZE(114),
+
+             1.f,  0.0f, 0.f,   NORMALIZE(217), NORMALIZE(63),  NORMALIZE(114),
+            -1.f,  0.0f, 0.f,   NORMALIZE(217), NORMALIZE(63),  NORMALIZE(114),
+            -1.f, -1.f,  0.f,   NORMALIZE(33),  NORMALIZE(114), NORMALIZE(255), 
+
+            -1.f, -0.0f, 0.f,   NORMALIZE(217), NORMALIZE(63),  NORMALIZE(114),
+             1.f, -0.0f, 0.f,   NORMALIZE(217), NORMALIZE(63),  NORMALIZE(114),
+             1.f,  1.f,  0.f,   NORMALIZE(190), NORMALIZE(105), NORMALIZE(170),
+
+             1.f,  1.f,  0.f,   NORMALIZE(190), NORMALIZE(105), NORMALIZE(170),
+            -1.f,  1.f,  0.f,   NORMALIZE(190), NORMALIZE(105), NORMALIZE(170),
+            -1.f,  0.0f, 0.f,   NORMALIZE(217), NORMALIZE(63),  NORMALIZE(114)
+        };
+
+        vbo << vertices;
+
+        megu::VertexArray vao_2;
+        megu::VerticeBuffer vbo_2(vao_2, {megu::layout::POSITION, megu::layout::COLOR}, 128, megu::EditMode::STATIC);
+
+        std::vector<float> vertices_2 = {
+            -0.5f, -0.5f, 0.0,  NORMALIZE(255), NORMALIZE(0), NORMALIZE(0),  
+             0.5f, -0.5f, 0.0,  NORMALIZE(0), NORMALIZE(255), NORMALIZE(0),  
+             0.0f,  0.5f, 0.0,  NORMALIZE(0), NORMALIZE(0), NORMALIZE(255),  
+        };
+
+        vbo_2 << vertices_2;
+
+        megu::VertexArray vao_F;
+        megu::VerticeBuffer vbo_F(vao_F, {megu::layout::POSITION, megu::layout::TEXTURE}, 64, megu::EditMode::STATIC);
+
+        std::vector<float> vertices_F = {
+            -1.f, -1.f, 0.f,    0.f, 0.f,
+             1.f, -1.f, 0.f,    1.f, 0.f,
+             1.f,  1.f, 0.f,    1.f, 1.f,
+
+            -1.f, -1.f, 0.f,    0.f, 0.f,
+             1.f,  1.f, 0.f,    1.f, 1.f,
+            -1.f,  1.f, 0.f,    0.f, 1.f
+        };
+
+        vbo_F << vertices_F;
+
+        //? FBO
+
+        megu::FrameBuffer fbo(WINDOW_WIDTH, WINDOW_HEIGHT);
+        megu::FrameBuffer fbo_2(WINDOW_WIDTH, WINDOW_HEIGHT);
+
+        //? Shaders
+        megu::Program program;
+
+        {
+            megu::Source vertex("assets/shaders/Basic.vert", megu::Source::Categorie::VERTEX);
+            megu::Source fragment("assets/shaders/Basic.frag", megu::Source::Categorie::FRAGMENT);
+
+            program << vertex;
+            program << fragment;
+
+            program.link();
+        }
+
+
+        megu::Program program_F;
+
+        {
+            megu::Source vertex("assets/shaders/Texture.vert", megu::Source::Categorie::VERTEX);
+            megu::Source fragment("assets/shaders/Texture.frag", megu::Source::Categorie::FRAGMENT);
+
+            program_F << vertex;
+            program_F << fragment;
+
+            program_F.link();
+        }
+
+
+        //? Render Loop
+        glClearColor(0.0f, 0.0f, 0.0f, 0.f);
+
+        std::cout << "Render Loop Begin !" << std::endl;
+        while(!glfwWindowShouldClose(window)) {
+            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+            glfwPollEvents();
+
+            fbo.bind();
+            vao.bind();
+            program.use();
+            glDrawArrays(GL_TRIANGLES, 0, static_cast<GLsizei>(vbo.size()));
+
+            fbo_2.bind();
+            vao_2.bind();
+            program.use();
+            glDrawArrays(GL_TRIANGLES, 0, static_cast<GLsizei>(vbo_2.size()));
+
+            megu::FrameBuffer::BindDefaultFrameBuffer();
+            vao_F.bind();
+            
+            fbo.texture().bind(0);
+            fbo_2.texture().bind(1);
+
+            program_F.use();
+            program_F.setUniform("uSamp", std::vector<GLint>({0, 1}));
+
+            glDrawArrays(GL_TRIANGLES, 0, static_cast<GLsizei>(vbo_F.size()));
+
+            glfwSwapBuffers(window);
+        }
+        std::cout << "Render Loop End !" << std::endl;
+    }
+    catch(std::exception & error) {
+        std::cerr << error.what() << std::endl;
+    }
+
     return EXIT_SUCCESS;
 }
\ No newline at end of file