#ifndef __NV_DDS_H__
#define __NV_DDS_H__
#ifdef WIN32
# include <windows.h>
#endif
#include <string>
#include <vector>
#include <assert.h>
#if defined(WIN32) || defined(LINUX)
#include <GL/gl.h>
#include <GL/glext.h>
#else
#include <OpenGL/gl.h>
#endif
using namespace std;
namespace nv_dds
{
const unsigned int DDS_FOURCC = 0x00000004;
const unsigned int DDS_RGB = 0x00000040;
const unsigned int DDS_RGBA = 0x00000041;
const unsigned int DDS_DEPTH = 0x00800000;
const unsigned int DDS_COMPLEX = 0x00000008;
const unsigned int DDS_CUBEMAP = 0x00000200;
const unsigned int DDS_VOLUME = 0x00200000;
const unsigned int FOURCC_DXT1 = 0x31545844;
const unsigned int FOURCC_DXT3 = 0x33545844;
const unsigned int FOURCC_DXT5 = 0x35545844;
struct DDS_PIXELFORMAT
{
unsigned int dwSize;
unsigned int dwFlags;
unsigned int dwFourCC;
unsigned int dwRGBBitCount;
unsigned int dwRBitMask;
unsigned int dwGBitMask;
unsigned int dwBBitMask;
unsigned int dwABitMask;
};
struct DXTColBlock
{
unsigned short col0;
unsigned short col1;
unsigned char row[4];
};
struct DXT3AlphaBlock
{
unsigned short row[4];
};
struct DXT5AlphaBlock
{
unsigned char alpha0;
unsigned char alpha1;
unsigned char row[6];
};
struct DDS_HEADER
{
unsigned int dwSize;
unsigned int dwFlags;
unsigned int dwHeight;
unsigned int dwWidth;
unsigned int dwPitchOrLinearSize;
unsigned int dwDepth;
unsigned int dwMipMapCount;
unsigned int dwReserved1[11];
DDS_PIXELFORMAT ddspf;
unsigned int dwCaps1;
unsigned int dwCaps2;
unsigned int dwReserved2[3];
};
class CSurface
{
friend class CTexture;
friend class CDDSImage;
public:
CSurface();
CSurface(int w, int h, int d, int imgsize);
CSurface(const CSurface ©);
CSurface &operator= (const CSurface &rhs);
virtual ~CSurface();
operator char*();
void create(int w, int h, int d, int imgsize);
void clear();
inline int get_width() { return width; }
inline int get_height() { return height; }
inline int get_depth() { return depth; }
inline int get_size() { return size; }
protected:
int width;
int height;
int depth;
int size;
char *pixels;
};
class CTexture : public CSurface
{
friend class CDDSImage;
public:
CTexture();
CTexture(int w, int h, int d, int imgSize);
CTexture(const CTexture ©);
CTexture &operator= (const CTexture &rhs);
~CTexture();
inline CSurface &get_mipmap(int index)
{
assert(index < (int)mipmaps.size());
return mipmaps[index];
}
inline int get_num_mipmaps() { return (int)mipmaps.size(); }
protected:
vector<CSurface> mipmaps;
};
class CDDSImage
{
public:
CDDSImage();
~CDDSImage();
bool load(string filename, bool flipImage = true);
void clear();
operator char*();
CTexture &operator[](int index);
bool upload_texture1D();
bool upload_texture2D(int imageIndex = 0, GLenum target = GL_TEXTURE_2D);
#ifdef GL_NV_texture_rectangle
bool upload_textureRectangle();
#endif
bool upload_texture3D();
bool upload_textureCubemap();
inline int get_width()
{
assert(valid);
assert(images.size() > 0);
return images[0].get_width();
}
inline int get_height()
{
assert(valid);
assert(images.size() > 0);
return images[0].get_height();
}
inline int get_depth()
{
assert(valid);
assert(images.size() > 0);
return images[0].get_depth();
}
inline int get_size()
{
assert(valid);
assert(images.size() > 0);
return images[0].get_size();
}
inline int get_num_mipmaps()
{
assert(valid);
assert(images.size() > 0);
return images[0].get_num_mipmaps();
}
inline CSurface &get_mipmap(int index)
{
assert(valid);
assert(images.size() > 0);
assert(index < images[0].get_num_mipmaps());
return images[0].get_mipmap(index);
}
inline int get_components() { return components; }
inline int get_format() { return format; }
inline bool is_compressed() { return compressed; }
inline bool is_cubemap() { return cubemap; }
inline bool is_volume() { return volume; }
inline bool is_valid() { return valid; }
private:
int clamp_size(int size);
int get_line_width(int width, int bpp);
int size_dxtc(int width, int height);
int size_rgb(int width, int height);
inline void swap_endian(void *val);
void align_memory(CTexture *surface);
void flip(char *image, int width, int height, int depth, int size);
void swap(void *byte1, void *byte2, int size);
void flip_blocks_dxtc1(DXTColBlock *line, int numBlocks);
void flip_blocks_dxtc3(DXTColBlock *line, int numBlocks);
void flip_blocks_dxtc5(DXTColBlock *line, int numBlocks);
void flip_dxt5_alpha(DXT5AlphaBlock *block);
int format;
int components;
bool compressed;
bool cubemap;
bool volume;
bool valid;
vector<CTexture> images;
#if defined(WIN32) || defined(LINUX)
static PFNGLTEXIMAGE3DEXTPROC glTexImage3D;
static PFNGLCOMPRESSEDTEXIMAGE1DARBPROC glCompressedTexImage1DARB;
static PFNGLCOMPRESSEDTEXIMAGE2DARBPROC glCompressedTexImage2DARB;
static PFNGLCOMPRESSEDTEXIMAGE3DARBPROC glCompressedTexImage3DARB;
#endif
};
}
#endif