I've seen lots of messages in these forums about anisotropic filtering, and how can you do it in DarkGDK?? People saying it didn't work or one who offered a DBPro .DLL, but with no instructions on using it in DarkGDK. Well it's quite possible in DarkGDK without such a .DLL, using a couple undocumented (but available) DarkGDK functions that provide access to lower-level data.
First of all, there already is an undocumented function available that does it:
But it doesn't give you much control. Using that open-source .DLL as a starting point, I wrote another function that provides more control, all within DarkGDK (no third-party stuff or hacks of source code). You can choose the anistropy level yourself (or choose the max supported by your video board). And you can choose which filters you'd like for mipmap selection, minification, and magnification separately.
Such filtering works at an object's texture level rather that a universal environmental level. So I've written a function to apply the filter too all objects up to and including the highest object passed in. I commented within it so you can follow along and easily make any modifications you wish.
Here's the function's prototype:
+ Code Snippetint FilterObjects(int highestObject, int mipmapFilter, int minificationFilter, int magnificationFilter, int anisotropy);
Here is a call to this function with everything set to match the defaults:
+ Code SnippetFilterObjects(-1, D3DTEXF_LINEAR, D3DTEXF_LINEAR, D3DTEXF_LINEAR, 0);
Here is a recommended call to this function to enable anisotropic filtering at your card's maximum supported level:
+ Code SnippetFilterObjects(-1, D3DTEXF_LINEAR, D3DTEXF_ANISOTROPIC, D3DTEXF_LINEAR, -1);
Since anisotropic filtering is heavier on your card's resources than linear, I kept the magnification filter set to linear, but you can do whatever you want. And anisotropic filtering is undefined on mipmap selection.
And here is the function itself:
The constants are defined in d3d9types.h.
+ Code Snippet// Valid Values for Mipmap Filter: D3DTEXF_POINT, D3DTEXF_LINEAR
// Valid Values for Minification Filter: D3DTEXF_POINT, D3DTEXF_LINEAR, D3DTEXF_ANISOTROPIC, D3DTEXF_PYRAMIDALQUAD, D3DTEXF_GAUSSIANQUAD
// Will effect all already-created objects up to and including the highestObject passed in (-1 means all objects until it reaches the first invalid object).
// For the 3 Filter values, (-1) means no change what whatever it's currently set to.
// For anisotropy, (-1) means to use the MaxAnisotropy allowed by the video driver.
// Documentation: http://msdn.microsoft.com/en-us/library/windows/desktop/bb172615%28v=vs.85%29.aspx
int FilterObjects (int highestObject, int mipmapFilter, int minificationFilter, int magnificationFilter, int anisotropy)
{
int sampler, object, meshIndex, textureIndex;
bool quitAtInvalidObject;
sObject* objectPtr;
IDirect3DDevice9* Device;
D3DCAPS9 caps;
Device = dbGetDirect3DDevice();
if ((minificationFilter == D3DTEXF_ANISOTROPIC) || (magnificationFilter == D3DTEXF_ANISOTROPIC))
{
// Check Device Capabilities. Assert that anisotropy does not exceed MaxAnisotropy.
Device->GetDeviceCaps(&caps);
if ((caps.MaxAnisotropy < anisotropy) || (anisotropy == -1))
{
anisotropy = caps.MaxAnisotropy;
}
}
else
{
anisotropy = 0;
}
// Set the anisotropy
sampler = 8;
while (sampler--)
{
Device->SetSamplerState(sampler, D3DSAMP_MAXANISOTROPY, anisotropy);
}
if (highestObject == -1)
{
highestObject = 22000000;
quitAtInvalidObject = true;
}
else
{
quitAtInvalidObject = false;
}
// Set object texture filters
object = -1;
while (++object <= highestObject)
{
// Next object. Check that the object exists.
if (dbObjectExist(object))
{
// Get a pointer to the object's underlying data.
objectPtr = dbGetObject(object);
if (objectPtr)
{
// Cycle through all the meshes within that object
meshIndex = objectPtr->iMeshCount;
while (meshIndex--)
{
// Cycle through all the textures within each mesh
textureIndex = objectPtr->ppMeshList[meshIndex]->dwTextureCount;
while (textureIndex--)
{
// Apply the Filter Settings, if >= 0
if ( minificationFilter >= 0) objectPtr->ppMeshList[meshIndex]->pTextures[textureIndex].dwMinState = minificationFilter;
if (magnificationFilter >= 0) objectPtr->ppMeshList[meshIndex]->pTextures[textureIndex].dwMagState = magnificationFilter;
if ( mipmapFilter >= 0) objectPtr->ppMeshList[meshIndex]->pTextures[textureIndex].dwMipState = mipmapFilter;
}
}
}
}
else if (quitAtInvalidObject)
{
if (object) object = highestObject;
}
}
// Return the anisotropy used, if used
return (anisotropy);
}