Texture compression questions

Hello! In my engine I store textures in .jpg format, load them, decompress them and finally upload them to the card and use the GL to compress them with S3TC. I think this is very unoptimized. I decided to use ARB-texture_compression. I read some tutorials and the following questions came to my mind:

  1. If I compress the textures with a special format (eg.S3TC), save the result to disk, and in the application I load the texture, the GL doesn’t have to compress it again. But what if the card doesn’t support the format of the compressed texture?
  2. To avoid the previous problem I can store the texture on disk in uncompressed format and the GL will compress it in load time. But in this case the texture file is much bigger than in jpg format, so loading it takes more time and also the real-time compession is slow. So wich would be faster (this method or the current (jpg) method)?

What should I do? How can I achieve better performance while keeping the portability of my textures?

I forgot another problem. If I want to generate mipmaps for uncompressed textures I simply call the glu function. But I think I can’t call it with a compressed texture. So if I want to build mipmaps from a compressed texture should precompress all the mipmaps and store them on disk?

There’s a more fundamental problem with your current algorithm: the use of JPEG compression for textures.

JPEG makes assumptions about how the image is going to be displayed. These assumptions are valid for normal images, but textures don’t work that way. With textures, you’re frequently applying lights and gamma correction to them. JPEG-compressed images tend to look much worse than they should when used as textures.

But what if the card doesn’t support the format of the compressed texture?

Most cards in use support the 3 compression formats exposed by EXT_texture_compression_s3tc. Generally, if they don’t, they don’t support texture compression at all.

Then I think if I want texture compression in my engine:

  1. I have to compress all the textures in load time
  2. or I have to store all the textures in two copies: in uncompressed and in compressed format
    How slow is real-time texture compression? Is it worth precompressing?

And another question. If I compress the textures in real-time, but I want to save some disk space what image compression should I use? Currently I use RLE for RGBA images (because jpg doesn’t support it). This is good enough for eg. font texture, where there are lots of same following colors. But this is not effective for noisy textures. So what do you seggest instead of jpg?

Try PNG. Quite good and lossless compression, and easy to read. You could also store your images precompressed with a texture compression format, and decompress them if the texture compression extension is not present. If you look in the s3tc spec you will find the compression algorithm, and it’s not difficult to write a decompressor for it.

S3TC compression can be quite involving. Eg compressing an RGBA DXT1 256x256 texture (a complete mipmap set) takes >1 second on ATI drivers. DXT1 RGB is faster. These things are already tuned for speed, so quality may still be sub-optimal and will also vary across OpenGL vendors.

For best quality you should really use an offline S3TC compressor. This also allows you to monitor quality and selectively disallow compression for textures that degrade too much. S3TC is a nice format for disk storage, too.

Decompressing S3TC for cards that don’t support it is relatively easy and very fast.

That’s a very good idea. I think I’ll try s3tc. Thanks for the help!

S3TC and PNG are different beasts. S3TC compression is good because it reduces texture fetch load on VRAM, leading to higher frame rates (or more detailed textures at the same frame rate).

Letting the driver compress is a bad idea, though, because the driver tries to do a semi-fast compression, and it doesn’t look very good. It also doesn’t compress that fast, either, but it’s faster than offline compressors (which look much better).

Using GLU to build MIP maps is never a good idea; your typical optimized C code is likely to perform better, and an MMX box filter MIP map generator will run at least 10x faster.

To answer the original questions:

Yes, you should pre-compress to S3TC and store on disk. Store all MIP maps in the file. You can use DDS files for this; they are easy to load and parse, and support pre-computed MIP maps.

For the cards that don’t support s3tc compression, you can de-compress the textures after you’ve read them from the file, and upload the uncompressed data, which should be good enough for old cards that don’t support s3tc (all halfway modern cards support it; you’d have to go back to ATI Rage 128 or NVIDIA TNT2 to find non-supporting cards).