2018-08-29 22:38:13 +02:00
/*************************************************************************/
/* resource_importer_layered_texture.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
2022-01-03 21:27:34 +01:00
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
2018-08-29 22:38:13 +02:00
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
2018-08-06 19:56:06 +02:00
# include "resource_importer_layered_texture.h"
2022-02-12 02:46:22 +01:00
# include "core/config/project_settings.h"
2022-01-18 13:39:55 +01:00
# include "core/error/error_macros.h"
2018-09-11 18:13:45 +02:00
# include "core/io/config_file.h"
# include "core/io/image_loader.h"
2022-01-18 13:39:55 +01:00
# include "core/object/ref_counted.h"
2018-08-06 19:56:06 +02:00
# include "editor/editor_file_system.h"
# include "editor/editor_node.h"
2020-05-01 14:34:23 +02:00
# include "resource_importer_texture.h"
2018-08-06 19:56:06 +02:00
# include "scene/resources/texture.h"
String ResourceImporterLayeredTexture : : get_importer_name ( ) const {
2019-06-11 20:43:37 +02:00
switch ( mode ) {
case MODE_CUBEMAP : {
return " cubemap_texture " ;
} break ;
case MODE_2D_ARRAY : {
return " 2d_array_texture " ;
} break ;
case MODE_CUBEMAP_ARRAY : {
return " cubemap_array_texture " ;
} break ;
2020-05-01 14:34:23 +02:00
case MODE_3D : {
2020-10-08 02:29:49 +02:00
return " 3d_texture " ;
2020-05-01 14:34:23 +02:00
} break ;
2019-06-11 20:43:37 +02:00
}
ERR_FAIL_V ( " " ) ;
2018-08-06 19:56:06 +02:00
}
String ResourceImporterLayeredTexture : : get_visible_name ( ) const {
2019-06-11 20:43:37 +02:00
switch ( mode ) {
case MODE_CUBEMAP : {
return " Cubemap " ;
} break ;
case MODE_2D_ARRAY : {
return " Texture2DArray " ;
} break ;
case MODE_CUBEMAP_ARRAY : {
return " CubemapArray " ;
} break ;
2020-05-01 14:34:23 +02:00
case MODE_3D : {
2020-09-09 17:40:51 +02:00
return " Texture3D " ;
2020-05-01 14:34:23 +02:00
} break ;
2019-06-11 20:43:37 +02:00
}
ERR_FAIL_V ( " " ) ;
2018-08-06 19:56:06 +02:00
}
2020-05-14 14:29:06 +02:00
2018-08-06 19:56:06 +02:00
void ResourceImporterLayeredTexture : : get_recognized_extensions ( List < String > * p_extensions ) const {
ImageLoader : : get_recognized_extensions ( p_extensions ) ;
}
2020-05-14 14:29:06 +02:00
2018-08-06 19:56:06 +02:00
String ResourceImporterLayeredTexture : : get_save_extension ( ) const {
2019-06-11 20:43:37 +02:00
switch ( mode ) {
case MODE_CUBEMAP : {
2022-03-10 04:22:36 +01:00
return " ccube " ;
2019-06-11 20:43:37 +02:00
} break ;
case MODE_2D_ARRAY : {
2022-03-10 04:22:36 +01:00
return " ctexarray " ;
2019-06-11 20:43:37 +02:00
} break ;
case MODE_CUBEMAP_ARRAY : {
2022-03-10 04:22:36 +01:00
return " ccubearray " ;
2020-05-01 14:34:23 +02:00
} break ;
case MODE_3D : {
2022-03-10 04:22:36 +01:00
return " ctex3d " ;
2019-06-11 20:43:37 +02:00
} break ;
}
ERR_FAIL_V ( String ( ) ) ;
2018-08-06 19:56:06 +02:00
}
String ResourceImporterLayeredTexture : : get_resource_type ( ) const {
2019-06-11 20:43:37 +02:00
switch ( mode ) {
case MODE_CUBEMAP : {
2022-03-05 16:43:38 +01:00
return " CompressedCubemap " ;
2019-06-11 20:43:37 +02:00
} break ;
case MODE_2D_ARRAY : {
2022-03-05 16:43:38 +01:00
return " CompressedTexture2DArray " ;
2019-06-11 20:43:37 +02:00
} break ;
case MODE_CUBEMAP_ARRAY : {
2022-03-05 16:43:38 +01:00
return " CompressedCubemapArray " ;
2020-05-01 14:34:23 +02:00
} break ;
case MODE_3D : {
2022-03-05 16:43:38 +01:00
return " CompressedTexture3D " ;
2019-06-11 20:43:37 +02:00
} break ;
}
ERR_FAIL_V ( String ( ) ) ;
2018-08-06 19:56:06 +02:00
}
2022-05-13 15:04:37 +02:00
bool ResourceImporterLayeredTexture : : get_option_visibility ( const String & p_path , const String & p_option , const HashMap < StringName , Variant > & p_options ) const {
2020-05-01 14:34:23 +02:00
if ( p_option = = " compress/lossy_quality " & & p_options . has ( " compress/mode " ) ) {
return int ( p_options [ " compress/mode " ] ) = = COMPRESS_LOSSY ;
}
2018-08-06 19:56:06 +02:00
return true ;
}
int ResourceImporterLayeredTexture : : get_preset_count ( ) const {
2019-06-11 20:43:37 +02:00
return 0 ;
2018-08-06 19:56:06 +02:00
}
2020-05-14 14:29:06 +02:00
2018-08-06 19:56:06 +02:00
String ResourceImporterLayeredTexture : : get_preset_name ( int p_idx ) const {
2019-06-11 20:43:37 +02:00
return " " ;
2018-08-06 19:56:06 +02:00
}
2021-11-14 18:02:38 +01:00
void ResourceImporterLayeredTexture : : get_import_options ( const String & p_path , List < ImportOption > * r_options , int p_preset ) const {
2022-10-28 19:24:32 +02:00
r_options - > push_back ( ImportOption ( PropertyInfo ( Variant : : INT , " compress/mode " , PROPERTY_HINT_ENUM , " Lossless,Lossy,VRAM Compressed,VRAM Uncompressed,Basis Universal " , PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED ) , 1 ) ) ;
2020-05-01 14:34:23 +02:00
r_options - > push_back ( ImportOption ( PropertyInfo ( Variant : : FLOAT , " compress/lossy_quality " , PROPERTY_HINT_RANGE , " 0,1,0.01 " ) , 0.7 ) ) ;
r_options - > push_back ( ImportOption ( PropertyInfo ( Variant : : INT , " compress/hdr_compression " , PROPERTY_HINT_ENUM , " Disabled,Opaque Only,Always " ) , 1 ) ) ;
r_options - > push_back ( ImportOption ( PropertyInfo ( Variant : : INT , " compress/bptc_ldr " , PROPERTY_HINT_ENUM , " Disabled,Enabled,RGBA Only " ) , 0 ) ) ;
2021-09-16 22:41:26 +02:00
r_options - > push_back ( ImportOption ( PropertyInfo ( Variant : : INT , " compress/channel_pack " , PROPERTY_HINT_ENUM , " sRGB Friendly,Optimized,Normal Map (RG Channels) " ) , 0 ) ) ;
2020-05-01 14:34:23 +02:00
r_options - > push_back ( ImportOption ( PropertyInfo ( Variant : : BOOL , " mipmaps/generate " ) , true ) ) ;
r_options - > push_back ( ImportOption ( PropertyInfo ( Variant : : INT , " mipmaps/limit " , PROPERTY_HINT_RANGE , " -1,256 " ) , - 1 ) ) ;
if ( mode = = MODE_2D_ARRAY | | mode = = MODE_3D ) {
2019-06-11 20:43:37 +02:00
r_options - > push_back ( ImportOption ( PropertyInfo ( Variant : : INT , " slices/horizontal " , PROPERTY_HINT_RANGE , " 1,256,1 " ) , 8 ) ) ;
r_options - > push_back ( ImportOption ( PropertyInfo ( Variant : : INT , " slices/vertical " , PROPERTY_HINT_RANGE , " 1,256,1 " ) , 8 ) ) ;
}
2020-05-01 14:34:23 +02:00
if ( mode = = MODE_CUBEMAP | | mode = = MODE_CUBEMAP_ARRAY ) {
r_options - > push_back ( ImportOption ( PropertyInfo ( Variant : : INT , " slices/arrangement " , PROPERTY_HINT_ENUM , " 1x6,2x3,3x2,6x1 " ) , 1 ) ) ;
if ( mode = = MODE_CUBEMAP_ARRAY ) {
r_options - > push_back ( ImportOption ( PropertyInfo ( Variant : : INT , " slices/layout " , PROPERTY_HINT_ENUM , " Horizontal,Vertical " ) , 1 ) ) ;
r_options - > push_back ( ImportOption ( PropertyInfo ( Variant : : INT , " slices/amount " , PROPERTY_HINT_RANGE , " 1,1024,1,or_greater " ) , 1 ) ) ;
}
2018-08-06 19:56:06 +02:00
}
2020-05-01 14:34:23 +02:00
}
2018-08-06 19:56:06 +02:00
2020-05-01 14:34:23 +02:00
void ResourceImporterLayeredTexture : : _save_tex ( Vector < Ref < Image > > p_images , const String & p_to_path , int p_compress_mode , float p_lossy , Image : : CompressMode p_vram_compression , Image : : CompressSource p_csource , Image : : UsedChannels used_channels , bool p_mipmaps , bool p_force_po2 ) {
2020-09-09 17:40:51 +02:00
Vector < Ref < Image > > mipmap_images ; //for 3D
if ( mode = = MODE_3D ) {
//3D saves in its own way
for ( int i = 0 ; i < p_images . size ( ) ; i + + ) {
if ( p_images . write [ i ] - > has_mipmaps ( ) ) {
p_images . write [ i ] - > clear_mipmaps ( ) ;
}
if ( p_force_po2 ) {
p_images . write [ i ] - > resize_to_po2 ( ) ;
}
2020-05-01 14:34:23 +02:00
}
2018-08-06 19:56:06 +02:00
2020-05-01 14:34:23 +02:00
if ( p_mipmaps ) {
2020-09-09 17:40:51 +02:00
Vector < Ref < Image > > parent_images = p_images ;
//create 3D mipmaps, this is horrible, though not used very often
int w = p_images [ 0 ] - > get_width ( ) ;
int h = p_images [ 0 ] - > get_height ( ) ;
int d = p_images . size ( ) ;
while ( w > 1 | | h > 1 | | d > 1 ) {
Vector < Ref < Image > > mipmaps ;
int mm_w = MAX ( 1 , w > > 1 ) ;
int mm_h = MAX ( 1 , h > > 1 ) ;
int mm_d = MAX ( 1 , d > > 1 ) ;
for ( int i = 0 ; i < mm_d ; i + + ) {
2022-07-22 20:06:19 +02:00
Ref < Image > mm = Image : : create_empty ( mm_w , mm_h , false , p_images [ 0 ] - > get_format ( ) ) ;
2020-09-09 17:40:51 +02:00
Vector3 pos ;
pos . z = float ( i ) * float ( d ) / float ( mm_d ) + 0.5 ;
for ( int x = 0 ; x < mm_w ; x + + ) {
for ( int y = 0 ; y < mm_h ; y + + ) {
pos . x = float ( x ) * float ( w ) / float ( mm_w ) + 0.5 ;
pos . y = float ( y ) * float ( h ) / float ( mm_h ) + 0.5 ;
Vector3i posi = Vector3i ( pos ) ;
Vector3 fract = pos - Vector3 ( posi ) ;
Vector3i posi_n = posi ;
if ( posi_n . x < w - 1 ) {
posi_n . x + + ;
}
if ( posi_n . y < h - 1 ) {
posi_n . y + + ;
}
if ( posi_n . z < d - 1 ) {
posi_n . z + + ;
}
Color c000 = parent_images [ posi . z ] - > get_pixel ( posi . x , posi . y ) ;
Color c100 = parent_images [ posi . z ] - > get_pixel ( posi_n . x , posi . y ) ;
Color c010 = parent_images [ posi . z ] - > get_pixel ( posi . x , posi_n . y ) ;
Color c110 = parent_images [ posi . z ] - > get_pixel ( posi_n . x , posi_n . y ) ;
Color c001 = parent_images [ posi_n . z ] - > get_pixel ( posi . x , posi . y ) ;
Color c101 = parent_images [ posi_n . z ] - > get_pixel ( posi_n . x , posi . y ) ;
Color c011 = parent_images [ posi_n . z ] - > get_pixel ( posi . x , posi_n . y ) ;
Color c111 = parent_images [ posi_n . z ] - > get_pixel ( posi_n . x , posi_n . y ) ;
Color cx00 = c000 . lerp ( c100 , fract . x ) ;
Color cx01 = c001 . lerp ( c101 , fract . x ) ;
Color cx10 = c010 . lerp ( c110 , fract . x ) ;
Color cx11 = c011 . lerp ( c111 , fract . x ) ;
Color cy0 = cx00 . lerp ( cx10 , fract . y ) ;
Color cy1 = cx01 . lerp ( cx11 , fract . y ) ;
Color cz = cy0 . lerp ( cy1 , fract . z ) ;
mm - > set_pixel ( x , y , cz ) ;
}
}
mipmaps . push_back ( mm ) ;
}
w = mm_w ;
h = mm_h ;
d = mm_d ;
mipmap_images . append_array ( mipmaps ) ;
parent_images = mipmaps ;
}
}
} else {
for ( int i = 0 ; i < p_images . size ( ) ; i + + ) {
if ( p_force_po2 ) {
p_images . write [ i ] - > resize_to_po2 ( ) ;
}
if ( p_mipmaps ) {
2021-08-29 10:19:45 +02:00
p_images . write [ i ] - > generate_mipmaps ( p_csource = = Image : : COMPRESS_SOURCE_NORMAL ) ;
2020-09-09 17:40:51 +02:00
} else {
p_images . write [ i ] - > clear_mipmaps ( ) ;
}
2020-05-01 14:34:23 +02:00
}
}
2018-08-06 19:56:06 +02:00
2022-03-23 10:08:58 +01:00
Ref < FileAccess > f = FileAccess : : open ( p_to_path , FileAccess : : WRITE ) ;
2020-05-01 14:34:23 +02:00
f - > store_8 ( ' G ' ) ;
f - > store_8 ( ' S ' ) ;
f - > store_8 ( ' T ' ) ;
f - > store_8 ( ' L ' ) ;
2018-08-06 19:56:06 +02:00
2022-03-05 16:43:38 +01:00
f - > store_32 ( CompressedTextureLayered : : FORMAT_VERSION ) ;
2022-01-18 13:39:55 +01:00
f - > store_32 ( p_images . size ( ) ) ; // For 2d layers or 3d depth.
2020-05-01 14:34:23 +02:00
f - > store_32 ( mode ) ;
2020-09-09 17:40:51 +02:00
f - > store_32 ( 0 ) ;
2018-08-06 19:56:06 +02:00
2020-05-01 14:34:23 +02:00
f - > store_32 ( 0 ) ;
2022-01-18 13:39:55 +01:00
f - > store_32 ( mipmap_images . size ( ) ) ; // Adjust the amount of mipmaps.
2020-05-01 14:34:23 +02:00
f - > store_32 ( 0 ) ;
f - > store_32 ( 0 ) ;
2018-08-06 19:56:06 +02:00
2020-05-01 14:34:23 +02:00
for ( int i = 0 ; i < p_images . size ( ) ; i + + ) {
2022-03-10 04:22:36 +01:00
ResourceImporterTexture : : save_to_ctex_format ( f , p_images [ i ] , ResourceImporterTexture : : CompressMode ( p_compress_mode ) , used_channels , p_vram_compression , p_lossy ) ;
2018-08-06 19:56:06 +02:00
}
2020-09-09 17:40:51 +02:00
for ( int i = 0 ; i < mipmap_images . size ( ) ; i + + ) {
2022-03-10 04:22:36 +01:00
ResourceImporterTexture : : save_to_ctex_format ( f , mipmap_images [ i ] , ResourceImporterTexture : : CompressMode ( p_compress_mode ) , used_channels , p_vram_compression , p_lossy ) ;
2020-09-09 17:40:51 +02:00
}
2018-08-06 19:56:06 +02:00
}
2022-05-13 15:04:37 +02:00
Error ResourceImporterLayeredTexture : : import ( const String & p_source_file , const String & p_save_path , const HashMap < StringName , Variant > & p_options , List < String > * r_platform_variants , List < String > * r_gen_files , Variant * r_metadata ) {
2018-08-06 19:56:06 +02:00
int compress_mode = p_options [ " compress/mode " ] ;
2020-05-01 14:34:23 +02:00
float lossy = p_options [ " compress/lossy_quality " ] ;
int hdr_compression = p_options [ " compress/hdr_compression " ] ;
int bptc_ldr = p_options [ " compress/bptc_ldr " ] ;
bool mipmaps = p_options [ " mipmaps/generate " ] ;
2019-06-11 20:43:37 +02:00
int channel_pack = p_options [ " compress/channel_pack " ] ;
int hslices = ( p_options . has ( " slices/horizontal " ) ) ? int ( p_options [ " slices/horizontal " ] ) : 0 ;
int vslices = ( p_options . has ( " slices/vertical " ) ) ? int ( p_options [ " slices/vertical " ] ) : 0 ;
2020-05-01 14:34:23 +02:00
int arrangement = ( p_options . has ( " slices/arrangement " ) ) ? int ( p_options [ " slices/arrangement " ] ) : 0 ;
int layout = ( p_options . has ( " slices/layout " ) ) ? int ( p_options [ " slices/layout " ] ) : 0 ;
int amount = ( p_options . has ( " slices/amount " ) ) ? int ( p_options [ " slices/amount " ] ) : 0 ;
if ( mode = = MODE_CUBEMAP | | mode = = MODE_CUBEMAP_ARRAY ) {
switch ( arrangement ) {
case CUBEMAP_FORMAT_1X6 : {
hslices = 1 ;
vslices = 6 ;
} break ;
case CUBEMAP_FORMAT_2X3 : {
hslices = 2 ;
vslices = 3 ;
} break ;
case CUBEMAP_FORMAT_3X2 : {
hslices = 3 ;
vslices = 2 ;
} break ;
case CUBEMAP_FORMAT_6X1 : {
hslices = 6 ;
vslices = 1 ;
} break ;
}
2019-06-11 20:43:37 +02:00
2020-05-01 14:34:23 +02:00
if ( mode = = MODE_CUBEMAP_ARRAY ) {
if ( layout = = 0 ) {
hslices * = amount ;
} else {
vslices * = amount ;
}
}
2019-06-11 20:43:37 +02:00
}
2018-08-06 19:56:06 +02:00
Ref < Image > image ;
2021-06-18 00:03:09 +02:00
image . instantiate ( ) ;
2022-08-23 12:25:14 +02:00
Error err = ImageLoader : : load_image ( p_source_file , image ) ;
2020-05-14 16:41:43 +02:00
if ( err ! = OK ) {
2018-08-06 19:56:06 +02:00
return err ;
2020-05-14 16:41:43 +02:00
}
2018-08-06 19:56:06 +02:00
2020-05-01 14:34:23 +02:00
if ( compress_mode = = COMPRESS_BASIS_UNIVERSAL & & image - > get_format ( ) > = Image : : FORMAT_RF ) {
//basis universal does not support float formats, fall back
compress_mode = COMPRESS_VRAM_COMPRESSED ;
2019-06-11 20:43:37 +02:00
}
2018-08-06 19:56:06 +02:00
2020-05-01 14:34:23 +02:00
if ( compress_mode = = COMPRESS_VRAM_COMPRESSED ) {
mipmaps = true ;
2018-08-06 19:56:06 +02:00
//if using video ram, optimize
2019-06-11 20:43:37 +02:00
if ( channel_pack = = 0 ) {
2018-08-06 19:56:06 +02:00
//remove alpha if not needed, so compression is more efficient
if ( image - > get_format ( ) = = Image : : FORMAT_RGBA8 & & ! image - > detect_alpha ( ) ) {
image - > convert ( Image : : FORMAT_RGB8 ) ;
}
2020-05-01 14:34:23 +02:00
} else if ( image - > get_format ( ) < Image : : FORMAT_RGBA8 ) {
2018-08-06 19:56:06 +02:00
image - > optimize_channels ( ) ;
}
}
2020-05-01 14:34:23 +02:00
Image : : CompressSource csource = Image : : COMPRESS_SOURCE_GENERIC ;
if ( channel_pack = = 0 ) {
csource = Image : : COMPRESS_SOURCE_SRGB ;
2021-08-29 10:19:45 +02:00
} else if ( channel_pack = = 2 ) {
// force normal
csource = Image : : COMPRESS_SOURCE_NORMAL ;
2020-05-01 14:34:23 +02:00
}
Image : : UsedChannels used_channels = image - > detect_used_channels ( csource ) ;
Vector < Ref < Image > > slices ;
int slice_w = image - > get_width ( ) / hslices ;
int slice_h = image - > get_height ( ) / vslices ;
2018-08-06 19:56:06 +02:00
for ( int i = 0 ; i < vslices ; i + + ) {
for ( int j = 0 ; j < hslices ; j + + ) {
int x = slice_w * j ;
int y = slice_h * i ;
2022-07-09 22:43:34 +02:00
Ref < Image > slice = image - > get_rect ( Rect2i ( x , y , slice_w , slice_h ) ) ;
2020-12-15 13:04:21 +01:00
ERR_CONTINUE ( slice . is_null ( ) | | slice - > is_empty ( ) ) ;
2018-08-06 19:56:06 +02:00
if ( slice - > get_width ( ) ! = slice_w | | slice - > get_height ( ) ! = slice_h ) {
slice - > resize ( slice_w , slice_h ) ;
}
slices . push_back ( slice ) ;
}
}
2019-02-26 22:43:37 +01:00
Array formats_imported ;
2022-01-18 13:39:55 +01:00
Ref < LayeredTextureImport > texture_import ;
texture_import . instantiate ( ) ;
texture_import - > csource = & csource ;
texture_import - > save_path = p_save_path ;
texture_import - > options = p_options ;
texture_import - > platform_variants = r_platform_variants ;
texture_import - > image = image ;
texture_import - > formats_imported = formats_imported ;
texture_import - > slices = & slices ;
texture_import - > compress_mode = compress_mode ;
texture_import - > lossy = lossy ;
texture_import - > hdr_compression = hdr_compression ;
texture_import - > bptc_ldr = bptc_ldr ;
texture_import - > mipmaps = mipmaps ;
texture_import - > used_channels = used_channels ;
2022-04-16 13:09:49 +02:00
_check_compress_ctex ( p_source_file , texture_import ) ;
2019-02-26 22:43:37 +01:00
if ( r_metadata ) {
2022-09-29 11:53:28 +02:00
Dictionary meta ;
meta [ " vram_texture " ] = compress_mode = = COMPRESS_VRAM_COMPRESSED ;
2019-02-26 22:43:37 +01:00
if ( formats_imported . size ( ) ) {
2022-09-29 11:53:28 +02:00
meta [ " imported_formats " ] = formats_imported ;
2019-02-26 22:43:37 +01:00
}
2022-09-29 11:53:28 +02:00
* r_metadata = meta ;
2019-02-26 22:43:37 +01:00
}
2018-08-06 19:56:06 +02:00
return OK ;
}
2019-02-26 22:43:37 +01:00
const char * ResourceImporterLayeredTexture : : compression_formats [ ] = {
" bptc " ,
" s3tc " ,
" etc " ,
" etc2 " ,
2020-04-02 01:20:12 +02:00
nullptr
2019-02-26 22:43:37 +01:00
} ;
String ResourceImporterLayeredTexture : : get_import_settings_string ( ) const {
String s ;
int index = 0 ;
while ( compression_formats [ index ] ) {
2021-02-17 17:44:49 +01:00
String setting_path = " rendering/textures/vram_compression/import_ " + String ( compression_formats [ index ] ) ;
2022-10-18 16:43:37 +02:00
bool test = GLOBAL_GET ( setting_path ) ;
2019-02-26 22:43:37 +01:00
if ( test ) {
s + = String ( compression_formats [ index ] ) ;
}
index + + ;
}
return s ;
}
bool ResourceImporterLayeredTexture : : are_import_settings_valid ( const String & p_path ) const {
//will become invalid if formats are missing to import
2022-09-29 11:53:28 +02:00
Dictionary meta = ResourceFormatImporter : : get_singleton ( ) - > get_resource_metadata ( p_path ) ;
2019-02-26 22:43:37 +01:00
2022-09-29 11:53:28 +02:00
if ( ! meta . has ( " vram_texture " ) ) {
2019-02-26 22:43:37 +01:00
return false ;
}
2022-09-29 11:53:28 +02:00
bool vram = meta [ " vram_texture " ] ;
2019-02-26 22:43:37 +01:00
if ( ! vram ) {
return true ; //do not care about non vram
}
Vector < String > formats_imported ;
2022-09-29 11:53:28 +02:00
if ( meta . has ( " imported_formats " ) ) {
formats_imported = meta [ " imported_formats " ] ;
2019-02-26 22:43:37 +01:00
}
int index = 0 ;
bool valid = true ;
while ( compression_formats [ index ] ) {
2021-02-17 17:44:49 +01:00
String setting_path = " rendering/textures/vram_compression/import_ " + String ( compression_formats [ index ] ) ;
2022-10-18 16:43:37 +02:00
bool test = GLOBAL_GET ( setting_path ) ;
2019-02-26 22:43:37 +01:00
if ( test ) {
2022-02-01 19:19:13 +01:00
if ( ! formats_imported . has ( compression_formats [ index ] ) ) {
2019-02-26 22:43:37 +01:00
valid = false ;
break ;
}
}
index + + ;
}
return valid ;
}
2020-04-02 01:20:12 +02:00
ResourceImporterLayeredTexture * ResourceImporterLayeredTexture : : singleton = nullptr ;
2018-08-06 19:56:06 +02:00
ResourceImporterLayeredTexture : : ResourceImporterLayeredTexture ( ) {
singleton = this ;
2019-06-11 20:43:37 +02:00
mode = MODE_CUBEMAP ;
2018-08-06 19:56:06 +02:00
}
ResourceImporterLayeredTexture : : ~ ResourceImporterLayeredTexture ( ) {
}
2022-01-18 13:39:55 +01:00
2022-04-16 13:09:49 +02:00
void ResourceImporterLayeredTexture : : _check_compress_ctex ( const String & p_source_file , Ref < LayeredTextureImport > r_texture_import ) {
2022-01-18 13:39:55 +01:00
String extension = get_save_extension ( ) ;
ERR_FAIL_NULL ( r_texture_import - > csource ) ;
if ( r_texture_import - > compress_mode ! = COMPRESS_VRAM_COMPRESSED ) {
// Import normally.
_save_tex ( * r_texture_import - > slices , r_texture_import - > save_path + " . " + extension , r_texture_import - > compress_mode , r_texture_import - > lossy , Image : : COMPRESS_S3TC /* IGNORED */ , * r_texture_import - > csource , r_texture_import - > used_channels , r_texture_import - > mipmaps , false ) ;
return ;
}
// Must import in all formats, in order of priority (so platform choses the best supported one. IE, etc2 over etc).
// Android, GLES 2.x
2022-10-18 16:43:37 +02:00
bool can_bptc = GLOBAL_GET ( " rendering/textures/vram_compression/import_bptc " ) ;
2022-01-18 13:39:55 +01:00
if ( can_bptc ) {
r_texture_import - > formats_imported . push_back ( " bptc " ) ; // BPTC needs to be added anyway.
}
bool can_compress_hdr = r_texture_import - > hdr_compression > 0 ;
ERR_FAIL_NULL ( r_texture_import - > image ) ;
bool is_hdr = ( r_texture_import - > image - > get_format ( ) > = Image : : FORMAT_RF & & r_texture_import - > image - > get_format ( ) < = Image : : FORMAT_RGBE9995 ) ;
bool is_ldr = ( r_texture_import - > image - > get_format ( ) > = Image : : FORMAT_L8 & & r_texture_import - > image - > get_format ( ) < = Image : : FORMAT_RGB565 ) ;
2022-10-18 16:43:37 +02:00
bool can_s3tc = GLOBAL_GET ( " rendering/textures/vram_compression/import_s3tc " ) ;
2022-01-18 13:39:55 +01:00
ERR_FAIL_NULL ( r_texture_import - > slices ) ;
// Can compress hdr, but hdr with alpha is not compressible.
if ( r_texture_import - > hdr_compression = = 2 ) {
// The user selected to compress hdr anyway, so force an alpha-less format.
if ( r_texture_import - > image - > get_format ( ) = = Image : : FORMAT_RGBAF ) {
for ( int i = 0 ; i < r_texture_import - > slices - > size ( ) ; i + + ) {
r_texture_import - > slices - > write [ i ] - > convert ( Image : : FORMAT_RGBF ) ;
}
} else if ( r_texture_import - > image - > get_format ( ) = = Image : : FORMAT_RGBAH ) {
for ( int i = 0 ; i < r_texture_import - > slices - > size ( ) ; i + + ) {
r_texture_import - > slices - > write [ i ] - > convert ( Image : : FORMAT_RGBH ) ;
}
}
} else {
can_compress_hdr = false ;
}
if ( is_hdr & & can_compress_hdr ) {
if ( ! can_bptc ) {
//default to rgbe
if ( r_texture_import - > image - > get_format ( ) ! = Image : : FORMAT_RGBE9995 ) {
for ( int i = 0 ; i < r_texture_import - > slices - > size ( ) ; i + + ) {
r_texture_import - > slices - > write [ i ] - > convert ( Image : : FORMAT_RGBE9995 ) ;
}
}
}
} else {
can_bptc = false ;
}
if ( is_ldr & & can_bptc ) {
if ( r_texture_import - > bptc_ldr = = 0 | | ( r_texture_import - > bptc_ldr = = 1 & & ! ( r_texture_import - > used_channels = = Image : : USED_CHANNELS_LA | | r_texture_import - > used_channels = = Image : : USED_CHANNELS_RGBA ) ) ) {
can_bptc = false ;
}
}
if ( ! ( r_texture_import - > used_channels = = Image : : USED_CHANNELS_LA | | r_texture_import - > used_channels = = Image : : USED_CHANNELS_RGBA ) ) {
2022-10-18 16:43:37 +02:00
if ( GLOBAL_GET ( " rendering/textures/vram_compression/import_etc2 " ) ) {
2022-01-18 13:39:55 +01:00
_save_tex ( * r_texture_import - > slices , r_texture_import - > save_path + " .etc2. " + extension , r_texture_import - > compress_mode , r_texture_import - > lossy , Image : : COMPRESS_ETC2 , * r_texture_import - > csource , r_texture_import - > used_channels , r_texture_import - > mipmaps , true ) ;
r_texture_import - > platform_variants - > push_back ( " etc2 " ) ;
r_texture_import - > formats_imported . push_back ( " etc2 " ) ;
}
if ( can_bptc | | can_s3tc ) {
_save_tex ( * r_texture_import - > slices , r_texture_import - > save_path + " .s3tc. " + extension , r_texture_import - > compress_mode , r_texture_import - > lossy , can_bptc ? Image : : COMPRESS_BPTC : Image : : COMPRESS_S3TC , * r_texture_import - > csource , r_texture_import - > used_channels , r_texture_import - > mipmaps , false ) ;
r_texture_import - > platform_variants - > push_back ( " s3tc " ) ;
r_texture_import - > formats_imported . push_back ( " s3tc " ) ;
}
return ;
}
2022-04-16 13:09:49 +02:00
EditorNode : : add_io_error ( vformat ( TTR ( " %s: No suitable PC VRAM compression algorithm enabled in Project Settings (S3TC or BPTC). This texture may not display correctly on desktop platforms. " ) , p_source_file ) ) ;
2022-01-18 13:39:55 +01:00
}