diff --git a/irr/src/OpenGL/Driver.cpp b/irr/src/OpenGL/Driver.cpp index 17d2c32e0..c33b3c9d9 100644 --- a/irr/src/OpenGL/Driver.cpp +++ b/irr/src/OpenGL/Driver.cpp @@ -1340,60 +1340,74 @@ void COpenGL3DriverBase::setTextureRenderStates(const SMaterial &material, bool CacheHandler->setActiveTexture(GL_TEXTURE0 + i); - if (resetAllRenderstates) - tmpTexture->getStatesCache().IsCached = false; + const auto &layer = material.TextureLayers[i]; + auto &states = tmpTexture->getStatesCache(); - if (!tmpTexture->getStatesCache().IsCached || material.TextureLayers[i].MagFilter != tmpTexture->getStatesCache().MagFilter) { - E_TEXTURE_MAG_FILTER magFilter = material.TextureLayers[i].MagFilter; + if (resetAllRenderstates) + states.IsCached = false; + + if (!states.IsCached || layer.MagFilter != states.MagFilter) { + E_TEXTURE_MAG_FILTER magFilter = layer.MagFilter; GL.TexParameteri(tmpTextureType, GL_TEXTURE_MAG_FILTER, magFilter == ETMAGF_NEAREST ? GL_NEAREST : (assert(magFilter == ETMAGF_LINEAR), GL_LINEAR)); - tmpTexture->getStatesCache().MagFilter = magFilter; + states.MagFilter = magFilter; } if (material.UseMipMaps && tmpTexture->hasMipMaps()) { - if (!tmpTexture->getStatesCache().IsCached || material.TextureLayers[i].MinFilter != tmpTexture->getStatesCache().MinFilter || - !tmpTexture->getStatesCache().MipMapStatus) { - E_TEXTURE_MIN_FILTER minFilter = material.TextureLayers[i].MinFilter; + if (!states.IsCached || layer.MinFilter != states.MinFilter || + !states.MipMapStatus) { + E_TEXTURE_MIN_FILTER minFilter = layer.MinFilter; GL.TexParameteri(tmpTextureType, GL_TEXTURE_MIN_FILTER, minFilter == ETMINF_NEAREST_MIPMAP_NEAREST ? GL_NEAREST_MIPMAP_NEAREST : minFilter == ETMINF_LINEAR_MIPMAP_NEAREST ? GL_LINEAR_MIPMAP_NEAREST : minFilter == ETMINF_NEAREST_MIPMAP_LINEAR ? GL_NEAREST_MIPMAP_LINEAR : (assert(minFilter == ETMINF_LINEAR_MIPMAP_LINEAR), GL_LINEAR_MIPMAP_LINEAR)); - tmpTexture->getStatesCache().MinFilter = minFilter; - tmpTexture->getStatesCache().MipMapStatus = true; + states.MinFilter = minFilter; + states.MipMapStatus = true; } } else { - if (!tmpTexture->getStatesCache().IsCached || material.TextureLayers[i].MinFilter != tmpTexture->getStatesCache().MinFilter || - tmpTexture->getStatesCache().MipMapStatus) { - E_TEXTURE_MIN_FILTER minFilter = material.TextureLayers[i].MinFilter; + if (!states.IsCached || layer.MinFilter != states.MinFilter || + states.MipMapStatus) { + E_TEXTURE_MIN_FILTER minFilter = layer.MinFilter; GL.TexParameteri(tmpTextureType, GL_TEXTURE_MIN_FILTER, (minFilter == ETMINF_NEAREST_MIPMAP_NEAREST || minFilter == ETMINF_NEAREST_MIPMAP_LINEAR) ? GL_NEAREST : (assert(minFilter == ETMINF_LINEAR_MIPMAP_NEAREST || minFilter == ETMINF_LINEAR_MIPMAP_LINEAR), GL_LINEAR)); - tmpTexture->getStatesCache().MinFilter = minFilter; - tmpTexture->getStatesCache().MipMapStatus = false; + states.MinFilter = minFilter; + states.MipMapStatus = false; } } + if (LODBiasSupported && + (!states.IsCached || layer.LODBias != states.LODBias)) { + if (layer.LODBias) { + const float tmp = core::clamp(layer.LODBias * 0.125f, -MaxTextureLODBias, MaxTextureLODBias); + GL.TexParameterf(tmpTextureType, GL.TEXTURE_LOD_BIAS, tmp); + } else + GL.TexParameterf(tmpTextureType, GL.TEXTURE_LOD_BIAS, 0.f); + + states.LODBias = layer.LODBias; + } + if (AnisotropicFilterSupported && - (!tmpTexture->getStatesCache().IsCached || material.TextureLayers[i].AnisotropicFilter != tmpTexture->getStatesCache().AnisotropicFilter)) { + (!states.IsCached || layer.AnisotropicFilter != states.AnisotropicFilter)) { GL.TexParameteri(tmpTextureType, GL.TEXTURE_MAX_ANISOTROPY, - material.TextureLayers[i].AnisotropicFilter > 1 ? core::min_(MaxAnisotropy, material.TextureLayers[i].AnisotropicFilter) : 1); + layer.AnisotropicFilter > 1 ? core::min_(MaxAnisotropy, layer.AnisotropicFilter) : 1); - tmpTexture->getStatesCache().AnisotropicFilter = material.TextureLayers[i].AnisotropicFilter; + states.AnisotropicFilter = layer.AnisotropicFilter; } - if (!tmpTexture->getStatesCache().IsCached || material.TextureLayers[i].TextureWrapU != tmpTexture->getStatesCache().WrapU) { - GL.TexParameteri(tmpTextureType, GL_TEXTURE_WRAP_S, getTextureWrapMode(material.TextureLayers[i].TextureWrapU)); - tmpTexture->getStatesCache().WrapU = material.TextureLayers[i].TextureWrapU; + if (!states.IsCached || layer.TextureWrapU != states.WrapU) { + GL.TexParameteri(tmpTextureType, GL_TEXTURE_WRAP_S, getTextureWrapMode(layer.TextureWrapU)); + states.WrapU = layer.TextureWrapU; } - if (!tmpTexture->getStatesCache().IsCached || material.TextureLayers[i].TextureWrapV != tmpTexture->getStatesCache().WrapV) { - GL.TexParameteri(tmpTextureType, GL_TEXTURE_WRAP_T, getTextureWrapMode(material.TextureLayers[i].TextureWrapV)); - tmpTexture->getStatesCache().WrapV = material.TextureLayers[i].TextureWrapV; + if (!states.IsCached || layer.TextureWrapV != states.WrapV) { + GL.TexParameteri(tmpTextureType, GL_TEXTURE_WRAP_T, getTextureWrapMode(layer.TextureWrapV)); + states.WrapV = layer.TextureWrapV; } - tmpTexture->getStatesCache().IsCached = true; + states.IsCached = true; } } diff --git a/irr/src/OpenGL/ExtensionHandler.h b/irr/src/OpenGL/ExtensionHandler.h index 403b828b3..0e3a0af2d 100644 --- a/irr/src/OpenGL/ExtensionHandler.h +++ b/irr/src/OpenGL/ExtensionHandler.h @@ -161,6 +161,7 @@ public: GL.BlendEquation(mode); } + bool LODBiasSupported = false; bool AnisotropicFilterSupported = false; bool BlendMinMaxSupported = false; bool TextureMultisampleSupported = false; diff --git a/irr/src/OpenGL3/Driver.cpp b/irr/src/OpenGL3/Driver.cpp index 5277c4dde..767ce5992 100644 --- a/irr/src/OpenGL3/Driver.cpp +++ b/irr/src/OpenGL3/Driver.cpp @@ -69,6 +69,7 @@ void COpenGL3Driver::initFeatures() TextureFormats[ECF_D24S8] = {GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8}; AnisotropicFilterSupported = isVersionAtLeast(4, 6) || queryExtension("GL_ARB_texture_filter_anisotropic") || queryExtension("GL_EXT_texture_filter_anisotropic"); + LODBiasSupported = true; BlendMinMaxSupported = true; TextureMultisampleSupported = true; diff --git a/irr/src/OpenGLES2/Driver.cpp b/irr/src/OpenGLES2/Driver.cpp index 7b84675aa..25c4f485d 100644 --- a/irr/src/OpenGLES2/Driver.cpp +++ b/irr/src/OpenGLES2/Driver.cpp @@ -120,10 +120,10 @@ void COpenGLES2Driver::initFeatures() } const bool MRTSupported = Version.Major >= 3 || queryExtension("GL_EXT_draw_buffers"); + LODBiasSupported = queryExtension("GL_EXT_texture_lod_bias"); AnisotropicFilterSupported = queryExtension("GL_EXT_texture_filter_anisotropic"); BlendMinMaxSupported = (Version.Major >= 3) || FeatureAvailable[IRR_GL_EXT_blend_minmax]; TextureMultisampleSupported = isVersionAtLeast(3, 1); - const bool TextureLODBiasSupported = queryExtension("GL_EXT_texture_lod_bias"); // COGLESCoreExtensionHandler::Feature static_assert(MATERIAL_MAX_TEXTURES <= 8, "Only up to 8 textures are guaranteed"); @@ -141,7 +141,7 @@ void COpenGLES2Driver::initFeatures() if (Version.Major >= 3 || queryExtension("GL_EXT_draw_range_elements")) MaxIndices = GetInteger(GL_MAX_ELEMENTS_INDICES); MaxTextureSize = GetInteger(GL_MAX_TEXTURE_SIZE); - if (TextureLODBiasSupported) + if (LODBiasSupported) GL.GetFloatv(GL_MAX_TEXTURE_LOD_BIAS, &MaxTextureLODBias); GL.GetFloatv(GL_ALIASED_LINE_WIDTH_RANGE, DimAliasedLine); // NOTE: this is not in the OpenGL ES 2.0 spec... GL.GetFloatv(GL_ALIASED_POINT_SIZE_RANGE, DimAliasedPoint);