From 55afc66de216644ff0ba6cc18e39a36f9e70b5ec Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Wed, 6 Mar 2019 09:28:53 +0100 Subject: [PATCH] R_FindCubeImage: fix irregular skyboxes, fix #142 --- src/engine/renderer/tr_image.cpp | 77 +++++++++++++++++++++++++------- 1 file changed, 61 insertions(+), 16 deletions(-) diff --git a/src/engine/renderer/tr_image.cpp b/src/engine/renderer/tr_image.cpp index aeb62572f8..16fbe8afbe 100644 --- a/src/engine/renderer/tr_image.cpp +++ b/src/engine/renderer/tr_image.cpp @@ -2040,9 +2040,15 @@ static const multifileCubeMapFormat_t multifileCubeMapFormats[] = static int numMultifileCubeMapFormats = ARRAY_LEN( multifileCubeMapFormats ); +struct face_t +{ + int width; + int height; +}; + image_t *R_FindCubeImage( const char *imageName, int bits, filterType_t filterType, wrapType_t wrapType ) { - int i, f; + int i, j, f; image_t *image = nullptr; int width = 0, height = 0, numLayers = 0, numMips = 0; byte *pic[ MAX_TEXTURE_MIPS * MAX_TEXTURE_LAYERS ]; @@ -2095,6 +2101,9 @@ image_t *R_FindCubeImage( const char *imageName, int bits, filterType_t filterTy for ( f = 0; f < numMultifileCubeMapFormats; f++ ) { + int greatestEdge = 0; + face_t faces[6]; + for ( i = 0; i < 6; i++ ) { Com_sprintf( filename, sizeof( filename ), "%s_%s", buffer, multifileCubeMapFormats[ f ].suffixes[ i ] ); @@ -2123,32 +2132,68 @@ image_t *R_FindCubeImage( const char *imageName, int bits, filterType_t filterTy break; } - if ( width != height ) + if ( width > greatestEdge ) { - Log::Warn("cubemap face '%s' is not a square with %d×%d dimension", filename, width, height); - break; - } - - if ( multifileCubeMapFormats[ f ].flipX[ i ] ) - { - R_Flip( pic[ i ], width, height ); + greatestEdge = width; } - if ( multifileCubeMapFormats[ f ].flipY[ i ] ) + if ( height > greatestEdge ) { - R_Flop( pic[ i ], width, height ); + greatestEdge = height; } - if ( multifileCubeMapFormats[ f ].rot[ i ] != 0 ) - { - R_Rotate( pic[ i ], width, height, multifileCubeMapFormats[ f ].rot[ i ] ); - } + faces[ i ].width = width; + faces[ i ].height = height; } if ( i == 6 ) { + + for ( j = 0; j < 6; j++ ) + { + width = faces[ j ].width; + height = faces[ j ].height; + + bool badSize = false; + + if ( width != height ) + { + Log::Warn("cubemap face '%s_%s' is not a square with %d×%d dimension, resizing to %d×%d", + imageName, multifileCubeMapFormats[ f ].suffixes[ j ], width, height, greatestEdge, greatestEdge ); + badSize = true; + } + + if ( width < greatestEdge || height < greatestEdge ) + { + Log::Warn("cubemap face '%s_%s' is too small with %d×%d dimension, resizing to %d×%d", + imageName, multifileCubeMapFormats[ f ].suffixes[ j ], width, height, greatestEdge, greatestEdge ); + badSize = true; + } + + // make face square before doing other operations like rotation + if ( badSize ) + { + pic[ j ] = R_Resize( pic[ j ], width, height, greatestEdge, greatestEdge ); + } + + if ( multifileCubeMapFormats[ f ].flipX[ j ] ) + { + R_Flip( pic[ j ], width, height ); + } + + if ( multifileCubeMapFormats[ f ].flipY[ j ] ) + { + R_Flop( pic[ j ], width, height ); + } + + if ( multifileCubeMapFormats[ f ].rot[ j ] != 0 ) + { + R_Rotate( pic[ j ], width, height, multifileCubeMapFormats[ f ].rot[ j ] ); + } + } + Log::Debug( "found %s multifile cube map '%s'", multifileCubeMapFormats[ f ].name, imageName ); - image = R_CreateCubeImage( ( char * ) buffer, ( const byte ** ) pic, width, height, bits, filterType, wrapType ); + image = R_CreateCubeImage( ( char * ) buffer, ( const byte ** ) pic, greatestEdge, greatestEdge, bits, filterType, wrapType ); R_FreeCubePics( pic, i ); return image; }