[MetaHook] Load DTX texture to OpenGL

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 }

 

posted @ 2015-08-04 19:24  Akatsuki-  阅读(552)  评论(0编辑  收藏  举报