This function load a LithTech *.dtx texture file and convert to OpenGL pixel format, compressed support.
Use FileSystem interface. :D
1 #pragma pack(1) 2 3 struct DtxHeader 4 { 5 unsigned int iResType; 6 int iVersion; 7 unsigned short usWidth; 8 unsigned short usHeight; 9 unsigned short usMipmaps; 10 unsigned short usSections; 11 int iFlags; 12 int iUserFlags; 13 unsigned char ubExtra[12]; 14 char szCommandString[128]; 15 }; 16 17 #pragma pack()
1 bool LoadDTX(const char *pszFileName, unsigned char *pBuffer, int iBufferSize, int *pInternalFormat, int *pWidth, int *pHeight, int *pImageSize) 2 { 3 FileHandle_t pFile = g_pFileSystem->Open(pszFileName, "rb"); 4 5 if (!pFile) 6 return false; 7 8 DtxHeader Header; 9 memset(&Header, 0, sizeof(Header)); 10 11 g_pFileSystem->Read(&Header, sizeof(Header), pFile); 12 13 if (Header.iResType != 0 || Header.iVersion != -5 || Header.usMipmaps == 0) 14 { 15 g_pFileSystem->Close(pFile); 16 return false; 17 } 18 19 *pWidth = Header.usWidth; 20 *pHeight = Header.usHeight; 21 22 int iBpp = Header.ubExtra[2]; 23 int iSize; 24 25 if (iBpp == 0) 26 iBpp = 3; 27 28 if (iBpp == 3) 29 { 30 iSize = Header.usWidth * Header.usHeight * 4; 31 *pInternalFormat = GL_RGBA; 32 } 33 else if (iBpp == 4) 34 { 35 iSize = (Header.usWidth * Header.usHeight) >> 1; 36 *pInternalFormat = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; 37 } 38 else if (iBpp == 5) 39 { 40 iSize = Header.usWidth * Header.usHeight; 41 *pInternalFormat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; 42 } 43 else if (iBpp == 6) 44 { 45 iSize = Header.usWidth * Header.usHeight; 46 *pInternalFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; 47 } 48 else 49 { 50 iSize = 0; 51 } 52 53 *pImageSize = iSize; 54 55 if (iSize == 0 || iSize > iBufferSize) 56 { 57 g_pFileSystem->Close(pFile); 58 return false; 59 } 60 61 g_pFileSystem->Read(pBuffer, iSize, pFile); 62 63 if (iBpp == 3) 64 { 65 for (uint32 i = 0; i < (uint32)iSize; i += 4) 66 { 67 pBuffer[i + 0] ^= pBuffer[i + 2]; 68 pBuffer[i + 2] ^= pBuffer[i + 0]; 69 pBuffer[i + 0] ^= pBuffer[i + 2]; 70 } 71 } 72 73 g_pFileSystem->Close(pFile); 74 return true; 75 }