The drawback is that textures in its compressed form are bigger than .jpg or .png files with the same image, so more disk space will be consumed. Further in the article I will also describe way how I solved it.
Creating ETC1 texture
Every GPU vendor has its own set of tools including tool for compressing textures. I am using tool from ARM. After you run the tool you will get initial screen. Open image file with you texture (do not forget that open GL ES needs height and width to be power of 2) and you should get screen like this:Select the texture(s) in left panel and press "Compress" icon. The compression parameters panel will pop up:
Choose ETC1/ETC2 tab (1.) and select PKM as output format. PKM is very simple format that ads small header to compressed data. The header is this:
+0: 4 bytes header "PKM "
+4: 2 bytes version "10"
+6: 2 bytes data type (always zero)
+8: 2 bytes extended width
+10: 2 bytes extended height
+12: 2 bytes original width
+14: 2 bytes original height
+16: compressed texture data
In ETC1 format each 4x4 pixel bloc is compressed into 64 bits. So the extended width and height are the original dimensions rounded up to multiple of four. If you are using power of 2 textures then the original and extended dimensions are the same.
From these parameters you can calculate the size of compressed data like this:(extended width / 4) * (extended height / 4) * 8
This formula just says: there is so many 4x4 pixel blocks and each of them is 8 bytes long (64 bits).
Parameters marked 2. and 5. on the picture will affect quality of compression. The compression takes quite a lot of time. So during development you can use worse quality if you do not want to wait. But be sure that when finishing your game you use maximum quality - the size of output remains the same.
Under 3. do not forget to check that ETC1 is chosen and udder 4. choose to create separate texture for alpha channel. This texture will have the same dimensions as the original one. But in the red channel of it there will be stored alpha instead of color. The green and blue channels are unused so theoretically you can put any additional information there (but not with the tool - it would be up to you how to do it).
Loading ETC1 texture
Now when you have the texture compressed it is time to load it into GPU.//------------------------------------------------------------------------ u16 TextureETC1::swapBytes(u16 aData) { return ((aData & 0x00FF) < 8) | ((aData & 0xFF00) > 8); } //------------------------------------------------------------------------ void TextureETC1::construct(SBC::System::Collections::ByteBuffer& unpacked) { // check if data is ETC1 PKM file - should start with text "PKM " (notice the space in the end) // read byte by byte to prevent endianness problems u8 header[4]; header[0] = (u8) unpacked.getChar; header[1] = (u8) unpacked.getChar; header[2] = (u8) unpacked.getChar; header[3] = (u8) unpacked.getChar; if (header[0] != 'P' || header[1] != 'K' || header[2] != 'M' || header[3] != ' ') LOGE("data are not in valid PKM format");
swapBytes is just help method the real work is done in construct method. ByteBuffer is our simple wrapper around array of bytes holding not only data but also its size. This is not important here it just increases readability.