From 8fd8d5ec29f813dc51fec07387a15d232dcf4b5c Mon Sep 17 00:00:00 2001 From: tovjemam Date: Sat, 16 Aug 2025 21:35:01 +0200 Subject: [PATCH] Fix GL_LINEAR_MIPMAP_LINEAR error --- README.md | 2 +- src/game/sector.cpp | 3 +- src/gfx/texture.cpp | 75 ++++++++++++++++++++++++++++++++------------- src/gfx/texture.hpp | 2 +- 4 files changed, 57 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 3a139a5..5566291 100644 --- a/README.md +++ b/README.md @@ -3,9 +3,9 @@ ## TODO Fix known issues: -- [ ] Fix GL_LINEAR_MIPMAP_LINEAR error - [ ] Use cached textures when loading meshes instead of always loading the textures again for each mesh - [ ] Fix apparently incorrect light radius of lights visible through scaled portals +- [x] Fix GL_LINEAR_MIPMAP_LINEAR error Add new features: - [ ] Text and UI rendering diff --git a/src/game/sector.cpp b/src/game/sector.cpp index c525648..74220bd 100644 --- a/src/game/sector.cpp +++ b/src/game/sector.cpp @@ -675,7 +675,8 @@ void game::Sector::BakeLightmap() GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, - GL_LINEAR + true, // LINEAR + false // No mipmaps ); } diff --git a/src/gfx/texture.cpp b/src/gfx/texture.cpp index 27d8d9f..0893daa 100644 --- a/src/gfx/texture.cpp +++ b/src/gfx/texture.cpp @@ -4,28 +4,58 @@ #define STB_IMAGE_IMPLEMENTATION #include -gfx::Texture::Texture(GLuint width, GLuint height, const void* data, GLint internalformat, GLenum format, GLenum type, GLenum filter) { - glGenTextures(1, &m_id); +static void GetGLFilterModes(bool linear, bool mipmaps, GLenum& filter_min, GLenum& filter_mag) { + if (linear) + { + filter_min = GL_LINEAR; + filter_mag = GL_LINEAR; + + if (mipmaps) + { + filter_min = GL_LINEAR_MIPMAP_LINEAR; + } + } + else + { + filter_min = GL_NEAREST; + filter_mag = GL_NEAREST; + + if (mipmaps) + { + // Mipmaps always linear + filter_min = GL_NEAREST_MIPMAP_LINEAR; + } + } +} - if (!m_id) - throw std::runtime_error("Nelze vytvorit texturu!"); +gfx::Texture::Texture(GLuint width, GLuint height, const void* data, GLint internalformat, GLenum format, GLenum type, bool linear, bool mipmaps) { + glGenTextures(1, &m_id); - glBindTexture(GL_TEXTURE_2D, m_id); + if (!m_id) + throw std::runtime_error("Nelze vytvorit texturu!"); - glTexImage2D(GL_TEXTURE_2D, 0, internalformat, width, height, 0, format, type, data); + glBindTexture(GL_TEXTURE_2D, m_id); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexImage2D(GL_TEXTURE_2D, 0, internalformat, width, height, 0, format, type, data); - glGenerateMipmap(GL_TEXTURE_2D); + GLenum filter_min, filter_mag; + GetGLFilterModes(linear, mipmaps, filter_min, filter_mag); - glBindTexture(GL_TEXTURE_2D, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter_min); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter_mag); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + if (mipmaps) + { + glGenerateMipmap(GL_TEXTURE_2D); + } + + glBindTexture(GL_TEXTURE_2D, 0); } gfx::Texture::~Texture() { - glDeleteTextures(1, &m_id); + glDeleteTextures(1, &m_id); } std::shared_ptr gfx::Texture::LoadFromFile(const std::string& filename) @@ -33,16 +63,17 @@ std::shared_ptr gfx::Texture::LoadFromFile(const std::string& file int width, height, channels; unsigned char* data = stbi_load(filename.c_str(), &width, &height, &channels, 4); - if (!data) { - throw std::runtime_error("Failed to load texture from file: " + filename); - } - + if (!data) { + throw std::runtime_error("Failed to load texture from file: " + filename); + } + std::shared_ptr texture; - try { - texture = std::make_shared(width, height, data, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GL_LINEAR_MIPMAP_LINEAR); - } catch (const std::exception& e) { - stbi_image_free(data); - throw; // Rethrow the exception after freeing the data + try { + texture = std::make_shared(width, height, data, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, true, true); + } + catch (const std::exception& e) { + stbi_image_free(data); + throw; // Rethrow the exception after freeing the data } stbi_image_free(data); diff --git a/src/gfx/texture.hpp b/src/gfx/texture.hpp index ebae318..2fa933c 100644 --- a/src/gfx/texture.hpp +++ b/src/gfx/texture.hpp @@ -14,7 +14,7 @@ class Texture : public NonCopyableNonMovable GLuint m_id; public: - Texture(GLuint width, GLuint height, const void* data, GLint internalformat, GLenum format, GLenum type, GLenum filter = GL_NEAREST); + Texture(GLuint width, GLuint height, const void* data, GLint internalformat, GLenum format, GLenum type, bool linear, bool mipmaps); ~Texture(); GLuint GetId() const { return m_id; }