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..45f6726 100644 --- a/CWindow/Renderer/OpenGL/Texture/Texture.cpp +++ b/CWindow/Renderer/OpenGL/Texture/Texture.cpp @@ -1,47 +1,66 @@ #include "Texture.h" -#define STB_IMAGE_IMPLEMENTATION -#include -CW::Renderer::Texture::Texture(){ + + + + + + +CW::Renderer::Texture::Texture() : is_compiled(false) {}; + + + +CW::Renderer::Texture::Texture(TextureData data, GLint min_filter, GLint max_filter) +: is_compiled(false){ + compile(data, min_filter, max_filter); }; + + CW::Renderer::Texture::~Texture() { - glDeleteTextures(0, &texture); + destroy(); }; -bool CW::Renderer::Texture::load(const std::string &path) { + + +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_MIPMAP_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); - 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); + + is_compiled = true; +}; - stbi_image_free(data); - return 0; -}; -void CW::Renderer::Texture::bind() { +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; + + 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 496ac98..47acad7 100644 --- a/CWindow/Renderer/OpenGL/Texture/Texture.h +++ b/CWindow/Renderer/OpenGL/Texture/Texture.h @@ -1,19 +1,31 @@ #pragma once - #include "glad/glad.h" + #include +#include "TextureLoader.h" +#include "TextureData.h" + + + + + + + namespace CW::Renderer{ class Texture{ private: GLuint texture; + bool is_compiled = false; public: Texture(); + Texture(TextureData data, GLint min_filter = GL_LINEAR, GLint max_filter = GL_LINEAR); ~Texture(); - bool load(const std::string& path); - void bind(); + void compile(TextureData data, GLint min_filter = GL_LINEAR, GLint max_filter = GL_LINEAR); + void destroy(); + void bind(unsigned int socket); void unbind(); }; }; \ No newline at end of file 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 new file mode 100644 index 0000000..19d8a61 --- /dev/null +++ b/CWindow/Renderer/OpenGL/Texture/TextureLoader.cpp @@ -0,0 +1,28 @@ +#include "TextureLoader.h" + +#define STB_IMAGE_IMPLEMENTATION +#include + + + + + + + +CW::Renderer::TextureLoader::TextureLoader(const std::string &path) +{ + stbi_set_flip_vertically_on_load(true); + data.data = stbi_load(path.c_str(), &data.width, &data.height, &data.channels, 0); + if(!data.data) return; + + 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.data); +}; diff --git a/CWindow/Renderer/OpenGL/Texture/TextureLoader.h b/CWindow/Renderer/OpenGL/Texture/TextureLoader.h new file mode 100644 index 0000000..03d0ba3 --- /dev/null +++ b/CWindow/Renderer/OpenGL/Texture/TextureLoader.h @@ -0,0 +1,23 @@ +#pragma once +#include "glad/glad.h" + +#include + +#include "TextureData.h" + + + + + + + +namespace CW::Renderer{ +class TextureLoader{ +public: + TextureData data; + +public: + TextureLoader(const std::string& path); + ~TextureLoader(); +}; +}; // namespace CW diff --git a/Example/Texture/Main.cpp b/Example/Texture/Main.cpp index a86dcec..712c531 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.compile(loader.data); + 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,20 +30,20 @@ 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); CW::Renderer::Uniform uniform; texture_shader.getUniforms().emplace_back(&uniform); - uniform["uTexture"]->set(0); - - + + while(!window.getWindowData()->should_close){ window.beginFrame(); - - texture.bind(); + + texture.bind(2); + uniform["uTexture"]->set(2); texture_shader.bind(); viewport.render(); texture_shader.unbind(); @@ -53,4 +54,4 @@ int main(){ }; return 0; -} \ No newline at end of file +}; diff --git a/Readme.md b/Readme.md index f8faf35..91eb3a8 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 @@ -811,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)