In this article I want to share my experience in developing a mobile game, since I’m a Windows Phone developer, I’ll talk about my experience with this system.
Memory and textures
If you are already engaged in the development of mobile games, then the main evil is not a lack of CPU / GPU resources, but a lack of memory. It is about the memory you need to think in the mobile development in the first place. In Windows Phone 7, the limit was 100 MB, in Window Phone 8 it became better, but not much:
Limit type | Application Type | Phones with a small amount of memory | 1Gb phones | 2 GB phones |
Default | XNA or native | 150 MB | 150 MB | 150 MB |
Default | XAML / .NET excluding XNA | 150 MB | 300 MB | 300 MB |
Higherher | All app types | 180 MB | 380 MB | 570 MB |
And if you are developing a game in which a fairly large number of sprites (laid, of course, in atlases) - then you will sooner or later think about the number of these same atlases and texture compression.
The standard atlas, with which all more or less self-respecting devices work, is 2048x2048 pixels. What in uncompressed form (32 bits per pixel) will take up as much as 2 * 2 * 4 = 16 MB of memory. Then texture compression formats come to the rescue, in our case it is DXT compression.
Compressed textures not only require significantly less video card memory, but also generally display faster than uncompressed textures, at the expense of reducing bandwidth requirements. But some image quality may be lost due to compression. However, reducing the amount of memory allows you to increase the resolution of the textures that will be used, which can actually give a significant gain in quality.
Dxt compression is already implemented in .XNA Frameworke, as well as in Monogame.
For clarity, let's take 256 images of size 128x128 pixels, one texture atlas of these textures of size 2048 * 2048, and compress this atlas.
It is rumored that textures that are multiples of powers of two are loaded faster, for the experiment we will change a little the original texture, cutting off one pixel, bringing it to 2048 * 2047 size.
To show the effectiveness of the methods described, we will make control measurements. We will conduct them on the Nokia Lumia 800 phone. For greater accuracy, we will do 10 measurements for each method.
We summarize the results in table 1 and summarize.
Table 1. Image download speed.
| 256 textures 128 * 128 each | 1 dxt 2048 * 2048 | 1 origin 2048 * 2048 | 1 origin 2048 * 2047 |
one | 00: 00: 00.6460000 | 00: 00: 00.0330000 | 00: 00: 00.1510000 | 00: 00: 00.1200000 |
2 | 00: 00: 00.6440000 | 00: 00: 00.0330000 | 00: 00: 00.1510000 | 00: 00: 00.1180000 |
3 | 00: 00: 00.6470000 | 00: 00: 00.0410000 | 00: 00: 00.1870000 | 00: 00: 00.1570000 |
four | 00: 00: 00.6400000 | 00: 00: 00.0330000 | 00: 00: 00.1490000 | 00: 00: 00.1190000 |
five | 00: 00: 00.6420000 | 00: 00: 00.0330000 | 00: 00: 00.1500000 | 00: 00: 00.120000 |
6 | 00: 00: 00.6340000 | 00: 00: 00.0470000 | 00: 00: 00.1320000 | 00: 00: 00.161000 |
7 | 00: 00: 00.6340000 | 00: 00: 00.0500000 | 00: 00: 00.1590000 | 00: 00: 00.179000 |
eight | 00: 00: 00.6300000 | 00: 00: 00.0500000 | 00: 00: 00.1580000 | 00: 00: 00.179000 |
9 | 00: 00: 00.6330000 | 00: 00: 00.0480000 | 00: 00: 00.1580000 | 00: 00: 00.179000 |
ten | 00: 00: 00.6210000 | 00: 00: 00.0470000 | 00: 00: 00.1650000 | 00: 00: 00.1820000 |
The average | 00: 00: 00.6371000 | 00: 00: 00.0412000 | 00: 00: 00.1558000 | 00: 00: 00.1514000 |
For clarity, the graph of the dependence of the various methods of loading from time (Fig. 1.)
')

Figure 1. A graph of the dependence of various methods of loading on time.
Table 2. Image sizes
| Methods | Sizes, MB |
one | Size 256 textures 128 * 128 each | sixteen |
2 | Texture size 2048 * 2048 without compression | sixteen |
3 | Texture size 2048 * 2048 with compression | four |
As we see from the presented experiments Dxt compression is very effective. Consider it in more detail.
DXT compression (also sometimes known as S3 compression) is actually very simple. Here's how it works:
- The image is divided into 4x4 blocks.
- For each block, there are two most important colors.
- The resulting two colors are stored in 16 bits, in RGB 5.6.5 format.
- For each of the 16 pixels in a block, 2 bits of value are stored, indicating how far it is between the two primary colors
This simple scheme, it turns out, works surprisingly well for many real world images.
There are five options for DXT compression:
- DXT1 works as I described above, plus some additional magic to encode the alpha channel.
- DXT3 color is encoded as well as DXT1, and also stores 4 bits of the alpha channel value in a pixel.
- DXT5 color is encoded in the same way as DXT1, and a similar scheme is used to encode the alpha channel.
- DXT2 and DXT4 were not a very well-thought out attempt at standardization, and nothing good happened. You must pretend that they do not exist
The DXT1 uses 64 bits on a 4x4 block. Compared to a 32-bit uncompressed texture, this is an 8x multiple of compression. The DXT2-5 uses 128 bits in a 4x4 block, which gives 4x compression ratio.
And now the bad news: DXT compression is lossy compression. Sometimes they can be very large. In fact, it works very well for some images and is not at all suitable for others.
So, when you want to use Dxt compression, say in XNA, when you set the texture property of the Texture format, the DxtCompressed, Content Pipeline parameter automatically selects between DXT1 and DXT5, depending on whether your texture has an alpha channel. If it does not contain an alpha channel or contains a uniform alpha channel, it will use DXT1 to get the best compression ratio, but if the texture contains fractional alpha values, it will select DXT5 instead.
Let us consider in more detail each of the methods of compression:
DXT1
The DXT1 format is intended for decompression in real time by the hardware on the video card during rendering. DXT1 is a lossy compression format with a fixed 8: 1 compression ratio. DXT1 compression is a form of truncated block coding (BTC), where the image is divided into disjoint blocks, and the pixels in each block are quantized into a limited number of values. Color values of pixels in a 4x4 pixel block are approximated from equidistant points on a line passing through the RGB color space. This line is defined by two endpoints, and for each pixel in a 4x4 block, a 2-bit index is stored in one of the equidistant points on the line. The ends of the line passing through the color space are encoded in a 16-bit 5: 6: 5 RGB format and one or two intermediate points are generated by interpolation. The format allows you to store a 1-bit alpha channel, by switching to another mode, based on the order of the end points, where only one intermediate point is created and one additional color output indicates that it is black and fully transparent.
Let's look at Figure 2 below:
The left image is the original. The right one illustrates compression in DXT1 format.

Figure 2. Example of Dxt1 compression.
Visually compressed image does not differ from the original, which makes the results of compression acceptable for most users. Compression, however, significantly reduces the size of the texture.
In this case, from 256 KB to 32 KB.
However, things are not so rosy with this texture (Figure 3):

Figure 3. Example of Dxt1 compression.
The main problem is the appearance of noise inside the text, as well as distinct bands on the background of the gradient.

Figure 4. Noise inside the text.
Figure 5 shows how compression affects color. On the left, you see 16 shades of red, from pure red to pure black. On the right, you see four colors that came out of DXT compression, out of these 16 shades.

Figure 5. The effect of compression on color.
Figure 6 shows what happens when different colors are not on the same line in the color space. In this case, all the extremes of the RGB palette (red, green and blue) were used. Obviously, as a result, the interpolated colors do not match the originals. Usually in the 4x4 pixel area there is not such a wide choice of colors, but it shows that textures with different colors suffer more.

Figure 6. The effect of compression on color.
DXT1 compression usually works well for noisy textures and is not so good for clean images as well as gradients. The trick is to use it wherever it is possible and not to use it only on those textures where compression artifacts are too undesirable.
DXT5
The DXT5 format differs from the DXT3 format, in that it stores information about the alpha channel, just like how to store color information.
For alpha channel information, it uses a palette similar to how digital information is stored. This palette contains the minimum and maximum values of the alpha channel. There are two options with 6 and 4 reference points.
6 other alpha values interpolate between this minimum and maximum. Thus, it allows for more gradual changes in the alpha value.
The second option makes interpolation only for 4 other alpha channel values between the minimum and maximum values, but also adds alpha values of 0 and 1 (for fully transparent and non-transparent). For some textures this may give better results.

Figure 7. Example of Dxt5 compression.
As you can see, the edges are not well processed in some parts.

Figure 8. Torn edges when using Dxt5 compression.
The size of the texture at the same time decreased from 256 KB to 64 KB.
The loss of quality on real images is not so significant and they can be neglected for most images.
Using Dxt compression allows you to:
- Reduce the size of the installation package
- Reduce RAM usage
- Increase the speed of "drawing" images
In my project, after creating the texture atlas, I get the output .jpg / .png / .bmp and the description of the atlas in .xml / .txt / .json. Since I use XNA / Monogame for compression in .xnb, I use
XNA 4.0 Content Compiler as a whole, this is a very clear and simple solution, only to use Dxt compression you need to add another property to ContentBuilder when creating buildProject:
buildProject.SetProperty(“XnaCompressContent“, “True”);
Sources:
S3 Texture CompressionDXT compression explainedDXT Compression TechniquesReal-Time YCoCg-DXT Compression