2014-02-10 01:10:30 +00:00
/*************************************************************************/
/* resource_format_image.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
2017-08-27 12:11:45 +00:00
/* https://godotengine.org */
2014-02-10 01:10:30 +00:00
/*************************************************************************/
2018-01-02 10:27:24 +00:00
/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
2014-02-10 01:10:30 +00: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. */
/*************************************************************************/
# include "resource_format_image.h"
# include "globals.h"
2017-03-18 23:36:26 +00:00
# include "io/image_loader.h"
2014-02-10 01:10:30 +00:00
# include "os/os.h"
2017-03-18 23:36:26 +00:00
# include "scene/resources/texture.h"
RES ResourceFormatLoaderImage : : load ( const String & p_path , const String & p_original_path , Error * r_error ) {
2016-03-08 23:00:52 +00:00
2015-08-23 23:15:56 +00:00
if ( r_error )
2017-03-18 23:36:26 +00:00
* r_error = ERR_CANT_OPEN ;
2015-08-23 23:15:56 +00:00
2017-03-18 23:36:26 +00:00
if ( p_path . extension ( ) = = " cube " ) {
2014-02-10 01:10:30 +00:00
// open as cubemap txture
2017-03-18 23:36:26 +00:00
CubeMap * ptr = memnew ( CubeMap ) ;
Ref < CubeMap > cubemap ( ptr ) ;
2014-02-10 01:10:30 +00:00
Error err ;
2017-03-18 23:36:26 +00:00
FileAccess * f = FileAccess : : open ( p_path , FileAccess : : READ , & err ) ;
2014-02-10 01:10:30 +00:00
if ( err ) {
2016-03-08 23:00:52 +00:00
2017-03-18 23:36:26 +00:00
ERR_FAIL_COND_V ( err , RES ( ) ) ;
2014-02-10 01:10:30 +00:00
}
2016-03-08 23:00:52 +00:00
2017-03-18 23:36:26 +00:00
String base_path = p_path . substr ( 0 , p_path . find_last ( " / " ) + 1 ) ;
2014-02-10 01:10:30 +00:00
2017-03-18 23:36:26 +00:00
for ( int i = 0 ; i < 6 ; i + + ) {
2016-03-08 23:00:52 +00:00
2014-02-10 01:10:30 +00:00
String file = f - > get_line ( ) . strip_edges ( ) ;
Image image ;
2016-03-08 23:00:52 +00:00
2017-03-18 23:36:26 +00:00
Error err = ImageLoader : : load_image ( base_path + file , & image ) ;
2016-03-08 23:00:52 +00:00
2014-02-10 01:10:30 +00:00
if ( err ) {
2016-03-08 23:00:52 +00:00
2014-02-10 01:10:30 +00:00
memdelete ( f ) ;
2017-03-18 23:36:26 +00:00
ERR_FAIL_COND_V ( err , RES ( ) ) ;
2014-02-10 01:10:30 +00:00
}
2016-03-08 23:00:52 +00:00
2017-03-18 23:36:26 +00:00
if ( i = = 0 ) {
2016-03-08 23:00:52 +00:00
2014-02-10 01:10:30 +00:00
//cubemap->create(image.get_width(),image.get_height(),image.get_format(),Texture::FLAGS_DEFAULT|Texture::FLAG_CUBEMAP);
}
2016-03-08 23:00:52 +00:00
2017-03-18 23:36:26 +00:00
static const CubeMap : : Side cube_side [ 6 ] = {
2014-02-10 01:10:30 +00:00
CubeMap : : SIDE_LEFT ,
CubeMap : : SIDE_RIGHT ,
CubeMap : : SIDE_BOTTOM ,
CubeMap : : SIDE_TOP ,
CubeMap : : SIDE_FRONT ,
CubeMap : : SIDE_BACK
} ;
2016-03-08 23:00:52 +00:00
2017-03-18 23:36:26 +00:00
cubemap - > set_side ( cube_side [ i ] , image ) ;
2014-02-10 01:10:30 +00:00
}
2016-03-08 23:00:52 +00:00
2014-02-10 01:10:30 +00:00
memdelete ( f ) ;
cubemap - > set_name ( p_path . get_file ( ) ) ;
2015-08-23 23:15:56 +00:00
if ( r_error )
2017-03-18 23:36:26 +00:00
* r_error = OK ;
2014-02-10 01:10:30 +00:00
return cubemap ;
2016-03-08 23:00:52 +00:00
2014-02-10 01:10:30 +00:00
} else {
2016-03-08 23:00:52 +00:00
// simple image
2014-02-10 01:10:30 +00:00
2017-03-18 23:36:26 +00:00
ImageTexture * ptr = memnew ( ImageTexture ) ;
Ref < ImageTexture > texture ( ptr ) ;
2014-02-10 01:10:30 +00:00
uint64_t begtime ;
double total ;
Image image ;
if ( debug_load_times )
2017-03-18 23:36:26 +00:00
begtime = OS : : get_singleton ( ) - > get_ticks_usec ( ) ;
2014-02-10 01:10:30 +00:00
2017-03-18 23:36:26 +00:00
Error err = ImageLoader : : load_image ( p_path , & image ) ;
2014-02-10 01:10:30 +00:00
if ( ! err & & debug_load_times ) {
2017-03-18 23:36:26 +00:00
double total = USEC_TO_SEC ( ( OS : : get_singleton ( ) - > get_ticks_usec ( ) - begtime ) ) ;
2017-12-11 15:59:59 +00:00
print_line ( " Image: " + itos ( image . get_width ( ) ) + " x " + itos ( image . get_height ( ) ) ) ;
2017-03-18 23:36:26 +00:00
print_line ( " -load: " + rtos ( total ) ) ;
2014-02-10 01:10:30 +00:00
}
2017-03-18 23:36:26 +00:00
ERR_EXPLAIN ( " Failed loading image: " + p_path ) ;
2016-03-08 23:00:52 +00:00
ERR_FAIL_COND_V ( err , RES ( ) ) ;
2015-08-23 23:15:56 +00:00
if ( r_error )
2017-03-18 23:36:26 +00:00
* r_error = ERR_FILE_CORRUPT ;
2014-02-10 01:10:30 +00:00
# ifdef DEBUG_ENABLED
# ifdef TOOLS_ENABLED
if ( max_texture_size & & ( image . get_width ( ) > max_texture_size | | image . get_height ( ) > max_texture_size ) ) {
if ( bool ( Globals : : get_singleton ( ) - > get ( " debug/max_texture_size_alert " ) ) ) {
2017-03-18 23:36:26 +00:00
OS : : get_singleton ( ) - > alert ( " Texture is too large: ' " + p_path + " ', at " + itos ( image . get_width ( ) ) + " x " + itos ( image . get_height ( ) ) + " . Max allowed size is: " + itos ( max_texture_size ) + " x " + itos ( max_texture_size ) + " . " , " BAD ARTIST, NO COOKIE! " ) ;
2014-02-10 01:10:30 +00:00
}
2017-03-18 23:36:26 +00:00
ERR_EXPLAIN ( " Texture is too large: ' " + p_path + " ', at " + itos ( image . get_width ( ) ) + " x " + itos ( image . get_height ( ) ) + " . Max allowed size is: " + itos ( max_texture_size ) + " x " + itos ( max_texture_size ) + " . " ) ;
2014-02-10 01:10:30 +00:00
ERR_FAIL_V ( RES ( ) ) ;
}
# endif
# endif
2016-03-08 23:00:52 +00:00
2017-03-18 23:36:26 +00:00
uint32_t flags = load_image_flags ( p_path ) ;
2014-02-10 01:10:30 +00:00
if ( debug_load_times )
2017-03-18 23:36:26 +00:00
begtime = OS : : get_singleton ( ) - > get_ticks_usec ( ) ;
2014-02-10 01:10:30 +00:00
//print_line("img: "+p_path+" flags: "+itos(flags));
2017-03-18 23:36:26 +00:00
texture - > create_from_image ( image , flags ) ;
2014-02-10 01:10:30 +00:00
texture - > set_name ( p_path . get_file ( ) ) ;
if ( debug_load_times ) {
2017-03-18 23:36:26 +00:00
total = USEC_TO_SEC ( OS : : get_singleton ( ) - > get_ticks_usec ( ) - begtime ) ;
print_line ( " -make texture: " + rtos ( total ) ) ;
2014-02-10 01:10:30 +00:00
}
2015-08-23 23:15:56 +00:00
if ( r_error )
2017-03-18 23:36:26 +00:00
* r_error = OK ;
2015-08-23 23:15:56 +00:00
2017-03-18 23:36:26 +00:00
return RES ( texture ) ;
2014-02-10 01:10:30 +00:00
}
}
2016-09-30 08:49:55 +00:00
uint32_t ResourceFormatLoaderImage : : load_image_flags ( const String & p_path ) {
2017-03-18 23:36:26 +00:00
FileAccess * f2 = FileAccess : : open ( p_path + " .flags " , FileAccess : : READ ) ;
Map < String , bool > flags_found ;
2016-09-30 08:49:55 +00:00
if ( f2 ) {
2017-03-18 23:36:26 +00:00
while ( ! f2 - > eof_reached ( ) ) {
2016-09-30 08:49:55 +00:00
String l2 = f2 - > get_line ( ) ;
int eqpos = l2 . find ( " = " ) ;
2017-03-18 23:36:26 +00:00
if ( eqpos ! = - 1 ) {
String flag = l2 . substr ( 0 , eqpos ) . strip_edges ( ) ;
String val = l2 . substr ( eqpos + 1 , l2 . length ( ) ) . strip_edges ( ) . to_lower ( ) ;
flags_found [ flag ] = ( val = = " true " | | val = = " 1 " ) ? true : false ;
2016-09-30 08:49:55 +00:00
}
}
memdelete ( f2 ) ;
}
2017-03-18 23:36:26 +00:00
uint32_t flags = 0 ;
2016-09-30 08:49:55 +00:00
if ( flags_found . has ( " filter " ) ) {
if ( flags_found [ " filter " ] )
2017-03-18 23:36:26 +00:00
flags | = Texture : : FLAG_FILTER ;
} else if ( bool ( GLOBAL_DEF ( " image_loader/filter " , true ) ) ) {
flags | = Texture : : FLAG_FILTER ;
2016-09-30 08:49:55 +00:00
}
if ( flags_found . has ( " gen_mipmaps " ) ) {
if ( flags_found [ " gen_mipmaps " ] )
2017-03-18 23:36:26 +00:00
flags | = Texture : : FLAG_MIPMAPS ;
} else if ( bool ( GLOBAL_DEF ( " image_loader/gen_mipmaps " , true ) ) ) {
flags | = Texture : : FLAG_MIPMAPS ;
2016-09-30 08:49:55 +00:00
}
if ( flags_found . has ( " repeat " ) ) {
if ( flags_found [ " repeat " ] )
2017-03-18 23:36:26 +00:00
flags | = Texture : : FLAG_REPEAT ;
} else if ( bool ( GLOBAL_DEF ( " image_loader/repeat " , true ) ) ) {
flags | = Texture : : FLAG_REPEAT ;
2016-09-30 08:49:55 +00:00
}
if ( flags_found . has ( " anisotropic " ) ) {
if ( flags_found [ " anisotropic " ] )
2017-03-18 23:36:26 +00:00
flags | = Texture : : FLAG_ANISOTROPIC_FILTER ;
2016-09-30 08:49:55 +00:00
}
if ( flags_found . has ( " tolinear " ) ) {
if ( flags_found [ " tolinear " ] )
2017-03-18 23:36:26 +00:00
flags | = Texture : : FLAG_CONVERT_TO_LINEAR ;
2016-09-30 08:49:55 +00:00
}
if ( flags_found . has ( " mirroredrepeat " ) ) {
if ( flags_found [ " mirroredrepeat " ] )
2017-03-18 23:36:26 +00:00
flags | = Texture : : FLAG_MIRRORED_REPEAT ;
2016-09-30 08:49:55 +00:00
}
return flags ;
}
2017-03-18 23:36:26 +00:00
bool ResourceFormatLoaderImage : : handles_type ( const String & p_type ) const {
2014-02-10 01:10:30 +00:00
2017-03-18 23:36:26 +00:00
return ObjectTypeDB : : is_type ( p_type , " Texture " ) | | ObjectTypeDB : : is_type ( p_type , " CubeMap " ) ;
2014-02-10 01:10:30 +00:00
}
void ResourceFormatLoaderImage : : get_recognized_extensions ( List < String > * p_extensions ) const {
2016-03-08 23:00:52 +00:00
2014-02-10 01:10:30 +00:00
ImageLoader : : get_recognized_extensions ( p_extensions ) ;
p_extensions - > push_back ( " cube " ) ;
}
String ResourceFormatLoaderImage : : get_resource_type ( const String & p_path ) const {
2017-03-18 23:36:26 +00:00
String ext = p_path . extension ( ) . to_lower ( ) ;
if ( ext = = " cube " )
2014-02-10 01:10:30 +00:00
return " CubeMap " ;
List < String > extensions ;
ImageLoader : : get_recognized_extensions ( & extensions ) ;
2017-03-18 23:36:26 +00:00
for ( List < String > : : Element * E = extensions . front ( ) ; E ; E = E - > next ( ) ) {
if ( E - > get ( ) = = ext )
2014-02-10 01:10:30 +00:00
return " ImageTexture " ;
}
return " " ;
}
ResourceFormatLoaderImage : : ResourceFormatLoaderImage ( ) {
2017-03-18 23:36:26 +00:00
max_texture_size = GLOBAL_DEF ( " debug/max_texture_size " , 0 ) ;
GLOBAL_DEF ( " debug/max_texture_size_alert " , false ) ;
debug_load_times = GLOBAL_DEF ( " debug/image_load_times " , false ) ;
GLOBAL_DEF ( " image_loader/filter " , true ) ;
GLOBAL_DEF ( " image_loader/gen_mipmaps " , true ) ;
GLOBAL_DEF ( " image_loader/repeat " , false ) ;
2014-02-10 01:10:30 +00:00
}