diff --git a/CMakeLists.txt b/CMakeLists.txt index 64f0a20..4f850ff 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -41,7 +41,7 @@ CPMAddPackage( CPMAddPackage( NAME ReTexture - URL https://git.redacted.cc/Redacted/ReTexture/archive/Release-1.1.zip + URL https://git.redacted.cc/Redacted/ReTexture/archive/Release-1.2.zip ) if (WIN32) diff --git a/include/JGL/Texture.h b/include/JGL/Texture.h index dfe611f..969915f 100644 --- a/include/JGL/Texture.h +++ b/include/JGL/Texture.h @@ -6,14 +6,21 @@ #include namespace JGL { - - enum class TextureFilteringMode { + using namespace ReTexture; + enum class TextureFilteringMode : u8 { NEAREST = 0, //Fastest for 2D, Sometimes causes graphical issues. BILINEAR = 1, //Fast and pretty, The best for 2D. MIPMAP_NEAREST = 2, //Nearest with mipmaps. The fastest for 3D, Sometimes causes graphical issues. Uses more vram. - MIPMAP_BILINEAR = 3, //Bilinear with mipmaps, Fast and pretty. - MIPMAP_TRILINEAR = 4 //The prettiest. Not much slower though. + MIPMAP_BILINEAR = 3, //Bilinear with mipmaps, Fast and pretty. Uses more vram. + MIPMAP_TRILINEAR = 4 //The prettiest. Still decent speed. Uses more vram. + }; + + enum class TextureWrappingMode : u8 { + REPEAT = 0, + MIRRORED_REPEAT = 1, + CLAMP_TO_EDGE = 2, + CLAMP_TO_BORDER = 3 //Effectively the same as clamp_to_edge }; class Texture { @@ -23,16 +30,17 @@ namespace JGL { ReTexture::TextureFlag texture_flags; ReTexture::TextureFormat texture_format; TextureFilteringMode texture_filtering_mode; - void load(ReTexture::Texture* software_texture, const Vector2& size, const ReTexture::TextureFormat& format, TextureFilteringMode filtering_mode); + TextureWrappingMode texture_wrapping_mode; + void load(SoftwareTexture* software_texture, const Vector2& size, const TextureFormat& format, TextureFilteringMode filtering_mode, TextureWrappingMode wrapping_mode); public: - explicit Texture(const std::string& file, TextureFilteringMode filtering_mode = TextureFilteringMode::BILINEAR); - Texture(const std::string& file, const ReTexture::TextureFlag& flags, TextureFilteringMode filtering_mode = TextureFilteringMode::BILINEAR); + explicit Texture(const std::string& file, TextureFilteringMode filtering_mode = TextureFilteringMode::BILINEAR, TextureWrappingMode wrapping_mode = TextureWrappingMode::CLAMP_TO_EDGE); + Texture(const std::string& file, const TextureFlag& flags, TextureFilteringMode filtering_mode = TextureFilteringMode::BILINEAR, TextureWrappingMode wrapping_mode = TextureWrappingMode::CLAMP_TO_EDGE); GLuint getTexture(); Vector2 getSize(); - TextureFilteringMode getTextureFilteringMode(); - ReTexture::TextureFlag getFlags(); - ReTexture::TextureFormat getFormat(); void erase(); + TextureFilteringMode getFilteringMode(); + TextureFlag getFlags(); + TextureFormat getFormat(); std::vector getPixelData(); }; diff --git a/src/JGL/Texture.cpp b/src/JGL/Texture.cpp index e1a3709..ee4e527 100644 --- a/src/JGL/Texture.cpp +++ b/src/JGL/Texture.cpp @@ -1,36 +1,52 @@ #include #include -JGL::Texture::Texture(const std::string& file, const ReTexture::TextureFlag& flags, TextureFilteringMode filtering_mode) { - auto* t = new ReTexture::Texture(file, flags); +using namespace ReTexture; - load(t, {(float) t->getWidth(), (float) t->getHeight()}, t->getTextureFormat(), filtering_mode); +JGL::Texture::Texture(const std::string& file, const TextureFlag& flags, TextureFilteringMode filtering_mode, TextureWrappingMode wrapping_mode) { + auto* t = new SoftwareTexture(file, flags); + + load(t, {(float) t->getWidth(), (float) t->getHeight()}, t->getTextureFormat(), filtering_mode, wrapping_mode); texture_flags = flags; delete t; } -JGL::Texture::Texture(const std::string& file, TextureFilteringMode filtering_mode) { - auto* t = new ReTexture::Texture(file); +JGL::Texture::Texture(const std::string& file, TextureFilteringMode filtering_mode, TextureWrappingMode wrapping_mode) { + auto* t = new SoftwareTexture(file); - load(t, {(float) t->getWidth(), (float) t->getHeight()}, t->getTextureFormat(), filtering_mode); - texture_flags = ReTexture::TextureFlag::NONE; + load(t, {(float) t->getWidth(), (float) t->getHeight()}, t->getTextureFormat(), filtering_mode, wrapping_mode); + texture_flags = TextureFlag::NONE; delete t; } -void JGL::Texture::load(ReTexture::Texture* software_texture, const Vector2& size, const ReTexture::TextureFormat& format, TextureFilteringMode filtering_mode) { +void JGL::Texture::load(SoftwareTexture* software_texture, const Vector2& size, const TextureFormat& format, TextureFilteringMode filtering_mode, TextureWrappingMode wrapping_mode) { glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); - if (format == ReTexture::TextureFormat::RGBA) + if (format == TextureFormat::RGBA) glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (int) size.x, (int) size.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, software_texture->pixelData.data()); - else if (format == ReTexture::TextureFormat::RGB) + else if (format == TextureFormat::RGB) glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, (int) size.x, (int) size.y, 0, GL_RGB, GL_UNSIGNED_BYTE, software_texture->pixelData.data()); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + if (wrapping_mode == TextureWrappingMode::CLAMP_TO_EDGE) + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE), + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + else if (wrapping_mode == TextureWrappingMode::REPEAT) + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT), + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + else if (wrapping_mode == TextureWrappingMode::MIRRORED_REPEAT) + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT), + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT); + + else if (wrapping_mode == TextureWrappingMode::CLAMP_TO_BORDER) + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER), + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); + if (filtering_mode == TextureFilteringMode::NEAREST) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST), @@ -42,20 +58,20 @@ void JGL::Texture::load(ReTexture::Texture* software_texture, const Vector2& siz else if (filtering_mode == TextureFilteringMode::MIPMAP_NEAREST || filtering_mode == TextureFilteringMode::MIPMAP_BILINEAR || filtering_mode == TextureFilteringMode::MIPMAP_TRILINEAR) { //3 mipmap levels. - auto* m1 = new ReTexture::Texture(software_texture->downscale(2)); - auto* m2 = new ReTexture::Texture(software_texture->downscale(4)); - auto* m3 = new ReTexture::Texture(software_texture->downscale(8)); + auto* m1 = new SoftwareTexture(software_texture->downscale(2)); + auto* m2 = new SoftwareTexture(software_texture->downscale(4)); + auto* m3 = new SoftwareTexture(software_texture->downscale(8)); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 3); - if (format == ReTexture::TextureFormat::RGBA) { + if (format == TextureFormat::RGBA) { glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, m1->getWidth(), m1->getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, m1->pixelData.data()); glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, m2->getWidth(), m2->getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, m2->pixelData.data()); glTexImage2D(GL_TEXTURE_2D, 3, GL_RGBA, m3->getWidth(), m3->getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, m3->pixelData.data()); } - if (format == ReTexture::TextureFormat::RGB) { + else if (format == TextureFormat::RGB) { glTexImage2D(GL_TEXTURE_2D, 1, GL_RGB, m1->getWidth(), m1->getHeight(), 0, GL_RGB, GL_UNSIGNED_BYTE, m1->pixelData.data()); glTexImage2D(GL_TEXTURE_2D, 2, GL_RGB, m2->getWidth(), m2->getHeight(), 0, GL_RGB, GL_UNSIGNED_BYTE, m2->pixelData.data()); glTexImage2D(GL_TEXTURE_2D, 3, GL_RGB, m3->getWidth(), m3->getHeight(), 0, GL_RGB, GL_UNSIGNED_BYTE, m3->pixelData.data()); @@ -88,14 +104,14 @@ std::vector JGL::Texture::getPixelData() { std::vector result((size_t) (texture_size.x * texture_size.y)); glBindTexture(GL_TEXTURE_2D, texture); - if (texture_format == ReTexture::TextureFormat::RGBA) { + if (texture_format == TextureFormat::RGBA) { glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, result.data()); return result; } + //if RGB std::vector color3((size_t) (texture_size.x * texture_size.y)); - if (texture_format == ReTexture::TextureFormat::RGB) - glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, color3.data()); + glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, color3.data()); for (const auto& c : color3) result.emplace_back(c); @@ -116,14 +132,14 @@ Vector2 JGL::Texture::getSize() { return texture_size; } -ReTexture::TextureFlag JGL::Texture::getFlags() { +TextureFlag JGL::Texture::getFlags() { return texture_flags; } -ReTexture::TextureFormat JGL::Texture::getFormat() { +TextureFormat JGL::Texture::getFormat() { return texture_format; } -JGL::TextureFilteringMode JGL::Texture::getTextureFilteringMode() { +JGL::TextureFilteringMode JGL::Texture::getFilteringMode() { return texture_filtering_mode; }