DDS Support
Posted: Fri Nov 11, 2005 4:37 pm
Will it be possible to see support for DDS textures in future releases ? DDS is way superior to, for example, TGAs so I think it will be wise to have support for them.
Official forum of the Irrlicht Engine
https://irrlicht.sourceforge.io/forum/
Code: Select all
glCompressedTexImage2DARB( GL_TEXTURE_2D,
i,
pDDSImageData->format,
nWidth,
nHeight,
0,
nSize,
pDDSImageData->pixels + nOffset );
Code: Select all
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, nWidth, nHeight, GL_RGB, pDDSImageData->format, pDDSImageData->pixels);
Code: Select all
//! copies DXT1 data to 32 bit A8R8G8B8 data
void CColorConverter::convertDXT1toA8R8G8B8(const u8* src, u32* dest, const s32& width, const s32& height )
{
u32 srcIndex = 0;
u32 destIndex = 0;
u32 colors[4] = { 0,0,0,0 };
// copy dxt1 to destination image
for( s32 y=0; y<height; y += 4 )
{
for( s32 x=0; x<width; x += 4 )
{
// call get color lookups function
getCompressedLookupColors( &src[ srcIndex ], colors );
srcIndex += 4;
// Now that we have our lookup colors, read in the 4x4 color index table
u32 colorTable = 0;
memcpy( &colorTable, &src[ srcIndex ], 4 );
srcIndex += 4;
u8 tmpIndex = 0;
for( u8 xx=0; xx<4; xx++ )
{
for( u8 yy=0; yy<4; yy++ )
{
tmpIndex = ( colorTable >> ( ( xx + yy * 4 ) * 2 ) ) & 3;
memcpy( &dest[ x + xx + ( y + yy ) * height ], &colors[ tmpIndex ], 4 );
destIndex++;
}
}
}
}
}
//! copies DXT2/3 data to 32 bit A8R8G8B8 data
void CColorConverter::convertDXT3toA8R8G8B8(const u8* src, u32* dest, const s32& width, const s32& height )
{
u32 srcIndex = 0;
u32 destIndex = 0;
u8 alphas[16] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
u32 colors[4] = { 0,0,0,0 };
for( s32 y=0; y<height; y += 4 )
{
for( s32 x=0; x<width; x += 4 )
{
// get alpha data first
getDXT3Alphas( &src[ srcIndex ], alphas );
srcIndex += 8;
getCompressedLookupColors( &src[ srcIndex ], colors );
srcIndex += 4;
// Now that we have our lookup colors, read in the 4x4 color index table
u32 colorTable = 0;
memcpy( &colorTable, &src[ srcIndex ], 4 );
srcIndex += 4;
u8 tmpIndex = 0;
u8 counter = 0;
for( u8 xx=0; xx<4; xx++ )
{
for( u8 yy=0; yy<4; yy++ )
{
tmpIndex = ( colorTable >> ( ( xx + yy * 4 ) * 2 ) ) & 3;
video::SColor tmpColor( colors[ tmpIndex ] );
tmpColor.setAlpha( alphas[ counter++ ] );
memcpy( &dest[ x + xx + ( y + yy ) * height ], &tmpColor.color, 4 );
destIndex++;
}
}
}
}
}
//! copies DXT4/5 data to 32 bit A8R8G8B8 data
void CColorConverter::convertDXT5toA8R8G8B8(const u8* src, u32* dest, const s32& width, const s32& height )
{
u32 srcIndex = 0;
u32 destIndex = 0;
u8 alphas[16] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
u32 colors[4] = { 0,0,0,0 };
for( s32 y=0; y<height; y += 4 )
{
for( s32 x=0; x<width; x += 4 )
{
// get alpha data first
getDXT3Alphas( &src[ srcIndex ], alphas );
srcIndex += 8;
getCompressedLookupColors( &src[ srcIndex ], colors );
srcIndex += 4;
// Now that we have our lookup colors, read in the 4x4 color index table
u32 colorTable = 0;
memcpy( &colorTable, &src[ srcIndex ], 4 );
srcIndex += 4;
u8 tmpIndex = 0;
u8 counter = 0;
for( u8 xx=0; xx<4; xx++ )
{
for( u8 yy=0; yy<4; yy++ )
{
tmpIndex = ( colorTable >> ( ( xx + yy * 4 ) * 2 ) ) & 3;
video::SColor tmpColor( colors[ tmpIndex ] );
tmpColor.setAlpha( alphas[ counter++ ] );
memcpy( &dest[ x + xx + ( y + yy ) * height ], &tmpColor.color, 4 );
destIndex++;
}
}
}
}
}
//! gets the lookup colors for compressed images( DXT1 - 5 ) color table data
void CColorConverter::getCompressedLookupColors(const u8* data, u32* colors )
{
u16 c0r5g6b5;
memcpy( &c0r5g6b5, data, 2 );
u16 c1r5g6b5;
memcpy( &c1r5g6b5, data+2, 2 );
colors[0] = R5G6B5toA8R8G8B8( c0r5g6b5 );
video::SColor c0( colors[0] );
colors[1] = R5G6B5toA8R8G8B8( c1r5g6b5 );
video::SColor c1( colors[1] );
video::SColor tmpColor( 255, 0, 0, 0 );
if( c0r5g6b5 > c1r5g6b5 )
{
tmpColor.setRed( (u32)( ( c0.getRed() + c0.getRed() + c1.getRed() ) / 3 ) );
tmpColor.setGreen( (u32)( ( c0.getGreen() + c0.getGreen() + c1.getGreen() ) / 3 ) );
tmpColor.setBlue( (u32)( ( c0.getBlue() + c0.getBlue() + c1.getBlue() ) / 3 ) );
colors[2] = tmpColor.toA8R8G8B8();
tmpColor.setRed( (u32)( ( c0.getRed() + c1.getRed() + c1.getRed() ) / 3 ) );
tmpColor.setGreen( (u32)( ( c0.getGreen() + c1.getGreen() + c1.getGreen() ) / 3 ) );
tmpColor.setBlue( (u32)( ( c0.getBlue() + c1.getBlue() + c1.getBlue() ) / 3 ) );
colors[3] = tmpColor.toA8R8G8B8();
}
else
{
tmpColor.set( 255,
(u32)( c0.getRed() * 0.5f + c1.getRed() * 0.5f ),
(u32)( c0.getGreen() * 0.5f + c1.getGreen() * 0.5f ),
(u32)( c0.getBlue() * 0.5f + c1.getBlue() * 0.5f ) );
colors[2] = tmpColor.toA8R8G8B8();
colors[3] = 0;
}
}
//! computes the alpha values for DXT2/3 formats
void CColorConverter::getDXT3Alphas(const u8* data, u8* alphas )
{
u32 alpha[2];
memcpy( &alpha[0], data, 4 );
memcpy( &alpha[1], data+4, 4 );
alphas[ 0] = (u8)( ( ( alpha[0] >> 28 ) & 0xf ) * 0xff / 0xf );
alphas[ 1] = (u8)( ( ( alpha[0] >> 24 ) & 0xf ) * 0xff / 0xf );
alphas[ 2] = (u8)( ( ( alpha[0] >> 20 ) & 0xf ) * 0xff / 0xf );
alphas[ 3] = (u8)( ( ( alpha[0] >> 16 ) & 0xf ) * 0xff / 0xf );
alphas[ 4] = (u8)( ( ( alpha[0] >> 12 ) & 0xf ) * 0xff / 0xf );
alphas[ 5] = (u8)( ( ( alpha[0] >> 8 ) & 0xf ) * 0xff / 0xf );
alphas[ 6] = (u8)( ( ( alpha[0] >> 4 ) & 0xf ) * 0xff / 0xf );
alphas[ 7] = (u8)( ( alpha[0] & 0xf ) * 0xff / 0xf );
alphas[ 8] = (u8)( ( ( alpha[1] >> 28 ) & 0xf ) * 0xff / 0xf );
alphas[ 9] = (u8)( ( ( alpha[1] >> 24 ) & 0xf ) * 0xff / 0xf );
alphas[10] = (u8)( ( ( alpha[1] >> 20 ) & 0xf ) * 0xff / 0xf );
alphas[11] = (u8)( ( ( alpha[1] >> 16 ) & 0xf ) * 0xff / 0xf );
alphas[12] = (u8)( ( ( alpha[1] >> 12 ) & 0xf ) * 0xff / 0xf );
alphas[13] = (u8)( ( ( alpha[1] >> 8 ) & 0xf ) * 0xff / 0xf );
alphas[14] = (u8)( ( ( alpha[1] >> 4 ) & 0xf ) * 0xff / 0xf );
alphas[15] = (u8)( ( alpha[1] & 0xf ) * 0xff / 0xf );
}
//! computes the alpha values for DXT4/5 formats
void CColorConverter::getDXT5Alphas(const u8* data, u8* alphas )
{
// alpha data comes first
u8 alphaLookup[8];
memcpy( &alphaLookup[0], data, 1 );
memcpy( &alphaLookup[1], data+1, 1 );
if( alphaLookup[0] > alphaLookup[1] )
{
alphaLookup[2] = ( 6 * alphaLookup[0] + 1 * alphaLookup[1] + 3 ) / 7;
alphaLookup[3] = ( 5 * alphaLookup[0] + 2 * alphaLookup[1] + 3 ) / 7;
alphaLookup[4] = ( 4 * alphaLookup[0] + 3 * alphaLookup[1] + 3 ) / 7;
alphaLookup[5] = ( 3 * alphaLookup[0] + 4 * alphaLookup[1] + 3 ) / 7;
alphaLookup[6] = ( 2 * alphaLookup[0] + 5 * alphaLookup[1] + 3 ) / 7;
alphaLookup[7] = ( 1 * alphaLookup[0] + 6 * alphaLookup[1] + 3 ) / 7;
}
else
{
alphaLookup[2] = ( 4 * alphaLookup[0] + 1 * alphaLookup[1] + 2 ) / 5;
alphaLookup[3] = ( 3 * alphaLookup[0] + 2 * alphaLookup[1] + 2 ) / 5;
alphaLookup[4] = ( 2 * alphaLookup[0] + 3 * alphaLookup[1] + 2 ) / 5;
alphaLookup[5] = ( 1 * alphaLookup[0] + 4 * alphaLookup[1] + 2 ) / 5;
alphaLookup[6] = 0;
alphaLookup[7] = 255;
}
// next 48 bits are the 4x4 3bit values representing which alpha value from the lookup table is for which color
u8 alphaRef[6];
memcpy( alphaRef, data+2, 6 );
alphas[ 0] = (u8)( alphaLookup[ alphaRef[0] & 7 ] );
alphas[ 1] = (u8)( alphaLookup[ ( alphaRef[0] >> 3 ) & 7 ] );
alphas[ 2] = (u8)( alphaLookup[ ( ( alphaRef[1] & 1 ) | ( alphaRef[0] >> 6 ) ) & 3 ] );
alphas[ 3] = (u8)( alphaLookup[ ( alphaRef[1] >> 1 ) & 7 ] );
alphas[ 4] = (u8)( alphaLookup[ ( alphaRef[1] >> 4 ) & 7 ] );
alphas[ 5] = (u8)( alphaLookup[ ( ( alphaRef[2] & 3 ) | ( alphaRef[1] >> 7 ) ) ] );
alphas[ 6] = (u8)( alphaLookup[ ( alphaRef[2] >> 2 ) & 7 ] );
alphas[ 7] = (u8)( alphaLookup[ ( alphaRef[2] >> 5 ) & 7 ] );
alphas[ 8] = (u8)( alphaLookup[ alphaRef[3] & 7 ] );
alphas[ 9] = (u8)( alphaLookup[ ( alphaRef[3] >> 3 ) & 7 ] );
alphas[10] = (u8)( alphaLookup[ ( ( alphaRef[4] & 1 ) | ( alphaRef[3] >> 6 ) ) & 3 ] );
alphas[11] = (u8)( alphaLookup[ ( alphaRef[4] >> 1 ) & 7 ] );
alphas[12] = (u8)( alphaLookup[ ( alphaRef[4] >> 4 ) & 7 ] );
alphas[13] = (u8)( alphaLookup[ ( ( alphaRef[5] & 3 ) | ( alphaRef[4] >> 7 ) ) ] );
alphas[14] = (u8)( alphaLookup[ ( alphaRef[5] >> 2 ) & 7 ] );
alphas[15] = (u8)( alphaLookup[ ( alphaRef[5] >> 5 ) & 7 ] );
}
Code: Select all
// Copyright (C) 2002-2007 Thomas Ince
// This file is part of the "3Demon Engine".
// For conditions of distribution and use, see copyright notice in 3Demon.h
#ifndef __C_IMAGE_LOADER_DDS_H_INCLUDED__
#define __C_IMAGE_LOADER_DDS_H_INCLUDED__
#include "CompileConfig.h"
#include "IImageLoader.h"
#include <stdio.h>
namespace demon
{
namespace video
{
class IVideoDriver;
class CImageLoaderDDS : public IImageLoader
{
public:
//! constructor
CImageLoaderDDS( IVideoDriver* driver );
//! destructor
virtual ~CImageLoaderDDS();
//! returns true if the file maybe is able to be loaded by this class
//! based on the file extension (e.g. ".tga")
virtual bool isALoadableFileExtension(const c8* fileName);
//! returns true if the file maybe is able to be loaded by this class
virtual bool isALoadableFileFormat(demon::io::IReadFile* file);
//! creates a surface from the file
virtual IImage* loadImage(demon::io::IReadFile* file);
private:
IVideoDriver* Driver;
struct S_PIXEL_FORMAT
{
u32 size;
u32 flags;
u32 fourCC;
u32 RGBBitCount;
u32 redBitMask;
u32 greenBitMask;
u32 blueBitMask;
u32 RGBAlphaMask;
};
struct S_CAPS2
{
u32 caps1;
u32 caps2;
u32 reserved[2];
};
struct S_SURFACE_FORMAT_HEADER
{
u32 size;
u32 flags;
u32 height;
u32 width;
u32 pitch;
u32 depth;
u32 mipMapCount;
u32 reserved1[11];
S_PIXEL_FORMAT pixelFormat;
S_CAPS2 caps;
u32 reserved2;
};
struct S_R5G6B5
{
u16 b : 5;
u16 g : 6;
u16 r : 5;
u32 toA8R8G8B8()
{
video::SColor tmp( 255,
r * 0xFF / 0x1F,
g * 0xFF / 0x3F,
b * 0xFF / 0x1F );
return tmp.toA8R8G8B8();
//return 0xFF000000 | ( ( r * 0xFF ) / 0x1F ) | ( ( g * 0xFF ) / 0x3F ) | ( ( b * 0xFF ) / 0x1F );
}
bool operator > ( const S_R5G6B5& other ) const
{
video::SColor tmp1( 255,
r * 0xFF / 0x1F,
g * 0xFF / 0x3F,
b * 0xFF / 0x1F );
video::SColor tmp2( 255,
other.r * 0xFF / 0x1F,
other.g * 0xFF / 0x3F,
other.b * 0xFF / 0x1F );
return tmp1.toA8R8G8B8() > tmp2.toA8R8G8B8();
//return (*(u16*)this) > (*(u16*)&other);
}
};
};
} // end namespace video
} // end namespace demon
#endif // __C_IMAGE_LOADER_DDS_H_INCLUDED__
Code: Select all
// Copyright (C) 2002-2007 Thomas Ince
// This file is part of the "3Demon Engine".
// For conditions of distribution and use, see copyright notice in 3Demon.h
#include "CompileConfig.h"
#include "CImageLoaderDDS.h"
#include "IVideoDriver.h"
#include "DemonString.h"
#include "CImage.h"
#include "os.h"
#define DDS_MAGIC 0x20534444
// S_SURFACE_FORMAT_HEADER.flags
#define DDSD_CAPS 0x00000001
#define DDSD_HEIGHT 0x00000002
#define DDSD_WIDTH 0x00000004
#define DDSD_PITCH 0x00000008
#define DDSD_PIXELFORMAT 0x00001000
#define DDSD_MIPMAPCOUNT 0x00020000
#define DDSD_LINEARSIZE 0x00080000
#define DDSD_DEPTH 0x00800000
// S_SURFACE_FORMAT_HEADER.S_PIXEL_FORMAT.flags
#define DDPF_ALPHAPIXELS 0x00000001
#define DDPF_ALPHA 0x00000002
#define DDPF_FOURCC 0x00000004
#define DDPF_RGB 0x00000040
#define DDPF_COMPRESSED 0x00000080
#define DDPF_LUMINANCE 0x00020000
// S_SURFACE_FORMAT_HEADER.caps.caps1
#define DDSCAPS1_COMPLEX 0x00000008
#define DDSCAPS1_TEXTURE 0x00001000
#define DDSCAPS1_MIPMAP 0x00400000
// S_SURFACE_FORMAT_HEADER.caps.caps2
#define DDSCAPS2_CUBEMAP 0x00000200
#define DDSCAPS2_CUBEMAP_POSITIVEX 0x00000400
#define DDSCAPS2_CUBEMAP_NEGATIVEX 0x00000800
#define DDSCAPS2_CUBEMAP_POSITIVEY 0x00001000
#define DDSCAPS2_CUBEMAP_NEGATIVEY 0x00002000
#define DDSCAPS2_CUBEMAP_POSITIVEZ 0x00004000
#define DDSCAPS2_CUBEMAP_NEGATIVEZ 0x00008000
#define DDSCAPS2_VOLUME 0x00200000
#ifndef MAKEFOURCC
#define MAKEFOURCC(ch0, ch1, ch2, ch3) \
((s32)(u8)(ch0) | ((s32)(u8)(ch1) << 8) | \
((s32)(u8)(ch2) << 16) | ((s32)(u8)(ch3) << 24 ))
#endif
#define D3DFMT_R8G8B8 20
#define D3DFMT_A8R8G8B8 21
#define D3DFMT_X8R8G8B8 22
#define D3DFMT_R5G6B5 23
#define D3DFMT_A1R5G5B5 25
#define D3DFMT_A4R4G4B4 26
#define D3DFMT_A8B8G8R8 32
#define D3DFMT_X8B8G8R8 33
#define D3DFMT_DXT1 MAKEFOURCC('D', 'X', 'T', '1')
#define D3DFMT_DXT2 MAKEFOURCC('D', 'X', 'T', '2')
#define D3DFMT_DXT3 MAKEFOURCC('D', 'X', 'T', '3')
#define D3DFMT_DXT4 MAKEFOURCC('D', 'X', 'T', '4')
#define D3DFMT_DXT5 MAKEFOURCC('D', 'X', 'T', '5')
namespace demon
{
namespace video
{
//! constructor
CImageLoaderDDS::CImageLoaderDDS( IVideoDriver* driver )
: Driver( driver )
{
#ifdef _DEBUG
setDebugName("CImageLoaderDDS");
#endif
}
//! destructor
CImageLoaderDDS::~CImageLoaderDDS()
{
}
//! returns true if the file maybe is able to be loaded by this class
//! based on the file extension (e.g. ".tga")
bool CImageLoaderDDS::isALoadableFileExtension(const c8* fileName)
{
return strstr(fileName, ".dds") != 0;
}
//! returns true if the file maybe is able to be loaded by this class
bool CImageLoaderDDS::isALoadableFileFormat(demon::io::IReadFile* file)
{
if(!file)
return false;
char magicWord[4];
file->read( &magicWord, 4 );
return (magicWord[0] == 'D' && magicWord[1] == 'D' && magicWord[2] == 'S' );
}
//! creates a surface from the file
IImage* CImageLoaderDDS::loadImage(demon::io::IReadFile* file)
{
IImage* image = NULL;
S_SURFACE_FORMAT_HEADER header;
file->seek( 4 );
file->read( &header, sizeof( S_SURFACE_FORMAT_HEADER ) );
if( header.size == 124 && ( header.flags & DDSD_PIXELFORMAT ) && ( header.flags & DDSD_CAPS ) )
{
// determine if texture is 3d( has depth )
bool is3D = header.depth > 0 && ( header.flags & DDSD_DEPTH );
if( !is3D )
header.depth = 1;
// determine if texture has alpha
bool usingAlpha = header.pixelFormat.flags & DDPF_ALPHAPIXELS;
// color format to create image
E_COLOR_FORMAT format = ECF_UNKNOWN;
u32 dataSize = 0;
if( header.pixelFormat.flags & DDPF_RGB )
{
u32 byteCount = header.pixelFormat.RGBBitCount / 8;
if( header.flags & DDSD_PITCH )
dataSize = header.pitch * header.height * header.depth * ( header.pixelFormat.RGBBitCount / 8 );
else
dataSize = header.width * header.height * header.depth * ( header.pixelFormat.RGBBitCount / 8 );
u8* data = new u8[dataSize];
file->read( data, dataSize );
// has an alpha mask
switch( header.pixelFormat.RGBBitCount )
{
case 16:
{
if( usingAlpha )
{
if( header.pixelFormat.RGBAlphaMask == 0x8000 )
{
format = ECF_A1R5G5B5;
os::Printer::print( "DDS : ECF_A1R5G5B5 format" );
}
else if( header.pixelFormat.RGBAlphaMask == 0xf000 )
{
format = ECF_A4R4G4B4;
os::Printer::print( "DDS : ECF_A4R4G4B4 format" );
}
else
{
os::Printer::print( "DDS : Unsupported 16 bit format with alpha" );
}
}
else
{
if( header.pixelFormat.redBitMask == 0xf800 )
{
format = ECF_R5G6B5;
os::Printer::print( "DDS : ECF_R5G6B5 format" );
}
}
break;
}
case 24:
{
if( usingAlpha )
{
os::Printer::print( "DDS : Unsupported 24 bit format with alpha" );
}
else
{
if( header.pixelFormat.redBitMask & 0xff0000 )
{
format = ECF_R8G8B8;
os::Printer::print( "DDS : ECF_R8G8B8 format" );
}
}
break;
}
case 32:
{
if( usingAlpha )
{
if( header.pixelFormat.redBitMask & 0xff0000 )
{
format = ECF_A8R8G8B8;
os::Printer::print( "DDS : ECF_A8R8G8B8 format" );
}
else if( header.pixelFormat.redBitMask & 0xff )
{
format = ECF_A8R8G8B8;
os::Printer::print( "DDS : ECF_A8R8G8B8 format" );
// convert data from A8B8G8R8 to A8R8G8B8
u8 tmp = 0;
for( u32 x=0; x<dataSize; x+=4 )
{
tmp = data[x];
data[x] = data[x+2];
data[x+2] = tmp;
}
}
else
{
os::Printer::print( "DDS : Unsupported 32 bit alpha format" );
}
}
else
{
if( header.pixelFormat.redBitMask & 0xff0000 )
{
format = ECF_X8R8G8B8;
os::Printer::print( "DDS : ECF_X8R8G8B8 format" );
}
else if( header.pixelFormat.redBitMask & 0xff )
{
format = ECF_X8R8G8B8;
os::Printer::print( "DDS : ECF_X8R8G8B8 format" );
// convert data from X8B8G8R8 to X8R8G8B8
u8 tmp = 0;
for( u32 x=0; x<dataSize; x+=4 )
{
data[x+3] = 255;
tmp = data[x];
data[x] = data[x+2];
data[x+2] = tmp;
}
}
}
break;
}
}
if( format != ECF_UNKNOWN )
{
if( is3D )
image = new CImage( format, core::vector3d< s32 >( header.width, header.height, header.depth ), data );
else
image = new CImage( format, core::vector2di( header.width, header.height ), data );
}
}
else if( header.pixelFormat.flags & DDPF_FOURCC )
{
switch( header.pixelFormat.fourCC )
{
case D3DFMT_DXT1:
{
dataSize = ( header.width / 4 ) * ( header.height / 4 ) * 8;
format = ECF_DXT1;
os::Printer::print( "DDS : ECF_DXT1 format" );
break;
}
case D3DFMT_DXT2:
case D3DFMT_DXT3:
{
dataSize = ( header.width / 4 ) * ( header.height / 4 ) * 16;
format = ECF_DXT3;
os::Printer::print( "DDS : ECF_DXT3 format" );
break;
}
case D3DFMT_DXT4:
case D3DFMT_DXT5:
{
dataSize = ( header.width / 4 ) * ( header.height / 4 ) * 16;
format = ECF_DXT5;
os::Printer::print( "DDS : ECF_DXT5 format" );
break;
}
}
if( format != ECF_UNKNOWN )
{
u8* data = new u8[ dataSize ];
file->read( data, dataSize );
if( is3D )
image = new CImage( format, core::vector3d< s32 >( header.width, header.height, header.depth ), data );
else
image = new CImage( format, core::vector2di( header.width, header.height ), data );
}
}
else if( header.pixelFormat.flags & DDPF_LUMINANCE ) // 8-bit luminance [ D3DFMT_L8 ]
{
format = ECF_L8;
dataSize = header.width * header.height * header.depth;
if( format != ECF_UNKNOWN )
{
u8* data = new u8[ dataSize ];
file->read( data, dataSize );
if( is3D )
image = new CImage( format, core::vector3d< s32 >( header.width, header.height, header.depth ), data );
else
image = new CImage( format, core::vector2di( header.width, header.height ), data );
}
}
else
{
os::Printer::print( "UNKNOWN DDS FORMAT TEXTURE" );
}
}
return image;
}
//! creates a loader which is able to load DDS images
IImageLoader* createImageLoaderDDS( video::IVideoDriver* driver )
{
return new CImageLoaderDDS( driver );
}
} // end namespace video
} // end namespace demon
Code: Select all
#include <stdio.h>
#include "VxTimer.h"
int counter = 0;
const int callCount1 = 4000;
const int callCount2 = 4000;
void func1( int i );
void func2( int i );
void func3( const int& i );
void func4( const int& i );
void func1( int i )
{
counter++;
if( counter < callCount1 )
func2( i );
}
void func2( int i )
{
counter++;
if( counter < callCount1 )
func1( i );
}
void func3( const int& i )
{
counter++;
if( counter < callCount2 )
func4( i );
}
void func4( const int& i )
{
counter++;
if( counter < callCount2 )
func3( i );
}
int main()
{
VxTimer timer1;
timer1.StartMilliTimer( 0.0 );
counter = 0;
func1( counter );
printf( "copy arg - %6.6f milliseconds\n", timer1.ElapsedMilliSec() );
VxTimer timer2;
timer2.StartMilliTimer( 0.0 );
counter = 0;
func3( counter );
printf( "const ref arg - %6.6f milliseconds\n", timer2.ElapsedMilliSec() );
return 0;
}
Code: Select all
copy arg - 0.774121 milliseconds
const ref arg - 0.186686 milliseconds
Code: Select all
copy arg - 0.002375 milliseconds
const ref arg - 0.002514 milliseconds