Split up texture filtering properties of SMaterialLayer into MinFilter and MagFilter

You can now set the filter used when scaling textures down and the filter used when scaling textures up separately.
This commit is contained in:
Gregor Parzefall 2023-06-23 13:58:50 +02:00 committed by sfan5
parent 9e0189019e
commit 5ececc7d29
10 changed files with 128 additions and 101 deletions

View File

@ -37,11 +37,11 @@ namespace video
//! Corresponds to SMaterial::FrontfaceCulling. //! Corresponds to SMaterial::FrontfaceCulling.
EMF_FRONT_FACE_CULLING = 0x80, EMF_FRONT_FACE_CULLING = 0x80,
//! Corresponds to SMaterialLayer::BilinearFilter. //! Corresponds to SMaterialLayer::MinFilter.
EMF_BILINEAR_FILTER = 0x100, EMF_MIN_FILTER = 0x100,
//! Corresponds to SMaterialLayer::TrilinearFilter. //! Corresponds to SMaterialLayer::MagFilter.
EMF_TRILINEAR_FILTER = 0x200, EMF_MAG_FILTER = 0x200,
//! Corresponds to SMaterialLayer::AnisotropicFilter. //! Corresponds to SMaterialLayer::AnisotropicFilter.
EMF_ANISOTROPIC_FILTER = 0x400, EMF_ANISOTROPIC_FILTER = 0x400,

View File

@ -426,7 +426,6 @@ namespace video
f32 PolygonOffsetSlopeScale; f32 PolygonOffsetSlopeScale;
//! Draw as wireframe or filled triangles? Default: false //! Draw as wireframe or filled triangles? Default: false
/** The user can access a material flag using \code material.Wireframe = true; \endcode */
bool Wireframe:1; bool Wireframe:1;
//! Draw as point cloud or filled triangles? Default: false //! Draw as point cloud or filled triangles? Default: false

View File

@ -43,6 +43,30 @@ namespace video
"texture_clamp_mirror_clamp_to_edge", "texture_clamp_mirror_clamp_to_edge",
"texture_clamp_mirror_clamp_to_border", 0}; "texture_clamp_mirror_clamp_to_border", 0};
//! Texture minification filter.
/** Used when scaling textures down. */
enum E_TEXTURE_MIN_FILTER {
//! Nearest-neighbor interpolation.
ETMINF_NEAREST = 0,
//! Linear interpolation.
ETMINF_BILINEAR,
//! Linear interpolation across mipmaps.
/** Is equivalent to ETMINF_BILINEAR if mipmaps are disabled.
Only available as a minification filter since mipmaps are only used
when scaling down. */
ETMINF_TRILINEAR,
};
//! Texture magnification filter.
/** Used when scaling textures up. */
enum E_TEXTURE_MAG_FILTER {
//! Nearest-neighbor interpolation.
ETMAGF_NEAREST = 0,
//! Linear interpolation.
ETMAGF_BILINEAR,
};
//! Struct for holding material parameters which exist per texture layer //! Struct for holding material parameters which exist per texture layer
// Note for implementors: Serialization is in CNullDriver // Note for implementors: Serialization is in CNullDriver
class SMaterialLayer class SMaterialLayer
@ -50,7 +74,7 @@ namespace video
public: public:
//! Default constructor //! Default constructor
SMaterialLayer() : Texture(0), TextureWrapU(ETC_REPEAT), TextureWrapV(ETC_REPEAT), TextureWrapW(ETC_REPEAT), SMaterialLayer() : Texture(0), TextureWrapU(ETC_REPEAT), TextureWrapV(ETC_REPEAT), TextureWrapW(ETC_REPEAT),
BilinearFilter(true), TrilinearFilter(false), AnisotropicFilter(0), LODBias(0), TextureMatrix(0) MinFilter(ETMINF_BILINEAR), MagFilter(ETMAGF_BILINEAR), AnisotropicFilter(0), LODBias(0), TextureMatrix(0)
{ {
} }
@ -104,8 +128,8 @@ namespace video
TextureWrapU = other.TextureWrapU; TextureWrapU = other.TextureWrapU;
TextureWrapV = other.TextureWrapV; TextureWrapV = other.TextureWrapV;
TextureWrapW = other.TextureWrapW; TextureWrapW = other.TextureWrapW;
BilinearFilter = other.BilinearFilter; MinFilter = other.MinFilter;
TrilinearFilter = other.TrilinearFilter; MagFilter = other.MagFilter;
AnisotropicFilter = other.AnisotropicFilter; AnisotropicFilter = other.AnisotropicFilter;
LODBias = other.LODBias; LODBias = other.LODBias;
@ -157,8 +181,8 @@ namespace video
TextureWrapU != b.TextureWrapU || TextureWrapU != b.TextureWrapU ||
TextureWrapV != b.TextureWrapV || TextureWrapV != b.TextureWrapV ||
TextureWrapW != b.TextureWrapW || TextureWrapW != b.TextureWrapW ||
BilinearFilter != b.BilinearFilter || MinFilter != b.MinFilter ||
TrilinearFilter != b.TrilinearFilter || MagFilter != b.MagFilter ||
AnisotropicFilter != b.AnisotropicFilter || AnisotropicFilter != b.AnisotropicFilter ||
LODBias != b.LODBias; LODBias != b.LODBias;
if (different) if (different)
@ -184,13 +208,11 @@ namespace video
u8 TextureWrapV:4; u8 TextureWrapV:4;
u8 TextureWrapW:4; u8 TextureWrapW:4;
//! Is bilinear filtering enabled? Default: true //! Minification (downscaling) filter
bool BilinearFilter:1; E_TEXTURE_MIN_FILTER MinFilter;
//! Is trilinear filtering enabled? Default: false //! Magnification (upscaling) filter
/** If the trilinear filter flag is enabled, E_TEXTURE_MAG_FILTER MagFilter;
the bilinear filtering flag is ignored. */
bool TrilinearFilter:1;
//! Is anisotropic filtering enabled? Default: 0, disabled //! Is anisotropic filtering enabled? Default: 0, disabled
/** In Irrlicht you can use anisotropic texture filtering /** In Irrlicht you can use anisotropic texture filtering
@ -208,6 +230,16 @@ namespace video
if the value is positive. */ if the value is positive. */
s8 LODBias; s8 LODBias;
//! Sets the MinFilter, MagFilter and AnisotropicFilter properties according
//! to the three relevant boolean values found in the Minetest settings.
/** The value of `trilinear` takes precedence over the value of `bilinear`. */
void setFiltersMinetest(bool bilinear, bool trilinear, bool anisotropic) {
MinFilter = trilinear ? ETMINF_TRILINEAR :
(bilinear ? ETMINF_BILINEAR : ETMINF_NEAREST);
MagFilter = (trilinear || bilinear) ? ETMAGF_BILINEAR : ETMAGF_NEAREST;
AnisotropicFilter = anisotropic ? 0xFF : 0;
}
private: private:
friend class SMaterial; friend class SMaterial;

View File

@ -104,21 +104,21 @@ namespace video
case EMF_ZWRITE_ENABLE: material.ZWriteEnable = Material.ZWriteEnable; break; case EMF_ZWRITE_ENABLE: material.ZWriteEnable = Material.ZWriteEnable; break;
case EMF_BACK_FACE_CULLING: material.BackfaceCulling = Material.BackfaceCulling; break; case EMF_BACK_FACE_CULLING: material.BackfaceCulling = Material.BackfaceCulling; break;
case EMF_FRONT_FACE_CULLING: material.FrontfaceCulling = Material.FrontfaceCulling; break; case EMF_FRONT_FACE_CULLING: material.FrontfaceCulling = Material.FrontfaceCulling; break;
case EMF_BILINEAR_FILTER: case EMF_MIN_FILTER:
for ( u32 i=0; i<MATERIAL_MAX_TEXTURES; ++i) for ( u32 i=0; i<MATERIAL_MAX_TEXTURES; ++i)
{ {
if ( EnableLayerFlags[i] ) if ( EnableLayerFlags[i] )
{ {
material.TextureLayer[i].BilinearFilter = Material.TextureLayer[i].BilinearFilter; material.TextureLayer[i].MinFilter = Material.TextureLayer[i].MinFilter;
} }
} }
break; break;
case EMF_TRILINEAR_FILTER: case EMF_MAG_FILTER:
for ( u32 i=0; i<MATERIAL_MAX_TEXTURES; ++i) for ( u32 i=0; i<MATERIAL_MAX_TEXTURES; ++i)
{ {
if ( EnableLayerFlags[i] ) if ( EnableLayerFlags[i] )
{ {
material.TextureLayer[i].TrilinearFilter = Material.TextureLayer[i].TrilinearFilter; material.TextureLayer[i].MagFilter = Material.TextureLayer[i].MagFilter;
} }
} }
break; break;

View File

@ -102,13 +102,13 @@ CNullDriver::CNullDriver(io::IFileSystem* io, const core::dimension2d<u32>& scre
InitMaterial2D.ZWriteEnable = video::EZW_OFF; InitMaterial2D.ZWriteEnable = video::EZW_OFF;
InitMaterial2D.ZBuffer = video::ECFN_DISABLED; InitMaterial2D.ZBuffer = video::ECFN_DISABLED;
InitMaterial2D.UseMipMaps = false; InitMaterial2D.UseMipMaps = false;
for (u32 i=0; i<video::MATERIAL_MAX_TEXTURES; ++i) InitMaterial2D.forEachTexture([] (auto &tex) {
{ tex.MinFilter = video::ETMINF_NEAREST;
InitMaterial2D.TextureLayer[i].BilinearFilter=false; tex.MagFilter = video::ETMAGF_NEAREST;
InitMaterial2D.TextureLayer[i].TextureWrapU=video::ETC_REPEAT; tex.TextureWrapU = video::ETC_REPEAT;
InitMaterial2D.TextureLayer[i].TextureWrapV=video::ETC_REPEAT; tex.TextureWrapV = video::ETC_REPEAT;
InitMaterial2D.TextureLayer[i].TextureWrapW = video::ETC_REPEAT; tex.TextureWrapW = video::ETC_REPEAT;
} });
OverrideMaterial2D = InitMaterial2D; OverrideMaterial2D = InitMaterial2D;
} }

View File

@ -1696,41 +1696,40 @@ COGLES2Driver::~COGLES2Driver()
if (resetAllRenderstates) if (resetAllRenderstates)
tmpTexture->getStatesCache().IsCached = false; tmpTexture->getStatesCache().IsCached = false;
if (!tmpTexture->getStatesCache().IsCached || material.TextureLayer[i].BilinearFilter != tmpTexture->getStatesCache().BilinearFilter || if (!tmpTexture->getStatesCache().IsCached || material.TextureLayer[i].MagFilter != tmpTexture->getStatesCache().MagFilter)
material.TextureLayer[i].TrilinearFilter != tmpTexture->getStatesCache().TrilinearFilter)
{ {
E_TEXTURE_MAG_FILTER magFilter = material.TextureLayer[i].MagFilter;
glTexParameteri(tmpTextureType, GL_TEXTURE_MAG_FILTER, glTexParameteri(tmpTextureType, GL_TEXTURE_MAG_FILTER,
(material.TextureLayer[i].BilinearFilter || material.TextureLayer[i].TrilinearFilter) ? GL_LINEAR : GL_NEAREST); magFilter == ETMAGF_BILINEAR ? GL_LINEAR : GL_NEAREST);
tmpTexture->getStatesCache().BilinearFilter = material.TextureLayer[i].BilinearFilter; tmpTexture->getStatesCache().MagFilter = magFilter;
tmpTexture->getStatesCache().TrilinearFilter = material.TextureLayer[i].TrilinearFilter;
} }
if (material.UseMipMaps && tmpTexture->hasMipMaps()) if (material.UseMipMaps && tmpTexture->hasMipMaps())
{ {
if (!tmpTexture->getStatesCache().IsCached || material.TextureLayer[i].BilinearFilter != tmpTexture->getStatesCache().BilinearFilter || if (!tmpTexture->getStatesCache().IsCached || material.TextureLayer[i].MinFilter != tmpTexture->getStatesCache().MinFilter ||
material.TextureLayer[i].TrilinearFilter != tmpTexture->getStatesCache().TrilinearFilter || !tmpTexture->getStatesCache().MipMapStatus) !tmpTexture->getStatesCache().MipMapStatus)
{ {
E_TEXTURE_MIN_FILTER minFilter = material.TextureLayer[i].MinFilter;
glTexParameteri(tmpTextureType, GL_TEXTURE_MIN_FILTER, glTexParameteri(tmpTextureType, GL_TEXTURE_MIN_FILTER,
material.TextureLayer[i].TrilinearFilter ? GL_LINEAR_MIPMAP_LINEAR : minFilter == ETMINF_TRILINEAR ? GL_LINEAR_MIPMAP_LINEAR :
material.TextureLayer[i].BilinearFilter ? GL_LINEAR_MIPMAP_NEAREST : minFilter == ETMINF_BILINEAR ? GL_LINEAR_MIPMAP_NEAREST :
GL_NEAREST_MIPMAP_NEAREST); GL_NEAREST_MIPMAP_NEAREST);
tmpTexture->getStatesCache().BilinearFilter = material.TextureLayer[i].BilinearFilter; tmpTexture->getStatesCache().MinFilter = minFilter;
tmpTexture->getStatesCache().TrilinearFilter = material.TextureLayer[i].TrilinearFilter;
tmpTexture->getStatesCache().MipMapStatus = true; tmpTexture->getStatesCache().MipMapStatus = true;
} }
} }
else else
{ {
if (!tmpTexture->getStatesCache().IsCached || material.TextureLayer[i].BilinearFilter != tmpTexture->getStatesCache().BilinearFilter || if (!tmpTexture->getStatesCache().IsCached || material.TextureLayer[i].MinFilter != tmpTexture->getStatesCache().MinFilter ||
material.TextureLayer[i].TrilinearFilter != tmpTexture->getStatesCache().TrilinearFilter || tmpTexture->getStatesCache().MipMapStatus) tmpTexture->getStatesCache().MipMapStatus)
{ {
E_TEXTURE_MIN_FILTER minFilter = material.TextureLayer[i].MinFilter;
glTexParameteri(tmpTextureType, GL_TEXTURE_MIN_FILTER, glTexParameteri(tmpTextureType, GL_TEXTURE_MIN_FILTER,
(material.TextureLayer[i].BilinearFilter || material.TextureLayer[i].TrilinearFilter) ? GL_LINEAR : GL_NEAREST); (minFilter == ETMINF_TRILINEAR || minFilter == ETMINF_BILINEAR) ? GL_LINEAR : GL_NEAREST);
tmpTexture->getStatesCache().BilinearFilter = material.TextureLayer[i].BilinearFilter; tmpTexture->getStatesCache().MinFilter = minFilter;
tmpTexture->getStatesCache().TrilinearFilter = material.TextureLayer[i].TrilinearFilter;
tmpTexture->getStatesCache().MipMapStatus = false; tmpTexture->getStatesCache().MipMapStatus = false;
} }
} }

View File

@ -1914,41 +1914,40 @@ void COGLES1Driver::setTextureRenderStates(const SMaterial& material, bool reset
} }
#endif #endif
if (!statesCache.IsCached || material.TextureLayer[i].BilinearFilter != statesCache.BilinearFilter || if (!statesCache.IsCached || material.TextureLayer[i].MagFilter != statesCache.MagFilter)
material.TextureLayer[i].TrilinearFilter != statesCache.TrilinearFilter)
{ {
E_TEXTURE_MAG_FILTER magFilter = material.TextureLayer[i].MagFilter;
glTexParameteri(tmpTextureType, GL_TEXTURE_MAG_FILTER, glTexParameteri(tmpTextureType, GL_TEXTURE_MAG_FILTER,
(material.TextureLayer[i].BilinearFilter || material.TextureLayer[i].TrilinearFilter) ? GL_LINEAR : GL_NEAREST); magFilter == ETMAGF_BILINEAR ? GL_LINEAR : GL_NEAREST);
statesCache.BilinearFilter = material.TextureLayer[i].BilinearFilter; statesCache.MagFilter = magFilter;
statesCache.TrilinearFilter = material.TextureLayer[i].TrilinearFilter;
} }
if (material.UseMipMaps && tmpTexture->hasMipMaps()) if (material.UseMipMaps && tmpTexture->hasMipMaps())
{ {
if (!statesCache.IsCached || material.TextureLayer[i].BilinearFilter != statesCache.BilinearFilter || if (!statesCache.IsCached || material.TextureLayer[i].MinFilter != statesCache.MinFilter ||
material.TextureLayer[i].TrilinearFilter != statesCache.TrilinearFilter || !statesCache.MipMapStatus) !statesCache.MipMapStatus)
{ {
E_TEXTURE_MIN_FILTER minFilter = material.TextureLayer[i].MinFilter;
glTexParameteri(tmpTextureType, GL_TEXTURE_MIN_FILTER, glTexParameteri(tmpTextureType, GL_TEXTURE_MIN_FILTER,
material.TextureLayer[i].TrilinearFilter ? GL_LINEAR_MIPMAP_LINEAR : minFilter == ETMINF_TRILINEAR ? GL_LINEAR_MIPMAP_LINEAR :
material.TextureLayer[i].BilinearFilter ? GL_LINEAR_MIPMAP_NEAREST : minFilter == ETMINF_BILINEAR ? GL_LINEAR_MIPMAP_NEAREST :
GL_NEAREST_MIPMAP_NEAREST); GL_NEAREST_MIPMAP_NEAREST);
statesCache.BilinearFilter = material.TextureLayer[i].BilinearFilter; statesCache.MinFilter = minFilter;
statesCache.TrilinearFilter = material.TextureLayer[i].TrilinearFilter;
statesCache.MipMapStatus = true; statesCache.MipMapStatus = true;
} }
} }
else else
{ {
if (!statesCache.IsCached || material.TextureLayer[i].BilinearFilter != statesCache.BilinearFilter || if (!statesCache.IsCached || material.TextureLayer[i].MinFilter != statesCache.MinFilter ||
material.TextureLayer[i].TrilinearFilter != statesCache.TrilinearFilter || statesCache.MipMapStatus) statesCache.MipMapStatus)
{ {
E_TEXTURE_MIN_FILTER minFilter = material.TextureLayer[i].MinFilter;
glTexParameteri(tmpTextureType, GL_TEXTURE_MIN_FILTER, glTexParameteri(tmpTextureType, GL_TEXTURE_MIN_FILTER,
(material.TextureLayer[i].BilinearFilter || material.TextureLayer[i].TrilinearFilter) ? GL_LINEAR : GL_NEAREST); (minFilter == ETMINF_TRILINEAR || minFilter == ETMINF_BILINEAR) ? GL_LINEAR : GL_NEAREST);
statesCache.BilinearFilter = material.TextureLayer[i].BilinearFilter; statesCache.MinFilter = minFilter;
statesCache.TrilinearFilter = material.TextureLayer[i].TrilinearFilter;
statesCache.MipMapStatus = false; statesCache.MipMapStatus = false;
} }
} }

View File

@ -31,8 +31,8 @@ public:
struct SStatesCache struct SStatesCache
{ {
SStatesCache() : WrapU(ETC_REPEAT), WrapV(ETC_REPEAT), WrapW(ETC_REPEAT), SStatesCache() : WrapU(ETC_REPEAT), WrapV(ETC_REPEAT), WrapW(ETC_REPEAT),
LODBias(0), AnisotropicFilter(0), BilinearFilter(false), TrilinearFilter(false), LODBias(0), AnisotropicFilter(0), MinFilter(video::ETMINF_NEAREST),
MipMapStatus(false), IsCached(false) MagFilter(video::ETMAGF_NEAREST), MipMapStatus(false), IsCached(false)
{ {
} }
@ -41,8 +41,8 @@ public:
u8 WrapW; u8 WrapW;
s8 LODBias; s8 LODBias;
u8 AnisotropicFilter; u8 AnisotropicFilter;
bool BilinearFilter; video::E_TEXTURE_MIN_FILTER MinFilter;
bool TrilinearFilter; video::E_TEXTURE_MAG_FILTER MagFilter;
bool MipMapStatus; bool MipMapStatus;
bool IsCached; bool IsCached;
}; };

View File

@ -2709,41 +2709,40 @@ void COpenGLDriver::setTextureRenderStates(const SMaterial& material, bool reset
} }
#endif #endif
if (!statesCache.IsCached || material.TextureLayer[i].BilinearFilter != statesCache.BilinearFilter || if (!statesCache.IsCached || material.TextureLayer[i].MagFilter != statesCache.MagFilter)
material.TextureLayer[i].TrilinearFilter != statesCache.TrilinearFilter)
{ {
E_TEXTURE_MAG_FILTER magFilter = material.TextureLayer[i].MagFilter;
glTexParameteri(tmpType, GL_TEXTURE_MAG_FILTER, glTexParameteri(tmpType, GL_TEXTURE_MAG_FILTER,
(material.TextureLayer[i].BilinearFilter || material.TextureLayer[i].TrilinearFilter) ? GL_LINEAR : GL_NEAREST); magFilter == ETMAGF_BILINEAR ? GL_LINEAR : GL_NEAREST);
statesCache.BilinearFilter = material.TextureLayer[i].BilinearFilter; statesCache.MagFilter = magFilter;
statesCache.TrilinearFilter = material.TextureLayer[i].TrilinearFilter;
} }
if (material.UseMipMaps && tmpTexture->hasMipMaps()) if (material.UseMipMaps && tmpTexture->hasMipMaps())
{ {
if (!statesCache.IsCached || material.TextureLayer[i].BilinearFilter != statesCache.BilinearFilter || if (!statesCache.IsCached || material.TextureLayer[i].MinFilter != statesCache.MinFilter ||
material.TextureLayer[i].TrilinearFilter != statesCache.TrilinearFilter || !statesCache.MipMapStatus) !statesCache.MipMapStatus)
{ {
E_TEXTURE_MIN_FILTER minFilter = material.TextureLayer[i].MinFilter;
glTexParameteri(tmpType, GL_TEXTURE_MIN_FILTER, glTexParameteri(tmpType, GL_TEXTURE_MIN_FILTER,
material.TextureLayer[i].TrilinearFilter ? GL_LINEAR_MIPMAP_LINEAR : minFilter == ETMINF_TRILINEAR ? GL_LINEAR_MIPMAP_LINEAR :
material.TextureLayer[i].BilinearFilter ? GL_LINEAR_MIPMAP_NEAREST : minFilter == ETMINF_BILINEAR ? GL_LINEAR_MIPMAP_NEAREST :
GL_NEAREST_MIPMAP_NEAREST); GL_NEAREST_MIPMAP_NEAREST);
statesCache.BilinearFilter = material.TextureLayer[i].BilinearFilter; statesCache.MinFilter = minFilter;
statesCache.TrilinearFilter = material.TextureLayer[i].TrilinearFilter;
statesCache.MipMapStatus = true; statesCache.MipMapStatus = true;
} }
} }
else else
{ {
if (!statesCache.IsCached || material.TextureLayer[i].BilinearFilter != statesCache.BilinearFilter || if (!statesCache.IsCached || material.TextureLayer[i].MinFilter != statesCache.MinFilter ||
material.TextureLayer[i].TrilinearFilter != statesCache.TrilinearFilter || statesCache.MipMapStatus) statesCache.MipMapStatus)
{ {
E_TEXTURE_MIN_FILTER minFilter = material.TextureLayer[i].MinFilter;
glTexParameteri(tmpType, GL_TEXTURE_MIN_FILTER, glTexParameteri(tmpType, GL_TEXTURE_MIN_FILTER,
(material.TextureLayer[i].BilinearFilter || material.TextureLayer[i].TrilinearFilter) ? GL_LINEAR : GL_NEAREST); (minFilter == ETMINF_TRILINEAR || minFilter == ETMINF_BILINEAR) ? GL_LINEAR : GL_NEAREST);
statesCache.BilinearFilter = material.TextureLayer[i].BilinearFilter; statesCache.MinFilter = minFilter;
statesCache.TrilinearFilter = material.TextureLayer[i].TrilinearFilter;
statesCache.MipMapStatus = false; statesCache.MipMapStatus = false;
} }
} }

View File

@ -1456,41 +1456,40 @@ COpenGL3DriverBase::~COpenGL3DriverBase()
if (resetAllRenderstates) if (resetAllRenderstates)
tmpTexture->getStatesCache().IsCached = false; tmpTexture->getStatesCache().IsCached = false;
if (!tmpTexture->getStatesCache().IsCached || material.TextureLayer[i].BilinearFilter != tmpTexture->getStatesCache().BilinearFilter || if (!tmpTexture->getStatesCache().IsCached || material.TextureLayer[i].MagFilter != tmpTexture->getStatesCache().MagFilter)
material.TextureLayer[i].TrilinearFilter != tmpTexture->getStatesCache().TrilinearFilter)
{ {
E_TEXTURE_MAG_FILTER magFilter = material.TextureLayer[i].MagFilter;
glTexParameteri(tmpTextureType, GL_TEXTURE_MAG_FILTER, glTexParameteri(tmpTextureType, GL_TEXTURE_MAG_FILTER,
(material.TextureLayer[i].BilinearFilter || material.TextureLayer[i].TrilinearFilter) ? GL_LINEAR : GL_NEAREST); magFilter == ETMAGF_BILINEAR ? GL_LINEAR : GL_NEAREST);
tmpTexture->getStatesCache().BilinearFilter = material.TextureLayer[i].BilinearFilter; tmpTexture->getStatesCache().MagFilter = magFilter;
tmpTexture->getStatesCache().TrilinearFilter = material.TextureLayer[i].TrilinearFilter;
} }
if (material.UseMipMaps && tmpTexture->hasMipMaps()) if (material.UseMipMaps && tmpTexture->hasMipMaps())
{ {
if (!tmpTexture->getStatesCache().IsCached || material.TextureLayer[i].BilinearFilter != tmpTexture->getStatesCache().BilinearFilter || if (!tmpTexture->getStatesCache().IsCached || material.TextureLayer[i].MinFilter != tmpTexture->getStatesCache().MinFilter ||
material.TextureLayer[i].TrilinearFilter != tmpTexture->getStatesCache().TrilinearFilter || !tmpTexture->getStatesCache().MipMapStatus) !tmpTexture->getStatesCache().MipMapStatus)
{ {
E_TEXTURE_MIN_FILTER minFilter = material.TextureLayer[i].MinFilter;
glTexParameteri(tmpTextureType, GL_TEXTURE_MIN_FILTER, glTexParameteri(tmpTextureType, GL_TEXTURE_MIN_FILTER,
material.TextureLayer[i].TrilinearFilter ? GL_LINEAR_MIPMAP_LINEAR : minFilter == ETMINF_TRILINEAR ? GL_LINEAR_MIPMAP_LINEAR :
material.TextureLayer[i].BilinearFilter ? GL_LINEAR_MIPMAP_NEAREST : minFilter == ETMINF_BILINEAR ? GL_LINEAR_MIPMAP_NEAREST :
GL_NEAREST_MIPMAP_NEAREST); GL_NEAREST_MIPMAP_NEAREST);
tmpTexture->getStatesCache().BilinearFilter = material.TextureLayer[i].BilinearFilter; tmpTexture->getStatesCache().MinFilter = minFilter;
tmpTexture->getStatesCache().TrilinearFilter = material.TextureLayer[i].TrilinearFilter;
tmpTexture->getStatesCache().MipMapStatus = true; tmpTexture->getStatesCache().MipMapStatus = true;
} }
} }
else else
{ {
if (!tmpTexture->getStatesCache().IsCached || material.TextureLayer[i].BilinearFilter != tmpTexture->getStatesCache().BilinearFilter || if (!tmpTexture->getStatesCache().IsCached || material.TextureLayer[i].MinFilter != tmpTexture->getStatesCache().MinFilter ||
material.TextureLayer[i].TrilinearFilter != tmpTexture->getStatesCache().TrilinearFilter || tmpTexture->getStatesCache().MipMapStatus) tmpTexture->getStatesCache().MipMapStatus)
{ {
E_TEXTURE_MIN_FILTER minFilter = material.TextureLayer[i].MinFilter;
glTexParameteri(tmpTextureType, GL_TEXTURE_MIN_FILTER, glTexParameteri(tmpTextureType, GL_TEXTURE_MIN_FILTER,
(material.TextureLayer[i].BilinearFilter || material.TextureLayer[i].TrilinearFilter) ? GL_LINEAR : GL_NEAREST); (minFilter == ETMINF_TRILINEAR || minFilter == ETMINF_BILINEAR) ? GL_LINEAR : GL_NEAREST);
tmpTexture->getStatesCache().BilinearFilter = material.TextureLayer[i].BilinearFilter; tmpTexture->getStatesCache().MinFilter = minFilter;
tmpTexture->getStatesCache().TrilinearFilter = material.TextureLayer[i].TrilinearFilter;
tmpTexture->getStatesCache().MipMapStatus = false; tmpTexture->getStatesCache().MipMapStatus = false;
} }
} }