Fixed #1: Implement anisotropic filtering for textures

This commit is contained in:
kervala 2012-10-27 17:46:13 +02:00
parent 100923cb6c
commit 40227ccec5
15 changed files with 116 additions and 2 deletions

View file

@ -293,6 +293,11 @@ public:
*/
virtual void forceDXTCCompression(bool dxtcComp)=0;
/** if different from 0, enable anisotropic filter on textures. -1 enables max value.
* Default is 0.
*/
virtual void setAnisotropicFilter(sint filter)=0;
/** if !=1, force mostly all the textures (but TextureFonts lightmaps, interfaces etc..)
* to be divided by Divisor (2, 4, 8...)
* Default is 1.

View file

@ -471,6 +471,7 @@ public:
virtual void delete3dMouseListener (U3dMouseListener *listener);
virtual TPolygonMode getPolygonMode ();
virtual void forceDXTCCompression(bool dxtcComp);
virtual void setAnisotropicFilter(sint filter);
virtual void forceTextureResize(uint divisor);
virtual void forceNativeFragmentPrograms(bool nativeOnly);
virtual bool setMonitorColorProperties (const CMonitorColorProperties &properties);

View file

@ -660,6 +660,11 @@ public:
*/
virtual void forceDXTCCompression(bool dxtcComp)=0;
/** if different from 0, enable anisotropic filter on textures. -1 enables max value.
* Default is 0.
*/
virtual void setAnisotropicFilter(sint filter)=0;
/** if !=1, force mostly all the textures (but TextureFonts lightmaps, interfaces etc..)
* to be divided by Divisor (2, 4, 8...)
* Default is 1.

View file

@ -33,7 +33,7 @@ namespace NL3D
{
// ***************************************************************************
const uint32 IDriver::InterfaceVersion = 0x6a; // added cursors methods
const uint32 IDriver::InterfaceVersion = 0x6b; // added anisotropic filter
// ***************************************************************************
IDriver::IDriver() : _SyncTexDrvInfos( "IDriver::_SyncTexDrvInfos" )

View file

@ -292,6 +292,11 @@ CDriverD3D::CDriverD3D()
_CurrIndexBufferFormat = CIndexBuffer::IndicesUnknownFormat;
_IsGeforce = false;
_NonPowerOfTwoTexturesSupported = false;
_MaxAnisotropy = 0;
_AnisotropicMinSupported = false;
_AnisotropicMagSupported = false;
_AnisotropicMinCubeSupported = false;
_AnisotropicMagCubeSupported = false;
_FrustumLeft= -1.f;
_FrustumRight= 1.f;
@ -1493,6 +1498,11 @@ bool CDriverD3D::setDisplay(nlWindow wnd, const GfxMode& mode, bool show, bool r
_MaxVertexIndex = caps.MaxVertexIndex;
_IsGeforce = !(caps.DevCaps & D3DDEVCAPS_NPATCHES) && (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0) || caps.PixelShaderVersion < D3DPS_VERSION(1, 4));
_NonPowerOfTwoTexturesSupported = !(caps.TextureCaps & D3DPTEXTURECAPS_POW2) || (caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL);
_MaxAnisotropy = caps.MaxAnisotropy;
_AnisotropicMinSupported = (caps.TextureFilterCaps & D3DPTFILTERCAPS_MINFANISOTROPIC) != 0;
_AnisotropicMagSupported = (caps.TextureFilterCaps & D3DPTFILTERCAPS_MAGFANISOTROPIC) != 0;
_AnisotropicMinCubeSupported = (caps.CubeTextureFilterCaps & D3DPTFILTERCAPS_MINFANISOTROPIC) != 0;
_AnisotropicMagCubeSupported = (caps.CubeTextureFilterCaps & D3DPTFILTERCAPS_MAGFANISOTROPIC) != 0;
}
else
{
@ -1506,6 +1516,11 @@ bool CDriverD3D::setDisplay(nlWindow wnd, const GfxMode& mode, bool show, bool r
_MaxVertexIndex = 0xffff;
_IsGeforce = false;
_NonPowerOfTwoTexturesSupported = false;
_MaxAnisotropy = 0;
_AnisotropicMinSupported = false;
_AnisotropicMagSupported = false;
_AnisotropicMinCubeSupported = false;
_AnisotropicMagCubeSupported = false;
}
// If 16 bits vertices only, build a vb for quads rendering
if (_MaxVertexIndex <= 0xffff)
@ -1607,6 +1622,7 @@ bool CDriverD3D::setDisplay(nlWindow wnd, const GfxMode& mode, bool show, bool r
// Init some variables
_ForceDXTCCompression = false;
_AnisotropicFilter = 0;
_ForceTextureResizePower = 0;
_FogEnabled = false;
@ -2049,6 +2065,25 @@ void CDriverD3D::forceDXTCCompression(bool dxtcComp)
// ***************************************************************************
void CDriverD3D::setAnisotropicFilter(sint filter)
{
H_AUTO_D3D(CDriverD3D_setAnisotropicFilter);
// anisotropic filter not supported
if (_MaxAnisotropy < 2) return;
if (filter < 0 || filter > _MaxAnisotropy)
{
_AnisotropicFilter = _MaxAnisotropy;
}
else
{
_AnisotropicFilter = filter;
}
}
// ***************************************************************************
void CDriverD3D::forceTextureResize(uint divisor)
{
H_AUTO_D3D(CDriverD3D_forceTextureResize);

View file

@ -777,6 +777,7 @@ public:
virtual void disableHardwareVertexArrayAGP();
virtual void disableHardwareTextureShader();
virtual void forceDXTCCompression(bool dxtcComp);
virtual void setAnisotropicFilter(sint filter);
virtual void forceTextureResize(uint divisor);
virtual void forceNativeFragmentPrograms(bool /* nativeOnly */) {} // ignored
@ -1521,6 +1522,7 @@ public:
setSamplerState (stage, D3DSAMP_MAGFILTER, d3dtext->MagFilter);
setSamplerState (stage, D3DSAMP_MINFILTER, d3dtext->MinFilter);
setSamplerState (stage, D3DSAMP_MIPFILTER, d3dtext->MipFilter);
setSamplerState (stage, D3DSAMP_MAXANISOTROPY, _AnisotropicFilter);
// Profile, log the use of this texture
if (_SumTextureMemoryUsed)
@ -2205,6 +2207,11 @@ private:
bool _CubbedMipMapSupported;
bool _IsGeforce;
bool _NonPowerOfTwoTexturesSupported;
uint _MaxAnisotropy;
bool _AnisotropicMinSupported;
bool _AnisotropicMagSupported;
bool _AnisotropicMinCubeSupported;
bool _AnisotropicMagCubeSupported;
uint _NbNeLTextureStages; // Number of texture stage for NeL (max IDRV_MAT_MAXTEXTURES)
uint _MaxVerticesByVertexBufferHard;
uint _MaxLight;
@ -2411,6 +2418,7 @@ private:
bool _MustRestoreLight;
D3DXMATRIX _D3DMatrixIdentity;
DWORD _FogColor;
uint _AnisotropicFilter;
// stencil buffer
bool _CurStencilTest;

View file

@ -506,6 +506,19 @@ inline void CDriverD3D::setupTextureWrapMode(ITexture& tex)
d3dtext->MagFilter = RemapMagTextureFilterTypeNeL2D3D[tex.getMagFilter()];
d3dtext->MinFilter = RemapMinTextureFilterTypeNeL2D3D[tex.getMinFilter()];
d3dtext->MipFilter = RemapMipTextureFilterTypeNeL2D3D[tex.getMinFilter()];
// only enable for min filter, because it's never supported for mag filter
if (_AnisotropicFilter > 1 && tex.getMinFilter() > ITexture::NearestMipMapLinear)
{
if (tex.isTextureCube())
{
if (_AnisotropicMinCubeSupported) d3dtext->MinFilter = D3DTEXF_ANISOTROPIC;
}
else
{
if (_AnisotropicMinSupported) d3dtext->MinFilter = D3DTEXF_ANISOTROPIC;
}
}
}

View file

@ -305,6 +305,8 @@ CDriverGL::CDriverGL()
_NVTextureShaderEnabled = false;
_AnisotropicFilter = 0.f;
// Compute the Flag which say if one texture has been changed in CMaterial.
_MaterialAllTextureTouchedFlag= 0;
for(i=0; i < IDRV_MAT_MAXTEXTURES; i++)

View file

@ -364,6 +364,7 @@ public:
virtual bool uploadTextureCube (ITexture& tex, NLMISC::CRect& rect, uint8 nNumMipMap, uint8 nNumFace);
virtual void forceDXTCCompression(bool dxtcComp);
virtual void setAnisotropicFilter(sint filter);
virtual void forceTextureResize(uint divisor);
@ -955,6 +956,8 @@ private:
bool _NVTextureShaderEnabled;
// Which stages support EMBM
bool _StageSupportEMBM[IDRV_MAT_MAXTEXTURES];
// Anisotropic filtering value
float _AnisotropicFilter;
// Prec settings for material.
CDriverGLStates _DriverGLStates;

View file

@ -157,7 +157,7 @@ public:
NVTextureRectangle = false;
EXTTextureRectangle = false;
EXTTextureFilterAnisotropic = false;
EXTTextureFilterAnisotropicMaximum = 1.f;
EXTTextureFilterAnisotropicMaximum = 0.f;
ARBTextureRectangle = false;
ARBTextureNonPowerOfTwo = false;
ARBMultisample = false;

View file

@ -823,6 +823,9 @@ void CDriverGL::setupTextureBasicParameters(ITexture &tex)
#endif
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB,GL_TEXTURE_MAG_FILTER, translateMagFilterToGl(gltext));
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB,GL_TEXTURE_MIN_FILTER, translateMinFilterToGl(gltext));
if (_AnisotropicFilter > 1.f && gltext->MinFilter > ITexture::NearestMipMapLinear)
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MAX_ANISOTROPY_EXT, _AnisotropicFilter);
}
}
else
@ -831,6 +834,9 @@ void CDriverGL::setupTextureBasicParameters(ITexture &tex)
glTexParameteri(gltext->TextureMode,GL_TEXTURE_WRAP_T, translateWrapToGl(gltext->WrapT, _Extensions));
glTexParameteri(gltext->TextureMode,GL_TEXTURE_MAG_FILTER, translateMagFilterToGl(gltext));
glTexParameteri(gltext->TextureMode,GL_TEXTURE_MIN_FILTER, translateMinFilterToGl(gltext));
if (_AnisotropicFilter > 1.f && gltext->MinFilter > ITexture::NearestMipMapLinear)
glTexParameteri(gltext->TextureMode, GL_TEXTURE_MAX_ANISOTROPY_EXT, _AnisotropicFilter);
}
//
tex.clearFilterOrWrapModeTouched();
@ -2184,6 +2190,25 @@ void CDriverGL::forceDXTCCompression(bool dxtcComp)
_ForceDXTCCompression= dxtcComp;
}
// ***************************************************************************
void CDriverGL::setAnisotropicFilter(sint filtering)
{
H_AUTO_OGL(CDriverGL_setAnisotropicFiltering);
if (!_Extensions.EXTTextureFilterAnisotropic) return;
if (filtering < 0 || filtering > _Extensions.EXTTextureFilterAnisotropicMaximum)
{
// set maximum value for anisotropic filter
_AnisotropicFilter = _Extensions.EXTTextureFilterAnisotropicMaximum;
}
else
{
// set specified value for anisotropic filter
_AnisotropicFilter = filtering;
}
}
// ***************************************************************************
void CDriverGL::forceTextureResize(uint divisor)
{

View file

@ -1469,12 +1469,21 @@ UDriver::TPolygonMode CDriverUser::getPolygonMode ()
return umode;
}
void CDriverUser::forceDXTCCompression(bool dxtcComp)
{
NL3D_HAUTO_UI_DRIVER;
_Driver->forceDXTCCompression(dxtcComp);
}
void CDriverUser::setAnisotropicFilter(sint filter)
{
NL3D_HAUTO_UI_DRIVER;
_Driver->setAnisotropicFilter(filter);
}
void CDriverUser::forceTextureResize(uint divisor)
{
NL3D_HAUTO_UI_DRIVER;

View file

@ -380,6 +380,7 @@ CClientConfig::CClientConfig()
ScreenAspectRatio = 0.f; // Default commmon Screen Aspect Ratio (no relation with the resolution) - 0.f = auto
FoV = 75.f; // Default value for the FoV.
ForceDXTC = false; // Default is no DXTC Compression.
AnisotropicFilter = 0; // Default is disabled (-1 = maximum value, 0 = disabled, 1+ = enabled)
DivideTextureSizeBy2= false; // Divide texture by 2
DisableVtxProgram = false; // Disable Hardware Vertex Program.
DisableVtxAGP = false; // Disable Hardware Vertex AGP.
@ -979,6 +980,8 @@ void CClientConfig::setValues()
READ_FLOAT_FV(FoV)
// ForceDXTC
READ_BOOL_FV(ForceDXTC)
// AnisotropicFilter
READ_INT_FV(AnisotropicFilter)
// DivideTextureSizeBy2
READ_BOOL_FV(DivideTextureSizeBy2)
// DisableVtxProgram

View file

@ -230,6 +230,8 @@ struct CClientConfig
float FoV;
/// Force the DXTC Compression.
bool ForceDXTC;
/// Set the anisotropic filter
sint AnisotropicFilter;
/// Divide texture size by 2
bool DivideTextureSizeBy2;
/// Disable Hardware Vertex Program.

View file

@ -1067,6 +1067,9 @@ void prelogInit()
// Init the DXTCCompression.
Driver->forceDXTCCompression(ClientCfg.ForceDXTC);
// Set the anisotropic filter
Driver->setAnisotropicFilter(ClientCfg.AnisotropicFilter);
// Divide the texture size.
if (ClientCfg.DivideTextureSizeBy2)
Driver->forceTextureResize(2);