diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..e2a14a608ced625ac1a1bcd11c3e85b904f63ba7
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,19 @@
+*.vscode
+
+*.o
+*.obj
+*.pdb
+
+*.a
+*.dll
+*.so
+*.lib
+
+*.exe
+*.git
+
+build/*
+include/*
+library/*
+vcpkg_installed/*
+old/*
\ No newline at end of file
diff --git a/CMakelists.txt b/CMakelists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..4ed6f26854f3a98e2dde36014ec43ca2c8e08846
--- /dev/null
+++ b/CMakelists.txt
@@ -0,0 +1,71 @@
+cmake_minimum_required(VERSION 3.1)
+
+#==============================================================
+#                           Configuration
+#==============================================================
+
+set(PROJECT_NAME "Main")
+set(EXECUTABLE_NAME "Main")
+
+set(CXX_STANDARD 20)
+set(CMAKE_CXX_STANDARD ${CXX_STANDARD})
+
+if (MSVC)
+	add_compile_options(/EHsc)
+endif()
+
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+set(CMAKE_CXX_EXTENSIONS OFF)
+
+#=====================================
+#				Options
+#=====================================
+
+if(WIN32)
+	option(CMAKE_TOOLCHAIN_FILE "C:/vcpkg/vcpkg/scripts/buildsystems/vcpkg.cmake")
+elseif(UNIX)
+	option(CMAKE_TOOLCHAIN_FILE "/usr/local/share/vcpkg/scripts/buildsystems/vcpkg.cmake")	
+endif()
+
+#==============================================================
+#                           Sources
+#==============================================================
+
+set(SOURCES ${CMAKE_SOURCE_DIR}/source/)
+set(LIBRARY ${CMAKE_SOURCE_DIR}/library/)
+set(INCLUDE ${CMAKE_SOURCE_DIR}/include/)
+
+set(VCPK_INCLUDE ${CMAKE_SOURCE_DIR}/vcpkg_installed/*/include)
+set(VCPK_INCLUDE ${CMAKE_SOURCE_DIR}/vcpkg_installed/*/lib)
+
+#==============================================================
+#                           Build
+#==============================================================
+
+project(${PROJECT_NAME})
+set(CURRENT_TARGET ${EXECUTABLE_NAME})
+
+add_executable(${CURRENT_TARGET})
+
+foreach(dir ${SOURCES})
+    add_subdirectory(${dir})
+endforeach()  
+
+set_property(TARGET ${CURRENT_TARGET} PROPERTY RUNTIME_OUTPUT_DIRECTORY $<1:${CMAKE_SOURCE_DIR}>)
+
+#==============================================================
+#                           Linking
+#==============================================================
+
+target_include_directories(${CURRENT_TARGET} PRIVATE ${INCLUDE})
+
+find_package(glfw3  REQUIRED)
+find_package(GLEW   REQUIRED)
+find_package(glm 	CONFIG REQUIRED)
+find_package(imgui 	REQUIRED)
+
+target_link_libraries(${CURRENT_TARGET} PRIVATE glfw)
+target_link_libraries(${CURRENT_TARGET} PRIVATE GLEW::GLEW)
+target_link_libraries(${CURRENT_TARGET} PRIVATE glm::glm-header-only)
+target_link_libraries(${CURRENT_TARGET} PRIVATE imgui::imgui)
+
diff --git a/README.md b/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..b925f9599c0a4c7b81d6de1e36ee6083b330d0a9
--- /dev/null
+++ b/README.md
@@ -0,0 +1,13 @@
+# Projet FIG
+
+## Building
+
+Debug mode :
+```shell
+cmake --build ./build
+```
+
+Release Mode :
+```shell
+cmake --build ./build --config Release
+```
\ No newline at end of file
diff --git a/source/CMakelists.txt b/source/CMakelists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..9faf4ac20bb8965699410280cda601902e960170
--- /dev/null
+++ b/source/CMakelists.txt
@@ -0,0 +1,4 @@
+target_include_directories(${CURRENT_TARGET} PRIVATE .)
+
+file(GLOB_RECURSE SOURCE ./**.cpp)
+target_sources(${CURRENT_TARGET} PRIVATE ${SOURCE})
\ No newline at end of file
diff --git a/source/engine/graphics/back.hpp b/source/engine/graphics/back.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..d04d031424ab0d33ac0f044542d0372b57cc6f4f
--- /dev/null
+++ b/source/engine/graphics/back.hpp
@@ -0,0 +1,20 @@
+#pragma once
+
+#include "back/buffers/ElementBuffer.hpp"
+#include "back/buffers/FrameBuffer.hpp"
+#include "back/buffers/VerticeBuffer.hpp"
+#include "back/buffers/VertexArray.hpp"
+#include "back/buffers/UniformeBuffer.hpp"
+
+#include "back/cameras/Target.hpp"
+#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"
+#include "back/shaders/Source.hpp"
+#include "back/shaders/UniformObject.hpp"
+
+#include "back/textures/Shared_Material.hpp"
\ No newline at end of file
diff --git a/source/engine/graphics/back/buffers/Buffer.hpp b/source/engine/graphics/back/buffers/Buffer.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..f2577d116a20c3d54c5901ca35e152d9ba92fda3
--- /dev/null
+++ b/source/engine/graphics/back/buffers/Buffer.hpp
@@ -0,0 +1,12 @@
+#pragma once
+
+#include <GL/glew.h>
+
+namespace megu {
+    class Buffer  {
+        public:
+            virtual void bind() const = 0;
+            virtual void unbind() const = 0;
+            virtual GLuint identifier() const = 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
new file mode 100644
index 0000000000000000000000000000000000000000..53e0cf00fa09463e50c15dca75049f22b450219b
--- /dev/null
+++ b/source/engine/graphics/back/buffers/DynamicBuffer-impl.cpp
@@ -0,0 +1,6 @@
+#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.cpp b/source/engine/graphics/back/buffers/DynamicBuffer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e9da1b1c1711f4e37c6772fe947a926e2e5baa4c
--- /dev/null
+++ b/source/engine/graphics/back/buffers/DynamicBuffer.cpp
@@ -0,0 +1,256 @@
+#include "DynamicBuffer.hpp"
+
+#include <GL/glew.h>
+#include <exception>
+#include <stdexcept>
+
+#include <iostream>
+
+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) {
+
+    }
+
+    template <typename T, uint32_t Y>
+    size_t DynamicBuffer<T,Y>::size() const {
+        return this->_size;
+    }
+
+    template <typename T, uint32_t Y>
+    size_t DynamicBuffer<T,Y>::max_size() const {
+        return this->_max_size;
+    }
+
+    template <typename T, uint32_t Y>
+    size_t DynamicBuffer<T,Y>::memory_size() const {
+        return this->_size * sizeof(T);
+    }
+
+    template <typename T, uint32_t Y>
+    size_t DynamicBuffer<T,Y>::max_memory_size() const {
+        return this->_max_size * sizeof(T);
+    }
+
+    template <typename T, uint32_t Y>
+    bool DynamicBuffer<T,Y>::empty() const {
+        return this->_size == 0;
+    }
+
+    template <typename T, uint32_t Y>
+    bool DynamicBuffer<T,Y>::full() const {
+        return this->_size == this->_max_size;
+    }
+
+    template <typename T, uint32_t Y>
+    void DynamicBuffer<T,Y>::set(const std::vector<T> & vertices) {
+        this->_max_size = vertices.size();
+        this->_size = vertices.size();
+        this->generate(vertices);
+    }
+
+    template <typename T, uint32_t Y>
+    void DynamicBuffer<T,Y>::insert(const std::vector<T> & vertices, size_t pos) {
+        if(this->_size + vertices.size() > this->_max_size) {
+            std::vector<T> data = this->extract();
+            data.insert(data.begin() + pos, vertices.begin(), vertices.end());
+            this->set(data);
+        }
+        else {
+            if(this->identifier() != 0) {
+                this->bind();
+                uint8_t * writer = static_cast<uint8_t *>(glMapBuffer(Y, GL_READ_WRITE));
+                
+                if(pos < this->_size) {
+                    memmove(writer + ((pos + vertices.size()) * sizeof(T)), writer + (pos * sizeof(T)), (this->_size-pos) * sizeof(T));
+                }
+                memmove(writer + (pos * sizeof(T)), std::vector<T>(vertices).data(), vertices.size() * sizeof(T));
+                glUnmapBuffer(Y);
+                
+                this->_size += vertices.size();
+
+            }
+            else {
+                this->generate(vertices);
+            }
+        }
+    }  
+
+    template <typename T, uint32_t Y>
+    void DynamicBuffer<T,Y>::replace(const std::vector<T> & vertices, size_t pos) {
+        if(this->empty()) {
+            throw std::range_error("Buffer is empty.");
+        }
+        
+        if(pos + vertices.size() > this->_size) {
+            throw std::overflow_error("Cannot replace datas out of buffer.");
+        }
+
+        this->bind();
+        glBufferSubData(Y, pos * sizeof(T),vertices.size() * sizeof(T), std::vector<T>(vertices).data());
+    }
+
+    template <typename T, uint32_t Y>
+    void DynamicBuffer<T,Y>::erase(size_t from, size_t to) {
+        if(this->empty()) {
+            throw std::range_error("Buffer is empty.");
+        }
+
+        if(this->_size - to - from  < 0) {
+            throw std::underflow_error("Cannot erase datas out of buffer.");
+        }
+        
+        this->bind();
+    
+        uint8_t * writer = static_cast<uint8_t *>(glMapBuffer(Y, GL_READ_WRITE));
+        memmove(writer + (from * sizeof(T)), writer + ((to+1) * sizeof(T)), (this->_size-to) * sizeof(T));
+        glUnmapBuffer(Y);
+
+        this->_size -= (to + 1 - from);
+    }
+
+    template <typename T, uint32_t Y>
+    void DynamicBuffer<T,Y>::merge(const DynamicBuffer<T,Y> & vbo, size_t pos) {
+        if(this->_size + vbo._size > this->_max_size) {
+            throw std::overflow_error("Cannot add datas out of buffer.");
+        }
+            
+        if(pos < this->_size) {
+            this->bind();
+            uint8_t * writer = static_cast<uint8_t *>(glMapBuffer(Y,GL_READ_WRITE));
+            memmove(writer + (pos + vbo._size) * sizeof(T), writer + (pos * sizeof(T)), (this->_size-pos) * sizeof(T));
+            glUnmapBuffer(Y);
+        }
+
+        this->_size += vbo._size;
+
+        glBindBuffer(GL_COPY_READ_BUFFER, vbo.identifier());
+        glBindBuffer(GL_COPY_WRITE_BUFFER, this->identifier());
+
+        glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, 0, pos * sizeof(T),vbo._size * sizeof(T));
+    }
+
+    template <typename T, uint32_t Y>
+    void DynamicBuffer<T,Y>::resize(size_t max_size) {
+        if(this->_size > max_size) {
+            throw std::overflow_error("Cannot set a new max size that is greater than current size");
+        }
+
+        std::vector<T> save = this->extract();
+        this->_max_size = max_size;
+        this->generate(save);
+    }
+
+    template <typename T, uint32_t Y>
+    void DynamicBuffer<T,Y>::push_back(const std::vector<T> & vertices) {
+        this->insert(vertices, this->_size);
+    }
+
+    template <typename T, uint32_t Y>
+    void DynamicBuffer<T,Y>::push_front(const std::vector<T> & vertices) {
+        this->insert(vertices, 0);
+    }
+
+    template <typename T, uint32_t Y>
+    void DynamicBuffer<T,Y>::pop_back(size_t offset) {
+        if(offset > this->_size) {
+            throw std::underflow_error("Cannot erase datas out of buffer.");
+        }
+
+        if(offset > 0) {
+            this->erase(this->_size-offset+1, this->_size);
+        }
+    }
+
+    template <typename T, uint32_t Y>
+    void DynamicBuffer<T,Y>::pop_front(size_t offset) {
+        if(offset > this->_size) {
+            throw std::overflow_error("Cannot add datas out of buffer.");
+        }
+
+        if(offset > 0) {
+            this->erase(0, offset-1);
+        }
+    }
+
+    template <typename T, uint32_t Y>
+    void DynamicBuffer<T,Y>::regenerate(size_t max_size) {
+        this->_max_size = max_size;
+        this->generate({});
+    }
+
+    template <typename T, uint32_t Y>
+    void DynamicBuffer<T,Y>::reset(const std::vector<T> & data) {
+        this->set(data);
+    }
+
+    template <typename T, uint32_t Y>
+    void DynamicBuffer<T,Y>::clear() {
+        this->generate({});
+    }
+
+    template <typename T, uint32_t Y>
+    T DynamicBuffer<T,Y>::back() const {
+        if(this->empty()) {
+            throw std::underflow_error("Cannot get data from empty buffer.");
+        }
+        
+        return this->operator[](0);
+    }
+
+    template <typename T, uint32_t Y>
+    T DynamicBuffer<T,Y>::front() const {
+        if(this->empty()) {
+            throw std::underflow_error("Cannot get data from empty buffer.");
+        }
+        
+        return this->operator[](this->_size-1);
+    }
+
+    template <typename T, uint32_t Y>
+    T DynamicBuffer<T,Y>::at(size_t index) const {
+        return this->operator[](index);
+    }
+
+    template <typename T, uint32_t Y>
+    std::vector<T> DynamicBuffer<T,Y>::extract() const {
+        return this->extract(0, this->_size);
+    }
+
+    template <typename T, uint32_t Y>
+    std::vector<T> DynamicBuffer<T,Y>::extract(size_t from,size_t to) const {
+        if(to > this->_size) {
+            throw std::overflow_error("Cannot extract datas out of buffer.");
+        }
+
+        this->bind();
+        void * writer = glMapBuffer(Y, GL_WRITE_ONLY);
+        std::vector<T> data{static_cast<T *>(writer) + from, static_cast<T *>(writer) + from + (to - from)};
+        glUnmapBuffer(Y);
+
+        return data;
+    }
+
+    template <typename T, uint32_t Y>
+    T DynamicBuffer<T,Y>::operator[](size_t index) const {
+        return this->extract(index,index)[0];
+    }
+
+    template <typename T, uint32_t Y>
+    void DynamicBuffer<T,Y>::modify(std::function<void(void *)> modif) {
+        this->bind();
+        modif(glMapBuffer(Y, GL_READ_WRITE));
+        glUnmapBuffer(Y);
+    }
+
+    template <typename T, uint32_t Y>
+    void DynamicBuffer<T,Y>::operator()(std::function<void(void *)> modif) {
+        this->modify(modif);
+    }
+
+    template <typename T, uint32_t Y>
+    void DynamicBuffer<T,Y>::operator<<(const DynamicBuffer<T,Y> & buffer) {
+        this->merge(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
new file mode 100644
index 0000000000000000000000000000000000000000..c09a61006e90497bec4572b4545dfa0a97d4bc23
--- /dev/null
+++ b/source/engine/graphics/back/buffers/DynamicBuffer.hpp
@@ -0,0 +1,67 @@
+#pragma once
+
+#include "Buffer.hpp"
+
+#include <stdint.h>
+#include <vector>
+#include <list>
+#include <functional>
+
+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);
+            DynamicBuffer(const DynamicBuffer &) = delete;
+
+            virtual void generate(const std::vector<T> &) = 0;
+            
+            size_t size() const;
+            size_t max_size() const;
+            size_t memory_size() const;
+            size_t max_memory_size() const;
+
+            bool empty() const;
+            bool full() const;
+
+            void set(const std::vector<T> &);
+            
+            void insert(const std::vector<T> &, size_t pos);
+            void replace(const std::vector<T> &, size_t pos);
+            void erase(size_t from,size_t to);
+
+            void merge(const DynamicBuffer<T,Y> &, size_t pos=0);
+
+            void push_back(const std::vector<T> &);
+            void push_front(const std::vector<T> &);
+
+            void regenerate(size_t max_size);
+            void reset(const std::vector<T> &);
+            void clear();
+
+            void resize(size_t max_size);
+
+            void pop_back(size_t offset=1);
+            void pop_front(size_t offset=1);
+
+            T back() const;
+            T front() const;
+
+            T at(size_t index) const;
+
+            std::vector<T> extract() const;
+            std::vector<T> extract(size_t from,size_t to) const;
+
+            T operator[](size_t index) const;
+
+            void modify(std::function<void(void *)>);
+            void operator()(std::function<void(void *)>);
+
+            void operator<<(const DynamicBuffer<T,Y> &);
+    };
+}
\ No newline at end of file
diff --git a/source/engine/graphics/back/buffers/ElementBuffer.cpp b/source/engine/graphics/back/buffers/ElementBuffer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b316b7790fd80d03d143ce13807c66b5863a684e
--- /dev/null
+++ b/source/engine/graphics/back/buffers/ElementBuffer.cpp
@@ -0,0 +1,90 @@
+#include "ElementBuffer.hpp"
+
+namespace megu {
+    ElementBuffer::ElementBuffer(const VertexArray & vao,size_t size,uint32_t 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) {
+        this->generate(indices);
+    }
+
+    ElementBuffer::~ElementBuffer() {
+        this->unbind();
+        glDeleteBuffers(1,&this->_id);
+    }
+
+    GLuint ElementBuffer::identifier() const {
+        return this->_id;
+    } 
+
+    void ElementBuffer::bind() const {
+        if(this->_id != 0) {
+            this->_vao->bind();
+            glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,this->_id);
+        }
+    }
+
+    void ElementBuffer::unbind() const {
+        GLint ebo = 0;
+        glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER, &ebo);
+        if(static_cast<GLuint>(ebo) == this->_id) {
+            this->_vao->unbind();
+            glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+        }
+    }
+
+    void ElementBuffer::generate(const std::vector<unsigned int> & vertices) {
+        this->_vao->bind();
+
+        if(this->_id != 0) {
+            glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);
+            glDeleteBuffers(1,&this->_id);
+        }
+
+        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);
+
+    }
+
+    bool ElementBuffer::operator==(const ElementBuffer & ebo) const {
+        return this->_id == ebo._id;
+    }
+
+    bool ElementBuffer::operator!=(const ElementBuffer & ebo) const {
+        return this->_id != ebo._id;
+    }
+
+    bool ElementBuffer::operator>(const ElementBuffer & ebo) const {
+        return this->_id > ebo._id;
+    }
+
+    bool ElementBuffer::operator>=(const ElementBuffer & ebo) const {
+        return this->_id >= ebo._id;
+    }
+
+    bool ElementBuffer::operator<(const ElementBuffer & ebo) const {
+        return this->_id < ebo._id;
+    }
+
+    bool ElementBuffer::operator<=(const ElementBuffer & ebo) const {
+        return this->_id <= ebo._id;
+    }
+
+    std::strong_ordering ElementBuffer::operator<=>(const ElementBuffer & ebo) const {
+        return this->_id <=> ebo._id; 
+    }
+
+    ElementBuffer & operator<<(ElementBuffer & ebo, const std::initializer_list<unsigned int> & data) {
+        ebo.push_back(data);
+        return ebo;
+    }
+
+    ElementBuffer & operator<<(ElementBuffer & ebo, const std::vector<unsigned int> & data) {
+        ebo.push_back(data);
+        return ebo;
+    }
+}
\ No newline at end of file
diff --git a/source/engine/graphics/back/buffers/ElementBuffer.hpp b/source/engine/graphics/back/buffers/ElementBuffer.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..43b693553ea4c20443c41c8d62835102a3708df4
--- /dev/null
+++ b/source/engine/graphics/back/buffers/ElementBuffer.hpp
@@ -0,0 +1,42 @@
+#pragma once
+
+#include <compare>
+
+#include "DynamicBuffer.hpp"
+#include "VertexArray.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 ElementBuffer &) = delete;
+   virtual ~ElementBuffer();
+
+            virtual inline GLuint identifier() const;
+
+            virtual void bind() const;
+            virtual void unbind() const;
+
+            virtual void generate(const std::vector<unsigned int> &);
+
+            inline bool operator==(const ElementBuffer &) const;
+            inline bool operator!=(const ElementBuffer &) const;
+            inline bool operator<=(const ElementBuffer &) const;
+            inline bool operator>=(const ElementBuffer &) const;
+
+            inline bool operator<(const ElementBuffer &) const;
+            inline bool operator>(const ElementBuffer &) const;
+
+            inline std::strong_ordering operator<=>(const ElementBuffer &) const;
+
+            friend ElementBuffer & operator<<(ElementBuffer &, const std::initializer_list<unsigned int> &);
+            friend ElementBuffer & operator<<(ElementBuffer &, const std::vector<unsigned int> &);
+    };
+}
\ No newline at end of file
diff --git a/source/engine/graphics/back/buffers/FrameBuffer.cpp b/source/engine/graphics/back/buffers/FrameBuffer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6be8653c4e36b8c32d6e43a21f1cf7639b72e1b6
--- /dev/null
+++ b/source/engine/graphics/back/buffers/FrameBuffer.cpp
@@ -0,0 +1,50 @@
+#include "FrameBuffer.hpp"
+
+#include <iostream>
+#include "../../errors/OpenGL_Error.hpp"
+
+namespace megu {
+    FrameBuffer::FrameBuffer(GLuint width, GLuint height) 
+    : _id(0), _rbo_id(0), _texture() {
+        glGenFramebuffers(1, &this->_id);
+        glBindFramebuffer(GL_FRAMEBUFFER, this->_id);
+
+        this->_texture.store(width, height, NULL, Texture::Format::RGB);
+        this->_texture.setSmoothing(false);
+        this->_texture.setWraping(Texture::Wraping::CLAMP_TO_EDGE, Texture::Axis::S | Texture::Axis::T);
+
+        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, this->_texture.identifier(), 0);
+        glGenRenderbuffers(1, &this->_rbo_id);
+        glBindRenderbuffer(GL_RENDERBUFFER, this->_rbo_id);
+        glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height);
+        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, this->_rbo_id);
+
+        if(!this->usable()) {
+            std::cerr << "Incomplete FrameBuffer." << std::endl;
+        }
+
+        glBindFramebuffer(GL_FRAMEBUFFER, 0);
+    }
+
+    FrameBuffer::~FrameBuffer() {
+        glDeleteRenderbuffers(1, &this->_rbo_id);
+        glDeleteFramebuffers(1, &this->_id);
+    }
+
+    bool FrameBuffer::usable() const {
+        this->bind();
+        return glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE;
+    }
+
+    void FrameBuffer::bind() const {
+        glBindFramebuffer(GL_FRAMEBUFFER, this->_id);
+    }
+
+    void FrameBuffer::unbind() const {
+        glBindFramebuffer(GL_FRAMEBUFFER, 0);
+    }
+
+    void FrameBuffer::BindDefaultFrameBuffer() {
+        glBindFramebuffer(GL_FRAMEBUFFER, 0);
+    }
+}
\ No newline at end of file
diff --git a/source/engine/graphics/back/buffers/FrameBuffer.hpp b/source/engine/graphics/back/buffers/FrameBuffer.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..782ef844720d653a3dc7cec20c4c1e6da95fee3b
--- /dev/null
+++ b/source/engine/graphics/back/buffers/FrameBuffer.hpp
@@ -0,0 +1,30 @@
+#pragma once
+
+#include "Buffer.hpp"
+#include "../textures/Texture.hpp"
+
+namespace megu {
+    class FrameBuffer : public Buffer {
+        private:
+            GLuint _id;
+            GLuint _rbo_id;
+            Texture _texture;
+
+        public:
+            FrameBuffer() = delete;
+            FrameBuffer(GLuint width, GLuint height);
+   virtual ~FrameBuffer();
+
+            inline const Texture & texture() const {return this->_texture;}
+            GLuint rbo_identifier() const {return this->_rbo_id;}
+
+            inline virtual GLuint identifier() const {return this->_id;}
+
+            bool usable() const;
+
+            virtual void bind() const;
+            virtual void unbind() const;
+
+            static void BindDefaultFrameBuffer();
+    }; 
+}
\ No newline at end of file
diff --git a/source/engine/graphics/back/buffers/Layout.hpp b/source/engine/graphics/back/buffers/Layout.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..faab8e0d01d0b0519c3aee305dea954a26bbd7e7
--- /dev/null
+++ b/source/engine/graphics/back/buffers/Layout.hpp
@@ -0,0 +1,26 @@
+#pragma once
+
+#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 {
+        inline size_t weight(const Layout & layout) {
+            return std::accumulate(layout.begin(), layout.end(), 0);
+        }
+
+        enum Value : unsigned char {
+            POSITION            = 3,
+            FLAT                = 2,
+            COLOR               = 3,
+            NORMAL              = 3,
+            TEXTURE             = 2,
+            BORDER              = 2,
+            ID                  = 1,
+        };
+    }
+}
\ No newline at end of file
diff --git a/source/engine/graphics/back/buffers/UniformeBuffer.hpp b/source/engine/graphics/back/buffers/UniformeBuffer.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..e1474ae3aaa32144894645b4e3de2efb4f95c1d3
--- /dev/null
+++ b/source/engine/graphics/back/buffers/UniformeBuffer.hpp
@@ -0,0 +1,36 @@
+#pragma once
+
+#include "Buffer.hpp"
+
+#include <optional>
+#include <string>
+#include <map>
+
+#include "../shaders/Program.hpp"
+
+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();
+
+            inline GLuint index(const Program & program) const {return this->_programs.at(&program);} 
+            inline std::optional<T> data() const {this->_data != nullptr ? std::optional<T>(*this->_data) : std::optional<T>();}
+            
+            void setData(T *);
+            void attach(const std::string &, const Program &);
+
+            inline virtual GLuint identifier() const {return this->_id;}
+
+            virtual void bind() const;
+            virtual void unbind() const;
+    }; 
+}
+
+#include "UniformeBuffer.tpp"
\ No newline at end of file
diff --git a/source/engine/graphics/back/buffers/UniformeBuffer.tpp b/source/engine/graphics/back/buffers/UniformeBuffer.tpp
new file mode 100644
index 0000000000000000000000000000000000000000..805ecf0a2e2328e7784a9e4bf9c1ff4a1762faad
--- /dev/null
+++ b/source/engine/graphics/back/buffers/UniformeBuffer.tpp
@@ -0,0 +1,45 @@
+#include "UniformeBuffer.hpp"
+
+namespace megu {
+    template <class T>
+    UniformeBuffer<T>::UniformeBuffer(T * data)
+    : _data(data), _id(0) {
+        glCreateBuffers(1, &this->_id);
+        glBindBuffer(GL_UNIFORM_BUFFER, this->_id);
+        glBufferData(GL_UNIFORM_BUFFER, sizeof(T), data, GL_DYNAMIC_DRAW);
+    }
+
+    template <class T>
+    UniformeBuffer<T>::~UniformeBuffer() {
+        glDeleteBuffers(1, &this->_id);
+    }
+
+    template <class T>
+    void UniformeBuffer<T>::setData(T * data) {
+        this->_data = data;
+        glBindBuffer(GL_UNIFORM_BUFFER, this->_id);
+        glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(T), data);
+    }
+
+    template <class T>
+    void UniformeBuffer<T>::attach(const std::string & name, const Program & program) {
+        this->_programs.insert(std::pair<const Program *, GLuint>(&program, 0));
+        glBindBuffer(GL_UNIFORM_BUFFER, this->_id);
+        this->_programs[&program] = glGetUniformBlockIndex(program.id(), name.c_str());
+		glBindBufferBase(GL_UNIFORM_BUFFER, this->_programs[&program], this->_id);
+    }
+
+    template <class T>
+    void UniformeBuffer<T>::bind() const {
+        glBindBuffer(GL_UNIFORM_BUFFER, this->_id);
+    }
+
+    template <class T>
+    void UniformeBuffer<T>::unbind() const {
+        GLint binded = 0;
+        glGetIntegerv(GL_UNIFORM_BUFFER_BINDING, &binded);
+        if(static_cast<GLuint>(binded) == this->_id) {
+            glBindBuffer(GL_UNIFORM_BUFFER, 0);
+        }
+    }
+}
\ No newline at end of file
diff --git a/source/engine/graphics/back/buffers/VertexArray.cpp b/source/engine/graphics/back/buffers/VertexArray.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ad2d67c556d534c00c85d73a8eae8456f0a9d27a
--- /dev/null
+++ b/source/engine/graphics/back/buffers/VertexArray.cpp
@@ -0,0 +1,59 @@
+#include "VertexArray.hpp"
+
+namespace megu {
+    VertexArray::VertexArray(bool binded) 
+    : _vao(0) {
+        glGenVertexArrays(1, &this->_vao);
+
+        if(binded) {
+            this->bind();
+        }
+    }
+
+    VertexArray::~VertexArray() {
+        this->unbind();
+        glDeleteVertexArrays(1,&this->_vao);
+    }
+
+    void VertexArray::bind() const {
+        if(this->_vao != 0) {
+            glBindVertexArray(this->_vao);
+        }
+    }
+
+    void VertexArray::unbind()const {
+        GLint vao;
+        glGetIntegerv(GL_ARRAY_BUFFER, &vao);
+        if(static_cast<GLuint>(vao) == this->_vao) {
+            glBindVertexArray(0);
+        }
+    }
+
+    bool VertexArray::operator==(const VertexArray & vao) const {
+        return this->_vao == vao._vao;
+    }
+
+    bool VertexArray::operator!=(const VertexArray & vao) const {
+        return this->_vao != vao._vao;
+    }
+
+    bool VertexArray::operator>(const VertexArray & vao) const {
+        return this->_vao > vao._vao;
+    }
+
+    bool VertexArray::operator>=(const VertexArray & vao) const {
+        return this->_vao >= vao._vao;
+    }
+
+    bool VertexArray::operator<(const VertexArray & vao) const {
+        return this->_vao < vao._vao;
+    }
+
+    bool VertexArray::operator<=(const VertexArray & vao) const {
+        return this->_vao <= vao._vao;
+    }
+
+    std::strong_ordering VertexArray::operator<=>(const VertexArray & vao) const {
+        return this->_vao <=> vao._vao; 
+    }
+}
\ No newline at end of file
diff --git a/source/engine/graphics/back/buffers/VertexArray.hpp b/source/engine/graphics/back/buffers/VertexArray.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..200a3eb6cf5eb96ab77bfcce74201ba415054c59
--- /dev/null
+++ b/source/engine/graphics/back/buffers/VertexArray.hpp
@@ -0,0 +1,33 @@
+#pragma once
+
+#include <compare>
+#include <GL/glew.h>
+
+#include "Buffer.hpp"
+
+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 void bind() const;
+            virtual void unbind() const;
+
+            bool operator==(const VertexArray &) const;
+            bool operator!=(const VertexArray &) const;
+            bool operator<=(const VertexArray &) const;
+            bool operator>=(const VertexArray &) const;
+
+            bool operator<(const VertexArray &) const;
+            bool operator>(const VertexArray &) const;
+
+            std::strong_ordering operator<=>(const VertexArray &) const;
+    };
+}
\ No newline at end of file
diff --git a/source/engine/graphics/back/buffers/VerticeBuffer.cpp b/source/engine/graphics/back/buffers/VerticeBuffer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..1a883d5ae2ef0f4087ad422903ae3686db7bb5cd
--- /dev/null
+++ b/source/engine/graphics/back/buffers/VerticeBuffer.cpp
@@ -0,0 +1,110 @@
+#include "VerticeBuffer.hpp"
+
+#include <list>
+
+namespace megu {
+    VerticeBuffer::VerticeBuffer(const VertexArray & vao,const Layout_Initializer & attributes,size_t size,uint32_t 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)
+    : DynamicBuffer(vertices.size(), vertices.size()), _vao(&vao), _id(0), _mode(mode), _layout(attributes) {
+        this->generate(vertices);
+    }
+
+    VerticeBuffer::~VerticeBuffer() {
+        this->unbind();
+        glDeleteBuffers(1, &this->_id);
+    }
+
+    GLuint VerticeBuffer::identifier() const {
+        return this->_id;
+    }  
+
+    size_t VerticeBuffer::weight() const {
+        return layout::weight(this->_layout);
+    }
+
+    size_t VerticeBuffer::vertices() const {
+        return this->size() / this->weight();
+    }
+
+    void VerticeBuffer::bind() const {
+        if(this->_id != 0) {
+            this->_vao->bind();
+            glBindBuffer(GL_ARRAY_BUFFER, this->_id);
+        }
+    }
+
+    void VerticeBuffer::unbind() const {
+        GLint vbo = 0;
+        glGetIntegerv(GL_ARRAY_BUFFER, &vbo);
+        if(static_cast<GLuint>(vbo) == this->_id) {
+            this->_vao->unbind();
+            glBindBuffer(GL_ARRAY_BUFFER, 0);
+        }
+    }
+
+    void VerticeBuffer::generate(const std::vector<float> & vertices) {
+        this->_vao->bind();
+
+        if(this->_id != 0) {
+            glBindBuffer(GL_ARRAY_BUFFER,0);
+            glDeleteBuffers(1, &this->_id);
+        }
+
+        glGenBuffers(1,&this->_id);
+        glBindBuffer(GL_ARRAY_BUFFER, this->_id);
+        glBufferData(GL_ARRAY_BUFFER, this->max_size()*sizeof(float), vertices.size() == 0 ? NULL : vertices.data(), this->_mode);
+
+        uint32_t layer = 0,accumulateWeight = 0,totalWeight = static_cast<uint32_t>(this->weight());
+        for(uint8_t attribute : this->_layout) {
+            glVertexAttribPointer(layer, attribute, GL_FLOAT, GL_FALSE, totalWeight * sizeof(float), (void*)(accumulateWeight * sizeof(float)));
+            glEnableVertexAttribArray(layer++);
+            accumulateWeight += attribute;
+        }
+    }
+
+    bool VerticeBuffer::compare(const Layout & layout) const {
+        return this->_layout == layout;
+    }
+
+    bool VerticeBuffer::operator==(const VerticeBuffer & vbo) const {
+        return this->_id == vbo._id;
+    }
+
+    bool VerticeBuffer::operator!=(const VerticeBuffer & vbo) const {
+        return this->_id != vbo._id;
+    }
+
+    bool VerticeBuffer::operator>(const VerticeBuffer & vbo) const {
+        return this->_id > vbo._id;
+    }
+
+    bool VerticeBuffer::operator>=(const VerticeBuffer & vbo) const {
+        return this->_id >= vbo._id;
+    }
+
+    bool VerticeBuffer::operator<(const VerticeBuffer & vbo) const {
+        return this->_id < vbo._id;
+    }
+
+    bool VerticeBuffer::operator<=(const VerticeBuffer & vbo) const {
+        return this->_id <= vbo._id;
+    }
+
+    std::strong_ordering VerticeBuffer::operator<=>(const VerticeBuffer & vbo) const {
+        return this->_id <=> vbo._id; 
+    }
+
+    VerticeBuffer & operator<<(VerticeBuffer & vbo,const std::initializer_list<float> & data) {
+        vbo.push_back(data);
+        return vbo;
+    }
+
+    VerticeBuffer & operator<<(VerticeBuffer & vbo,const std::vector<float> & data) {
+        vbo.push_back(data);
+        return vbo;
+    }
+}
\ No newline at end of file
diff --git a/source/engine/graphics/back/buffers/VerticeBuffer.hpp b/source/engine/graphics/back/buffers/VerticeBuffer.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..215341125ea34c775ff394ffdd62a2247f3a6789
--- /dev/null
+++ b/source/engine/graphics/back/buffers/VerticeBuffer.hpp
@@ -0,0 +1,55 @@
+#pragma once
+
+#include "DynamicBuffer.hpp"
+
+#include <compare>
+
+#include "VertexArray.hpp"
+#include "Layout.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 VerticeBuffer &) = delete;
+   virtual ~VerticeBuffer();
+
+            const Layout & layout() const {return this->_layout;}
+
+            size_t weight() const;
+            size_t vertices() const;
+
+            virtual GLuint identifier() const;
+           
+            virtual void bind() const;
+            virtual void unbind() const;
+
+            virtual void generate(const std::vector<float> &);
+
+            bool compare(const Layout &) const;
+
+            bool operator==(const VerticeBuffer &) const;
+            bool operator!=(const VerticeBuffer &) const;
+            bool operator<=(const VerticeBuffer &) const;
+            bool operator>=(const VerticeBuffer &) const;
+            
+            bool operator<(const VerticeBuffer &) const;
+            bool operator>(const VerticeBuffer &) const;
+
+            std::strong_ordering operator<=>(const VerticeBuffer &) const;
+
+            friend VerticeBuffer & operator<<(VerticeBuffer &, const std::initializer_list<float> &);
+            friend VerticeBuffer & operator<<(VerticeBuffer &, const std::vector<float> &);
+    };
+
+    
+}
\ No newline at end of file
diff --git a/source/engine/graphics/back/cameras/Camera.hpp b/source/engine/graphics/back/cameras/Camera.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..bc062fa1a20204fabf6300ac58e8631a6f7f4b8e
--- /dev/null
+++ b/source/engine/graphics/back/cameras/Camera.hpp
@@ -0,0 +1,18 @@
+#pragma once
+
+#include <glm/mat4x4.hpp>
+
+namespace megu {
+    class Camera {
+        protected:
+            enum Update_Flags {
+                NONE        = 0,
+                VIEW        = 1,
+                PROJECTION  = 2,
+            };
+
+        public:
+            virtual const glm::mat4 & view() const = 0;
+            virtual const glm::mat4 & projection() const = 0;
+    };
+}
\ No newline at end of file
diff --git a/source/engine/graphics/back/cameras/Target.cpp b/source/engine/graphics/back/cameras/Target.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..522184419ba1c59a4843d09776d3d6184b678a2b
--- /dev/null
+++ b/source/engine/graphics/back/cameras/Target.cpp
@@ -0,0 +1,84 @@
+#include "Target.hpp"
+
+#include <glm/gtc/matrix_transform.hpp>
+
+#include <iostream>
+
+namespace megu {
+    Target::Target(const glm::vec3 & position, const glm::vec3 & target, double fov, double near, double far)
+    : _position(position), _target(target), _rotation(0.f, 0.f, 0.f), _view(1.f), _projection(1.f), _fov(fov), _ratio(1.f), _near(near), _far(far), _update(0) {
+        this->update(Update_Flags::VIEW | Update_Flags::PROJECTION);
+    }
+
+    void Target::update(uint8_t flags) const {
+        this->_update |= flags;
+        if(this->_update != Update_Flags::NONE) {
+
+            if((this->_update & Update_Flags::VIEW) != 0) {
+                this->_view = glm::lookAt(this->_position, this->_target, glm::vec3(0.0f, 1.0f, 0.0f));
+                this->_view = glm::rotate(this->_view, glm::radians(this->_rotation.x), {1.f, 0.f, 0.f});
+                this->_view = glm::rotate(this->_view, glm::radians(this->_rotation.y), {0.f, 1.f, 0.f});
+                this->_view = glm::rotate(this->_view, glm::radians(this->_rotation.z), {0.f, 0.f, 1.f});
+            }
+
+            if((this->_update & Update_Flags::PROJECTION) != 0) {
+                this->_projection = glm::perspective(glm::radians(this->_fov), this->_ratio, this->_near, this->_far);
+            }   
+
+            this->_update = Update_Flags::NONE;
+        }
+    }
+
+    void Target::setPosition(double x, double y, double z) {
+        this->_position = {x, y, z};
+        this->_update |= VIEW;
+    }
+
+    void Target::setTarget(double x, double y, double z) {
+        this->_target = {x, y, z};
+        this->_update |= VIEW;
+    }
+
+    void Target::setRotation(double x, double y, double z) {
+        this->_rotation = {x, y, z};
+        this->_update |= VIEW;
+    }
+
+    void Target::setFov(double fov) {
+        this->_fov = fov;
+        this->_update |= PROJECTION;
+    }
+
+    void Target::setRatio(double ratio) {
+        this->_ratio = ratio;
+        this->_update |= PROJECTION;
+    }
+
+    void Target::setViewDistance(double near, double far) {
+        this->_near = near;
+        this->_far = far;
+        this->_update |= PROJECTION;
+    }
+
+    void Target::move(const glm::vec3 & movement) {
+        this->_position += movement;
+        this->_update |= VIEW; 
+    }
+
+    void Target::rotate(const glm::vec3 & rotation) {
+        this->_rotation += rotation;
+        this->_view = glm::rotate(this->_view, glm::radians(rotation.x), {1.f, 0.f, 0.f});
+        this->_view = glm::rotate(this->_view, glm::radians(rotation.y), {0.f, 1.f, 0.f});
+        this->_view = glm::rotate(this->_view, glm::radians(rotation.z), {0.f, 0.f, 1.f});
+    }
+
+    const glm::mat4 & Target::view() const {
+        this->update();
+        return this->_view;
+    }
+
+    const glm::mat4 & Target::projection() const {
+        this->update();
+        return this->_projection;
+    }
+}
\ No newline at end of file
diff --git a/source/engine/graphics/back/cameras/Target.hpp b/source/engine/graphics/back/cameras/Target.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..04bc2dfa58f2e48429caa799b523d478d4accef8
--- /dev/null
+++ b/source/engine/graphics/back/cameras/Target.hpp
@@ -0,0 +1,54 @@
+#pragma once
+
+#include "Camera.hpp"
+
+#include <glm/vec3.hpp>
+
+namespace megu {
+    class Target : public Camera {
+        private:
+            glm::vec3 _position;
+            glm::vec3 _target;
+            glm::vec3 _rotation;
+
+            mutable glm::mat4 _view;
+            mutable glm::mat4 _projection;
+
+            double _fov;
+            double _ratio;
+            double _near;
+            double _far;
+
+            mutable uint8_t _update;
+
+            void update(uint8_t flags = NONE) const;
+
+        public:
+            Target(const glm::vec3 & = {0.f, 0.f, 3.f}, const glm::vec3 & = {0.f, 0.f, 0.f}, double=65.f, double=0.1f, double=100.f);
+
+            inline const glm::vec3 & getPosition() const {return this->_position;}
+            inline const glm::vec3 & getTarget() const {return this->_target;}
+
+            inline double getFov() const {return this->_fov;}
+            inline double getRatio() const {return this->_ratio;}
+            inline double getNear() const {return this->_near;}
+            inline double getFar() const {return this->_far;}
+
+            void setPosition(double, double, double);
+            void setTarget(double, double, double);
+            void setRotation(double, double, double);
+            
+            void setFov(double fov);
+            void setRatio(double ratio);
+            void setViewDistance(double near, double far); 
+
+            void move(const glm::vec3 & movement);
+            void rotate(const glm::vec3 & rotation);
+
+            inline void move(double x, double y, double z = 0.0) {this->move({x, y, z});}
+            inline void rotate(double pitch, double yaw, double roll = 0.0) {this->rotate({pitch, yaw, roll});}
+ 
+            const glm::mat4 & view() const;
+            const glm::mat4 & projection() const;
+    };
+}
\ No newline at end of file
diff --git a/source/engine/graphics/back/cameras/View.cpp b/source/engine/graphics/back/cameras/View.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..5f81d5cc6145a836b2c9a5e7c5081f99b7577e90
--- /dev/null
+++ b/source/engine/graphics/back/cameras/View.cpp
@@ -0,0 +1,69 @@
+#include "View.hpp"
+
+#include <glm/gtc/matrix_transform.hpp>
+
+namespace megu {
+    View::View(float x, float y, float w, float h, float near, float far) 
+    : View({x, y}, {w, h}, near, far) {}
+
+    View::View(const glm::vec2 & position, const glm::vec2 & dimension, float near, float far)
+    : _view(1.f), _projection(1.f), _position(position), _dimension(dimension), _roll(0.f), _near(near), _far(far), _update() {
+        this->update(Update_Flags::VIEW | Update_Flags::PROJECTION);
+    }
+
+    void View::update(uint8_t flags) const {
+        this->_update |= flags;
+        if(this->_update != Update_Flags::NONE) {
+            if((this->_update & VIEW) != 0) {
+                this->_view = glm::rotate(this->_view, this->_roll, {0.0, 0.0, 1.0});
+            }
+
+            if((this->_update & PROJECTION) != 0) {
+                glm::vec2 center = {this->_position.x + this->_dimension.x / 2, this->_position.y + this->_dimension.y / 2};
+                this->_projection = glm::ortho(center.x - this->_dimension.x/2, center.x + this->_dimension.x/2, center.y - this->_dimension.y/2, center.y + this->_dimension.y/2, this->_near, this->_far);
+            }
+        }
+        this->_update = Update_Flags::NONE;
+    }
+
+    void View::setPosition(const glm::vec2 & position) {
+        this->_position = position;
+        this->_update |= Update_Flags::PROJECTION;
+    }
+
+    void View::setDimension(const glm::vec2 & dimension) {
+        this->_dimension = dimension;
+        this->_update |= Update_Flags::PROJECTION;
+    }
+
+    void View::setDistance(float near, float far) {
+        this->_near = near;
+        this->_far = far;
+        this->_update |= Update_Flags::PROJECTION;
+    }
+
+    void View::move(const glm::vec2 & position) {
+        this->_position += position;
+        this->_update |= Update_Flags::PROJECTION;
+    }
+
+    void View::setRoll(float roll) {
+        this->_roll = roll;
+        this->_update |= Update_Flags::VIEW;
+    }
+
+    void View::roll(float roll) {
+        this->_roll += roll;
+        this->_update |= Update_Flags::VIEW;
+    } 
+
+    const glm::mat4 & View::view() const {
+        this->update();
+        return this->_view;
+    }
+
+    const glm::mat4 & View::projection() const {
+        this->update();
+        return this->_projection;
+    }
+}
\ No newline at end of file
diff --git a/source/engine/graphics/back/cameras/View.hpp b/source/engine/graphics/back/cameras/View.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..4792d6cf7292bb0bdbd0b72cc48f7e3089d9bb58
--- /dev/null
+++ b/source/engine/graphics/back/cameras/View.hpp
@@ -0,0 +1,51 @@
+#pragma once
+
+#include "Camera.hpp"
+
+#include <glm/vec2.hpp>
+#include <algorithm>
+#include <iterator>
+#include <set>
+
+namespace megu {
+    class View : public Camera {
+        private:
+            mutable glm::mat4 _view;
+            mutable glm::mat4 _projection;
+            glm::vec2 _position;
+            glm::vec2 _dimension;
+            
+            float _roll;
+            float _near;
+            float _far;
+
+            mutable uint8_t _update;
+            
+            void update(uint8_t = NONE) const;
+
+        public:
+            View() = delete;
+            View(float x, float y, float w, float h, float = -10, float = 10.0);
+            View(const glm::vec2 &, const glm::vec2 &, float = -10, float = 10.0);
+
+            inline const glm::vec2 & position() const {return this->_position;}
+            inline const glm::vec2 & dimension() const {return this->_dimension;}
+            
+            inline float roll() const {return this->_roll;}
+            inline float getNear() const {return this->_near;}
+            inline float getFar() const {return this->_far;}
+
+            void setPosition(const glm::vec2 &);
+            void setDimension(const glm::vec2 &);
+            void setRoll(float);
+            void setDistance(float near, float far);
+
+            void move(const glm::vec2 &);
+            void roll(float);
+
+            inline void move(float x, float y) {this->move({x, y});}
+
+            const glm::mat4 & view() const;
+            const glm::mat4 & projection() const;
+    };
+}
\ No newline at end of file
diff --git a/source/engine/graphics/back/cameras/Walkaround.cpp b/source/engine/graphics/back/cameras/Walkaround.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..650cae67c5c0634574116dda9c0a3d9609fe2516
--- /dev/null
+++ b/source/engine/graphics/back/cameras/Walkaround.cpp
@@ -0,0 +1,102 @@
+#include "Walkaround.hpp"
+
+#include <glm/gtc/matrix_transform.hpp>
+
+namespace megu {
+    Walkaround::Walkaround()
+    : Walkaround(glm::vec3(0.f, 0.f, 3.f)) {}
+
+    Walkaround::Walkaround(const glm::vec3 & position, double fov, double ratio, double near, double far)
+    : _view(1.f), 
+      _projection(1.f), 
+      _position(position), 
+      _up(0.f, 1.f, 0.f),
+      _pitch(0.f),
+      _yaw(-90.f),
+      _roll(0.f),
+      _fov(fov),
+      _ratio(ratio),
+      _near(near),
+      _far(far),
+      _update(Update_Flags::NONE) {
+        this->update(Update_Flags::VIEW | Update_Flags::PROJECTION);
+    }
+
+    void Walkaround::update(uint8_t flags) const {
+        this->_update |= flags;
+        if(this->_update != Update_Flags::NONE) {
+            if((this->_update & VIEW) != 0) {
+                glm::vec3 front;
+                front.x = static_cast<float>(std::cos(glm::radians(this->_yaw)) * std::cos(glm::radians(this->_pitch)));
+                front.y = static_cast<float>(std::sin(glm::radians(this->_pitch)));
+                front.z = static_cast<float>(std::sin(glm::radians(this->_yaw)) * std::cos(glm::radians(this->_pitch)));
+            
+                glm::vec right = glm::normalize(glm::cross(front, this->_up));
+                glm::mat4 roll_mat = glm::rotate(glm::mat4(1.f), (float)glm::radians(this->_roll), front);
+                
+                this->_up = glm::normalize(glm::cross(right, front));
+                this->_up = glm::mat3(roll_mat) * this->_up;
+               
+                this->_view = glm::lookAt(this->_position, this->_position + front, this->_up);
+            }
+
+            if((this->_update & PROJECTION) != 0) {
+                this->_projection = glm::perspective(glm::radians(this->_fov), this->_ratio, this->_near, this->_far);
+            }
+        }
+        this->_update = Update_Flags::NONE;
+    }
+
+    void Walkaround::setPosition(const glm::vec3 & position) {
+        this->_position = position;
+        this->_update |= Update_Flags::VIEW;
+    }
+
+    void Walkaround::setPitch(double pitch) {
+        this->_pitch = pitch;
+        this->_update |= Update_Flags::VIEW;
+    }
+
+    void Walkaround::setYaw(double yaw) {
+        this->_yaw = yaw;
+        this->_update |= Update_Flags::VIEW;
+    }
+
+    void Walkaround::setRoll(double roll) {
+        this->_roll = std::fmod(roll, 360.0);
+        this->_update |= Update_Flags::VIEW;
+    }
+
+    void Walkaround::setRatio(double ratio) {
+        this->_ratio = ratio;
+        this->_update |= Update_Flags::PROJECTION;
+    }
+
+    void Walkaround::setDistance(double near, double far) {
+        this->_near = near;
+        this->_far = far;
+        this->_update |= Update_Flags::PROJECTION;
+    }
+
+    void Walkaround::move(const glm::vec3 & movement) {
+        this->_position += movement;
+        this->_update |= Update_Flags::VIEW;
+    }
+
+    void Walkaround::rotate(const glm::vec3 & rotation) {
+        this->_pitch += rotation.x;
+        this->_yaw += rotation.y;
+        this->_roll += rotation.z;
+        this->_update |= Update_Flags::VIEW;
+    }
+
+    const glm::mat4 & Walkaround::view() const {
+        this->update();
+        return this->_view;
+    }
+
+    const glm::mat4 & Walkaround::projection() const {
+        this->update();
+        return this->_projection;
+    }
+}
\ No newline at end of file
diff --git a/source/engine/graphics/back/cameras/Walkaround.hpp b/source/engine/graphics/back/cameras/Walkaround.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..893cfa95b37c72f04a22e93afcaed3a9f3d34fff
--- /dev/null
+++ b/source/engine/graphics/back/cameras/Walkaround.hpp
@@ -0,0 +1,63 @@
+#pragma once
+
+#include "Camera.hpp"
+
+#include <glm/vec3.hpp>
+
+namespace megu {
+    class Walkaround : public Camera {
+        private:
+            mutable glm::mat4 _view;
+            mutable glm::mat4 _projection;
+
+            glm::vec3 _position;
+            mutable glm::vec3 _up;
+
+            double _pitch;
+            double _yaw;
+            double _roll;
+
+            double _fov;
+            double _ratio;
+            double _near;
+            double _far;
+
+            mutable uint8_t _update;
+
+            void update(uint8_t = NONE) const;
+
+        public:
+            Walkaround();
+            Walkaround(const glm::vec3 &, double = 70.0f, double = 1.f, double = 0.1f, double = 100.0f);
+
+            inline const glm::vec3 & position() const {return this->_position;}
+            
+            inline double pitch() const {return this->_pitch;}
+            inline double roll() const {return this->_roll;}
+            inline double yaw() const {return this->_yaw;}
+
+            inline double ratio() const {return this->_ratio;}
+            inline double getNear() const {return this->_near;}
+            inline double getFar() const {return this->_far;}
+            inline double fov() const {return this->_fov;}
+
+            void setPosition(const glm::vec3 &);
+            void setPitch(double);
+            void setYaw(double);
+            void setRoll(double);
+            void setRatio(double);
+            void setDistance(double near, double far);
+
+            void move(const glm::vec3 &);
+            void rotate(const glm::vec3 &);
+
+            inline void move(double x, double y, double z = 0.0) {this->move({x, y, z});}
+            inline void rotate(double pitch, double yaw, double roll = 0.0) {this->rotate({pitch, yaw, roll});}
+
+            inline void setRatio(double w, double h) {this->setRatio(w/h);}
+
+            const glm::mat4 & view() const;
+            const glm::mat4 & projection() const;
+            
+    };
+}
\ No newline at end of file
diff --git a/source/engine/graphics/back/geometry/Transform.cpp b/source/engine/graphics/back/geometry/Transform.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..1b931b5b59e2e6b651afe8743004f75f7122bd3b
--- /dev/null
+++ b/source/engine/graphics/back/geometry/Transform.cpp
@@ -0,0 +1,87 @@
+#include "Transform.hpp"
+
+#include <glm/gtc/matrix_transform.hpp>
+
+#include <iostream>
+
+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);
+    }
+
+    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) {
+            this->_rotation.x = angle; 
+        }
+
+        if((axis & Axis::Y) != 0) {
+            this->_rotation.y = angle; 
+        }
+
+        if((axis & Axis::Z) != 0) {
+            this->_rotation.z = angle; 
+        }
+
+        this->_updated = true;
+    }
+
+    void Transform::setScaling(const glm::vec3 & scaling) {
+        this->_scaling = scaling;
+        this->_updated = true;
+    }
+
+    void Transform::move(const glm::vec3 & position) {
+        this->_position += position;
+        this->_updated = true;
+    }
+
+    void Transform::rotate(float angle, uint8_t axis) {
+        if((axis & Axis::X) != 0) {
+            this->_rotation.x += angle; 
+        }
+
+        if((axis & Axis::Y) != 0) {
+            this->_rotation.y += angle; 
+        }
+
+        if((axis & Axis::Z) != 0) {
+            this->_rotation.z += angle; 
+        }
+
+        this->_updated = true;
+    }
+
+    void Transform::scale(const glm::vec3 & scaling) {
+        this->_scaling += scaling;
+        this->_updated = true;
+    }
+
+    const glm::mat4x4 & Transform::model() const {
+        if(this->_updated) {
+            glm::mat4x4 model = glm::mat4x4(1.f);
+
+            model = glm::translate(model, this->_position);
+            model = glm::translate(model, this->_origine);
+           
+            model = glm::rotate(model, glm::radians(this->_rotation.z), {0.f, 0.f, 1.f});
+            model = glm::rotate(model, glm::radians(this->_rotation.y), {0.f, 1.f, 0.f});
+            model = glm::rotate(model, glm::radians(this->_rotation.x), {1.f, 0.f, 0.f});
+
+            model = glm::translate(model, -this->_origine);
+            model = glm::scale(model, this->_scaling);
+            
+            this->_model = model;
+            this->_updated = false;
+        }
+        return this->_model;
+    }
+}
\ No newline at end of file
diff --git a/source/engine/graphics/back/geometry/Transform.hpp b/source/engine/graphics/back/geometry/Transform.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..0f1ec2be7da951ead7e9d3e0e95b2f8ec25abed4
--- /dev/null
+++ b/source/engine/graphics/back/geometry/Transform.hpp
@@ -0,0 +1,69 @@
+#pragma once
+
+#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;
+
+        public:
+            enum Axis : unsigned char {
+                X = 1,
+                Y = 2, 
+                Z = 4
+            };
+
+            Transform(const glm::mat4 & = glm::mat4(1.f));
+            Transform(const glm::vec3 &, float, uint8_t, const glm::vec3 & = {1.f, 1.f, 1.f});
+
+            inline const glm::vec3 & position() const {return this->_position;}
+            inline glm::vec3 & position() {return this->_position;}
+
+            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 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 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 scale(const glm::vec3 &);
+            inline void scale(float x, float y, float z = 0.0f) {this->scale({x, y, z});}
+            
+            virtual const glm::mat4x4 & model() const;
+
+            inline void translate(const glm::vec3 & translation) {this->move(translation);}
+    };
+}
\ No newline at end of file
diff --git a/source/engine/graphics/back/shaders/Program.cpp b/source/engine/graphics/back/shaders/Program.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..aa7f73d2b881f7c21e7801207bb84f39022594ba
--- /dev/null
+++ b/source/engine/graphics/back/shaders/Program.cpp
@@ -0,0 +1,155 @@
+#include "Program.hpp"
+
+#include <GLM/gtc/type_ptr.hpp>
+#include "../../errors/Shader_Error.hpp"
+
+namespace megu {
+    Program::Program() 
+    : _id(0), _usable(false), _attached(NONE) {
+        this->_id = glCreateProgram();
+    }
+
+    Program::~Program() {
+        glDeleteProgram(this->_id);
+    }
+
+    const uint8_t Program::Categorie(const Source::Categorie categorie) {
+        switch (categorie) {
+            case Source::Categorie::VERTEX:
+                return Bit_Categorie::VERTEX;
+
+            case Source::Categorie::FRAGMENT:
+                return Bit_Categorie::FRAGMENT;
+
+            case Source::Categorie::GEOMETRY:
+                return Bit_Categorie::GEOMETRY;
+            
+            case Source::Categorie::TESS_CONTROL:
+                return Bit_Categorie::TESS_CONTROL;
+
+            case Source::Categorie::TESS_EVALUATION:
+                return Bit_Categorie::TESS_CONTROL;
+
+            case Source::Categorie::COMPUTE:
+                return Bit_Categorie::COMPUTE;
+        
+            default:
+                return Bit_Categorie::NONE;
+        }
+    }
+
+    void Program::attach(const Source & source) {
+        if(source.usable()) {
+            glAttachShader(this->_id, source.id());
+            this->_attached |= Program::Categorie(source.categorie());
+        }
+    }
+
+    void Program::dettach(const Source & source) {
+        glDetachShader(this->_id, source.id());
+        this->_attached = this->_attached & ~Program::Categorie(source.categorie());
+        this->_usable = ((this->_attached & Bit_Categorie::VERTEX) != 0 && (this->_attached & Bit_Categorie::FRAGMENT) != 0);
+    }
+
+    void Program::link() {
+        this->_usable = ((this->_attached & Bit_Categorie::VERTEX) != 0 && (this->_attached & Bit_Categorie::FRAGMENT) != 0);
+        if(this->_usable) {
+            glLinkProgram(this->_id);
+
+            int success;
+            char infoLog[512];
+
+            glGetProgramiv(this->_id, GL_LINK_STATUS, &success);
+            if(!success) {
+                this->_usable = false;
+                glGetProgramInfoLog(this->_id, 512, NULL, infoLog);
+                throw error::shader_error(infoLog);
+            }
+        }
+        else {
+            if((this->_attached & Bit_Categorie::VERTEX) == 0) {
+                throw error::shader_error("Missing Vertex Source attached to Program");
+            }
+            else if((this->_attached & Bit_Categorie::FRAGMENT) == 0) {
+                throw error::shader_error("Missing Fragment Source attached to Program");
+            }
+        }
+    }
+
+    void Program::use() const {
+        if(this->_usable) {
+            glUseProgram(this->_id);
+        }
+    }
+
+    void Program::kill() {
+        this->_usable = false;
+        this->_attached = Bit_Categorie::NONE;
+        this->_id = glCreateProgram();
+    }
+
+    void Program::setUniform(const std::string & name, GLint value) const {
+        glUniform1i(glGetUniformLocation(this->_id, name.c_str()), value);
+    }
+
+    void Program::setUniform(const std::string & name, GLuint value) const {
+        glUniform1ui(glGetUniformLocation(this->_id, name.c_str()), value);
+    }
+
+    void Program::setUniform(const std::string & name, GLfloat value) const {
+        glUniform1f(glGetUniformLocation(this->_id, name.c_str()), value);
+    }
+
+    void Program::setUniform(const std::string & name, GLdouble value) const {
+        glUniform1d(glGetUniformLocation(this->_id, name.c_str()), value);
+    }
+
+    void Program::setUniform(const std::string & name, GLchar value) const {
+        this->setUniform(name,(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]);
+    }
+
+    void Program::setUniform(const std::string & name, const glm::vec2 & value) const {
+        glUniform2f(glGetUniformLocation(this->_id, name.c_str()), 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);
+    }
+
+    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);
+    }
+
+    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);
+    }
+
+    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);
+    }
+
+    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());
+    }
+
+    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());
+    }
+
+    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());
+    }
+
+    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());
+    }
+
+    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]));
+    }
+
+}
\ No newline at end of file
diff --git a/source/engine/graphics/back/shaders/Program.hpp b/source/engine/graphics/back/shaders/Program.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..a1b356262f3c1a9f015269da878cb980f8e646f3
--- /dev/null
+++ b/source/engine/graphics/back/shaders/Program.hpp
@@ -0,0 +1,68 @@
+#pragma once
+
+#include <GL/glew.h>
+#include <glm/mat4x4.hpp>
+#include <vector>
+
+#include "Source.hpp"
+
+namespace megu {
+    class Program {
+        private:
+            GLuint _id;
+            bool _usable;
+            uint8_t _attached;
+
+        protected:
+            enum Bit_Categorie {
+                NONE            = 0,
+                VERTEX          = 1,
+                FRAGMENT        = 2,
+                GEOMETRY        = 4,
+                TESS_CONTROL    = 8,
+                TESS_EVALUATION = 16,
+                COMPUTE         = 32,
+            }; 
+
+            static const uint8_t Categorie(const Source::Categorie);
+
+        public:
+            Program();
+            Program(const Program &) = delete;
+            Program(const Program &&) = delete;
+            Program operator=(const Program &) = delete;
+   virtual ~Program();
+
+            void attach(const Source &);
+            void dettach(const Source &);
+            void link();
+            void kill();
+
+            virtual void use() const;
+
+            inline GLuint id() const {return this->_id;}
+            inline bool usable() const {return this->_usable;}
+
+            inline void operator<<(const Source & source) {this->attach(source);}
+
+            void setUniform(const std::string &, GLint) const;
+            void setUniform(const std::string &, GLuint) const;
+            void setUniform(const std::string &, GLfloat) const;
+            void setUniform(const std::string &, GLdouble) const;
+            void setUniform(const std::string &, GLchar) const;
+
+            void setUniform(const std::string &, const glm::vec2 &) const;
+            void setUniform(const std::string &, const glm::vec3 &) const;
+            void setUniform(const std::string &, const glm::vec<3, uint32_t> &) const;
+            void setUniform(const std::string &, const glm::vec<3, int32_t> &)  const;
+            void setUniform(const std::string &, const glm::vec4 &) const;
+
+            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<GLfloat> &) const;
+            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;
+    };
+}
\ No newline at end of file
diff --git a/source/engine/graphics/back/shaders/Source.cpp b/source/engine/graphics/back/shaders/Source.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..aac5ab756eccbc710f203a340f9c3016b74fbe66
--- /dev/null
+++ b/source/engine/graphics/back/shaders/Source.cpp
@@ -0,0 +1,70 @@
+#include "Source.hpp"
+
+#include <filesystem>
+#include <fstream>
+#include <sstream>
+#include <exception>
+
+#include "../../errors/Shader_Error.hpp"
+
+namespace megu {
+    Source::Source() 
+    : _id(0), _categorie(Categorie::NONE), _path("") {
+
+    }
+
+    Source::Source(const std::filesystem::path & path, Categorie categorie) 
+    : _id(0), _categorie(categorie), _path("") {
+        this->load(path, categorie);
+    }
+
+    Source::~Source() {
+        glDeleteShader(this->_id);
+    }
+
+    void Source::load(const std::filesystem::path & path, Categorie categorie) {
+        if(this->_id != 0) {
+            this->release();
+        }
+
+        if(!std::filesystem::exists(path)) {
+            throw std::runtime_error(std::string("Can't open : ").append(path.string()));
+        }
+
+       
+        this->_path = path;
+        std::ifstream is(path);
+
+        if(is.fail()) {
+            throw std::runtime_error("Stream fail.");
+        }
+
+        std::stringstream buffer;
+        buffer << is.rdbuf();
+
+        std::string ssource = buffer.str();
+        const char * ccsource = ssource.c_str();
+
+        this->_id = glCreateShader(static_cast<GLenum>(categorie));
+        this->_categorie = categorie;
+
+
+        glShaderSource(this->_id,1,&ccsource,NULL);
+        glCompileShader(this->_id);
+        buffer.clear();
+        
+        int success;
+        char infoLog[512];
+        glGetShaderiv(this->_id, GL_COMPILE_STATUS, &success);
+        if(!success) {
+            glGetShaderInfoLog(this->_id, 512, NULL, infoLog);
+            throw error::shader_error(infoLog, &this->_path);
+        }
+    }
+
+    void Source::release() {
+        glDeleteShader(this->_id);
+        this->_id = NO_SOURCE_ID;
+        this->_categorie = Categorie::NONE;
+    }
+}
\ No newline at end of file
diff --git a/source/engine/graphics/back/shaders/Source.hpp b/source/engine/graphics/back/shaders/Source.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..49a59f14f324b62c06d1788fa137ff4166155964
--- /dev/null
+++ b/source/engine/graphics/back/shaders/Source.hpp
@@ -0,0 +1,44 @@
+#pragma once
+
+#include <GL/glew.h>
+#include <filesystem>
+
+namespace megu {
+    class Source {
+        public:
+            enum class Categorie : GLenum {
+                NONE            = 0,
+                VERTEX          = GL_VERTEX_SHADER,
+                FRAGMENT        = GL_FRAGMENT_SHADER,
+                GEOMETRY        = GL_GEOMETRY_SHADER,
+                TESS_CONTROL    = GL_TESS_CONTROL_SHADER,
+                TESS_EVALUATION = GL_TESS_EVALUATION_SHADER,
+                COMPUTE         = GL_COMPUTE_SHADER,
+            };
+
+        private:
+            GLuint _id;
+            Categorie _categorie;
+            std::filesystem::path _path;
+
+        protected:
+            static constexpr GLuint NO_SOURCE_ID = 0;
+
+        public:
+            Source();
+            Source(const std::filesystem::path &, Categorie categorie);
+            Source(const Source &) = delete;
+            Source(const Source &&) = delete;
+            Source operator=(const Source &) = delete;
+           ~Source();
+
+            void load(const std::filesystem::path &, Categorie categorie);
+            void release();
+
+            inline GLuint id() const {return this->_id;}
+            inline Categorie categorie() const {return this->_categorie;}
+
+            inline bool usable() const {return this->_id != 0;}
+            inline const std::filesystem::path & path() const {return this->_path;}
+    };
+}
\ No newline at end of file
diff --git a/source/engine/graphics/back/shaders/UniformObject.hpp b/source/engine/graphics/back/shaders/UniformObject.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..d323b37c4c6c4cdd75594f72a05400dd9e93c420
--- /dev/null
+++ b/source/engine/graphics/back/shaders/UniformObject.hpp
@@ -0,0 +1,69 @@
+#pragma once
+
+#include <optional>
+#include <variant>
+#include <map>
+#include <string>
+
+#include "Program.hpp"
+
+namespace megu {
+    template <class... Ts>
+    struct overloaded : Ts ... {
+        using Ts::operator()...;
+    };
+
+    template <class... Ts> overloaded(Ts...) -> overloaded<Ts...>;
+
+    template <typename ... T>
+    class UniformObject {
+        private:
+            Program * _program;
+            std::map<std::string, std::variant<T ...>> _values; 
+
+        public:
+            UniformObject() : _program(nullptr) {}
+            UniformObject(Program & p) : _program(&p) {}
+           ~UniformObject() {}
+
+            template <typename U>
+            void add(const std::string & name, U data) {
+                this->_values.insert(std::pair<std::string, std::variant<T ...>>(name, std::variant<T ...>(data)));
+            }
+
+            template <typename U>
+            void set(const std::string & name, U data) {
+                this->_values.insert_or_assign(name, std::variant<T ...>(data));
+            }
+
+            template <typename U>
+            U get(const std::string & name) const {
+                return std::get<U>(this->_values.at(name));
+            }
+
+            bool contain(const std::string & name) const {
+                return this->_values.contains(name);
+            }
+
+            inline void apply() {
+                if(this->_program != nullptr) {
+                    this->apply(*this->_program);
+                }
+            }
+
+            void apply(const Program & prog) {
+                for(auto & value : this->_values) {
+                    const std::string name = value.first; 
+
+                    std::visit(overloaded{
+                        [&prog, &name](GLint & data) {       // Avoid error when passing GLint for Sample2D. 
+                            prog.setUniform(name, data);
+                        },
+                        [&prog, &name](auto & data){ 
+                            prog.setUniform(name, data);
+                        }
+                    }, value.second);          
+                }
+            } 
+    };
+}
\ No newline at end of file
diff --git a/source/engine/graphics/back/textures/Material.cpp b/source/engine/graphics/back/textures/Material.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ee4b81bf7a6b3ae68e2f0f0357c9f518908ea611
--- /dev/null
+++ b/source/engine/graphics/back/textures/Material.cpp
@@ -0,0 +1,47 @@
+#include "Material.hpp"
+
+#include <exception>
+
+#define STB_IMAGE_IMPLEMENTATION
+#include <stb/image/stb_image.h>
+
+namespace megu {
+    Material::Material()
+    : Texture(0, GL_TEXTURE_2D), _ressource("./") {
+
+    }
+
+    Material::Material(const std::string & path, bool invert, Texture::Format format)
+    : Texture(), _ressource() {
+        this->load(path, format, invert);
+    }
+
+    void Material::load(const std::string & path, Texture::Format format, 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;
+        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;
+            }
+        }
+
+        this->store(width, height, data, format);
+        stbi_image_free(data);
+    }
+}
\ No newline at end of file
diff --git a/source/engine/graphics/back/textures/Material.hpp b/source/engine/graphics/back/textures/Material.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..04074a23937001cb17e51745ab1a5171a35eb5dc
--- /dev/null
+++ b/source/engine/graphics/back/textures/Material.hpp
@@ -0,0 +1,23 @@
+#pragma once
+
+#include <filesystem>
+#include <string>
+
+#include "Texture.hpp"
+
+namespace megu {
+    class Material : public Texture {
+        private:
+            std::filesystem::path _ressource;
+        
+        public:
+            Material();
+            Material(const Material &) = delete;
+            Material(const std::string &, bool = false, Texture::Format = Texture::RGBA);
+            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);
+    };
+}
\ 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
new file mode 100644
index 0000000000000000000000000000000000000000..2320d7cb267274b790fc8b782aefbb1156a4fa23
--- /dev/null
+++ b/source/engine/graphics/back/textures/Shared_Material.cpp
@@ -0,0 +1,140 @@
+#include "Shared_Material.hpp"
+
+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 *>>();
+
+    Shared_Material::Shared_Material() 
+    : _material(std::make_shared<Material>()) {
+
+    }
+
+    Shared_Material::Shared_Material(const std::string & path, bool invert, Texture::Format format)
+    : _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);
+        }
+        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}));
+        }
+    }
+
+    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);
+        }
+        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_Material() {
+        if(Shared_Material::_shared.contains(this->_material->ressource())) {
+            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 {
+        return *this->_material.get();
+    }
+
+    GLuint Shared_Material::identifier() const {
+        return this->_material->identifier();
+    }
+
+    GLuint Shared_Material::format() const {
+        return this->_material->type();
+    }
+
+    uint16_t Shared_Material::width() const {
+        return this->_material->width();
+    }
+
+    uint16_t Shared_Material::height() const {
+        return this->_material->height();
+    }
+
+    const std::filesystem::path & Shared_Material::path() const {
+        return this->_material->ressource();
+    }
+
+    void Shared_Material::bind() const {
+        this->_material->bind();
+    }
+
+    void Shared_Material::bind(uint32_t slot) const {
+        this->_material->bind(slot);
+    }
+
+    void Shared_Material::load(const std::string & path, Texture::Format format, bool flip_y) {
+        if(!this->_material->ressource().empty()) {
+            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);
+        }
+        else {
+            this->_material->load(path, format, flip_y);
+            Shared_Material::_shared.insert(std::pair<std::filesystem::path,std::set<const 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);
+        }
+        else {
+            this->_material = std::shared_ptr<Material>(&material);
+        }
+    }
+
+    bool Shared_Material::valide() const {
+        return this->_material->valide();
+    }
+
+    bool Shared_Material::operator==(const Shared_Material & material) const {
+        return this->material() == material.material();
+    }
+
+    bool Shared_Material::operator!=(const Shared_Material & material) const {
+        return this->material() != material.material();
+    }
+
+    bool Shared_Material::operator>=(const Shared_Material & material) const {
+        return this->material() >= material.material();
+    }
+
+    bool Shared_Material::operator<=(const Shared_Material & material) const {
+        return this->material() <= material.material();
+    }
+
+    bool Shared_Material::operator>(const Shared_Material & material) const {
+        return this->material() > material.material();
+    }
+
+    bool Shared_Material::operator<(const Shared_Material & material) const {
+        return this->material() < material.material();
+    }
+
+    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();
+    }
+}
\ 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
new file mode 100644
index 0000000000000000000000000000000000000000..9247bdf1c5913a8a4bfd39536d914be988fda28a
--- /dev/null
+++ b/source/engine/graphics/back/textures/Shared_Material.hpp
@@ -0,0 +1,53 @@
+#pragma once
+
+#include <memory>
+#include <map>
+#include <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(Material &);
+   virtual ~Shared_Material();
+
+            const Material & material() const;
+
+            GLuint identifier() const;
+            GLuint format() const;
+
+            uint16_t width() const;
+            uint16_t height() const;
+
+            const std::filesystem::path & path() const;
+
+            void bind() const;
+            void bind(uint32_t slot) const;
+
+            void load(const std::string &, Texture::Format=Texture::RGB, bool=true);
+            void load(Material &);
+
+            bool valide() const;
+
+            bool operator==(const Shared_Material &) const;
+            bool operator!=(const Shared_Material &) const;
+            bool operator>=(const Shared_Material &) const;
+            bool operator<=(const Shared_Material &) const;
+            bool operator>(const Shared_Material &) const;
+            bool operator<(const Shared_Material &) const;
+
+            Material * operator->() const;
+
+            std::strong_ordering operator<=>(const Shared_Material &) 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
new file mode 100644
index 0000000000000000000000000000000000000000..0db023fa5bbcd9535ec222bdd644b4c6f6789bde
--- /dev/null
+++ b/source/engine/graphics/back/textures/Texture.cpp
@@ -0,0 +1,122 @@
+#include "Texture.hpp"
+
+#include <exception>
+#include <iostream>
+
+namespace megu {
+    Texture::Texture(GLuint slot, GLuint type) 
+    : _id(0), _type(type), _slot(slot) {
+        glGenTextures(1, &this->_id);
+        
+    }
+
+    Texture::~Texture() {
+        glDeleteTextures(1, &this->_id);
+    }
+
+    void Texture::bind() const {
+        glActiveTexture(GL_TEXTURE0 + this->_slot);
+        glBindTexture(this->_type, this->_id);
+    }
+
+    void Texture::bind(GLuint slot) const {
+        this->_slot = slot;
+        this->bind();
+    }
+
+    GLint Texture::width() const {
+        if(this->_id == 0) {
+            throw std::runtime_error("Void texture.");
+        }
+
+        GLint width;
+        glGetTexLevelParameteriv(this->_type, 0, GL_TEXTURE_WIDTH, &width);
+        return width;
+    }
+
+    GLint Texture::height() const {
+        if(this->_id == 0) {
+            throw std::runtime_error("Void texture.");
+        }
+
+        GLint height;
+        glGetTexLevelParameteriv(this->_type, 0, GL_TEXTURE_HEIGHT, &height);
+        return height;
+    }
+
+    void Texture::changeTextureSlot(GLuint slot) {
+        this->_slot = slot;
+    }
+
+    void Texture::setWraping(Wraping wraping, uint32_t flags) {
+        glBindTexture(this->_type, this->_id);
+        if(flags != 0) {
+            if((flags & S) != 0) {
+                glTexParameteri(this->_type, GL_TEXTURE_WRAP_S, wraping);
+            }
+
+            if((flags & T) != 0) {
+                glTexParameteri(this->_type, GL_TEXTURE_WRAP_T, wraping);
+            }
+
+            if((flags & R) != 0) {
+                glTexParameteri(this->_type, GL_TEXTURE_WRAP_R, wraping);
+            }
+        }
+    }
+
+    void Texture::setSmoothing(bool state) {
+        glBindTexture(this->_type, this->_id);
+        glTexParameteri(this->_type, GL_TEXTURE_MIN_FILTER, state ? GL_LINEAR : GL_NEAREST);
+        glTexParameteri(this->_type, GL_TEXTURE_MAG_FILTER, state ? GL_LINEAR : GL_NEAREST);
+    }
+
+    void Texture::store(GLsizei width, GLsizei height, const void * data, GLuint format) {
+        if(this->valide()) {
+            glDeleteTextures(1, &this->_id);
+            glGenTextures(1, &this->_id);
+        }
+        
+        glBindTexture(this->_type, this->_id);
+        glTexImage2D(this->_type, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, data);
+        glGenerateMipmap(this->_type);
+        this->setWraping(CLAMP_TO_BORDER, S | T );
+        this->setSmoothing(false);
+    }
+
+    bool Texture::valide() const {
+        return this->_id != 0;
+    }
+
+    bool Texture::operator==(const Texture & texture) const {
+        return this->_id == texture._id;
+    }
+
+    bool Texture::operator!=(const Texture & texture) const {
+        return this->_id != texture._id;
+    }
+
+    bool Texture::operator>=(const Texture & texture) const {
+        return this->_id >= texture._id;
+    }
+
+    bool Texture::operator<=(const Texture & texture) const {
+        return this->_id <= texture._id;
+    }
+
+    bool Texture::operator>(const Texture & texture) const {
+        return this->_id > texture._id;
+    }
+
+    bool Texture::operator<(const Texture & texture) const {
+        return this->_id < texture._id;
+    }
+
+    std::strong_ordering Texture::operator<=>(const Texture & texture) const {
+        return this->_id <=> texture._id;
+    }
+
+    void Texture::Unbind(GLuint type) {
+        glBindTexture(type, 0);
+    }
+}
\ No newline at end of file
diff --git a/source/engine/graphics/back/textures/Texture.hpp b/source/engine/graphics/back/textures/Texture.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..4eabc13b9944ecd2c949b23b8f27e18b67e7f5eb
--- /dev/null
+++ b/source/engine/graphics/back/textures/Texture.hpp
@@ -0,0 +1,72 @@
+#pragma once
+
+#include <GL/glew.h>
+#include <compare>
+
+namespace megu {
+    class Texture {
+        private:
+            GLuint _id;
+            GLuint _type;
+            mutable GLuint _slot;
+
+        public:
+            Texture(GLuint = 0, GLuint = GL_TEXTURE_2D);
+            Texture(const Texture &) = delete;
+            Texture & operator=(const Texture &) = delete;
+           ~Texture();
+
+            enum Wraping {
+                REPEAT              = GL_REPEAT,
+                MIRRORED_REPEAT     = GL_MIRRORED_REPEAT,
+                CLAMP_TO_BORDER     = GL_CLAMP_TO_BORDER,
+                CLAMP_TO_EDGE       = GL_CLAMP_TO_EDGE
+            };
+
+            enum Axis {
+                S = 1,
+                T = 2,
+                R = 4
+            };
+
+            enum Format {
+                AUTO,
+                RGB     = GL_RGB,
+                BGR     = GL_BGR,
+                RGBA    = GL_RGBA,
+                RED     = GL_RED,
+                GREEN   = GL_GREEN,
+                BLUE    = GL_BLUE,
+            };
+
+            void bind() const;
+            void bind(GLuint) const;
+
+            GLint width() const;
+            GLint height() const;
+
+            inline GLuint slot() const {return this->_slot;}
+            inline GLuint type() const {return this->_type;}
+            inline GLuint identifier() const {return this->_id;}
+
+            void changeTextureSlot(GLuint);
+            void setWraping(Wraping, uint32_t = S | T);
+            void setSmoothing(bool);
+
+            void store(GLsizei, GLsizei, const void *, GLuint = RGBA);
+            bool valide() 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;
+
+            std::strong_ordering operator<=>(const Texture &) const;
+
+            static void Unbind(GLuint = GL_TEXTURE_2D);
+
+            
+    };
+}
\ No newline at end of file
diff --git a/source/engine/graphics/errors.hpp b/source/engine/graphics/errors.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..c1dac55a2fbf545389d09d22bc9387cc3900d33b
--- /dev/null
+++ b/source/engine/graphics/errors.hpp
@@ -0,0 +1,4 @@
+#pragma once
+
+#include "./errors/OpenGL_Error.hpp"
+#include "./errors/Shader_Error.hpp"
\ No newline at end of file
diff --git a/source/engine/graphics/errors/OpenGL_Error.cpp b/source/engine/graphics/errors/OpenGL_Error.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6eb1910641032679b8a74bd02622a3a928d98781
--- /dev/null
+++ b/source/engine/graphics/errors/OpenGL_Error.cpp
@@ -0,0 +1,56 @@
+#include "OpenGL_Error.hpp"
+
+namespace megu::error {
+    opengl_error::opengl_error() 
+    : opengl_error(glGetError()) {}
+
+    opengl_error::opengl_error(GLenum code) 
+    : _code(code) {}
+
+    opengl_error::~opengl_error() {}
+
+    const char * opengl_error::what() const noexcept {
+        switch (this->_code) {
+            case GL_NO_ERROR:
+                return "GL NO ERROR";
+            
+            case GL_INVALID_ENUM:
+                return "GL INVALIDE ENUM";
+
+            case GL_INVALID_VALUE:
+                return "GL INVALID VALUE";
+
+            case GL_INVALID_OPERATION:
+                return "GL INVALID OPERATION";
+
+            case GL_STACK_OVERFLOW:
+                return "GL STACK OVERFLOW";
+
+            case GL_STACK_UNDERFLOW:
+                return "GL STACK UNDERFLOW";
+
+            case GL_OUT_OF_MEMORY:
+                return "GL OUT OF MEMORY";
+
+            case GL_INVALID_FRAMEBUFFER_OPERATION:
+                return "GL INVALID FRAMEBUFFER OPERATION";
+
+            case GL_CONTEXT_LOST:
+                return "GL CONTEXT LOST";
+        
+            default:
+                return "UNKNOWN GL ERROR";
+        }
+    }
+
+    void opengl_error::check(bool throws, std::ostream & os, const std::source_location & location) {
+        GLenum error = glGetError();
+        if(error != GL_NO_ERROR) {
+            error::opengl_error exception(error);
+            if(throws) {
+                throw exception;
+            }
+            std::cerr << location.file_name() << "(" << location.line() << " : " << location.column() << ") : " << exception.what() << std::endl;
+        }
+    }
+}
\ No newline at end of file
diff --git a/source/engine/graphics/errors/OpenGL_Error.hpp b/source/engine/graphics/errors/OpenGL_Error.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..341200a4ccd2311b190b475bb824b9406c72bef3
--- /dev/null
+++ b/source/engine/graphics/errors/OpenGL_Error.hpp
@@ -0,0 +1,23 @@
+#pragma once
+
+#include <exception>
+#include <GL/glew.h>
+#include <iostream>
+#include <source_location>
+
+namespace megu::error {
+    class opengl_error : public std::exception {
+        private:
+            GLenum _code;
+
+        public:
+            opengl_error();
+            opengl_error(GLenum error);
+           ~opengl_error();
+
+            virtual const char * what() const noexcept;
+            static void check(bool = false, std::ostream & = std::cerr, const std::source_location & = std::source_location::current());
+    };
+
+    
+}
\ No newline at end of file
diff --git a/source/engine/graphics/errors/Shader_Error.cpp b/source/engine/graphics/errors/Shader_Error.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ed864f0b3b5b5d87c4548e10cedfab39969c9a3b
--- /dev/null
+++ b/source/engine/graphics/errors/Shader_Error.cpp
@@ -0,0 +1,19 @@
+#include "Shader_Error.hpp"
+
+#include <iostream>
+#include <sstream>
+
+namespace megu::error {
+    shader_error::shader_error(const char * message, const std::filesystem::path * path)
+    : _message(message) {
+        
+       this->_message = (path != nullptr ? std::filesystem::canonical(*path).string() + " : \n " : "Unknow : \n");
+       this->_message.append(message);
+    }
+
+    shader_error::~shader_error() {}
+
+    const char * shader_error::what() const noexcept {
+        return this->_message.c_str();
+    }
+}
\ No newline at end of file
diff --git a/source/engine/graphics/errors/Shader_Error.hpp b/source/engine/graphics/errors/Shader_Error.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..e98ac904a36420b56ba5465299a0a6e9be9484ac
--- /dev/null
+++ b/source/engine/graphics/errors/Shader_Error.hpp
@@ -0,0 +1,21 @@
+#pragma once
+
+#include <exception>
+#include <string>
+#include <source_location>
+
+#include "../back/shaders/Source.hpp"
+
+namespace megu::error {
+    class shader_error : public std::exception {
+        private:
+            std::string _message;
+        
+        public:
+            shader_error() = delete;
+            shader_error(const char *, const std::filesystem::path * = nullptr);
+   virtual ~shader_error();
+
+            virtual const char * what() const noexcept; 
+    };
+}
diff --git a/source/main.cpp b/source/main.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..65dc652fb31193956f9ca609f5cc0ee16aa8e746
--- /dev/null
+++ b/source/main.cpp
@@ -0,0 +1,6 @@
+#include <iostream>
+
+int main(int argc, const char * argv[]) {
+    std::cout << "Hello World !" << std::endl;
+    return EXIT_SUCCESS;
+}
\ No newline at end of file
diff --git a/vcpkg.json b/vcpkg.json
new file mode 100644
index 0000000000000000000000000000000000000000..ade0a95183bb2ebcdbe220e91ab34ac57ebd38d7
--- /dev/null
+++ b/vcpkg.json
@@ -0,0 +1,15 @@
+{
+    "dependencies": [
+        "opengl",
+        "glew",
+        "glfw3",
+        "glm",
+        {
+            "name": "imgui", 
+            "features": [
+                "opengl3-binding",
+                "glfw-binding"
+            ] 
+        }
+    ]
+}
\ No newline at end of file