Since the release of the DirectX 8 SDK, I have received a lot of questions regarding how to perform various 2D operations using DirectX Graphics, which is a 3D oriented API. One such operation, which we will cover here, is the display of full screen images, such as those used for splash screens or background images.
This task can be somewhat troublesome, because the 4:3 aspect ratio and use of standard screen resolutions for full screen images does not comply with the dimensional requirements of texture surfaces, which must have dimensions that are powers of two. Also, on some hardware, the maximum texture dimensions may be smaller than the required image size, requiring the image to be divided into multiple textures.
What are the Options?
There are two basic options here:
We will now take a look at how to implement the second option above. This will require some modification to our media files, as well as a modest bit of code.
Preparing the Media
To prepare our media, we will need to resize the image so that its dimensions are powers of two. To prevent loss of quality, choose dimensions that are larger than the original, corresponding to the smallest power of two that is larger than the original dimensions of the image. For example, a 640x480 image would be stretched to 1024x768. Use the best available resampling to stretch the image - bicubic sampling in Adobe Photoshop or comparable will do just fine.
This results in a larger image, but you can compensate for this by using the DirectX Texture Tool included in the SDK to compress the image into a DDS file. The results will often be significantly smaller than the original (smaller) bitmap file. For example, a 640x480x24 bit BMP file is 900K in size. After resizing to 1024x512 and conversion to DXT1 texture format, the image takes up only 256K of drive space.
Below you will find source code for a class named CSplash. This is a stripped down version of a class that I use to display splash screens.
To use the class, first create an instance of CSplash, passing it the path to an image file (any file type the D3DX texture functions can load, such as DDS, BMP, JPG, etc), a pointer to the 3D device, and the dimensions of the frame buffer to be rendered to. This will load the image file, subdividing it into multiple textures if required by hardware limitations.
To render to the screen, call the draw() member function with a pointer to the 3D device. The image will be rendered into the frame buffer, from 0,0 to the dimensions specified during instance creation. This function must be called from within a scene, and lighting (the D3DRS_LIGHTING state) must be turned off. In addition, to insure the quality of the resized image, set the D3DTSS_MINFILTER and D3DTSS_MAGFILTER states for the first texture stage to D3DTEXF_LINEAR.
When done with the image, simply delete the class instance.
Update: This function has been updated from its original form to utilize the D3DXGetImageInfoFromFileInMemory() function introduced in the DirectX 8.1 SDK. If using the 8.0 SDK, you can find the original source code here.
Visitors Since 1/1/2000: