From 49c68e581aa28581ac76b98cd6d2ff9946911c65 Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 11 May 2020 13:58:12 +0200 Subject: [PATCH] OpenGL: Fix TextureSampler mipmap issue --- .../OpenGLRenderer/OpenGLTextureSampler.hpp | 9 ++++--- .../OpenGLRenderer/OpenGLTextureSampler.inl | 4 +-- .../OpenGLRenderer/OpenGLShaderBinding.cpp | 2 +- .../OpenGLRenderer/OpenGLTextureSampler.cpp | 27 ++++++++++++------- 4 files changed, 27 insertions(+), 15 deletions(-) diff --git a/include/Nazara/OpenGLRenderer/OpenGLTextureSampler.hpp b/include/Nazara/OpenGLRenderer/OpenGLTextureSampler.hpp index efe9b37bf..f6ac10f0d 100644 --- a/include/Nazara/OpenGLRenderer/OpenGLTextureSampler.hpp +++ b/include/Nazara/OpenGLRenderer/OpenGLTextureSampler.hpp @@ -17,18 +17,21 @@ namespace Nz class NAZARA_OPENGLRENDERER_API OpenGLTextureSampler : public TextureSampler { public: - OpenGLTextureSampler(OpenGLDevice& device, TextureSamplerInfo samplerInfo); + OpenGLTextureSampler(OpenGLDevice& device, const TextureSamplerInfo& samplerInfo); OpenGLTextureSampler(const OpenGLTextureSampler&) = default; OpenGLTextureSampler(OpenGLTextureSampler&&) noexcept = default; ~OpenGLTextureSampler() = default; - inline const GL::Sampler& GetSampler() const; + inline const GL::Sampler& GetSampler(bool mipmaps) const; OpenGLTextureSampler& operator=(const OpenGLTextureSampler&) = delete; OpenGLTextureSampler& operator=(OpenGLTextureSampler&&) = delete; private: - GL::Sampler m_sampler; + static void BuildSampler(OpenGLDevice& device, GL::Sampler& sampler, const TextureSamplerInfo& samplerInfo, bool withMipmaps); + + GL::Sampler m_samplerWithMipmaps; + GL::Sampler m_samplerWithoutMipmaps; }; } diff --git a/include/Nazara/OpenGLRenderer/OpenGLTextureSampler.inl b/include/Nazara/OpenGLRenderer/OpenGLTextureSampler.inl index 710e835fb..a9df7fba4 100644 --- a/include/Nazara/OpenGLRenderer/OpenGLTextureSampler.inl +++ b/include/Nazara/OpenGLRenderer/OpenGLTextureSampler.inl @@ -7,9 +7,9 @@ namespace Nz { - inline const GL::Sampler& OpenGLTextureSampler::GetSampler() const + inline const GL::Sampler& OpenGLTextureSampler::GetSampler(bool withMipmaps) const { - return m_sampler; + return (withMipmaps) ? m_samplerWithMipmaps : m_samplerWithoutMipmaps; } } diff --git a/src/Nazara/OpenGLRenderer/OpenGLShaderBinding.cpp b/src/Nazara/OpenGLRenderer/OpenGLShaderBinding.cpp index 8a36d9c97..371aa6248 100644 --- a/src/Nazara/OpenGLRenderer/OpenGLShaderBinding.cpp +++ b/src/Nazara/OpenGLRenderer/OpenGLShaderBinding.cpp @@ -43,8 +43,8 @@ namespace Nz OpenGLTextureSampler& glSampler = *static_cast(texBinding.sampler); auto& textureDescriptor = m_owner.GetTextureDescriptor(m_poolIndex, m_bindingIndex, resourceIndex); - textureDescriptor.sampler = glSampler.GetSampler().GetObjectId(); textureDescriptor.texture = glTexture.GetTexture().GetObjectId(); + textureDescriptor.sampler = glSampler.GetSampler(glTexture.GetLevelCount() > 1).GetObjectId(); break; } diff --git a/src/Nazara/OpenGLRenderer/OpenGLTextureSampler.cpp b/src/Nazara/OpenGLRenderer/OpenGLTextureSampler.cpp index 72dac5f12..1f49bbc30 100644 --- a/src/Nazara/OpenGLRenderer/OpenGLTextureSampler.cpp +++ b/src/Nazara/OpenGLRenderer/OpenGLTextureSampler.cpp @@ -9,21 +9,30 @@ namespace Nz { - OpenGLTextureSampler::OpenGLTextureSampler(OpenGLDevice& device, TextureSamplerInfo samplerInfo) + OpenGLTextureSampler::OpenGLTextureSampler(OpenGLDevice& device, const TextureSamplerInfo& samplerInfo) { - if (!m_sampler.Create(device)) + BuildSampler(device, m_samplerWithMipmaps, samplerInfo, true); + BuildSampler(device, m_samplerWithoutMipmaps, samplerInfo, false); + } + + void OpenGLTextureSampler::BuildSampler(OpenGLDevice& device, GL::Sampler& sampler, const TextureSamplerInfo& samplerInfo, bool withMipmaps) + { + if (!sampler.Create(device)) throw std::runtime_error("failed to create sampler object"); - // In OpenGL, min and mipmap sampler are part of the same enum + // In OpenGL, min and mipmap sampler are part of the same enum (and mipmaps filter should only be used with mipmaps) + if (withMipmaps) + sampler.SetParameteri(GL_TEXTURE_MIN_FILTER, ToOpenGL(samplerInfo.minFilter, samplerInfo.mipmapMode)); + else + sampler.SetParameteri(GL_TEXTURE_MIN_FILTER, ToOpenGL(samplerInfo.minFilter)); - m_sampler.SetParameteri(GL_TEXTURE_MIN_FILTER, ToOpenGL(samplerInfo.minFilter, samplerInfo.mipmapMode)); - m_sampler.SetParameteri(GL_TEXTURE_MAG_FILTER, ToOpenGL(samplerInfo.magFilter)); + sampler.SetParameteri(GL_TEXTURE_MAG_FILTER, ToOpenGL(samplerInfo.magFilter)); - m_sampler.SetParameteri(GL_TEXTURE_WRAP_S, ToOpenGL(samplerInfo.wrapModeU)); - m_sampler.SetParameteri(GL_TEXTURE_WRAP_T, ToOpenGL(samplerInfo.wrapModeV)); - m_sampler.SetParameteri(GL_TEXTURE_WRAP_R, ToOpenGL(samplerInfo.wrapModeW)); + sampler.SetParameteri(GL_TEXTURE_WRAP_S, ToOpenGL(samplerInfo.wrapModeU)); + sampler.SetParameteri(GL_TEXTURE_WRAP_T, ToOpenGL(samplerInfo.wrapModeV)); + sampler.SetParameteri(GL_TEXTURE_WRAP_R, ToOpenGL(samplerInfo.wrapModeW)); if (samplerInfo.anisotropyLevel > 1.f) - m_sampler.SetParameterf(GL_TEXTURE_MAX_ANISOTROPY_EXT, samplerInfo.anisotropyLevel); + sampler.SetParameterf(GL_TEXTURE_MAX_ANISOTROPY_EXT, samplerInfo.anisotropyLevel); } }