Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

dds.cpp File Reference

#include <iostream>
#include <fstream>
#include <algorithm>
#include <celutil/debug.h>
#include <celutil/bytes.h>
#include <celengine/gl.h>
#include <celengine/glext.h>
#include <celengine/image.h>

Include dependency graph for dds.cpp:

Go to the source code of this file.

Defines

#define DDPF_FOURCC   0x04
#define DDPF_RGB   0x40

Functions

static uint32 FourCC (const char *s)
ImageLoadDDSImage (const string &filename)


Define Documentation

#define DDPF_FOURCC   0x04
 

Definition at line 84 of file dds.cpp.

#define DDPF_RGB   0x40
 

Definition at line 83 of file dds.cpp.


Function Documentation

static uint32 FourCC const char *  s  )  [static]
 

Definition at line 74 of file dds.cpp.

Referenced by LoadDDSImage().

00075 {
00076     return (((uint32) s[3] << 24) |
00077             ((uint32) s[2] << 16) |
00078             ((uint32) s[1] << 8) |
00079             (uint32) s[0]);
00080 }

Image* LoadDDSImage const string filename  ) 
 

Definition at line 87 of file dds.cpp.

References DPRINTF, ExtensionSupported(), Image::format, FourCC(), Image::getPixels(), Image::getSize(), GL_BGR_EXT, GL_BGRA_EXT, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, Image::height, LE_TO_CPU_INT32, max, and Image::width.

Referenced by LoadImageFromFile().

00088 {
00089     ifstream in(filename.c_str(), ios::in | ios::binary);
00090     if (!in.good())
00091     {
00092         DPRINTF(0, "Error opening DDS texture file %s.\n", filename.c_str());
00093         return NULL;
00094     }
00095 
00096     char header[4];
00097     in.read(header, sizeof header);
00098     if (header[0] != 'D' || header[1] != 'D' ||
00099         header[2] != 'S' || header[3] != ' ')
00100     {
00101         DPRINTF(0, "DDS texture file %s has bad header.\n", filename.c_str());
00102         return NULL;
00103     }
00104 
00105     DDSurfaceDesc ddsd;
00106     in.read(reinterpret_cast<char*>(&ddsd), sizeof ddsd);
00107     LE_TO_CPU_INT32(ddsd.size, ddsd.size);
00108     LE_TO_CPU_INT32(ddsd.pitch, ddsd.pitch);
00109     LE_TO_CPU_INT32(ddsd.width, ddsd.width);
00110     LE_TO_CPU_INT32(ddsd.height, ddsd.height);
00111     LE_TO_CPU_INT32(ddsd.mipMapLevels, ddsd.mipMapLevels);
00112     LE_TO_CPU_INT32(ddsd.format.flags, ddsd.format.flags);
00113     LE_TO_CPU_INT32(ddsd.format.redMask, ddsd.format.redMask);
00114     LE_TO_CPU_INT32(ddsd.format.greenMask, ddsd.format.greenMask);
00115     LE_TO_CPU_INT32(ddsd.format.blueMask, ddsd.format.blueMask);
00116     LE_TO_CPU_INT32(ddsd.format.alphaMask, ddsd.format.alphaMask);
00117     LE_TO_CPU_INT32(ddsd.format.bpp, ddsd.format.bpp);
00118     LE_TO_CPU_INT32(ddsd.format.fourCC, ddsd.format.fourCC);
00119 
00120     int format = -1;
00121 
00122     if (ddsd.format.fourCC != 0)
00123     {
00124         if (ddsd.format.fourCC == FourCC("DXT1"))
00125         {
00126             format = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
00127         }
00128         else if (ddsd.format.fourCC == FourCC("DXT3"))
00129         {
00130             format = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
00131         }
00132         else if (ddsd.format.fourCC == FourCC("DXT5"))
00133         {
00134             format = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
00135         }
00136         else
00137         {
00138             cerr << "Unknown FourCC in DDS file: " << ddsd.format.fourCC;
00139         }
00140     }
00141     else
00142     {
00143         clog << "DDS Format: " << ddsd.format.fourCC << '\n';
00144         if (ddsd.format.bpp == 32)
00145         {
00146             if (ddsd.format.redMask   == 0x00ff0000 &&
00147                 ddsd.format.greenMask == 0x0000ff00 &&
00148                 ddsd.format.blueMask  == 0x000000ff &&
00149                 ddsd.format.alphaMask == 0xff000000)
00150             {
00151                 format = GL_BGRA_EXT;
00152             }
00153             else if (ddsd.format.redMask   == 0x000000ff &&
00154                      ddsd.format.greenMask == 0x0000ff00 &&
00155                      ddsd.format.blueMask  == 0x00ff0000 &&
00156                      ddsd.format.alphaMask == 0xff000000)
00157             {
00158                 format = GL_RGBA;
00159             }
00160         }
00161         else if (ddsd.format.bpp == 24)
00162         {
00163             if (ddsd.format.redMask   == 0x00ff0000 &&
00164                 ddsd.format.greenMask == 0x0000ff00 &&
00165                 ddsd.format.blueMask  == 0x000000ff)
00166             {
00167                 format = GL_BGR_EXT;
00168             }
00169             else if (ddsd.format.redMask   == 0x000000ff &&
00170                      ddsd.format.greenMask == 0x0000ff00 &&
00171                      ddsd.format.blueMask  == 0x00ff0000)
00172             {
00173                 format = GL_RGB;
00174             }
00175         }
00176     }
00177 
00178     if (format == -1)
00179     {
00180         DPRINTF(0, "Unsupported format for DDS texture file %s.\n",
00181                 filename.c_str());
00182         return NULL;
00183     }
00184 
00185     // If we have a compressed format, give up if S3 texture compression
00186     // isn't supported
00187     if (format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT ||
00188         format == GL_COMPRESSED_RGBA_S3TC_DXT3_EXT ||
00189         format == GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)
00190     {
00191         if (!ExtensionSupported("GL_EXT_texture_compression_s3tc"))
00192             return NULL;
00193     }
00194 
00195     // TODO: Verify that the reported texture size matches the amount of
00196     // data expected.
00197 
00198     Image* img = new Image(format,
00199                            (int) ddsd.width,
00200                            (int) ddsd.height,
00201                            max(ddsd.mipMapLevels, 1u));
00202     if (img == NULL)
00203         return NULL;
00204 
00205     in.read(reinterpret_cast<char*>(img->getPixels()), img->getSize());
00206     if (!in.eof() && !in.good())
00207     {
00208         DPRINTF(0, "Failed reading data from DDS texture file %s.\n",
00209                 filename.c_str());
00210         delete img;
00211         return NULL;
00212     }
00213 
00214 #if 0
00215     cout << "sizeof(ddsd) = " << sizeof(ddsd) << '\n';
00216     cout << "dimensions: " << ddsd.width << 'x' << ddsd.height << '\n';
00217     cout << "mipmap levels: " << ddsd.mipMapLevels << '\n';
00218     cout << "fourCC: " << ddsd.format.fourCC << '\n';
00219     cout << "bpp: " << ddsd.format.bpp << '\n';
00220 #endif
00221 
00222     return img;
00223 }


Generated on Sat Jan 14 22:30:44 2006 for Celestia by  doxygen 1.4.1