Commit e2aee66c authored by nadro's avatar nadro

- Removed IImageCompressed and derived.

- Extended IImage class for support compressed textures.
- Improved DDS loader for support mip map loading.
- Added DXT1-5 compressed textures support for OpenGL.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@4449 dfc29bdd-3216-0410-991c-e03cc46cb475
parent 6f278dd4
......@@ -98,6 +98,12 @@ public:
//! fills the surface with given color
virtual void fill(const SColor &color) =0;
//! Inform whether the image is compressed
virtual bool isCompressed() const = 0;
//! Inform wheather the image has mipmaps
virtual bool hasMipMap() const = 0;
//! get the amount of Bits per Pixel of the given color format
static u32 getBitsPerPixelFromFormat(const ECOLOR_FORMAT format)
{
......@@ -111,6 +117,13 @@ public:
return 24;
case ECF_A8R8G8B8:
return 32;
case ECF_DXT1:
return 16;
case ECF_DXT2:
case ECF_DXT3:
case ECF_DXT4:
case ECF_DXT5:
return 32;
case ECF_R16F:
return 16;
case ECF_G16R16F:
......@@ -128,6 +141,22 @@ public:
}
}
//! test if this is compressed color format
static bool isCompressedFormat(const ECOLOR_FORMAT format)
{
switch(format)
{
case ECF_DXT1:
case ECF_DXT2:
case ECF_DXT3:
case ECF_DXT4:
case ECF_DXT5:
return true;
default:
return false;
}
}
//! test if the color format is only viable for RenderTarget textures
/** Since we don't have support for e.g. floating point IImage formats
one should test if the color format can be used for arbitrary usage, or
......@@ -148,56 +177,6 @@ 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,15 +43,6 @@ 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,18 +1218,6 @@ 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.
......
......@@ -6,6 +6,7 @@
#include "irrString.h"
#include "CColorConverter.h"
#include "CBlit.h"
#include "os.h"
namespace irr
{
......@@ -14,7 +15,7 @@ namespace video
//! Constructor of empty image
CImage::CImage(ECOLOR_FORMAT format, const core::dimension2d<u32>& size)
:Data(0), Size(size), Format(format), DeleteMemory(true)
:Data(0), Size(size), Format(format), DeleteMemory(true), Compressed(false)
{
initData();
}
......@@ -22,8 +23,8 @@ CImage::CImage(ECOLOR_FORMAT format, const core::dimension2d<u32>& size)
//! Constructor from raw data
CImage::CImage(ECOLOR_FORMAT format, const core::dimension2d<u32>& size, void* data,
bool ownForeignMemory, bool deleteForeignMemory)
: Data(0), Size(size), Format(format), DeleteMemory(deleteForeignMemory)
bool ownForeignMemory, bool deleteForeignMemory, bool compressed, bool hasMipMapData)
: Data(0), Size(size), Format(format), DeleteMemory(deleteForeignMemory), Compressed(compressed), HasMipMap(hasMipMapData)
{
if (ownForeignMemory)
{
......@@ -181,6 +182,12 @@ u32 CImage::getAlphaMask() const
//! sets a pixel
void CImage::setPixel(u32 x, u32 y, const SColor &color, bool blend)
{
if (Compressed)
{
os::Printer::log("IImage::setPixel method doesn't work with compressed images.", ELL_WARNING);
return;
}
if (x >= Size.Width || y >= Size.Height)
return;
......@@ -222,6 +229,12 @@ void CImage::setPixel(u32 x, u32 y, const SColor &color, bool blend)
//! returns a pixel
SColor CImage::getPixel(u32 x, u32 y) const
{
if (Compressed)
{
os::Printer::log("IImage::getPixel method doesn't work with compressed images.", ELL_WARNING);
return SColor(0);
}
if (x >= Size.Width || y >= Size.Height)
return SColor(0);
......@@ -258,6 +271,12 @@ ECOLOR_FORMAT CImage::getColorFormat() const
//! copies this surface into another at given position
void CImage::copyTo(IImage* target, const core::position2d<s32>& pos)
{
if (Compressed)
{
os::Printer::log("IImage::copyTo method doesn't work with compressed images.", ELL_WARNING);
return;
}
Blit(BLITTER_TEXTURE, target, 0, &pos, this, 0, 0);
}
......@@ -265,6 +284,12 @@ void CImage::copyTo(IImage* target, const core::position2d<s32>& pos)
//! copies this surface partially into another at given position
void CImage::copyTo(IImage* target, const core::position2d<s32>& pos, const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect)
{
if (Compressed)
{
os::Printer::log("IImage::copyTo method doesn't work with compressed images.", ELL_WARNING);
return;
}
Blit(BLITTER_TEXTURE, target, clipRect, &pos, this, &sourceRect, 0);
}
......@@ -272,6 +297,12 @@ void CImage::copyTo(IImage* target, const core::position2d<s32>& pos, const core
//! copies this surface into another, using the alpha mask, a cliprect and a color to add with
void CImage::copyToWithAlpha(IImage* target, const core::position2d<s32>& pos, const core::rect<s32>& sourceRect, const SColor &color, const core::rect<s32>* clipRect)
{
if (Compressed)
{
os::Printer::log("IImage::copyToWithAlpha method doesn't work with compressed images.", ELL_WARNING);
return;
}
// color blend only necessary on not full spectrum aka. color.color != 0xFFFFFFFF
Blit(color.color == 0xFFFFFFFF ? BLITTER_TEXTURE_ALPHA_BLEND: BLITTER_TEXTURE_ALPHA_COLOR_BLEND,
target, clipRect, &pos, this, &sourceRect, color.color);
......@@ -282,6 +313,12 @@ void CImage::copyToWithAlpha(IImage* target, const core::position2d<s32>& pos, c
// note: this is very very slow.
void CImage::copyToScaling(void* target, u32 width, u32 height, ECOLOR_FORMAT format, u32 pitch)
{
if (Compressed)
{
os::Printer::log("IImage::copyToScaling method doesn't work with compressed images.", ELL_WARNING);
return;
}
if (!target || !width || !height)
return;
......@@ -338,6 +375,12 @@ void CImage::copyToScaling(void* target, u32 width, u32 height, ECOLOR_FORMAT fo
// note: this is very very slow.
void CImage::copyToScaling(IImage* target)
{
if (Compressed)
{
os::Printer::log("IImage::copyToScaling method doesn't work with compressed images.", ELL_WARNING);
return;
}
if (!target)
return;
......@@ -357,6 +400,12 @@ void CImage::copyToScaling(IImage* target)
//! copies this surface into another, scaling it to fit it.
void CImage::copyToScalingBoxFilter(IImage* target, s32 bias, bool blend)
{
if (Compressed)
{
os::Printer::log("IImage::copyToScalingBoxFilter method doesn't work with compressed images.", ELL_WARNING);
return;
}
const core::dimension2d<u32> destSize = target->getDimension();
const f32 sourceXStep = (f32) Size.Width / (f32) destSize.Width;
......@@ -389,6 +438,12 @@ void CImage::copyToScalingBoxFilter(IImage* target, s32 bias, bool blend)
//! fills the surface with given color
void CImage::fill(const SColor &color)
{
if (Compressed)
{
os::Printer::log("IImage::fill method doesn't work with compressed images.", ELL_WARNING);
return;
}
u32 c;
switch ( Format )
......@@ -424,9 +479,28 @@ void CImage::fill(const SColor &color)
}
//! Inform whether the image is compressed
bool CImage::isCompressed() const
{
return Compressed;
}
//! Inform wheather the image store mipmaps
bool CImage::hasMipMap() const
{
return HasMipMap;
}
//! get a filtered pixel
inline SColor CImage::getPixelBox( s32 x, s32 y, s32 fx, s32 fy, s32 bias ) const
{
if (Compressed)
{
os::Printer::log("IImage::getPixelBox method doesn't work with compressed images.", ELL_WARNING);
return SColor(0);
}
SColor c;
s32 a = 0, r = 0, g = 0, b = 0;
......@@ -458,111 +532,5 @@ 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
......@@ -24,7 +24,7 @@ public:
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. */
CImage(ECOLOR_FORMAT format, const core::dimension2d<u32>& size,
void* data, bool ownForeignMemory=true, bool deleteMemory = true);
void* data, bool ownForeignMemory=true, bool deleteMemory = true, bool compressed = false, bool hasMipMapData = false);
//! constructor for empty image
CImage(ECOLOR_FORMAT format, const core::dimension2d<u32>& size);
......@@ -103,6 +103,12 @@ public:
//! fills the surface with given color
virtual void fill(const SColor &color);
//! Inform whether the image is compressed
virtual bool isCompressed() const;
//! Inform wheather the image has mipmaps
virtual bool hasMipMap() const;
private:
//! assumes format and size has been set and creates the rest
......@@ -117,59 +123,9 @@ private:
ECOLOR_FORMAT Format;
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;
bool Compressed;
bool HasMipMap;
};
} // end namespace video
......
......@@ -113,6 +113,8 @@ s32 DDSGetInfo(ddsHeader* dds, s32* width, s32* height, eDDSPixelFormat* pf)
}
#ifdef _IRR_COMPILE_WITH_DDS_DECODER_LOADER_
/*
DDSDecompressARGB8888()
decompresses an argb 8888 format texture
......@@ -141,8 +143,6 @@ s32 DDSDecompressARGB8888(ddsHeader* dds, u8* data, s32 width, s32 height, u8* p
}
#ifdef _IRR_COMPILE_WITH_DDS_DECODER_LOADER_
/*!
DDSGetColorBlockColors()
extracts colors from a dds color block
......@@ -692,92 +692,188 @@ IImage* CImageLoaderDDS::loadImage(io::IReadFile* file) const
IImage* image = 0;
s32 width, height;
eDDSPixelFormat pixelFormat;
ECOLOR_FORMAT format = ECF_UNKNOWN;
u32 dataSize = 0;
bool is3D = false;
bool useAlpha = false;
u32 mipMapCount = 0;
file->seek(0);
file->read(&header, sizeof(ddsHeader));
if (0 == DDSGetInfo(&header, &width, &height, &pixelFormat))
{
#ifndef _IRR_COMPILE_WITH_DDS_DECODER_LOADER_
if(pixelFormat == DDS_PF_ARGB8888)
#endif
{
u32 newSize = file->getSize() - sizeof(ddsHeader);
u8* memFile = new u8[newSize];
file->read(memFile, newSize);
is3D = header.Depth > 0 && (header.Flags & DDSD_DEPTH);
image = new CImage(ECF_A8R8G8B8, core::dimension2d<u32>(width, height));
if (!is3D)
header.Depth = 1;
#ifndef _IRR_COMPILE_WITH_DDS_DECODER_LOADER_
DDSDecompressARGB8888(&header, memFile, width, height, (u8*)image->lock());
#else
if (DDSDecompress(&header, memFile, (u8*)image->lock()) == -1)
{
image->unlock();
image->drop();
image = 0;
}
#endif
useAlpha = header.PixelFormat.Flags & DDPF_ALPHAPIXELS;
delete[] memFile;
if (header.MipMapCount > 0 && (header.Flags & DDSD_MIPMAPCOUNT))
mipMapCount = header.MipMapCount;
if (image)
image->unlock();
}
}
#ifdef _IRR_COMPILE_WITH_DDS_DECODER_LOADER_
u32 newSize = file->getSize() - sizeof(ddsHeader);
u8* memFile = new u8[newSize];
file->read(memFile, newSize);
return image;
}
image = new CImage(ECF_A8R8G8B8, core::dimension2d<u32>(width, height));
if (DDSDecompress(&header, memFile, (u8*)image->lock()) == -1)
{
image->unlock();
image->drop();
image = 0;
}
//! creates a compressed surface from the file
IImageCompressed* CImageLoaderDDS::loadImageCompressed(io::IReadFile* file) const
{
#ifndef _IRR_COMPILE_WITH_DDS_DECODER_LOADER_
ddsHeader header;
IImageCompressed* image = 0;
s32 width, height;
eDDSPixelFormat pixelFormat;
delete[] memFile;
#else
if (header.PixelFormat.Flags & DDPF_RGB) // Uncompressed formats
{
u32 byteCount = header.PixelFormat.RGBBitCount / 8;
if( header.Flags & DDSD_PITCH )
dataSize = header.PitchOrLinearSize * header.Height * header.Depth * (header.PixelFormat.RGBBitCount / 8);
else
dataSize = header.Width * header.Height * header.Depth * (header.PixelFormat.RGBBitCount / 8);
file->seek(0);
file->read(&header, sizeof(ddsHeader));
u8* data = new u8[dataSize];
file->read(data, dataSize);
ECOLOR_FORMAT format = ECF_UNKNOWN;
u32 dataSize = 0;
bool is3D = false;
switch (header.PixelFormat.RGBBitCount) // Bytes per pixel
{
case 16:
{
if (useAlpha)
{
if (header.PixelFormat.ABitMask == 0x8000)
format = ECF_A1R5G5B5;
}
else
{
if (header.PixelFormat.RBitMask == 0xf800)
format = ECF_R5G6B5;
}
if (0 == DDSGetInfo(&header, &width, &height, &pixelFormat))
{
is3D = header.Depth > 0 && (header.Flags & DDSD_DEPTH);
break;
}
case 24:
{
if (!useAlpha)
{
if (header.PixelFormat.RBitMask == 0xff0000)
format = ECF_R8G8B8;
}
if (!is3D)
header.Depth = 1;
break;
}
case 32:
{
if (useAlpha)
{
if (header.PixelFormat.RBitMask & 0xff0000)
format = ECF_A8R8G8B8;
else if (header.PixelFormat.RBitMask & 0xff)
{
// convert from A8B8G8R8 to A8R8G8B8
u8 tmp = 0;
for (u32 i = 0; i < dataSize; i += 4)
{
tmp = data[i];
data[i] = data[i+2];
data[i+2] = tmp;
}
}
}
break;
}
}
if (header.PixelFormat.Flags & DDPF_FOURCC) // Compressed formats
if (format != ECF_UNKNOWN)
{
if (!is3D) // Currently 3D textures are unsupported.
{
image = new CImage(format, core::dimension2d<u32>(header.Width, header.Height ), data, true, true, false);
}
}
else
{
delete[] data;
}
}
else if (header.PixelFormat.Flags & DDPF_FOURCC) // Compressed formats
{
switch(pixelFormat)
{
case DDS_PF_DXT1:
{
dataSize = (header.Width / 4 ) * (header.Height / 4) * 8;
u32 curWidth = header.Width;
u32 curHeight = header.Height;
dataSize = ((curWidth + 3) / 4) * ((curHeight + 3) / 4) * 8;
do
{
if (curWidth > 1)
curWidth >>= 1;
if (curHeight > 1)
curHeight >>= 1;
dataSize += ((curWidth + 3) / 4) * ((curHeight + 3) / 4) * 8;
}
while (curWidth != 1 || curWidth != 1);
format = ECF_DXT1;
os::Printer::log("Detected ECF_DXT1 format", ELL_DEBUG);
break;
}
case DDS_PF_DXT2:
case DDS_PF_DXT3:
{
dataSize = (header.Width / 4 ) * (header.Height / 4) * 16;
u32 curWidth = header.Width;
u32 curHeight = header.Height;
dataSize = ((curWidth + 3) / 4) * ((curHeight + 3) / 4) * 16;
do
{
if (curWidth > 1)
curWidth >>= 1;
if (curHeight > 1)
curHeight >>= 1;
dataSize += ((curWidth + 3) / 4) * ((curHeight + 3) / 4) * 16;
}
while (curWidth != 1 || curWidth != 1);
format = ECF_DXT3;
os::Printer::log("Detected ECF_DXT3 format", ELL_DEBUG);
break;
}
case DDS_PF_DXT4:
case DDS_PF_DXT5:
{
dataSize = (header.Width / 4 ) * (header.Height / 4) * 16;
u32 curWidth = header.Width;
u32 curHeight = header.Height;
dataSize = ((curWidth + 3) / 4) * ((curHeight + 3) / 4) * 16;
do
{
if (curWidth > 1)
curWidth >>= 1;
if (curHeight > 1)
curHeight >>= 1;
dataSize += ((curWidth + 3) / 4) * ((curHeight + 3) / 4) * 16;
}
while (curWidth != 1 || curWidth != 1);
format = ECF_DXT5;
os::Printer::log("Detected ECF_DXT5 format", ELL_DEBUG);
break;
}
}
......@@ -789,16 +885,16 @@ IImageCompressed* CImageLoaderDDS::loadImageCompressed(io::IReadFile* file) cons
u8* data = new u8[dataSize];
file->read(data, dataSize);
image = new CImageCompressed(format, core::dimension2d<u32>(header.Width, header.Height ), data);
bool hasMipMap = (mipMapCount > 0) ? true : false;
image = new CImage(format, core::dimension2d<u32>(header.Width, header.Height), data, true, true, true, hasMipMap);
}
}
}
#endif
}
return image;
#else
return 0;
#endif
}
......
......@@ -204,9 +204,6 @@ 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;
};
......
......@@ -1402,77 +1402,6 @@ 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,17 +352,6 @@ 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);
......
......@@ -50,7 +50,7 @@ COpenGLExtensionHandler::COpenGLExtensionHandler() :
pGlPointParameterfARB(0), pGlPointParameterfvARB(0),
pGlStencilFuncSeparate(0), pGlStencilOpSeparate(0),
pGlStencilFuncSeparateATI(0), pGlStencilOpSeparateATI(0),
pGlCompressedTexImage2D(0),
pGlCompressedTexImage2D(0), pGlCompressedTexSubImage2D(0),
// ARB framebuffer object
pGlBindFramebuffer(0), pGlDeleteFramebuffers(0), pGlGenFramebuffers(0),
pGlCheckFramebufferStatus(0), pGlFramebufferTexture2D(0),
......@@ -473,6 +473,7 @@ void COpenGLExtensionHandler::initExtensions(bool stencilBuffer)
// compressed textures
pGlCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC) IRR_OGL_LOAD_EXTENSION("glCompressedTexImage2D");
pGlCompressedTexSubImage2D = (PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) IRR_OGL_LOAD_EXTENSION("glCompressedTexSubImage2D");
// ARB FrameBufferObjects
pGlBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC) IRR_OGL_LOAD_EXTENSION("glBindFramebuffer");
......
......@@ -992,6 +992,9 @@ class COpenGLExtensionHandler
void extGlCompressedTexImage2D(GLenum target, GLint level,
GLenum internalformat, GLsizei width, GLsizei height,
GLint border, GLsizei imageSize, const void* data);
void extGlCompressedTexSubImage2D(GLenum target, GLint level,
GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
GLenum format, GLsizei imageSize, const void* data);
// shader programming
void extGlGenPrograms(GLsizei n, GLuint *programs);
......@@ -1168,6 +1171,7 @@ class COpenGLExtensionHandler
PFNGLSTENCILFUNCSEPARATEATIPROC pGlStencilFuncSeparateATI;
PFNGLSTENCILOPSEPARATEATIPROC pGlStencilOpSeparateATI;
PFNGLCOMPRESSEDTEXIMAGE2DPROC pGlCompressedTexImage2D;
PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC pGlCompressedTexSubImage2D;
// ARB framebuffer object
PFNGLBINDFRAMEBUFFERPROC pGlBindFramebuffer;
PFNGLDELETEFRAMEBUFFERSPROC pGlDeleteFramebuffers;
......@@ -1934,6 +1938,19 @@ inline void COpenGLExtensionHandler::extGlCompressedTexImage2D (GLenum target, G
#endif
}
inline void COpenGLExtensionHandler::extGlCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data)
{
#ifdef _IRR_OPENGL_USE_EXTPOINTER_
if (pGlCompressedTexSubImage2D)
pGlCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, data);
#elif defined(GL_ARB_texture_compression)
glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, data);
#else
os::Printer::log("glCompressedTexSubImage2D not supported", ELL_ERROR);
#endif
}
inline void COpenGLExtensionHandler::extGlBindFramebuffer(GLenum target, GLuint framebuffer)
{
#ifdef _IRR_OPENGL_USE_EXTPOINTER_
......
This diff is collapsed.
......@@ -169,6 +169,8 @@ protected:
bool ReadOnlyLock;
bool KeepImage;
bool Compressed;
mutable SStatesCache StatesCache;
};
......
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