From 23f069e9b0b18a130cf761181dd60417501663d9 Mon Sep 17 00:00:00 2001
From: Brett <brettmaster1@gmail.com>
Date: Fri, 3 May 2024 20:01:45 -0400
Subject: [PATCH] renamed classes in model.h to be more descriptive - vbo is
 now vertex_array - ebo is now element_array etc

---
 CMakeLists.txt                               |  2 +-
 include/blt/gfx/model.h                      | 53 +++++------
 include/blt/gfx/renderer/batch_2d_renderer.h | 16 ++--
 include/blt/gfx/renderer/post_process.h      | 84 ++++++++++++++++++
 libraries/glfw-3.3.8/examples/particles.c    |  8 +-
 src/blt/gfx/framebuffer.cpp                  |  6 ++
 src/blt/gfx/model.cpp                        | 26 +++---
 src/blt/gfx/renderer/batch_2d_renderer.cpp   | 53 +++++------
 src/blt/gfx/renderer/postprocess.cpp         | 31 +++++++
 src/blt/gfx/texture.cpp                      | 92 +++++++++++++++++---
 tests/src/main.cpp                           | 10 +--
 11 files changed, 285 insertions(+), 96 deletions(-)
 create mode 100644 include/blt/gfx/renderer/post_process.h
 create mode 100644 src/blt/gfx/renderer/postprocess.cpp

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 06a4baa..72671ee 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,6 +1,6 @@
 cmake_minimum_required(VERSION 3.25)
 
-set(BLT_GRAPHICS_VERSION 0.13.0)
+set(BLT_GRAPHICS_VERSION 0.13.1)
 set(BLT_GRAPHICS_TEST_VERSION 0.0.1)
 
 project(BLT_WITH_GRAPHICS VERSION ${BLT_GRAPHICS_VERSION})
diff --git a/include/blt/gfx/model.h b/include/blt/gfx/model.h
index f82ebc3..9e41194 100644
--- a/include/blt/gfx/model.h
+++ b/include/blt/gfx/model.h
@@ -32,12 +32,13 @@ namespace blt::gfx
     
     class static_dynamic_array;
     
-    class vertex_array;
+    class vertex_array_t;
     
-    struct vbo_t
+    // vbo
+    struct vertex_buffer_t
     {
             friend vbo_t_owner;
-            friend vertex_array;
+            friend vertex_array_t;
             friend static_dynamic_array;
         private:
             GLuint bufferID_ = 0;
@@ -67,34 +68,36 @@ namespace blt::gfx
             void destroy();
     };
     
-    struct ssbo_t : public vbo_t
+    // ssbo
+    struct shader_buffer_t : public vertex_buffer_t
     {
         public:
             inline void create()
             {
-                vbo_t::create(GL_SHADER_STORAGE_BUFFER);
+                vertex_buffer_t::create(GL_SHADER_STORAGE_BUFFER);
             }
     };
     
-    struct ebo_t : public vbo_t
+    // ebo
+    struct element_buffer_t : public vertex_buffer_t
     {
         public:
             inline void create()
             {
-                vbo_t::create(GL_ELEMENT_ARRAY_BUFFER);
+                vertex_buffer_t::create(GL_ELEMENT_ARRAY_BUFFER);
             }
     };
     
     struct vbo_t_owner
     {
-        vbo_t vbo;
+        vertex_buffer_t vbo;
         
         vbo_t_owner() = default;
         
-        explicit vbo_t_owner(vbo_t vbo): vbo(vbo)
+        explicit vbo_t_owner(vertex_buffer_t vbo): vbo(vbo)
         {}
         
-        vbo_t* operator->()
+        vertex_buffer_t* operator->()
         {
             return &vbo;
         }
@@ -153,26 +156,26 @@ namespace blt::gfx
     /**
      * basic VAO class.
      */
-    class vertex_array
+    class vertex_array_t
     {
         private:
             GLuint vaoID;
             static_dynamic_array VBOs;
             blt::hashset_t<GLuint> used_attributes;
-            vbo_t element;
+            vertex_buffer_t element;
             
-            void handle_vbo(const vbo_t& vbo, int attribute_number, int coordinate_size, GLenum type, int stride, long offset);
+            void handle_vbo(const vertex_buffer_t& vbo, int attribute_number, int coordinate_size, GLenum type, int stride, long offset);
         
         public:
-            vertex_array();
+            vertex_array_t();
             
-            vertex_array(const vertex_array&) = delete;
+            vertex_array_t(const vertex_array_t&) = delete;
             
-            vertex_array(vertex_array&&) = delete;
+            vertex_array_t(vertex_array_t&&) = delete;
             
-            vertex_array& operator=(const vertex_array&) = delete;
+            vertex_array_t& operator=(const vertex_array_t&) = delete;
             
-            vertex_array& operator=(vertex_array&&) = delete;
+            vertex_array_t& operator=(vertex_array_t&&) = delete;
             
             /**
              * This function takes ownership of the underlying VBO (GPU side). It will be freed when the basic vertex array is deleted
@@ -185,12 +188,12 @@ namespace blt::gfx
              * @param offset offset into the data structure to where the data is stored
              * @return a shared pointer to the stored vbo. used for chaining VAOs with multiple shared VBOs
              */
-            static_dynamic_array::vbo_type bindVBO(const vbo_t& vbo, int attribute_number, int coordinate_size, GLenum type, int stride, long offset);
+            static_dynamic_array::vbo_type bindVBO(const vertex_buffer_t& vbo, int attribute_number, int coordinate_size, GLenum type, int stride, long offset);
             
             // same as the other bind method except you provide the shared reference.
             void bindVBO(const static_dynamic_array::vbo_type& vbo, int attribute_number, int coordinate_size, GLenum type, int stride, long offset);
             
-            inline void bindElement(const vbo_t& vbo)
+            inline void bindElement(const vertex_buffer_t& vbo)
             {
                 bind();
                 element = vbo;
@@ -198,7 +201,7 @@ namespace blt::gfx
                 unbind();
             }
             
-            inline vbo_t& getElement()
+            inline vertex_buffer_t& getElement()
             {
                 return element;
             }
@@ -207,12 +210,12 @@ namespace blt::gfx
              * Returns a non-owning reference to a vbo allowing for updating the VBO
              * The VBO is considered invalid if its ID is 0
              */
-            inline vbo_t& operator[](size_t index)
+            inline vertex_buffer_t& operator[](size_t index)
             {
                 return getBuffer(index);
             }
             
-            inline vbo_t& getBuffer(size_t index)
+            inline vertex_buffer_t& getBuffer(size_t index)
             {
                 return VBOs[index]->vbo;
             }
@@ -227,12 +230,12 @@ namespace blt::gfx
                 glBindVertexArray(0);
             }
             
-            static inline static_dynamic_array::vbo_type createSharedVBO(const vbo_t& vbo)
+            static inline static_dynamic_array::vbo_type createSharedVBO(const vertex_buffer_t& vbo)
             {
                 return std::make_shared<vbo_t_owner>(vbo);
             }
             
-            ~vertex_array();
+            ~vertex_array_t();
     };
     
 }
diff --git a/include/blt/gfx/renderer/batch_2d_renderer.h b/include/blt/gfx/renderer/batch_2d_renderer.h
index f2cd403..6e00897 100644
--- a/include/blt/gfx/renderer/batch_2d_renderer.h
+++ b/include/blt/gfx/renderer/batch_2d_renderer.h
@@ -21,6 +21,7 @@
 
 #include "blt/gfx/model.h"
 #include "blt/gfx/shader.h"
+#include "blt/gfx/framebuffer.h"
 #include "blt/gfx/renderer/resource_manager.h"
 #include <blt/std/hashmap.h>
 #include <blt/std/memory_util.h>
@@ -147,14 +148,7 @@ namespace blt::gfx
     class batch_renderer_2d
     {
         private:
-            struct vec_hash
-            {
-                std::size_t operator()(const vec4& key) const
-                {
-                    using namespace blt::mem;
-                    return type_cast<i32>(key.x()) ^ type_cast<i32>(key.y()) ^ type_cast<i32>(key.y()) ^ type_cast<i32>(key.z());
-                }
-            };
+            fbo_t draw_buffer;
             
             template<typename T>
             struct render_object_t
@@ -174,8 +168,8 @@ namespace blt::gfx
             using object_container = hashmap_t<std::string, std::vector<std::pair<render_info_t, T>>>;
         
         private:
-            vertex_array* square_vao = nullptr;
-            vertex_array* line_vao = nullptr;
+            vertex_array_t* square_vao = nullptr;
+            vertex_array_t* line_vao = nullptr;
             shader_t* square_shader = nullptr;
             shader_t* point_shader = nullptr;
             resource_manager& resources;
@@ -261,7 +255,7 @@ namespace blt::gfx
             void drawLine(const T& render_info, f32 z_index, P... p)
             { drawLineInternal(render_info, {p...}, z_index); }
             
-            void render(bool transparency = true);
+            void render(i32 width, i32 height, bool transparency = true);
             
             void cleanup();
             
diff --git a/include/blt/gfx/renderer/post_process.h b/include/blt/gfx/renderer/post_process.h
new file mode 100644
index 0000000..d91f844
--- /dev/null
+++ b/include/blt/gfx/renderer/post_process.h
@@ -0,0 +1,84 @@
+#pragma once
+/*
+ *  Copyright (C) 2024  Brett Terpstra
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef BLT_GRAPHICS_POST_PROCESS_H
+#define BLT_GRAPHICS_POST_PROCESS_H
+
+#include <blt/std/types.h>
+#include <blt/gfx/framebuffer.h>
+#include <blt/gfx/shader.h>
+#include <blt/gfx/model.h>
+#include <vector>
+#include <memory>
+
+namespace blt::gfx
+{
+    namespace detail
+    {
+        class pp_link;
+        
+        class pp_iterator;
+        
+        class pp_link
+        {
+            public:
+            
+            private:
+            
+        };
+        
+        class pp_iterator
+        {
+            public:
+            
+            private:
+            
+        };
+    }
+    
+    class pp_step
+    {
+        public:
+            virtual void create(i32 width, i32 height) = 0;
+            
+            virtual void draw(i32 width, i32 height) = 0;
+            
+            fbo_t& getBuffer()
+            {
+                return draw_buffer;
+            }
+        
+        protected:
+            fbo_t draw_buffer;
+    };
+    
+    class pp_engine
+    {
+        public:
+            void create();
+            
+            void render(i32 width, i32 height);
+        
+        private:
+            std::vector<std::unique_ptr<pp_step>> steps;
+            shader_t screen_shader;
+            
+    };
+}
+
+#endif //BLT_GRAPHICS_POST_PROCESS_H
diff --git a/libraries/glfw-3.3.8/examples/particles.c b/libraries/glfw-3.3.8/examples/particles.c
index 9556cca..7ca1199 100644
--- a/libraries/glfw-3.3.8/examples/particles.c
+++ b/libraries/glfw-3.3.8/examples/particles.c
@@ -394,7 +394,7 @@ static void particle_engine(double t, float dt)
 static void draw_particles(GLFWwindow* window, double t, float dt)
 {
     int i, particle_count;
-    Vertex vertex_array[BATCH_PARTICLES * PARTICLE_VERTS];
+    Vertex vertex_array_t[BATCH_PARTICLES * PARTICLE_VERTS];
     Vertex* vptr;
     float alpha;
     GLuint rgba;
@@ -449,7 +449,7 @@ static void draw_particles(GLFWwindow* window, double t, float dt)
     // situations). GL_T2F_C4UB_V3F means: 2 floats for texture coords,
     // 4 ubytes for color and 3 floats for vertex coord (in that order).
     // Most OpenGL cards / drivers are optimized for this format.
-    glInterleavedArrays(GL_T2F_C4UB_V3F, 0, vertex_array);
+    glInterleavedArrays(GL_T2F_C4UB_V3F, 0, vertex_array_t);
 
     // Wait for particle physics thread to be done
     mtx_lock(&thread_sync.particles_lock);
@@ -473,7 +473,7 @@ static void draw_particles(GLFWwindow* window, double t, float dt)
 
     // Loop through all particles and build vertex arrays.
     particle_count = 0;
-    vptr = vertex_array;
+    vptr = vertex_array_t;
     pptr = particles;
 
     for (i = 0;  i < MAX_PARTICLES;  i++)
@@ -546,7 +546,7 @@ static void draw_particles(GLFWwindow* window, double t, float dt)
             // The last argument is the vertex count
             glDrawArrays(GL_QUADS, 0, PARTICLE_VERTS * particle_count);
             particle_count = 0;
-            vptr = vertex_array;
+            vptr = vertex_array_t;
         }
 
         // Next particle
diff --git a/src/blt/gfx/framebuffer.cpp b/src/blt/gfx/framebuffer.cpp
index 91b0e23..0afa8bc 100644
--- a/src/blt/gfx/framebuffer.cpp
+++ b/src/blt/gfx/framebuffer.cpp
@@ -152,6 +152,9 @@ namespace blt::gfx
     
     void fbo_t::updateBuffersStorage(blt::i32 width, blt::i32 height)
     {
+        if (width == width_ && height == height_)
+            return;
+        
         width_ = width;
         height_ = height;
         for (auto& rbo : render_buffers)
@@ -162,6 +165,9 @@ namespace blt::gfx
         
         for (auto& texture : texture_buffers)
             texture->updateSize(width, height);
+        
+        if (!fbo_t::validate())
+            BLT_ERROR("Failed to update framebuffer storage size!");
     }
     
     void fbo_t::blitTexture(const fbo_t& draw, blt::i32 srcX, blt::i32 srcY, blt::i32 destX, blt::i32 destY, GLuint filter,
diff --git a/src/blt/gfx/model.cpp b/src/blt/gfx/model.cpp
index dfbed18..3ec121d 100644
--- a/src/blt/gfx/model.cpp
+++ b/src/blt/gfx/model.cpp
@@ -61,13 +61,13 @@ namespace blt::gfx
      *              vbo_t
      * -----------------------------------
      */
-    void vbo_t::create(GLint type)
+    void vertex_buffer_t::create(GLint type)
     {
         glGenBuffers(1, &bufferID_);
         buffer_type = type;
     }
     
-    void vbo_t::destroy()
+    void vertex_buffer_t::destroy()
     {
         // prevent multiple destroys of the same object, in cases of multi attribute binds
         if (bufferID_ == 0)
@@ -76,7 +76,7 @@ namespace blt::gfx
         bufferID_ = 0;
     }
     
-    void vbo_t::allocate(GLsizeiptr size, GLint mem_type, const void* data)
+    void vertex_buffer_t::allocate(GLsizeiptr size, GLint mem_type, const void* data)
     {
         bind();
         size_ = size;
@@ -84,7 +84,7 @@ namespace blt::gfx
         memory_type = mem_type;
     }
     
-    void vbo_t::update(GLsizeiptr size, void* data)
+    void vertex_buffer_t::update(GLsizeiptr size, void* data)
     {
         if (size <= size_)
             sub_update(0, size, data);
@@ -93,18 +93,18 @@ namespace blt::gfx
         size_ = size;
     }
     
-    void vbo_t::sub_update(GLsizeiptr offset, GLsizeiptr size, void* data) const
+    void vertex_buffer_t::sub_update(GLsizeiptr offset, GLsizeiptr size, void* data) const
     {
         bind();
         glBufferSubData(buffer_type, offset, size, data);
     }
     
-    void vbo_t::bind() const
+    void vertex_buffer_t::bind() const
     {
         glBindBuffer(buffer_type, bufferID_);
     }
     
-    void vbo_t::unbind() const
+    void vertex_buffer_t::unbind() const
     {
         glBindBuffer(buffer_type, 0);
     }
@@ -115,12 +115,12 @@ namespace blt::gfx
      * ----------------------------
      */
     
-    vertex_array::vertex_array(): vaoID(0)
+    vertex_array_t::vertex_array_t(): vaoID(0)
     {
         glGenVertexArrays(1, &vaoID);
     }
     
-    vertex_array::~vertex_array()
+    vertex_array_t::~vertex_array_t()
     {
         // free all VBOs
         for (size_t i = 0; i < VBOs.used(); i++)
@@ -130,21 +130,21 @@ namespace blt::gfx
         glDeleteVertexArrays(1, &vaoID);
     }
     
-    static_dynamic_array::vbo_type vertex_array::bindVBO(const vbo_t& vbo, int attribute_number, int coordinate_size, GLenum type, int stride,
-                                                         long offset)
+    static_dynamic_array::vbo_type vertex_array_t::bindVBO(const vertex_buffer_t& vbo, int attribute_number, int coordinate_size, GLenum type, int stride,
+                                                           long offset)
     {
         handle_vbo(vbo, attribute_number, coordinate_size, type, stride, offset);
         VBOs[attribute_number] = createSharedVBO(vbo);
         return VBOs[attribute_number];
     }
     
-    void vertex_array::bindVBO(const static_dynamic_array::vbo_type& vbo, int attribute_number, int coordinate_size, GLenum type, int stride, long offset)
+    void vertex_array_t::bindVBO(const static_dynamic_array::vbo_type& vbo, int attribute_number, int coordinate_size, GLenum type, int stride, long offset)
     {
         handle_vbo(vbo->vbo, attribute_number, coordinate_size, type, stride, offset);
         VBOs[attribute_number] = vbo;
     }
     
-    void vertex_array::handle_vbo(const vbo_t& vbo, int attribute_number, int coordinate_size, GLenum type, int stride, long offset)
+    void vertex_array_t::handle_vbo(const vertex_buffer_t& vbo, int attribute_number, int coordinate_size, GLenum type, int stride, long offset)
     {
         used_attributes.insert(attribute_number);
         bind();
diff --git a/src/blt/gfx/renderer/batch_2d_renderer.cpp b/src/blt/gfx/renderer/batch_2d_renderer.cpp
index bc274dc..b54a38d 100644
--- a/src/blt/gfx/renderer/batch_2d_renderer.cpp
+++ b/src/blt/gfx/renderer/batch_2d_renderer.cpp
@@ -51,8 +51,8 @@ namespace blt::gfx
     void batch_renderer_2d::create()
     {
         {
-            vbo_t vertices_vbo;
-            ebo_t indices_vbo;
+            vertex_buffer_t vertices_vbo;
+            element_buffer_t indices_vbo;
             
             vertices_vbo.create();
             indices_vbo.create();
@@ -60,14 +60,14 @@ namespace blt::gfx
             vertices_vbo.allocate(sizeof(square_vertices), square_vertices);
             indices_vbo.allocate(sizeof(square_indices), square_indices);
             
-            square_vao = new vertex_array();
+            square_vao = new vertex_array_t();
             const auto tb = square_vao->bindVBO(vertices_vbo, 0, 3, GL_FLOAT, 5 * sizeof(float), 0);
             square_vao->bindVBO(tb, 1, 2, GL_FLOAT, 5 * sizeof(float), 3 * sizeof(float));
             square_vao->bindElement(indices_vbo);
         }
         {
-            vbo_t vertices_vbo;
-            ebo_t indices_vbo;
+            vertex_buffer_t vertices_vbo;
+            element_buffer_t indices_vbo;
             
             vertices_vbo.create();
             indices_vbo.create();
@@ -75,7 +75,7 @@ namespace blt::gfx
             vertices_vbo.allocate(sizeof(line_vertices), line_vertices);
             indices_vbo.allocate(sizeof(square_indices), square_indices);
             
-            line_vao = new vertex_array();
+            line_vao = new vertex_array_t();
             auto tb = line_vao->bindVBO(vertices_vbo, 0, 3, GL_FLOAT, 5 * sizeof(float), 0);
             line_vao->bindVBO(tb, 1, 2, GL_FLOAT, 5 * sizeof(float), 3 * sizeof(float));
             line_vao->bindElement(indices_vbo);
@@ -88,6 +88,21 @@ namespace blt::gfx
         point_shader = new shader_t(shader_2d_textured_vert, shader_2d_textured_cirlce_frag);
         point_shader->bindAttribute(0, "vertex");
         point_shader->bindAttribute(1, "uv_in");
+        
+        draw_buffer.create();
+        draw_buffer.bind();
+        
+        auto* texture = new texture_gl2D(1440, 720);
+        draw_buffer.attachTexture(texture, fbo_t::attachment_t::COLOR0);
+        auto* mask = new texture_gl2D(1440, 720);
+        draw_buffer.attachTexture(mask, fbo_t::attachment_t::COLOR1);
+        
+        rbo_t depth_rbo = rbo_t::make_render_buffer(GL_DEPTH24_STENCIL8, 1440, 720);
+        draw_buffer.attachRenderBuffer(depth_rbo, fbo_t::attachment_t::DEPTH_STENCIL);
+        
+        if (!fbo_t::validate())
+            BLT_ERROR("Failed to create render framebuffer!");
+        fbo_t::unbind();
     }
     
     void batch_renderer_2d::drawRectangleInternal(const std::string_view texture, const rectangle2d_t& rectangle, const f32 z_index)
@@ -151,27 +166,11 @@ namespace blt::gfx
         delete point_shader;
     }
     
-    template<typename T>
-    void find_min_and_max(T& container, f32& min, f32& max)
-    {
-        for (auto& textures : container)
-        {
-            for (auto& colors : textures.second)
-            {
-                for (auto& blend_factors : colors.second)
-                {
-                    for (auto& obj : blend_factors.second)
-                    {
-                        min = std::min(min, obj.z_index);
-                        max = std::max(max, obj.z_index);
-                    }
-                }
-            }
-        }
-    }
-    
-    void batch_renderer_2d::render(const bool transparency)
+    void batch_renderer_2d::render(i32 width, i32 height, const bool transparency)
     {
+        draw_buffer.bind();
+        draw_buffer.updateBuffersStorage(width, height);
+        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
         if (transparency)
         {
             glEnable(GL_BLEND);
@@ -187,6 +186,8 @@ namespace blt::gfx
             glDisable(GL_BLEND);
         
         render_reset();
+        draw_buffer.blitToScreen(width, height);
+        fbo_t::unbind();
     }
     
     void batch_renderer_2d::draw_objects()
diff --git a/src/blt/gfx/renderer/postprocess.cpp b/src/blt/gfx/renderer/postprocess.cpp
new file mode 100644
index 0000000..bfbcf47
--- /dev/null
+++ b/src/blt/gfx/renderer/postprocess.cpp
@@ -0,0 +1,31 @@
+/*
+ *  <Short Description>
+ *  Copyright (C) 2024  Brett Terpstra
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+#include <blt/gfx/renderer/post_process.h>
+
+namespace blt::gfx
+{
+    void pp_engine::create()
+    {
+    
+    }
+    
+    void pp_engine::render(i32 width, i32 height)
+    {
+    
+    }
+}
\ No newline at end of file
diff --git a/src/blt/gfx/texture.cpp b/src/blt/gfx/texture.cpp
index f6b665e..7c34e63 100644
--- a/src/blt/gfx/texture.cpp
+++ b/src/blt/gfx/texture.cpp
@@ -36,6 +36,78 @@
 #include <blt/gfx/stb/stb_image.h>
 #include <blt/gfx/stb/stb_perlin.h>
 #include <blt/gfx/texture.h>
+#include <blt/std/hashmap.h>
+
+struct format_t
+{
+    GLenum format;
+    GLenum type;
+};
+
+blt::hashmap_t<GLint, format_t> make_format_table()
+{
+    blt::hashmap_t<GLint, format_t> map;
+    
+    map[GL_R8] = {GL_RED, GL_UNSIGNED_BYTE};
+    map[GL_R8_SNORM] = {GL_RED, GL_BYTE};
+    map[GL_R16F] = {GL_RED, GL_FLOAT};
+    map[GL_R32F] = {GL_RED, GL_FLOAT};
+    map[GL_R8UI] = {GL_RED_INTEGER, GL_UNSIGNED_BYTE};
+    map[GL_R8I] = {GL_RED_INTEGER, GL_BYTE};
+    map[GL_R16UI] = {GL_RED_INTEGER, GL_UNSIGNED_SHORT};
+    map[GL_R16I] = {GL_RED_INTEGER, GL_SHORT};
+    map[GL_R32UI] = {GL_RED_INTEGER, GL_UNSIGNED_INT};
+    map[GL_R32I] = {GL_RED_INTEGER, GL_INT};
+    map[GL_RG8] = {GL_RG, GL_UNSIGNED_BYTE};
+    map[GL_RG8_SNORM] = {GL_RG, GL_BYTE};
+    map[GL_RG16F] = {GL_RG, GL_FLOAT};
+    map[GL_RG32F] = {GL_RG, GL_FLOAT};
+    map[GL_RG8UI] = {GL_RG_INTEGER, GL_UNSIGNED_BYTE};
+    map[GL_RG8I] = {GL_RG_INTEGER, GL_BYTE};
+    map[GL_RG16UI] = {GL_RG_INTEGER, GL_UNSIGNED_SHORT};
+    map[GL_RG16I] = {GL_RG_INTEGER, GL_SHORT};
+    map[GL_RG32UI] = {GL_RG_INTEGER, GL_UNSIGNED_INT};
+    map[GL_RG32I] = {GL_RG_INTEGER, GL_INT};
+    map[GL_RGB8] = {GL_RGB, GL_UNSIGNED_BYTE};
+    map[GL_SRGB8] = {GL_RGB, GL_UNSIGNED_BYTE};
+    map[GL_RGB565] = {GL_RGB, GL_UNSIGNED_BYTE};
+    map[GL_RGB8_SNORM] = {GL_RGB, GL_BYTE};
+    map[GL_R11F_G11F_B10F] = {GL_RGB, GL_FLOAT};
+    map[GL_RGB9_E5] = {GL_RGB, GL_FLOAT};
+    map[GL_RGB16F] = {GL_RGB, GL_FLOAT};
+    map[GL_RGB32F] = {GL_RGB, GL_FLOAT};
+    map[GL_RGB8UI] = {GL_RGB_INTEGER, GL_UNSIGNED_BYTE};
+    map[GL_RGB8I] = {GL_RGB_INTEGER, GL_BYTE};
+    map[GL_RGB16UI] = {GL_RGB_INTEGER, GL_UNSIGNED_SHORT};
+    map[GL_RGB16I] = {GL_RGB_INTEGER, GL_RGB16I};
+    map[GL_RGB32UI] = {GL_RGB_INTEGER, GL_UNSIGNED_INT};
+    map[GL_RGB32I] = {GL_RGB_INTEGER, GL_INT};
+    map[GL_RGBA8] = {GL_RGBA, GL_UNSIGNED_BYTE};
+    map[GL_SRGB8_ALPHA8] = {GL_RGBA, GL_UNSIGNED_BYTE};
+    map[GL_RGBA8_SNORM] = {GL_RGBA, GL_BYTE};
+    map[GL_RGB5_A1] = {GL_RGBA, GL_UNSIGNED_BYTE};
+    map[GL_RGBA4] = {GL_RGBA, GL_UNSIGNED_BYTE};
+    map[GL_RGB10_A2] = {GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV};
+    map[GL_RGBA16F] = {GL_RGBA, GL_FLOAT};
+    map[GL_RGBA32F] = {GL_RGBA, GL_FLOAT};
+    map[GL_RGBA8UI] = {GL_RGBA_INTEGER, GL_UNSIGNED_BYTE};
+    map[GL_RGBA8I] = {GL_RGBA_INTEGER, GL_BYTE};
+    map[GL_RGB10_A2UI] = {GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV};
+    map[GL_RGBA16UI] = {GL_RGBA_INTEGER, GL_UNSIGNED_SHORT};
+    map[GL_RGBA16I] = {GL_RGBA_INTEGER, GL_SHORT};
+    map[GL_RGBA32I] = {GL_RGBA_INTEGER, GL_INT};
+    map[GL_RGBA32UI] = {GL_RGBA_INTEGER, GL_UNSIGNED_INT};
+    map[GL_DEPTH_COMPONENT16] = {GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT};
+    map[GL_DEPTH_COMPONENT24] = {GL_DEPTH_COMPONENT, GL_UNSIGNED_INT};
+    map[GL_DEPTH_COMPONENT32F] = {GL_DEPTH_COMPONENT, GL_FLOAT};
+    map[GL_DEPTH24_STENCIL8] = {GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8};
+    map[GL_DEPTH32F_STENCIL8] = {GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV};
+    map[GL_STENCIL_INDEX8] = {GL_STENCIL_INDEX, GL_UNSIGNED_BYTE};
+    
+    return map;
+}
+
+blt::hashmap_t<GLint, format_t> internal_to_texture = make_format_table();
 
 blt::gfx::texture_file::texture_file(const std::string& path, const std::string& name): m_name(name.empty() ? path : name), m_path(path)
 {
@@ -45,7 +117,7 @@ blt::gfx::texture_file::texture_file(const std::string& path, const std::string&
             reinterpret_cast<int*>(&m_texture.m_width), reinterpret_cast<int*>(&m_texture.m_height),
             reinterpret_cast<int*>(&m_texture.m_channels),
             0
-    );
+                                );
 }
 
 blt::gfx::texture_file& blt::gfx::texture_file::resize(int target_width, int target_height)
@@ -56,7 +128,7 @@ blt::gfx::texture_file& blt::gfx::texture_file::resize(int target_width, int tar
     // that matches with what stb image uses, which is malloc, since we unload with stbi_image_free -> (free)
     auto* output_Data = (unsigned char*) malloc(
             target_width * target_height * m_texture.channels()
-    );
+                                               );
     
     // resize the texture
     if (stbir_resize_uint8_linear(
@@ -66,7 +138,7 @@ blt::gfx::texture_file& blt::gfx::texture_file::resize(int target_width, int tar
             output_Data, target_width, target_height, 0,
             // channels
             static_cast<stbir_pixel_layout>(m_texture.channels())
-    ))
+                                 ))
     {
         BLT_WARN("Error resizing block texture image!");
     }
@@ -132,7 +204,9 @@ void blt::gfx::texture_gl2D::resize(int width, int height)
     m_width = width;
     m_height = height;
     bind();
-    glTexStorage2D(textureBindType, 0, textureColorMode, m_width, m_height);
+    //glTexStorage2D(textureBindType, 4, textureColorMode, m_width, m_height);
+    auto format = internal_to_texture[textureColorMode];
+    glTexImage2D(textureBindType, 0, textureColorMode, m_width, m_height, 0, format.format, format.type, nullptr);
     unbind();
 }
 
@@ -140,9 +214,8 @@ blt::gfx::texture_gl2D::texture_gl2D(int width, int height, GLint colorMode): te
 {
     bind();
     setDefaults();
-    // TODO:
-    const int MIPMAP_LEVELS = 4;
-    glTexStorage2D(textureBindType, MIPMAP_LEVELS, colorMode, width, height);
+    resize(width, height);
+    //glTexStorage2D(textureBindType, 4, colorMode, width, height);
 }
 
 blt::gfx::texture_gl2D::texture_gl2D(const blt::gfx::texture_data& data):
@@ -165,10 +238,7 @@ void blt::gfx::gl_texture2D_array::upload(void* data, int index, GLint dataColor
     if (sub_height < 0)
         sub_height = m_height;
     bind();
-    glTexSubImage3D(
-            textureBindType, level, x_offset, y_offset, index, sub_width, sub_height, 1,
-            dataColorMode, GL_UNSIGNED_BYTE, data
-    );
+    glTexSubImage3D(textureBindType, level, x_offset, y_offset, index, sub_width, sub_height, 1, dataColorMode, GL_UNSIGNED_BYTE, data);
     generateMipmaps();
     unbind();
 }
diff --git a/tests/src/main.cpp b/tests/src/main.cpp
index 3bb1943..e028d9d 100644
--- a/tests/src/main.cpp
+++ b/tests/src/main.cpp
@@ -16,7 +16,7 @@ blt::gfx::resource_manager resources;
 blt::gfx::batch_renderer_2d renderer_2d(resources);
 blt::gfx::first_person_camera camera;
 
-std::vector<std::pair<blt::gfx::vertex_array*, size_t>> vaos;
+std::vector<std::pair<blt::gfx::vertex_array_t*, size_t>> vaos;
 blt::gfx::shader_t* shader;
 
 float x = 0, y = 0, z = 0;
@@ -60,18 +60,18 @@ void init()
     
     auto object = blt::parse::quick_load("../resources/models/many_objects.obj");
     
-    vbo_t vertices_vbo;
+    vertex_buffer_t vertices_vbo;
     vertices_vbo.create();
     vertices_vbo.allocate(static_cast<long>(object.vertex_data().size() * sizeof(blt::parse::constructed_vertex_t)), object.vertex_data().data());
-    auto ptr = vertex_array::createSharedVBO(vertices_vbo);
+    auto ptr = vertex_array_t::createSharedVBO(vertices_vbo);
     
     for (auto obj : object.objects())
     {
-        vbo_t indices_vbo;
+        vertex_buffer_t indices_vbo;
         indices_vbo.create(GL_ELEMENT_ARRAY_BUFFER);
         indices_vbo.allocate(static_cast<long>(obj.indices.size() * sizeof(blt::parse::triangle_t)), obj.indices.data());
         
-        auto* vao = new vertex_array();
+        auto* vao = new vertex_array_t();
         vao->bindVBO(ptr, 0, 3, GL_FLOAT, sizeof(float) * (3 + 3 + 2), 0);
         vao->bindVBO(ptr, 1, 2, GL_FLOAT, sizeof(float) * (3 + 3 + 2), sizeof(float) * 3);
         vao->bindVBO(ptr, 2, 3, GL_FLOAT, sizeof(float) * (3 + 3 + 2), sizeof(float) * (3 + 2));