Texture Filtering with Mipmaps
A version of this page is also available for
4/8/2010
A mipmap is a sequence of textures, each of which is a progressively lower resolution representation of the same image. The height and width of each image, or level, in the mipmap is a power of two smaller than the previous level. Mipmaps do not have to be square.
A high-resolution mipmap image is used for objects that are close to the user. Lower-resolution images are used as the object appears farther away. Mipmapping improves the quality of rendered textures at the expense of using more memory.
Microsoft® Direct3D® Mobile represents mipmaps as a chain of attached surfaces. The highest resolution texture is at the head of the chain and has the next level of the mipmap as an attachment. In turn, that level has an attachment that is the next level in the mipmap, and so on, down to the lowest resolution level of the mipmap.
The following illustrations shows an example of these levels. The bitmap textures represent a sign on a container in a 3-D, first-person game. When created as a mipmap, the highest-resolution texture is first in the set. Each succeeding texture in the mipmap set is smaller in height and width by a power of 2. In this case, the maximum-resolution mipmap is 256 pixels by 256 pixels. The next, texture is 128x128. The last texture in the chain is 64x64.
This sign has a maximum distance from which it is visible. If the user begins far away from the sign, the game displays the smallest texture in the mipmap chain, which in this case the 64x64 texture.
As the user moves the point of view closer to the sign, progressively higher-resolution textures in the mipmap chain are used. The resolution in the following illustration is 128x128.
The highest-resolution texture is used when the user's point of view is at the minimum allowable distance from the sign.
This is a computationally lower-overhead way of simulating perspective for textures. Rather than render a single texture at many resolutions, it is faster to use multiple textures at varying resolutions.
Direct3D Mobile can assess which texture in a mipmap set is the closest resolution to the desired output, and it can map pixels into its texel space. If the resolution of the final image is between the resolutions of the textures in the mipmap set, Direct3D Mobile can examine texels in both mipmaps and blend their color values together.
To use mipmaps, your application must build a set of mipmaps. Applications apply mipmaps by selecting the mipmap set as the first texture in the set of current textures. For more information, see Multiple Texture Blending.
Creating a Set of Mipmaps
The following code example shows how your application can call the IDirect3DMobileDevice::CreateTexture method to build a chain of five mipmap levels: 256×256, 128×128, 64×64, 32×32, and 16×16.
// This code example assumes that the variable d3dmDevice is a
// valid pointer to a IDirect3DMobileDevice interface.
IDirect3DMobileTexture * pMipMap;
d3dmDevice->CreateTexture(256, 256, 5, 0, D3DMFMT_R8G8B8, D3DMPOOL_MANAGED, &pMipMap);
The first two parameters that are accepted by CreateTexture are the size and width of the top-level texture. The third parameter specifies the number of levels in the texture. If you set this to zero, Direct3D Mobile creates a chain of surfaces, each a power of two smaller than the previous one, down to the smallest possible size of 1x1. The fourth parameter specifies the usage for this resource; in this case, 0 is specified to indicate no specific usage for the resource. The fifth parameter specifies the surface format for the texture. Use a value from the D3DMFORMAT enumerated type for this parameter. The sixth parameter specifies a member of the D3DMPOOL enumerated type indicating the memory class into which to place the created resource. Unless you are using dynamic textures, D3DPOOL_MANAGED is recommended. The final parameter takes the address of a pointer to a IDirect3DMobileTexture interface.
Note
Each surface in a mipmap chain has dimensions that are one-half that of the previous surface in the chain. If the top-level mipmap has dimensions of 256×128, the dimensions of the second-level mipmap are 128×64, the third-level is 64×32, and so on, down to 1×1. You cannot request a number of mipmap levels in Levels that would cause either the width or height of any mipmap in the chain to be smaller than 1. In the simple case of a 4×2 top-level mipmap surface, the maximum value allowed for Levels is three. The top-level dimensions are 4×2, the second-level dimensions are 2×1, and the dimensions for the third level are 1×1. A value larger than 3 in Levels results in a fractional value in the height of the second-level mipmap, and is therefore disallowed.
Selecting and Displaying a Mipmap
Call the IDirect3DMobileDevice::SetTexture method to set the mipmap texture set as the first texture in the list of current textures. For more information, see Multiple Texture Blending.
After your application selects the mipmap texture set, it must assign values from the D3DMTEXTUREFILTERTYPE enumerated type to the D3DMTSS_MIPFILTER texture stage state. Direct3D Mobile then automatically performs mipmap texture filtering. Enabling mipmap texture filtering is demonstrated in the following code example.
d3dmDevice->SetTexture(0, pMipMap);
d3dmDevice->SetTextureStageState(0, D3DMTSS_MIPFILTER, D3DMTEXF_POINT);
Your application can also manually traverse a chain of mipmap surfaces by using the IDirect3DMobileTexture::GetSurfaceLevel method and specifying the mipmap level to retrieve. The following code example traverses a mipmap chain from highest to lowest resolutions.
IDirect3DMobileSurface * pSurfaceLevel;
for (int iLevel = 0; iLevel < pMipMap->GetLevelCount(); iLevel++)
{
pMipMap->GetSurfaceLevel(iLevel, &pSurfaceLevel);
//Process this level.
pSurfaceLevel->Release();
}
Applications need to manually traverse a mipmap chain to load bitmap data into each surface in the chain. This is typically the only reason to traverse the chain. An application can retrieve the number of levels in a mipmap by calling IDirect3DMobileBaseTexture::GetLevelCount.