From 0c34ff9f90fdf52a41fe84c78369a1f3a5fa2bda Mon Sep 17 00:00:00 2001 From: Daynlight Date: Sat, 23 May 2026 01:09:20 +0100 Subject: [PATCH 1/4] Texture Loader and Texture Creation Seperation --- CWindow/Renderer/OpenGL/CMakeLists.txt | 2 ++ CWindow/Renderer/OpenGL/Renderer.h | 2 ++ CWindow/Renderer/OpenGL/Texture/Texture.cpp | 27 +++++-------------- CWindow/Renderer/OpenGL/Texture/Texture.h | 9 ++++--- .../Renderer/OpenGL/Texture/TextureLoader.cpp | 24 +++++++++++++++++ .../Renderer/OpenGL/Texture/TextureLoader.h | 20 ++++++++++++++ Example/Texture/Main.cpp | 16 ++++++----- 7 files changed, 69 insertions(+), 31 deletions(-) create mode 100644 CWindow/Renderer/OpenGL/Texture/TextureLoader.cpp create mode 100644 CWindow/Renderer/OpenGL/Texture/TextureLoader.h diff --git a/CWindow/Renderer/OpenGL/CMakeLists.txt b/CWindow/Renderer/OpenGL/CMakeLists.txt index 6f35376..ccfef72 100644 --- a/CWindow/Renderer/OpenGL/CMakeLists.txt +++ b/CWindow/Renderer/OpenGL/CMakeLists.txt @@ -21,6 +21,8 @@ set(src "Uniform/Uniform.h" "Texture/Texture.cpp" "Texture/Texture.h" + "Texture/TextureLoader.cpp" + "Texture/TextureLoader.h" ${ROOT_DIR}/vendor/stb/deprecated/stb_image.c ${ROOT_DIR}/vendor/glad/src/glad.c ) diff --git a/CWindow/Renderer/OpenGL/Renderer.h b/CWindow/Renderer/OpenGL/Renderer.h index e557552..98f6f2c 100644 --- a/CWindow/Renderer/OpenGL/Renderer.h +++ b/CWindow/Renderer/OpenGL/Renderer.h @@ -10,6 +10,8 @@ #include "Uniform/Uniform.h" #include "Texture/Texture.h" +#include "Texture/TextureLoader.h" + #include "../Data/WindowData.h" #include "../Data/InputData.h" diff --git a/CWindow/Renderer/OpenGL/Texture/Texture.cpp b/CWindow/Renderer/OpenGL/Texture/Texture.cpp index e9b421a..ae481df 100644 --- a/CWindow/Renderer/OpenGL/Texture/Texture.cpp +++ b/CWindow/Renderer/OpenGL/Texture/Texture.cpp @@ -1,44 +1,29 @@ #include "Texture.h" -#define STB_IMAGE_IMPLEMENTATION -#include CW::Renderer::Texture::Texture(){ }; CW::Renderer::Texture::~Texture() { - glDeleteTextures(0, &texture); + glDeleteTextures(1, &texture); }; -bool CW::Renderer::Texture::load(const std::string &path) { +void CW::Renderer::Texture::create(TextureLoader data) { glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - int width, height, channels; - stbi_set_flip_vertically_on_load(true); - unsigned char* data = stbi_load(path.c_str(), &width, &height, &channels, 0); - if(!data) return 1; - - GLenum format = GL_RGB; - if (channels == 1) format = GL_RED; - else if (channels == 3) format = GL_RGB; - else if (channels == 4) format = GL_RGBA; - - glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, data); + glTexImage2D(GL_TEXTURE_2D, 0, data.format, data.width, data.height, 0, data.format, GL_UNSIGNED_BYTE, data.data); glGenerateMipmap(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, 0); - - stbi_image_free(data); - - return 0; }; -void CW::Renderer::Texture::bind() { +void CW::Renderer::Texture::bind(unsigned int socket) { + glActiveTexture(GL_TEXTURE0 + socket); glBindTexture(GL_TEXTURE_2D, texture); }; diff --git a/CWindow/Renderer/OpenGL/Texture/Texture.h b/CWindow/Renderer/OpenGL/Texture/Texture.h index 496ac98..d5541d7 100644 --- a/CWindow/Renderer/OpenGL/Texture/Texture.h +++ b/CWindow/Renderer/OpenGL/Texture/Texture.h @@ -1,8 +1,11 @@ #pragma once - #include "glad/glad.h" #include +#include "TextureLoader.h" + + + namespace CW::Renderer{ class Texture{ private: @@ -12,8 +15,8 @@ class Texture{ Texture(); ~Texture(); - bool load(const std::string& path); - void bind(); + void create(TextureLoader data); + void bind(unsigned int socket); void unbind(); }; }; \ No newline at end of file diff --git a/CWindow/Renderer/OpenGL/Texture/TextureLoader.cpp b/CWindow/Renderer/OpenGL/Texture/TextureLoader.cpp new file mode 100644 index 0000000..4044026 --- /dev/null +++ b/CWindow/Renderer/OpenGL/Texture/TextureLoader.cpp @@ -0,0 +1,24 @@ +#include "TextureLoader.h" + + +#define STB_IMAGE_IMPLEMENTATION +#include + + + +CW::Renderer::TextureLoader::TextureLoader(const std::string& path) +{ + stbi_set_flip_vertically_on_load(true); + data = stbi_load(path.c_str(), &width, &height, &channels, 0); + if(!data) return; + + format = GL_RGB; + if (channels == 1) format = GL_RED; + else if (channels == 3) format = GL_RGB; + else if (channels == 4) format = GL_RGBA; +}; + + +CW::Renderer::TextureLoader::~TextureLoader() { + stbi_image_free(data); +}; \ No newline at end of file diff --git a/CWindow/Renderer/OpenGL/Texture/TextureLoader.h b/CWindow/Renderer/OpenGL/Texture/TextureLoader.h new file mode 100644 index 0000000..8c75550 --- /dev/null +++ b/CWindow/Renderer/OpenGL/Texture/TextureLoader.h @@ -0,0 +1,20 @@ +#pragma once +#include "glad/glad.h" + +#include + + + + +namespace CW::Renderer{ +class TextureLoader{ +public: + GLenum format; + int width, height, channels; + unsigned char* data; + +public: + TextureLoader(const std::string& path); + ~TextureLoader(); +}; +}; // namespace CW diff --git a/Example/Texture/Main.cpp b/Example/Texture/Main.cpp index a86dcec..84f14d2 100644 --- a/Example/Texture/Main.cpp +++ b/Example/Texture/Main.cpp @@ -5,19 +5,20 @@ int main(){ CW::Renderer::Renderer window; + CW::Renderer::TextureLoader loader("../Assets/image.png"); CW::Renderer::Texture texture; - if(texture.load("../Assets/image.png")) - return -1; + texture.create(loader); + CW::Renderer::Mesh viewport; std::vector vertices({ -1.0f, 1.0f, 0.0f, -1.0f, -1.0f, 0.0f, - 1.0f, 1.0f, 0.0f, - 1.0f, -1.0f, 0.0f, + 1.0f, 1.0f, 0.0f, + 1.0f, -1.0f, 0.0f, }); - viewport.addVertices(vertices); + viewport.addVertices(vertices, 3); std::vector indicies({ 0, 1, 2, @@ -29,8 +30,9 @@ int main(){ 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, - 1.0f, 0.0f + 1.0f, 0.0f, }); + viewport.setData(idtx, 2, 1, GL_FLOAT); CW::Renderer::Shader texture_shader(Texture::vertex, Texture::fragment); @@ -42,7 +44,7 @@ int main(){ while(!window.getWindowData()->should_close){ window.beginFrame(); - texture.bind(); + texture.bind(0); texture_shader.bind(); viewport.render(); texture_shader.unbind(); From 98b0b575d1894756661337e3fc852f4debf50a1a Mon Sep 17 00:00:00 2001 From: Daynlight Date: Sat, 23 May 2026 01:38:38 +0100 Subject: [PATCH 2/4] Clean up --- CWindow/Renderer/OpenGL/Texture/Texture.cpp | 38 ++++++++++++++++--- CWindow/Renderer/OpenGL/Texture/Texture.h | 10 ++++- CWindow/Renderer/OpenGL/Texture/TextureData.h | 17 +++++++++ .../Renderer/OpenGL/Texture/TextureLoader.cpp | 24 +++++++----- .../Renderer/OpenGL/Texture/TextureLoader.h | 10 +++-- Example/Texture/Main.cpp | 13 +++---- 6 files changed, 85 insertions(+), 27 deletions(-) create mode 100644 CWindow/Renderer/OpenGL/Texture/TextureData.h diff --git a/CWindow/Renderer/OpenGL/Texture/Texture.cpp b/CWindow/Renderer/OpenGL/Texture/Texture.cpp index ae481df..bcaf597 100644 --- a/CWindow/Renderer/OpenGL/Texture/Texture.cpp +++ b/CWindow/Renderer/OpenGL/Texture/Texture.cpp @@ -1,32 +1,58 @@ #include "Texture.h" -CW::Renderer::Texture::Texture(){ + + + + + + +CW::Renderer::Texture::Texture() : is_compiled(false) {}; + +CW::Renderer::Texture::Texture(TextureData data) +: is_compiled(false){ + compile(data); }; + + CW::Renderer::Texture::~Texture() { - glDeleteTextures(1, &texture); + if(is_compiled) + glDeleteTextures(1, &texture); + + is_compiled = false; }; -void CW::Renderer::Texture::create(TextureLoader data) { + + +void CW::Renderer::Texture::compile(TextureData data, GLint min_filter, GLint max_filter) { glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, max_filter); glTexImage2D(GL_TEXTURE_2D, 0, data.format, data.width, data.height, 0, data.format, GL_UNSIGNED_BYTE, data.data); glGenerateMipmap(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, 0); + + is_compiled = true; }; + + void CW::Renderer::Texture::bind(unsigned int socket) { + if(!is_compiled) + return; + glActiveTexture(GL_TEXTURE0 + socket); glBindTexture(GL_TEXTURE_2D, texture); }; + + void CW::Renderer::Texture::unbind() { glBindTexture(GL_TEXTURE_2D, 0); -}; \ No newline at end of file +}; diff --git a/CWindow/Renderer/OpenGL/Texture/Texture.h b/CWindow/Renderer/OpenGL/Texture/Texture.h index d5541d7..43a9115 100644 --- a/CWindow/Renderer/OpenGL/Texture/Texture.h +++ b/CWindow/Renderer/OpenGL/Texture/Texture.h @@ -1,8 +1,14 @@ #pragma once #include "glad/glad.h" + #include #include "TextureLoader.h" +#include "TextureData.h" + + + + @@ -10,12 +16,14 @@ namespace CW::Renderer{ class Texture{ private: GLuint texture; + bool is_compiled = false; public: Texture(); + Texture(TextureData data); ~Texture(); - void create(TextureLoader data); + void compile(TextureData data, GLint min_filter = GL_LINEAR, GLint max_filter = GL_LINEAR); void bind(unsigned int socket); void unbind(); }; diff --git a/CWindow/Renderer/OpenGL/Texture/TextureData.h b/CWindow/Renderer/OpenGL/Texture/TextureData.h new file mode 100644 index 0000000..85aa647 --- /dev/null +++ b/CWindow/Renderer/OpenGL/Texture/TextureData.h @@ -0,0 +1,17 @@ +#pragma once + +#include "glad/glad.h" + + + + + + + +namespace CW::Renderer{ +struct TextureData{ + GLenum format; + int width, height, channels; + unsigned char* data; +}; +}; diff --git a/CWindow/Renderer/OpenGL/Texture/TextureLoader.cpp b/CWindow/Renderer/OpenGL/Texture/TextureLoader.cpp index 4044026..19d8a61 100644 --- a/CWindow/Renderer/OpenGL/Texture/TextureLoader.cpp +++ b/CWindow/Renderer/OpenGL/Texture/TextureLoader.cpp @@ -1,24 +1,28 @@ #include "TextureLoader.h" - #define STB_IMAGE_IMPLEMENTATION #include -CW::Renderer::TextureLoader::TextureLoader(const std::string& path) + + + + +CW::Renderer::TextureLoader::TextureLoader(const std::string &path) { stbi_set_flip_vertically_on_load(true); - data = stbi_load(path.c_str(), &width, &height, &channels, 0); - if(!data) return; + data.data = stbi_load(path.c_str(), &data.width, &data.height, &data.channels, 0); + if(!data.data) return; - format = GL_RGB; - if (channels == 1) format = GL_RED; - else if (channels == 3) format = GL_RGB; - else if (channels == 4) format = GL_RGBA; + data.format = GL_RGB; + if (data.channels == 1) data.format = GL_RED; + else if (data.channels == 3) data.format = GL_RGB; + else if (data.channels == 4) data.format = GL_RGBA; }; + CW::Renderer::TextureLoader::~TextureLoader() { - stbi_image_free(data); -}; \ No newline at end of file + stbi_image_free(data.data); +}; diff --git a/CWindow/Renderer/OpenGL/Texture/TextureLoader.h b/CWindow/Renderer/OpenGL/Texture/TextureLoader.h index 8c75550..3e54691 100644 --- a/CWindow/Renderer/OpenGL/Texture/TextureLoader.h +++ b/CWindow/Renderer/OpenGL/Texture/TextureLoader.h @@ -3,17 +3,21 @@ #include +#include "TextureData.h" + + + + namespace CW::Renderer{ class TextureLoader{ public: - GLenum format; - int width, height, channels; - unsigned char* data; + TextureData data; public: + TextureLoader(); TextureLoader(const std::string& path); ~TextureLoader(); }; diff --git a/Example/Texture/Main.cpp b/Example/Texture/Main.cpp index 84f14d2..ea1ed39 100644 --- a/Example/Texture/Main.cpp +++ b/Example/Texture/Main.cpp @@ -7,7 +7,7 @@ int main(){ CW::Renderer::TextureLoader loader("../Assets/image.png"); CW::Renderer::Texture texture; - texture.create(loader); + texture.compile(loader.data); CW::Renderer::Mesh viewport; @@ -32,19 +32,18 @@ int main(){ 1.0f, 1.0f, 1.0f, 0.0f, }); - viewport.setData(idtx, 2, 1, GL_FLOAT); CW::Renderer::Shader texture_shader(Texture::vertex, Texture::fragment); CW::Renderer::Uniform uniform; texture_shader.getUniforms().emplace_back(&uniform); - uniform["uTexture"]->set(0); - - + + while(!window.getWindowData()->should_close){ window.beginFrame(); - + texture.bind(0); + uniform["uTexture"]->set(0); texture_shader.bind(); viewport.render(); texture_shader.unbind(); @@ -55,4 +54,4 @@ int main(){ }; return 0; -} \ No newline at end of file +}; From 0737651630e619b6b00bdef10b482f208cc73c86 Mon Sep 17 00:00:00 2001 From: Daynlight Date: Sat, 23 May 2026 02:01:20 +0100 Subject: [PATCH 3/4] Docs --- CWindow/Renderer/OpenGL/Texture/Texture.cpp | 20 +++++-- CWindow/Renderer/OpenGL/Texture/Texture.h | 3 +- .../Renderer/OpenGL/Texture/TextureLoader.h | 1 - Example/Texture/Main.cpp | 4 +- Readme.md | 58 +++++++++++++++++-- 5 files changed, 71 insertions(+), 15 deletions(-) diff --git a/CWindow/Renderer/OpenGL/Texture/Texture.cpp b/CWindow/Renderer/OpenGL/Texture/Texture.cpp index bcaf597..45f6726 100644 --- a/CWindow/Renderer/OpenGL/Texture/Texture.cpp +++ b/CWindow/Renderer/OpenGL/Texture/Texture.cpp @@ -8,18 +8,17 @@ CW::Renderer::Texture::Texture() : is_compiled(false) {}; -CW::Renderer::Texture::Texture(TextureData data) + + +CW::Renderer::Texture::Texture(TextureData data, GLint min_filter, GLint max_filter) : is_compiled(false){ - compile(data); + compile(data, min_filter, max_filter); }; CW::Renderer::Texture::~Texture() { - if(is_compiled) - glDeleteTextures(1, &texture); - - is_compiled = false; + destroy(); }; @@ -43,6 +42,15 @@ void CW::Renderer::Texture::compile(TextureData data, GLint min_filter, GLint ma +void CW::Renderer::Texture::destroy(){ + if(is_compiled) + glDeleteTextures(1, &texture); + + is_compiled = false; +} + + + void CW::Renderer::Texture::bind(unsigned int socket) { if(!is_compiled) return; diff --git a/CWindow/Renderer/OpenGL/Texture/Texture.h b/CWindow/Renderer/OpenGL/Texture/Texture.h index 43a9115..47acad7 100644 --- a/CWindow/Renderer/OpenGL/Texture/Texture.h +++ b/CWindow/Renderer/OpenGL/Texture/Texture.h @@ -20,10 +20,11 @@ class Texture{ public: Texture(); - Texture(TextureData data); + Texture(TextureData data, GLint min_filter = GL_LINEAR, GLint max_filter = GL_LINEAR); ~Texture(); void compile(TextureData data, GLint min_filter = GL_LINEAR, GLint max_filter = GL_LINEAR); + void destroy(); void bind(unsigned int socket); void unbind(); }; diff --git a/CWindow/Renderer/OpenGL/Texture/TextureLoader.h b/CWindow/Renderer/OpenGL/Texture/TextureLoader.h index 3e54691..03d0ba3 100644 --- a/CWindow/Renderer/OpenGL/Texture/TextureLoader.h +++ b/CWindow/Renderer/OpenGL/Texture/TextureLoader.h @@ -17,7 +17,6 @@ class TextureLoader{ TextureData data; public: - TextureLoader(); TextureLoader(const std::string& path); ~TextureLoader(); }; diff --git a/Example/Texture/Main.cpp b/Example/Texture/Main.cpp index ea1ed39..712c531 100644 --- a/Example/Texture/Main.cpp +++ b/Example/Texture/Main.cpp @@ -42,8 +42,8 @@ int main(){ while(!window.getWindowData()->should_close){ window.beginFrame(); - texture.bind(0); - uniform["uTexture"]->set(0); + texture.bind(2); + uniform["uTexture"]->set(2); texture_shader.bind(); viewport.render(); texture_shader.unbind(); diff --git a/Readme.md b/Readme.md index f8faf35..794254b 100644 --- a/Readme.md +++ b/Readme.md @@ -67,26 +67,31 @@ swapping window etc. Good to use in simple project or just learning shaders and - [Usage](#usage) - [Supported Types](#supported-types) - [Memory Management](#memory-management) -- [Shader](#shader) +- [Textures](#textures) - [Info](#info-6) - [Usage](#usage-1) + - [Memory Management](#memory-management-1) + - [Texture](#texture) +- [Shader](#shader) + - [Info](#info-7) + - [Usage](#usage-2) - [Add Geometry Shader](#add-geometry-shader) - [Hot-Reloading](#hot-reloading) - - [Memory Management](#memory-management-1) + - [Memory Management](#memory-management-2) - [Example](#example) - [ComputeShader](#computeshader) - - [Info](#info-7) + - [Info](#info-8) - [Basic Usage](#basic-usage) - [Data Processing Example](#data-processing-example) - [Available Functions](#available-functions) - [Mesh](#mesh) - - [Info](#info-8) + - [Info](#info-9) - [Storing Data](#storing-data) - [Mesh control and functions](#mesh-control-and-functions) - [Render Example](#render-example) - [Also check](#also-check) - [FreeCamera3D](#freecamera3d) - - [Info](#info-9) + - [Info](#info-10) - [Camera control and functions](#camera-control-and-functions) - [Code Example](#code-example) - [Also check](#also-check-1) @@ -377,6 +382,49 @@ glm::vec3 color = uniform["color"]->get(); +## Textures +### Info +1. Each Texture is loaded via ```TextureLoader``` (**stb**). +2. ```TextureData``` is struct of texture data. +3. If texture is un compiled than we skip binding. +4. After creating ```Texture``` you can delete your ```TextureData``` if needed any more. +5. ```Texture``` stores data fully on **GPU**. + +### Usage +#### Loading Texture +For loading texture create ```TextureLoader``` +```cpp +CW::Renderer::TextureLoader loader("example.png"); +``` + +#### Creating Texture +Texture is created via ```Texture``` class. +```cpp +CW::Renderer::Texture texture; +// GLint min_filter = GL_LINEAR, GLint max_filter = GL_LINEAR (pass optional values) +texture.compile(loader.data); +``` + +#### Binding Texture +To bind use: +```cpp +texture.bind(2); +uniform["uTexture"]->set(2); // in shader variable +``` + +### Memory Management +#### Texture Loader +* ```TextureLoader(const std::string& path);``` - loads asset to ```data``` public variable. +* ```~TextureLoader();``` - destroys whole class. + +### Texture +* ````void compile(TextureData data, GLint min_filter = GL_LINEAR, GLint max_filter = GL_LINEAR);```` - creates texture on **GPU**. +* ```void destroy();``` - destroys texture from **GPU**. +* ```void bind(unsigned int socket);``` - binds texture to **socket** slot. +* ```void unbind();``` - unbinds textures. + + + ## Shader ### Info 1. Shader combines multiple shaders to one program for rendering From c7f4c72c032947f2944d61cf7b1fe46e91cbfab4 Mon Sep 17 00:00:00 2001 From: Daynlight Date: Sat, 23 May 2026 02:05:01 +0100 Subject: [PATCH 4/4] Add stb in docs --- Readme.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Readme.md b/Readme.md index 794254b..91eb3a8 100644 --- a/Readme.md +++ b/Readme.md @@ -859,6 +859,7 @@ int main(){ * [glad](https://glad.dav1d.de/) * [imgui](https://github.com/ocornut/imgui/tree/docking) * [glm](https://github.com/g-truc/glm) +* [stb](https://github.com/nothings/stb.git)