diff --git a/engine/client/gl_image.c b/engine/client/gl_image.c index 9f1e93c4..e3ca859c 100644 --- a/engine/client/gl_image.c +++ b/engine/client/gl_image.c @@ -1570,7 +1570,7 @@ int GL_LoadTextureArray( const char **names, int flags, imgfilter_t *filter ) uint numLayers = 0; uint picFlags = 0; char name[256]; - uint i, hash; + uint i, j, hash; if( !names || !names[0] || !glw_state.initialized ) return 0; @@ -1614,6 +1614,8 @@ int GL_LoadTextureArray( const char **names, int flags, imgfilter_t *filter ) // load all the images and pack it into single image for( i = 0, pic = NULL; i < numLayers; i++ ) { + size_t srcsize, dstsize, mipsize; + src = FS_LoadImage( names[i], NULL, 0 ); if( !src ) break; // coldn't find layer @@ -1627,29 +1629,47 @@ int GL_LoadTextureArray( const char **names, int flags, imgfilter_t *filter ) if( pic->numMips != src->numMips ) break; + if( pic->encode != src->encode ) + break; + // but allow to rescale raw images if( ImageRAW( pic->type ) && ImageRAW( src->type ) && ( pic->width != src->width || pic->height != src->height )) Image_Process( &src, pic->width, pic->height, 0.0f, IMAGE_RESAMPLE, NULL ); if( pic->size != src->size ) break; - - Q_memcpy( pic->buffer + (i * pic->size), src->buffer, pic->size ); - FS_FreeImage( src ); } else { - pic = src; + // create new image + pic = Mem_Alloc( host.imagepool, sizeof( rgbdata_t )); + Q_memcpy( pic, src, sizeof( rgbdata_t )); + // expand pic buffer for all layers - pic->buffer = Mem_Realloc( host.imagepool, pic->buffer, pic->size * numLayers ); + pic->buffer = Mem_Alloc( host.imagepool, pic->size * numLayers ); + pic->depth = 0; } + mipsize = srcsize = dstsize = 0; + + for( j = 0; j < max( 1, pic->numMips ); j++ ) + { + int width = max( 1, ( pic->width >> j )); + int height = max( 1, ( pic->height >> j )); + mipsize = GL_CalcImageSize( pic->type, width, height, 1 ); + Q_memcpy( pic->buffer + dstsize + mipsize * i, src->buffer + srcsize, mipsize ); + dstsize += mipsize * numLayers; + srcsize += mipsize; + } + + FS_FreeImage( src ); + // increase layers pic->depth++; } // there were errors - if( pic->depth != numLayers ) + if( !pic || ( pic->depth != numLayers )) { if( pic ) FS_FreeImage( pic ); return 0; @@ -1657,6 +1677,7 @@ int GL_LoadTextureArray( const char **names, int flags, imgfilter_t *filter ) // it's multilayer image! pic->flags |= IMAGE_MULTILAYER; + pic->size *= numLayers; // find a free texture slot if( r_numTextures == MAX_TEXTURES ) diff --git a/engine/common/imagelib/img_bmp.c b/engine/common/imagelib/img_bmp.c index 95707b0e..5b97741b 100644 --- a/engine/common/imagelib/img_bmp.c +++ b/engine/common/imagelib/img_bmp.c @@ -295,6 +295,7 @@ qboolean Image_LoadBMP( const char *name, const byte *buffer, size_t filesize ) VectorDivide( reflectivity, ( image.width * image.height ), image.fogParams ); if( image.palette ) Image_GetPaletteBMP( image.palette ); + image.depth = 1; return true; } diff --git a/engine/common/imagelib/img_tga.c b/engine/common/imagelib/img_tga.c index 4ca9e6db..4d0f3407 100644 --- a/engine/common/imagelib/img_tga.c +++ b/engine/common/imagelib/img_tga.c @@ -214,6 +214,7 @@ qboolean Image_LoadTGA( const char *name, const byte *buffer, size_t filesize ) } VectorDivide( reflectivity, ( image.width * image.height ), image.fogParams ); + image.depth = 1; return true; } diff --git a/engine/common/imagelib/img_wad.c b/engine/common/imagelib/img_wad.c index 10e071e3..4264019c 100644 --- a/engine/common/imagelib/img_wad.c +++ b/engine/common/imagelib/img_wad.c @@ -58,6 +58,7 @@ qboolean Image_LoadPAL( const char *name, const byte *buffer, size_t filesize ) image.rgba = NULL; // only palette, not real image image.size = 1024; // expanded palette image.width = image.height = 0; + image.depth = 1; return true; } @@ -119,6 +120,7 @@ qboolean Image_LoadFNT( const char *name, const byte *buffer, size_t filesize ) } image.type = PF_INDEXED_32; // 32-bit palette + image.depth = 1; return Image_AddIndexedImageToPack( fin, image.width, image.height ); } @@ -170,6 +172,7 @@ qboolean Image_LoadMDL( const char *name, const byte *buffer, size_t filesize ) } image.type = PF_INDEXED_32; // 32-bit palete + image.depth = 1; return Image_AddIndexedImageToPack( fin, image.width, image.height ); } @@ -214,6 +217,7 @@ qboolean Image_LoadSPR( const char *name, const byte *buffer, size_t filesize ) // sorry, can't validate palette rendermode if( !Image_LumpValidSize( name )) return false; image.type = PF_INDEXED_32; // 32-bit palete + image.depth = 1; // detect alpha-channel by palette type switch( image.d_rendermode ) @@ -305,6 +309,7 @@ qboolean Image_LoadLMP( const char *name, const byte *buffer, size_t filesize ) if( fin[0] == 255 ) image.flags |= IMAGE_HAS_ALPHA; Image_GetPaletteLMP( pal, rendermode ); image.type = PF_INDEXED_32; // 32-bit palete + image.depth = 1; return Image_AddIndexedImageToPack( fin, image.width, image.height ); } @@ -476,5 +481,7 @@ qboolean Image_LoadMIP( const char *name, const byte *buffer, size_t filesize ) } image.type = PF_INDEXED_32; // 32-bit palete + image.depth = 1; + return Image_AddIndexedImageToPack( fin, image.width, image.height ); } \ No newline at end of file