# Loading and Saving DDS Files

# Loading and Saving DDS Files

DirectDraw Surface is Microsoft's file format for storing textures. You can find information on this file format and on its Imaging support in Supported File Formats/DDS section. This section shows how to perform some load/save operations specific for DDS files (cube map and volume texture support). Each example consists of description of a action you want to do and code listing in which the action is carried out by Imaging.
Example 1: Simple Loading and Saving
You have single texture without mipmaps and you want to load it and save it.
uses ImagingTypes, Imaging; var Img: TImageData; begin // call this before using any TImageData record InitImage(Img); // load texture from file LoadImageFromFile('X:\images\tex01.dds', Img); ... // do something with the image ... // save the image to file SaveImageToFile('X:\images\tex02.dds', Img); // memory occupied by the image is freed FreeImage(Img); end.
Example 2: Loading and Saving Mipmapped Texture
You have single texture with mipmaps and you want to load it and save it.
Imaging saves mipmaps in the same order as you send them to SaveMultiImageTo* functions in Images parameter. Mipmap dimensions (next level has width and height of the previous level divided by two) and format (must be same as the main image's) are automatically adjusted during saving.
uses ImagingTypes, Imaging; var ImgArray: TDynImageDataArray; MipMapLevels: LongInt; begin // load texture from file LoadMultiImageFromFile('X:\images\tex01mip.dds', ImgArray); // get the number of mipmap levels in the loaded DDS file // in this case it is equal to Length(ImgArray) MipMapLevels := GetOption(ImagingDDSLoadedMipMapCount); ... // do something with the image ... // save the texture with mipmaps to file, number of mipmaps saved to // file will be Length(ImgArray) SaveMultiImageToFile('X:\images\tex02mip.dds', ImgArray); // memory occupied by the images is freed FreeImagesInArray(ImgArray); end.
Example 3: Loading and Saving Mipmapped Cube Map
You have cubic environment map with mipmaps and you want to load it and save it. The cube faces in DDS files are written in this order: positive x, negative x, positive y, negative y, positive z, negative z. Each face is written with its main image followed by any mipmap levels. All faces must be the same size and have the same number of mipmap levels.
Imaging saves cube faces and mipmaps in the same order as you send them to SaveMultiImageTo* functions in Images parameter. Make sure that number of images you send to saving functions is equal to NumberOfFaces * MipMapLevels where these two values are defined by options interface (see code below). If the number of images is not right then DDS is saved as simple 2D texture. Mipmap dimensions (next level has width and height of the previous level divided by two) and format (must be same as the main image's) are automatically adjusted during saving.
uses ImagingTypes, Imaging; var ImgArray: TDynImageDataArray; MipMapLevels, Faces: LongInt; IsCubeMap: Boolean; begin // load texture from file LoadMultiImageFromFile('X:\images\tex01cubemip.dds', ImgArray); // get the number of mipmap levels in the loaded DDS file // in this case it is equal to Length(ImgArray) div Faces MipMapLevels := GetOption(ImagingDDSLoadedMipMapCount); // check whether we have loaded cube map IsCubeMap := Boolean(GetOption(ImagingDDSLoadedCubeMap)); // get the number of cube faces in the loaded DDS file // Length(ImgArray) = Faces * MipMapLevels Faces := GetOption(ImagingDDSLoadedDepth); ... // do something with the image ... // tell Imaging how many mipmap levels next DDS file should have (for each face) SetOption(ImagingDDSSaveMipMapCount, MipMapLevels); // tell Imaging that the next DDS file should be cubic environment map SetOption(ImagingDDSSaveCubeMap, IsCubeMap); // tell Imaging how many faces next DDS file should have SetOption(ImagingDDSSaveDepth, Faces); // save the cube map with mipmaps to file SaveMultiImageToFile('X:\images\tex02cubemip.dds', ImgArray); // memory occupied by the images is freed FreeImagesInArray(ImgArray); end.
Example 4: Loading and Saving Mipmapped Volume Texture
You have volume texture with mipmaps and you want to load it and save it. For volumes without mipmaps, each depth slice is written to the file in order. If mipmaps are included, all depth slices for a given mipmap level are written together, with each level containing half as many slices as the previous level with a minimum of 1. Volume textures do not support DXTn compression as of DirectX 9.0.
Imaging saves volume slices and mipmaps in the same order as you send them to SaveMultiImageTo* functions in Images parameter. Make sure that number of images you send to saving functions is right (it is not NumberOfFaces * MipMapLevels!). If the number of images is not right then DDS is saved as simple 2D texture. Mipmap dimensions (next level has width and height of the previous level divided by two) and format (must be same as the main image's) are automatically adjusted during saving.
uses ImagingTypes, Imaging; var ImgArray: TDynImageDataArray; MipMapLevels, Slices: LongInt; IsVolume: Boolean; begin // load texture from file LoadMultiImageFromFile('X:\images\tex01volmip.dds', ImgArray); // get the number of mipmap levels in the loaded DDS file // in this case it is NOT equal to Length(ImgArray) div Slices MipMapLevels := GetOption(ImagingDDSLoadedMipMapCount); // check whether we have loaded volume texture IsVolume := Boolean(GetOption(ImagingDDSLoadedVolume)); // get the number of volume slices in the loaded DDS file // Length(ImgArray) <> Slices * MipMapLevels Slices := GetOption(ImagingDDSLoadedDepth); ... // do something with the image ... // tell Imaging how many mipmap levels next DDS file should have SetOption(ImagingDDSSaveMipMapCount, MipMapLevels); // tell Imaging that the next DDS file should be volume texture SetOption(ImagingDDSSaveVolume, IsVolume); // tell Imaging how many slices next DDS file should have SetOption(ImagingDDSSaveDepth, Slices); // save the volume texture with mipmaps to file SaveMultiImageToFile('X:\images\tex02volmip.dds', ImgArray); // memory occupied by the images is freed FreeImagesInArray(ImgArray); end.