Commit 6f278dd4 authored by nadro's avatar nadro

- Added partially (IImageCompressed part) support for compressed textures....

- Added partially (IImageCompressed part) support for compressed textures. Currently only DDS format is supported.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@4448 dfc29bdd-3216-0410-991c-e03cc46cb475
parent 4250b6f7
......@@ -148,6 +148,56 @@ public:
};
//! Interface for software compressed image data.
/** Image loaders create these images from files. IVideoDrivers convert
these images into their (hardware) textures.
*/
class IImageCompressed : public virtual IReferenceCounted
{
public:
//! Use this to get a pointer to the image data.
virtual const void* getData() const = 0;
//! Returns width and height of image data.
virtual const core::dimension2d<u32>& getDimension() const = 0;
//! Returns bits per pixel.
virtual u32 getBitsPerPixel() const = 0;
//! Returns bytes per pixel
virtual u32 getBytesPerPixel() const = 0;
//! Returns image data size in bytes
virtual u32 getImageDataSizeInBytes() const = 0;
//! Returns image data size in pixels
virtual u32 getImageDataSizeInPixels() const = 0;
//! Returns the color format
virtual ECOLOR_FORMAT getColorFormat() const = 0;
//! Returns pitch of image
virtual u32 getPitch() const = 0;
//! get the amount of Bits per Pixel of the given color format
static u32 getBitsPerPixelFromFormat(const ECOLOR_FORMAT format)
{
switch(format)
{
case ECF_DXT1:
return 16;
case ECF_DXT2:
case ECF_DXT3:
case ECF_DXT4:
case ECF_DXT5:
return 32;
default:
return 0;
}
}
};
} // end namespace video
} // end namespace irr
......
......@@ -43,6 +43,15 @@ public:
/** \param file File handle to check.
\return Pointer to newly created image, or 0 upon error. */
virtual IImage* loadImage(io::IReadFile* file) const = 0;
//! Creates a compressed surface from the file
/** \param file File handle to check.
\return Pointer to newly created image, or 0 upon error. */
virtual IImageCompressed* loadImageCompressed(io::IReadFile* file) const
{
// The most of supported file formats are uncompressed, so we define it here.
return 0;
}
};
......
......@@ -1218,6 +1218,18 @@ namespace video
bool ownForeignMemory=false,
bool deleteMemory = true) =0;
//! Creates a compressed software image from a file.
virtual IImageCompressed* createImageCompressedFromFile(const io::path& filename) = 0;
//! Creates a compressed software image from a file.
virtual IImageCompressed* createImageCompressedFromFile(io::IReadFile* file) = 0;
//! Creates a software compressed image from a byte array.
virtual IImageCompressed* createImageCompressedFromData(ECOLOR_FORMAT format,
const core::dimension2d<u32>& size, void *data,
bool ownForeignMemory=false,
bool deleteMemory = true) = 0;
//! Creates an empty software image.
/**
\param format Desired color format of the image.
......
......@@ -532,14 +532,24 @@ B3D, MS3D or X meshes */
#ifdef NO_IRR_COMPILE_WITH_PSD_LOADER_
#undef _IRR_COMPILE_WITH_PSD_LOADER_
#endif
//! Define _IRR_COMPILE_WITH_DDS_LOADER_ if you want to load .dds files
//! Define _IRR_COMPILE_WITH_DDS_LOADER_ if you want to load compressed .dds files
// Patent problem isn't related to this loader.
#define _IRR_COMPILE_WITH_DDS_LOADER_
#ifdef NO_IRR_COMPILE_WITH_DDS_LOADER_
#undef _IRR_COMPILE_WITH_DDS_LOADER_
#endif
//! Define _IRR_COMPILE_WITH_DDS_DECODER_LOADER_ if you want to load .dds files
//! loader will decompress these files and will send to the memory as uncompressed files.
// Outcommented because
// a) it doesn't compile on 64-bit currently
// b) anyone enabling it should be aware that S3TC compression algorithm which might be used in that loader
// is patented in the US by S3 and they do collect license fees when it's used in applications.
// So if you are unfortunate enough to develop applications for US market and their broken patent system be careful.
// #define _IRR_COMPILE_WITH_DDS_LOADER_
#ifdef NO_IRR_COMPILE_WITH_DDS_LOADER_
// #define _IRR_COMPILE_WITH_DDS_DECODER_LOADER_
#ifdef NO_IRR_COMPILE_WITH_DDS_DECODER_LOADER_
#undef _IRR_COMPILE_WITH_DDS_DECODER_LOADER_
#endif
#ifdef _IRR_COMPILE_WITH_DDS_DECODER_LOADER_
#undef _IRR_COMPILE_WITH_DDS_LOADER_
#endif
//! Define _IRR_COMPILE_WITH_TGA_LOADER_ if you want to load .tga files
......
......@@ -31,6 +31,23 @@ namespace video
//! Default 32 bit color format. 8 bits are used for every component: red, green, blue and alpha.
ECF_A8R8G8B8,
/** Compressed image formats. **/
//! DXT1 color format.
ECF_DXT1,
//! DXT2 color format.
ECF_DXT2,
//! DXT3 color format.
ECF_DXT3,
//! DXT4 color format.
ECF_DXT4,
//! DXT5 color format.
ECF_DXT5,
/** Floating Point formats. The following formats may only be used for render target textures. */
//! 16 bit floating point format using 16 bits for the red channel.
......
......@@ -458,5 +458,111 @@ inline SColor CImage::getPixelBox( s32 x, s32 y, s32 fx, s32 fy, s32 bias ) cons
}
/** Compressed image **/
//! Constructor
CImageCompressed::CImageCompressed(ECOLOR_FORMAT format, const core::dimension2d<u32>& size, void* data,
bool ownForeignMemory, bool deleteForeignMemory)
: Data(0), Size(size), Format(format), DeleteMemory(deleteForeignMemory)
{
if (ownForeignMemory)
{
Data = (u8*)0xbadf00d;
initData();
Data = (u8*)data;
}
else
{
Data = 0;
initData();
memcpy(Data, data, Size.Height * Pitch);
}
}
//! Destructor
CImageCompressed::~CImageCompressed()
{
if (DeleteMemory)
delete [] Data;
}
//! assumes format and size has been set and creates the rest
void CImageCompressed::initData()
{
#ifdef _DEBUG
setDebugName("CImageCompressed");
#endif
BytesPerPixel = getBitsPerPixelFromFormat(Format) / 8;
// Pitch should be aligned...
Pitch = BytesPerPixel * Size.Width;
if (!Data)
{
DeleteMemory=true;
Data = new u8[Size.Height * Pitch];
}
}
//! Use this to get a pointer to the image data.
const void* CImageCompressed::getData() const
{
return Data;
}
//! Returns width and height of image data.
const core::dimension2d<u32>& CImageCompressed::getDimension() const
{
return Size;
}
//! Returns bits per pixel.
u32 CImageCompressed::getBitsPerPixel() const
{
return getBitsPerPixelFromFormat(Format);
}
//! Returns bytes per pixel
u32 CImageCompressed::getBytesPerPixel() const
{
return BytesPerPixel;
}
//! Returns image data size in bytes
u32 CImageCompressed::getImageDataSizeInBytes() const
{
return Pitch * Size.Height;
}
//! Returns image data size in pixels
u32 CImageCompressed::getImageDataSizeInPixels() const
{
return Size.Width * Size.Height;
}
//! returns the color format
ECOLOR_FORMAT CImageCompressed::getColorFormat() const
{
return Format;
}
//! returns pitch of image
u32 CImageCompressed::getPitch() const
{
return Pitch;
}
} // end namespace video
} // end namespace irr
......@@ -119,6 +119,59 @@ private:
bool DeleteMemory;
};
//! Internal interface for software compressed image data.
class CImageCompressed : public IImageCompressed
{
public:
//! Constructor
/** \param useForeignMemory: If true, the image will use the data pointer
directly and own it from now on, which means it will also try to delete [] the
data when the image will be destructed. If false, the memory will by copied. */
CImageCompressed(ECOLOR_FORMAT format, const core::dimension2d<u32>& size,
void* data, bool ownForeignMemory=true, bool deleteMemory = true);
//! Destructor
virtual ~CImageCompressed();
//! Use this to get a pointer to the image data.
virtual const void* getData() const;
//! Returns width and height of image data.
virtual const core::dimension2d<u32>& getDimension() const;
//! Returns bits per pixel.
virtual u32 getBitsPerPixel() const;
//! Returns bytes per pixel
virtual u32 getBytesPerPixel() const;
//! Returns image data size in bytes
virtual u32 getImageDataSizeInBytes() const;
//! Returns image data size in pixels
virtual u32 getImageDataSizeInPixels() const;
//! returns the color format
virtual ECOLOR_FORMAT getColorFormat() const;
//! returns pitch of image
virtual u32 getPitch() const;
private:
//! assumes format and size has been set and creates the rest
void initData();
u8* Data;
core::dimension2d<u32> Size;
u32 BytesPerPixel;
u32 Pitch;
ECOLOR_FORMAT Format;
bool DeleteMemory;
};
} // end namespace video
} // end namespace irr
......
This diff is collapsed.
......@@ -7,7 +7,7 @@
#include "IrrCompileConfig.h"
#if defined(_IRR_COMPILE_WITH_DDS_LOADER_)
#if defined(_IRR_COMPILE_WITH_DDS_LOADER_) || defined(_IRR_COMPILE_WITH_DDS_DECODER_LOADER_)
#include "IImageLoader.h"
......@@ -16,8 +16,7 @@ namespace irr
namespace video
{
/* dependencies */
/* dds definition */
/* dds pixel format types */
enum eDDSPixelFormat
{
DDS_PF_ARGB8888,
......@@ -29,24 +28,24 @@ enum eDDSPixelFormat
DDS_PF_UNKNOWN
};
/* 16bpp stuff */
#define DDS_LOW_5 0x001F;
#define DDS_MID_6 0x07E0;
#define DDS_HIGH_5 0xF800;
#define DDS_MID_555 0x03E0;
#define DDS_HI_555 0x7C00;
// byte-align structures
#include "irrpack.h"
/* structures */
struct ddsColorKey
struct ddsPixelFormat
{
u32 colorSpaceLowValue;
u32 colorSpaceHighValue;
u32 Size;
u32 Flags;
u32 FourCC;
u32 RGBBitCount;
u32 RBitMask;
u32 GBitMask;
u32 BBitMask;
u32 ABitMask;
} PACK_STRUCT;
struct ddsCaps
{
u32 caps1;
......@@ -55,108 +54,25 @@ struct ddsCaps
u32 caps4;
} PACK_STRUCT;
struct ddsMultiSampleCaps
{
u16 flipMSTypes;
u16 bltMSTypes;
} PACK_STRUCT;
struct ddsPixelFormat
struct ddsHeader
{
u32 size;
u32 flags;
u32 fourCC;
union
{
u32 rgbBitCount;
u32 yuvBitCount;
u32 zBufferBitDepth;
u32 alphaBitDepth;
u32 luminanceBitCount;
u32 bumpBitCount;
u32 privateFormatBitCount;
};
union
{
u32 rBitMask;
u32 yBitMask;
u32 stencilBitDepth;
u32 luminanceBitMask;
u32 bumpDuBitMask;
u32 operations;
};
union
{
u32 gBitMask;
u32 uBitMask;
u32 zBitMask;
u32 bumpDvBitMask;
ddsMultiSampleCaps multiSampleCaps;
};
union
{
u32 bBitMask;
u32 vBitMask;
u32 stencilBitMask;
u32 bumpLuminanceBitMask;
};
union
{
u32 rgbAlphaBitMask;
u32 yuvAlphaBitMask;
u32 luminanceAlphaBitMask;
u32 rgbZBitMask;
u32 yuvZBitMask;
};
c8 Magic[4];
u32 Size;
u32 Flags;
u32 Height;
u32 Width;
u32 PitchOrLinearSize;
u32 Depth;
u32 MipMapCount;
u32 Reserved1[11];
ddsPixelFormat PixelFormat;
ddsCaps Caps;
u32 Reserved2;
} PACK_STRUCT;
struct ddsBuffer
{
/* magic: 'dds ' */
c8 magic[ 4 ];
/* directdraw surface */
u32 size;
u32 flags;
u32 height;
u32 width;
union
{
s32 pitch;
u32 linearSize;
};
u32 backBufferCount;
union
{
u32 mipMapCount;
u32 refreshRate;
u32 srcVBHandle;
};
u32 alphaBitDepth;
u32 reserved;
void *surface;
union
{
ddsColorKey ckDestOverlay;
u32 emptyFaceColor;
};
ddsColorKey ckDestBlt;
ddsColorKey ckSrcOverlay;
ddsColorKey ckSrcBlt;
union
{
ddsPixelFormat pixelFormat;
u32 fvf;
};
ddsCaps caps;
u32 textureStage;
/* data (Varying size) */
u8 data[ 4 ];
} PACK_STRUCT;
#ifdef _IRR_COMPILE_WITH_DDS_DECODER_LOADER_
struct ddsColorBlock
{
......@@ -184,6 +100,9 @@ struct ddsColor
u8 r, g, b, a;
} PACK_STRUCT;
#endif
// Default alignment
#include "irrunpack.h"
......@@ -285,6 +204,9 @@ public:
//! creates a surface from the file
virtual IImage* loadImage(io::IReadFile* file) const;
//! creates a compressed surface from the file
virtual IImageCompressed* loadImageCompressed(io::IReadFile* file) const;
};
......
......@@ -139,7 +139,7 @@ CNullDriver::CNullDriver(io::IFileSystem* io, const core::dimension2d<u32>& scre
#ifdef _IRR_COMPILE_WITH_PSD_LOADER_
SurfaceLoader.push_back(video::createImageLoaderPSD());
#endif
#ifdef _IRR_COMPILE_WITH_DDS_LOADER_
#if defined(_IRR_COMPILE_WITH_DDS_LOADER_) || defined(_IRR_COMPILE_WITH_DDS_DECODER_LOADER_)
SurfaceLoader.push_back(video::createImageLoaderDDS());
#endif
#ifdef _IRR_COMPILE_WITH_PCX_LOADER_
......@@ -1402,6 +1402,77 @@ IImage* CNullDriver::createImageFromData(ECOLOR_FORMAT format,
}
//! Creates a compressed software image from a file.
IImageCompressed* CNullDriver::createImageCompressedFromFile(const io::path& filename)
{
if (!filename.size())
return 0;
IImageCompressed* image = 0;
io::IReadFile* file = FileSystem->createAndOpenFile(filename);
if (file)
{
image = createImageCompressedFromFile(file);
file->drop();
}
else
os::Printer::log("Could not open file of image", filename, ELL_WARNING);
return image;
}
//! Creates a compressed software image from a file.
IImageCompressed* CNullDriver::createImageCompressedFromFile(io::IReadFile* file)
{
if (!file)
return 0;
IImageCompressed* image = 0;
s32 i;
// try to load file based on file extension
for (i=SurfaceLoader.size()-1; i>=0; --i)
{
if (SurfaceLoader[i]->isALoadableFileExtension(file->getFileName()))
{
// reset file position which might have changed due to previous loadImage calls
file->seek(0);
image = SurfaceLoader[i]->loadImageCompressed(file);
if (image)
return image;
}
}
// try to load file based on what is in it
for (i=SurfaceLoader.size()-1; i>=0; --i)
{
// dito
file->seek(0);
if (SurfaceLoader[i]->isALoadableFileFormat(file))
{
file->seek(0);
image = SurfaceLoader[i]->loadImageCompressed(file);
if (image)
return image;
}
}
return 0; // failed to load
}
//! Creates a software compressed image from a byte array.
IImageCompressed* CNullDriver::createImageCompressedFromData(ECOLOR_FORMAT format,
const core::dimension2d<u32>& size, void *data,
bool ownForeignMemory, bool deleteMemory)
{
return new CImageCompressed(format, size, data, ownForeignMemory, deleteMemory);
}
//! Creates an empty software image.
IImage* CNullDriver::createImage(ECOLOR_FORMAT format, const core::dimension2d<u32>& size)
{
......
......@@ -352,6 +352,17 @@ namespace video
const core::dimension2d<u32>& size, void *data,
bool ownForeignMemory=true, bool deleteForeignMemory = true);
//! Creates a compressed software image from a file.
virtual IImageCompressed* createImageCompressedFromFile(const io::path& filename);
//! Creates a compressed software image from a file.
virtual IImageCompressed* createImageCompressedFromFile(io::IReadFile* file);
//! Creates a software compressed image from a byte array.
virtual IImageCompressed* createImageCompressedFromData(ECOLOR_FORMAT format,
const core::dimension2d<u32>& size, void *data,
bool ownForeignMemory=false, bool deleteMemory = true);
//! Creates an empty software image.
virtual IImage* createImage(ECOLOR_FORMAT format, const core::dimension2d<u32>& size);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment