home *** CD-ROM | disk | FTP | other *** search
/ Xentax forum attachments archive / xentax.7z / 5257 / source.7z / x_dds.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2012-03-23  |  12.2 KB  |  475 lines

  1. #include "xentax.h"
  2. #include "x_dds.h"
  3.  
  4. BOOL CreateUncompressedDDSHeader(DWORD dx, DWORD dy, DWORD mipmaps, DWORD maskR, DWORD maskG, DWORD maskB, DWORD maskA, BOOL cubemap, DDS_HEADER* header)
  5. {
  6.  // validate
  7.  if(!header) return FALSE;
  8.  if(dx == 0) return FALSE;
  9.  if(dy == 0) return FALSE;
  10.  
  11.  // set header size
  12.  header->dwSize = 124;
  13.  
  14.  // set flags
  15.  header->dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PITCH | DDSD_PIXELFORMAT;
  16.  if(mipmaps) header->dwFlags |= DDSD_MIPMAPCOUNT;
  17.  
  18.  // set dimensions
  19.  header->dwHeight = dy;
  20.  header->dwWidth  = dx;
  21.  header->dwDepth  = 0;
  22.  
  23.  // set pitch
  24.  DWORD bpp = 0;
  25.  if(maskR) bpp += 8;
  26.  if(maskG) bpp += 8;
  27.  if(maskB) bpp += 8;
  28.  if(maskA) bpp += 8;
  29.  header->dwPitchOrLinearSize = (bpp*dx + 7)/8;
  30.  
  31.  // set mipmap count
  32.  header->dwMipMapCount = mipmaps;
  33.  
  34.  // set reserved data
  35.  header->dwReserved01 = 0;
  36.  header->dwReserved02 = 0;
  37.  header->dwReserved03 = 0;
  38.  header->dwReserved04 = 0;
  39.  header->dwReserved05 = 0;
  40.  header->dwReserved06 = 0;
  41.  header->dwReserved07 = 0;
  42.  header->dwReserved08 = 0;
  43.  header->dwReserved09 = 0;
  44.  header->dwReserved10 = 0;
  45.  header->dwReserved11 = 0;
  46.  
  47.  // set pixel format
  48.  header->ddspf.dwSize = 32;
  49.  header->ddspf.dwFlags = DDPF_RGB;
  50.  if(maskA) header->ddspf.dwFlags |= DDPF_ALPHAPIXELS;
  51.  header->ddspf.dwFourCC = 0;
  52.  header->ddspf.dwRGBBitCount = bpp;
  53.  header->ddspf.dwRBitMask = maskR;
  54.  header->ddspf.dwGBitMask = maskG;
  55.  header->ddspf.dwBBitMask = maskB;
  56.  header->ddspf.dwABitMask = maskA;
  57.  
  58.  // set capabilities
  59.  DWORD DDS_CUBEMAP_ALLFACES = 0xFC00;
  60.  header->dwCaps1 = DDSCAPS_TEXTURE;
  61.  if(mipmaps) header->dwCaps1 |= (DDSCAPS_COMPLEX | DDSCAPS_MIPMAP);
  62.  header->dwCaps2 = 0;
  63.  if(mipmaps) header->dwCaps2 |= (DDSCAPS2_CUBEMAP | DDS_CUBEMAP_ALLFACES);
  64.  header->dwCaps3 = 0;
  65.  header->dwCaps4 = 0;
  66.  header->dwReserved12 = 0;
  67.  
  68.  return TRUE;
  69. }
  70.  
  71. BOOL CreateDXT1Header(DWORD dx, DWORD dy, DWORD mipmaps, BOOL cubemap, DDS_HEADER* header)
  72. {
  73.  // validate
  74.  if(!header) return FALSE;
  75.  if(dx == 0) return FALSE;
  76.  if(dy == 0) return FALSE;
  77.  
  78.  // set header size
  79.  header->dwSize = 124;
  80.  
  81.  // set flags
  82.  header->dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_LINEARSIZE | DDSD_PIXELFORMAT;
  83.  if(mipmaps) header->dwFlags |= DDSD_MIPMAPCOUNT;
  84.  
  85.  // set dimensions
  86.  header->dwHeight = dy;
  87.  header->dwWidth  = dx;
  88.  header->dwDepth  = 0;
  89.  
  90.  // set linear size
  91.  DWORD blocksize = 8;
  92.  DWORD rows = std::max((DWORD)1, (DWORD)((dy + 3)/4));
  93.  DWORD cols = std::max((DWORD)1, (DWORD)((dx + 3)/4));
  94.  header->dwPitchOrLinearSize = rows*cols*blocksize;
  95.  
  96.  // set mipmap count
  97.  header->dwMipMapCount = mipmaps;
  98.  
  99.  // set reserved data
  100.  header->dwReserved01 = 0;
  101.  header->dwReserved02 = 0;
  102.  header->dwReserved03 = 0;
  103.  header->dwReserved04 = 0;
  104.  header->dwReserved05 = 0;
  105.  header->dwReserved06 = 0;
  106.  header->dwReserved07 = 0;
  107.  header->dwReserved08 = 0;
  108.  header->dwReserved09 = 0;
  109.  header->dwReserved10 = 0;
  110.  header->dwReserved11 = 0;
  111.  
  112.  // set pixel format
  113.  header->ddspf.dwSize = 32;
  114.  header->ddspf.dwFlags = DDPF_FOURCC;
  115.  header->ddspf.dwFourCC = 0x31545844;
  116.  
  117.  // set capabilities
  118.  DWORD DDS_CUBEMAP_ALLFACES = 0xFC00;
  119.  header->dwCaps1 = DDSCAPS_TEXTURE;
  120.  if(mipmaps) header->dwCaps1 |= (DDSCAPS_COMPLEX | DDSCAPS_MIPMAP);
  121.  header->dwCaps2 = 0;
  122.  if(mipmaps) header->dwCaps2 |= (DDSCAPS2_CUBEMAP | DDS_CUBEMAP_ALLFACES);
  123.  header->dwCaps3 = 0;
  124.  header->dwCaps4 = 0;
  125.  header->dwReserved12 = 0;
  126.  
  127.  return TRUE;
  128. }
  129.  
  130. BOOL CreateDXT2Header(DWORD dx, DWORD dy, DWORD mipmaps, BOOL cubemap, DDS_HEADER* header)
  131. {
  132.  // validate
  133.  if(!header) return FALSE;
  134.  if(dx == 0) return FALSE;
  135.  if(dy == 0) return FALSE;
  136.  
  137.  // set header size
  138.  header->dwSize = 124;
  139.  
  140.  // set flags
  141.  header->dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_LINEARSIZE | DDSD_PIXELFORMAT;
  142.  if(mipmaps) header->dwFlags |= DDSD_MIPMAPCOUNT;
  143.  
  144.  // set dimensions
  145.  header->dwHeight = dy;
  146.  header->dwWidth  = dx;
  147.  header->dwDepth  = 0;
  148.  
  149.  // set linear size
  150.  DWORD blocksize = 16;
  151.  DWORD rows = std::max((DWORD)1, (DWORD)((dy + 3)/4));
  152.  DWORD cols = std::max((DWORD)1, (DWORD)((dx + 3)/4));
  153.  header->dwPitchOrLinearSize = rows*cols*blocksize;
  154.  
  155.  // set mipmap count
  156.  header->dwMipMapCount = mipmaps;
  157.  
  158.  // set reserved data
  159.  header->dwReserved01 = 0;
  160.  header->dwReserved02 = 0;
  161.  header->dwReserved03 = 0;
  162.  header->dwReserved04 = 0;
  163.  header->dwReserved05 = 0;
  164.  header->dwReserved06 = 0;
  165.  header->dwReserved07 = 0;
  166.  header->dwReserved08 = 0;
  167.  header->dwReserved09 = 0;
  168.  header->dwReserved10 = 0;
  169.  header->dwReserved11 = 0;
  170.  
  171.  // set pixel format
  172.  header->ddspf.dwSize = 32;
  173.  header->ddspf.dwFlags = DDPF_FOURCC;
  174.  header->ddspf.dwFourCC = 0x32545844;
  175.  
  176.  // set capabilities
  177.  DWORD DDS_CUBEMAP_ALLFACES = 0xFC00;
  178.  header->dwCaps1 = DDSCAPS_TEXTURE;
  179.  if(mipmaps) header->dwCaps1 |= (DDSCAPS_COMPLEX | DDSCAPS_MIPMAP);
  180.  header->dwCaps2 = 0;
  181.  if(mipmaps) header->dwCaps2 |= (DDSCAPS2_CUBEMAP | DDS_CUBEMAP_ALLFACES);
  182.  header->dwCaps3 = 0;
  183.  header->dwCaps4 = 0;
  184.  header->dwReserved12 = 0;
  185.  
  186.  return TRUE;
  187. }
  188.  
  189. BOOL CreateDXT3Header(DWORD dx, DWORD dy, DWORD mipmaps, BOOL cubemap, DDS_HEADER* header)
  190. {
  191.  // validate
  192.  if(!header) return FALSE;
  193.  if(dx == 0) return FALSE;
  194.  if(dy == 0) return FALSE;
  195.  
  196.  // set header size
  197.  header->dwSize = 124;
  198.  
  199.  // set flags
  200.  header->dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_LINEARSIZE | DDSD_PIXELFORMAT;
  201.  if(mipmaps) header->dwFlags |= DDSD_MIPMAPCOUNT;
  202.  
  203.  // set dimensions
  204.  header->dwHeight = dy;
  205.  header->dwWidth  = dx;
  206.  header->dwDepth  = 0;
  207.  
  208.  // set linear size
  209.  DWORD blocksize = 16;
  210.  DWORD rows = std::max((DWORD)1, (DWORD)((dy + 3)/4));
  211.  DWORD cols = std::max((DWORD)1, (DWORD)((dx + 3)/4));
  212.  header->dwPitchOrLinearSize = rows*cols*blocksize;
  213.  
  214.  // set mipmap count
  215.  header->dwMipMapCount = mipmaps;
  216.  
  217.  // set reserved data
  218.  header->dwReserved01 = 0;
  219.  header->dwReserved02 = 0;
  220.  header->dwReserved03 = 0;
  221.  header->dwReserved04 = 0;
  222.  header->dwReserved05 = 0;
  223.  header->dwReserved06 = 0;
  224.  header->dwReserved07 = 0;
  225.  header->dwReserved08 = 0;
  226.  header->dwReserved09 = 0;
  227.  header->dwReserved10 = 0;
  228.  header->dwReserved11 = 0;
  229.  
  230.  // set pixel format
  231.  header->ddspf.dwSize = 32;
  232.  header->ddspf.dwFlags = DDPF_FOURCC;
  233.  header->ddspf.dwFourCC = 0x33545844;
  234.  
  235.  // set capabilities
  236.  DWORD DDS_CUBEMAP_ALLFACES = 0xFC00;
  237.  header->dwCaps1 = DDSCAPS_TEXTURE;
  238.  if(mipmaps) header->dwCaps1 |= (DDSCAPS_COMPLEX | DDSCAPS_MIPMAP);
  239.  header->dwCaps2 = 0;
  240.  if(mipmaps) header->dwCaps2 |= (DDSCAPS2_CUBEMAP | DDS_CUBEMAP_ALLFACES);
  241.  header->dwCaps3 = 0;
  242.  header->dwCaps4 = 0;
  243.  header->dwReserved12 = 0;
  244.  
  245.  return TRUE;
  246. }
  247.  
  248. BOOL CreateDXT4Header(DWORD dx, DWORD dy, DWORD mipmaps, BOOL cubemap, DDS_HEADER* header)
  249. {
  250.  // validate
  251.  if(!header) return FALSE;
  252.  if(dx == 0) return FALSE;
  253.  if(dy == 0) return FALSE;
  254.  
  255.  // set header size
  256.  header->dwSize = 124;
  257.  
  258.  // set flags
  259.  header->dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_LINEARSIZE | DDSD_PIXELFORMAT;
  260.  if(mipmaps) header->dwFlags |= DDSD_MIPMAPCOUNT;
  261.  
  262.  // set dimensions
  263.  header->dwHeight = dy;
  264.  header->dwWidth  = dx;
  265.  header->dwDepth  = 0;
  266.  
  267.  // set linear size
  268.  DWORD blocksize = 16;
  269.  DWORD rows = std::max((DWORD)1, (DWORD)((dy + 3)/4));
  270.  DWORD cols = std::max((DWORD)1, (DWORD)((dx + 3)/4));
  271.  header->dwPitchOrLinearSize = rows*cols*blocksize;
  272.  
  273.  // set mipmap count
  274.  header->dwMipMapCount = mipmaps;
  275.  
  276.  // set reserved data
  277.  header->dwReserved01 = 0;
  278.  header->dwReserved02 = 0;
  279.  header->dwReserved03 = 0;
  280.  header->dwReserved04 = 0;
  281.  header->dwReserved05 = 0;
  282.  header->dwReserved06 = 0;
  283.  header->dwReserved07 = 0;
  284.  header->dwReserved08 = 0;
  285.  header->dwReserved09 = 0;
  286.  header->dwReserved10 = 0;
  287.  header->dwReserved11 = 0;
  288.  
  289.  // set pixel format
  290.  header->ddspf.dwSize = 32;
  291.  header->ddspf.dwFlags = DDPF_FOURCC;
  292.  header->ddspf.dwFourCC = 0x34545844;
  293.  
  294.  // set capabilities
  295.  DWORD DDS_CUBEMAP_ALLFACES = 0xFC00;
  296.  header->dwCaps1 = DDSCAPS_TEXTURE;
  297.  if(mipmaps) header->dwCaps1 |= (DDSCAPS_COMPLEX | DDSCAPS_MIPMAP);
  298.  header->dwCaps2 = 0;
  299.  if(mipmaps) header->dwCaps2 |= (DDSCAPS2_CUBEMAP | DDS_CUBEMAP_ALLFACES);
  300.  header->dwCaps3 = 0;
  301.  header->dwCaps4 = 0;
  302.  header->dwReserved12 = 0;
  303.  
  304.  return TRUE;
  305. }
  306.  
  307. BOOL CreateDXT5Header(DWORD dx, DWORD dy, DWORD mipmaps, BOOL cubemap, DDS_HEADER* header)
  308. {
  309.  // validate
  310.  if(!header) return FALSE;
  311.  if(dx == 0) return FALSE;
  312.  if(dy == 0) return FALSE;
  313.  
  314.  // set header size
  315.  header->dwSize = 124;
  316.  
  317.  // set flags
  318.  header->dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_LINEARSIZE | DDSD_PIXELFORMAT;
  319.  if(mipmaps) header->dwFlags |= DDSD_MIPMAPCOUNT;
  320.  
  321.  // set dimensions
  322.  header->dwHeight = dy;
  323.  header->dwWidth  = dx;
  324.  header->dwDepth  = 0;
  325.  
  326.  // set linear size
  327.  DWORD blocksize = 16;
  328.  DWORD rows = std::max((DWORD)1, (DWORD)((dy + 3)/4));
  329.  DWORD cols = std::max((DWORD)1, (DWORD)((dx + 3)/4));
  330.  header->dwPitchOrLinearSize = 0;//rows*cols*blocksize;
  331.  
  332.  // set mipmap count
  333.  header->dwMipMapCount = mipmaps;
  334.  
  335.  // set reserved data
  336.  header->dwReserved01 = 0;
  337.  header->dwReserved02 = 0;
  338.  header->dwReserved03 = 0;
  339.  header->dwReserved04 = 0;
  340.  header->dwReserved05 = 0;
  341.  header->dwReserved06 = 0;
  342.  header->dwReserved07 = 0;
  343.  header->dwReserved08 = 0;
  344.  header->dwReserved09 = 0;
  345.  header->dwReserved10 = 0;
  346.  header->dwReserved11 = 0;
  347.  
  348.  // set pixel format
  349.  header->ddspf.dwSize = 32;
  350.  header->ddspf.dwFlags = DDPF_FOURCC;
  351.  header->ddspf.dwFourCC = 0x35545844;
  352.  
  353.  // set capabilities
  354.  DWORD DDS_CUBEMAP_ALLFACES = 0xFC00;
  355.  header->dwCaps1 = DDSCAPS_TEXTURE;
  356.  if(mipmaps) header->dwCaps1 |= (DDSCAPS_COMPLEX | DDSCAPS_MIPMAP);
  357.  header->dwCaps2 = 0;
  358.  if(mipmaps) header->dwCaps2 |= (DDSCAPS2_CUBEMAP | DDS_CUBEMAP_ALLFACES);
  359.  header->dwCaps3 = 0;
  360.  header->dwCaps4 = 0;
  361.  header->dwReserved12 = 0;
  362.  
  363.  return TRUE;
  364. }
  365.  
  366. DWORD UncompressedDDSFileSize(DWORD dx, DWORD dy, DWORD mipmaps, DWORD maskR, DWORD maskG, DWORD maskB, DWORD maskA)
  367. {
  368.  // validate
  369.  if(dx == 0) return 0;
  370.  if(dy == 0) return 0;
  371.  
  372.  // compute filesize
  373.  DWORD bpp = 0;
  374.  if(maskR) bpp += 8;
  375.  if(maskG) bpp += 8;
  376.  if(maskB) bpp += 8;
  377.  if(maskA) bpp += 8;
  378.  
  379.  // TODO: handle mipmaps
  380.  return ((bpp*dx + 7)/8)*dy;
  381. }
  382.  
  383. DWORD DXT1Filesize(DWORD dx, DWORD dy, DWORD mipmaps)
  384. {
  385.  // validate
  386.  if(dx == 0) return 0;
  387.  if(dy == 0) return 0;
  388.  
  389.  // set linear size
  390.  DWORD blocksize = 8;
  391.  DWORD rows = std::max((DWORD)1, (DWORD)((dy + 3)/4));
  392.  DWORD cols = std::max((DWORD)1, (DWORD)((dx + 3)/4));
  393.  
  394.  // TODO: handle mipmaps
  395.  return rows*cols*blocksize;
  396. }
  397.  
  398. DWORD DXT2Filesize(DWORD dx, DWORD dy, DWORD mipmaps)
  399. {
  400.  // validate
  401.  if(dx == 0) return 0;
  402.  if(dy == 0) return 0;
  403.  
  404.  // set linear size
  405.  DWORD blocksize = 16;
  406.  DWORD rows = std::max((DWORD)1, (DWORD)((dy + 3)/4));
  407.  DWORD cols = std::max((DWORD)1, (DWORD)((dx + 3)/4));
  408.  
  409.  // TODO: handle mipmaps
  410.  return rows*cols*blocksize;
  411. }
  412.  
  413. DWORD DXT3Filesize(DWORD dx, DWORD dy, DWORD mipmaps)
  414. {
  415.  // validate
  416.  if(dx == 0) return 0;
  417.  if(dy == 0) return 0;
  418.  
  419.  // set linear size
  420.  DWORD blocksize = 16;
  421.  DWORD rows = std::max((DWORD)1, (DWORD)((dy + 3)/4));
  422.  DWORD cols = std::max((DWORD)1, (DWORD)((dx + 3)/4));
  423.  
  424.  // TODO: handle mipmaps
  425.  return rows*cols*blocksize;
  426. }
  427.  
  428. DWORD DXT4Filesize(DWORD dx, DWORD dy, DWORD mipmaps)
  429. {
  430.  // validate
  431.  if(dx == 0) return 0;
  432.  if(dy == 0) return 0;
  433.  
  434.  // set linear size
  435.  DWORD blocksize = 16;
  436.  DWORD rows = std::max((DWORD)1, (DWORD)((dy + 3)/4));
  437.  DWORD cols = std::max((DWORD)1, (DWORD)((dx + 3)/4));
  438.  
  439.  // TODO: handle mipmaps
  440.  return rows*cols*blocksize;
  441. }
  442.  
  443. DWORD DXT5Filesize(DWORD dx, DWORD dy, DWORD mipmaps)
  444. {
  445.  // validate
  446.  if(dx == 0) return 0;
  447.  if(dy == 0) return 0;
  448.  
  449.  // set linear size
  450.  DWORD blocksize = 16;
  451.  DWORD rows = std::max((DWORD)1, (DWORD)((dy + 3)/4));
  452.  DWORD cols = std::max((DWORD)1, (DWORD)((dx + 3)/4));
  453.  
  454.  // TODO: handle mipmaps
  455.  return rows*cols*blocksize;
  456. }
  457.  
  458. BOOL SaveDDSFile(const char* filename, const DDS_HEADER& ddsh, boost::shared_array<char> data, uint32 size)
  459. {
  460.  // validate
  461.  if(!filename || !strlen(filename)) return FALSE;
  462.  if(!data.get() || !size) return FALSE;
  463.  
  464.  // create file
  465.  using namespace std;
  466.  ofstream ofile(filename, ios::binary);
  467.  if(!ofile) return FALSE;
  468.  
  469.  // save data
  470.  BE_write_uint32(ofile, 0x44445320);
  471.  BE_write_array(ofile, (char*)&ddsh, sizeof(ddsh));
  472.  BE_write_array(ofile, data.get(), (size_t)size);
  473.  
  474.  return TRUE;
  475. }