dds.cpp
上传用户:center1979
上传日期:2022-07-26
资源大小:50633k
文件大小:6k
源码类别:

OpenGL

开发平台:

Visual C++

  1. // dds.cpp
  2. //
  3. // Copyright (C) 2001, Chris Laurel
  4. //
  5. // This program is free software; you can redistribute it and/or
  6. // modify it under the terms of the GNU General Public License
  7. // as published by the Free Software Foundation; either version 2
  8. // of the License, or (at your option) any later version.
  9. #include <iostream>
  10. #include <fstream>
  11. #include <algorithm>
  12. #include <celutil/debug.h>
  13. #include <celutil/bytes.h>
  14. #include <celengine/gl.h>
  15. #include <celengine/glext.h>
  16. #include <celengine/image.h>
  17. using namespace std;
  18. struct DDPixelFormat
  19. {
  20.     uint32 size;
  21.     uint32 flags;
  22.     uint32 fourCC;
  23.     uint32 bpp;
  24.     uint32 redMask;
  25.     uint32 greenMask;
  26.     uint32 blueMask;
  27.     uint32 alphaMask;
  28. };
  29. struct DDSCaps
  30. {
  31.     uint32 caps;
  32.     uint32 caps2;
  33.     uint32 caps3;
  34.     uint32 caps4;
  35. };
  36. struct DDColorKey
  37. {
  38.     uint32 lowVal;
  39.     uint32 highVal;
  40. };
  41. struct DDSurfaceDesc
  42. {
  43.     uint32 size;
  44.     uint32 flags;
  45.     uint32 height;
  46.     uint32 width;
  47.     uint32 pitch;
  48.     uint32 depth;
  49.     uint32 mipMapLevels;
  50.     uint32 alphaBitDepth;
  51.     uint32 reserved;
  52.     uint32 surface;
  53.     DDColorKey ckDestOverlay;
  54.     DDColorKey ckDestBlt;
  55.     DDColorKey ckSrcOverlay;
  56.     DDColorKey ckSrcBlt;
  57.     DDPixelFormat format;
  58.     DDSCaps caps;
  59.     
  60.     uint32 textureStage;
  61. };
  62. static uint32 FourCC(const char* s)
  63. {
  64.     return (((uint32) s[3] << 24) |
  65.             ((uint32) s[2] << 16) |
  66.             ((uint32) s[1] << 8) |
  67.             (uint32) s[0]);
  68. }
  69. #define DDPF_RGB    0x40
  70. #define DDPF_FOURCC 0x04
  71. Image* LoadDDSImage(const string& filename)
  72. {
  73.     ifstream in(filename.c_str(), ios::in | ios::binary);
  74.     if (!in.good())
  75.     {
  76.         DPRINTF(0, "Error opening DDS texture file %s.n", filename.c_str());
  77.         return NULL;
  78.     }
  79.     char header[4];
  80.     in.read(header, sizeof header);
  81.     if (header[0] != 'D' || header[1] != 'D' ||
  82.         header[2] != 'S' || header[3] != ' ')
  83.     {
  84.         DPRINTF(0, "DDS texture file %s has bad header.n", filename.c_str());
  85.         return NULL;
  86.     }
  87.     DDSurfaceDesc ddsd;
  88.     in.read(reinterpret_cast<char*>(&ddsd), sizeof ddsd);
  89.     LE_TO_CPU_INT32(ddsd.size, ddsd.size);
  90.     LE_TO_CPU_INT32(ddsd.pitch, ddsd.pitch);
  91.     LE_TO_CPU_INT32(ddsd.width, ddsd.width);
  92.     LE_TO_CPU_INT32(ddsd.height, ddsd.height);
  93.     LE_TO_CPU_INT32(ddsd.mipMapLevels, ddsd.mipMapLevels);
  94.     LE_TO_CPU_INT32(ddsd.format.flags, ddsd.format.flags);
  95.     LE_TO_CPU_INT32(ddsd.format.redMask, ddsd.format.redMask);
  96.     LE_TO_CPU_INT32(ddsd.format.greenMask, ddsd.format.greenMask);
  97.     LE_TO_CPU_INT32(ddsd.format.blueMask, ddsd.format.blueMask);
  98.     LE_TO_CPU_INT32(ddsd.format.alphaMask, ddsd.format.alphaMask);
  99.     LE_TO_CPU_INT32(ddsd.format.bpp, ddsd.format.bpp);
  100.     LE_TO_CPU_INT32(ddsd.format.fourCC, ddsd.format.fourCC);
  101.     int format = -1;
  102.     if (ddsd.format.fourCC != 0)
  103.     {
  104.         if (ddsd.format.fourCC == FourCC("DXT1"))
  105.         {
  106.             format = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
  107.         }
  108.         else if (ddsd.format.fourCC == FourCC("DXT3"))
  109.         {
  110.             format = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
  111.         }
  112.         else if (ddsd.format.fourCC == FourCC("DXT5"))
  113.         {
  114.             format = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
  115.         }
  116.         else
  117.         {
  118.             cerr << "Unknown FourCC in DDS file: " << ddsd.format.fourCC;
  119.         }
  120.     }
  121.     else
  122.     {
  123.         clog << "DDS Format: " << ddsd.format.fourCC << 'n';
  124.         if (ddsd.format.bpp == 32)
  125.         {
  126.             if (ddsd.format.redMask   == 0x00ff0000 &&
  127.                 ddsd.format.greenMask == 0x0000ff00 &&
  128.                 ddsd.format.blueMask  == 0x000000ff &&
  129.                 ddsd.format.alphaMask == 0xff000000)
  130.             {
  131.                 format = GL_BGRA_EXT;
  132.             }
  133.             else if (ddsd.format.redMask   == 0x000000ff &&
  134.                      ddsd.format.greenMask == 0x0000ff00 &&
  135.                      ddsd.format.blueMask  == 0x00ff0000 &&
  136.                      ddsd.format.alphaMask == 0xff000000)
  137.             {
  138.                 format = GL_RGBA;
  139.             }
  140.         }
  141.         else if (ddsd.format.bpp == 24)
  142.         {
  143.             if (ddsd.format.redMask   == 0x00ff0000 &&
  144.                 ddsd.format.greenMask == 0x0000ff00 &&
  145.                 ddsd.format.blueMask  == 0x000000ff)
  146.             {
  147.                 format = GL_BGR_EXT;
  148.             }
  149.             else if (ddsd.format.redMask   == 0x000000ff &&
  150.                      ddsd.format.greenMask == 0x0000ff00 &&
  151.                      ddsd.format.blueMask  == 0x00ff0000)
  152.             {
  153.                 format = GL_RGB;
  154.             }
  155.         }
  156.     }
  157.     if (format == -1)
  158.     {
  159.         DPRINTF(0, "Unsupported format for DDS texture file %s.n",
  160.                 filename.c_str());
  161.         return NULL;
  162.     }
  163.     // If we have a compressed format, give up if S3 texture compression
  164.     // isn't supported
  165.     if (format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT ||
  166.         format == GL_COMPRESSED_RGBA_S3TC_DXT3_EXT ||
  167.         format == GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)
  168.     {
  169.         if (!ExtensionSupported("GL_EXT_texture_compression_s3tc"))
  170.             return NULL;
  171.     }
  172.     // TODO: Verify that the reported texture size matches the amount of
  173.     // data expected.
  174.     Image* img = new Image(format,
  175.                            (int) ddsd.width,
  176.                            (int) ddsd.height,
  177.                            max(ddsd.mipMapLevels, 1u));
  178.     if (img == NULL)
  179.         return NULL;
  180.     in.read(reinterpret_cast<char*>(img->getPixels()), img->getSize());
  181.     if (!in.eof() && !in.good())
  182.     {
  183.         DPRINTF(0, "Failed reading data from DDS texture file %s.n",
  184.                 filename.c_str());
  185.         delete img;
  186.         return NULL;
  187.     }
  188. #if 0
  189.     cout << "sizeof(ddsd) = " << sizeof(ddsd) << 'n';
  190.     cout << "dimensions: " << ddsd.width << 'x' << ddsd.height << 'n';
  191.     cout << "mipmap levels: " << ddsd.mipMapLevels << 'n';
  192.     cout << "fourCC: " << ddsd.format.fourCC << 'n';
  193.     cout << "bpp: " << ddsd.format.bpp << 'n';
  194. #endif
  195.     return img;
  196. }