diff --git a/core/io/image.cpp b/core/io/image.cpp index f80552d6ae4..199871ba970 100644 --- a/core/io/image.cpp +++ b/core/io/image.cpp @@ -2694,6 +2694,19 @@ Error Image::decompress() { return OK; } +bool Image::can_decompress(const String &p_format_tag) { + if (p_format_tag == "astc") { + return _image_decompress_astc != nullptr; + } else if (p_format_tag == "bptc") { + return _image_decompress_bptc != nullptr; + } else if (p_format_tag == "etc2") { + return _image_decompress_etc2 != nullptr; + } else if (p_format_tag == "s3tc") { + return _image_decompress_bc != nullptr; + } + return false; +} + Error Image::compress(CompressMode p_mode, CompressSource p_source, ASTCFormat p_astc_format) { ERR_FAIL_INDEX_V_MSG(p_mode, COMPRESS_MAX, ERR_INVALID_PARAMETER, "Invalid compress mode."); ERR_FAIL_INDEX_V_MSG(p_source, COMPRESS_SOURCE_MAX, ERR_INVALID_PARAMETER, "Invalid compress source."); diff --git a/core/io/image.h b/core/io/image.h index 85b4c86dc5d..3cb57a3a01c 100644 --- a/core/io/image.h +++ b/core/io/image.h @@ -379,6 +379,8 @@ public: bool is_compressed() const; static bool is_format_compressed(Format p_format); + static bool can_decompress(const String &p_format_tag); + void fix_alpha_edges(); void premultiply_alpha(); void srgb_to_linear(); diff --git a/core/io/resource_importer.cpp b/core/io/resource_importer.cpp index b7a14f2b880..a36d0bf9886 100644 --- a/core/io/resource_importer.cpp +++ b/core/io/resource_importer.cpp @@ -32,6 +32,7 @@ #include "core/config/project_settings.h" #include "core/io/config_file.h" +#include "core/io/image.h" #include "core/os/os.h" #include "core/variant/variant_parser.h" @@ -41,7 +42,7 @@ bool ResourceFormatImporter::SortImporterByName::operator()(const Refget_importer_name() < p_b->get_importer_name(); } -Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndType &r_path_and_type, bool *r_valid) const { +Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndType &r_path_and_type, bool p_load, bool *r_valid) const { Error err; Ref f = FileAccess::open(p_path + ".import", FileAccess::READ, &err); @@ -65,7 +66,10 @@ Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndTy int lines = 0; String error_text; - bool path_found = false; //first match must have priority + bool path_found = false; // First match must have priority. + + String decomp_path; + bool decomp_path_found = false; while (true) { assign = Variant(); next_tag.fields.clear(); @@ -73,6 +77,11 @@ Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndTy err = VariantParser::parse_tag_assign_eof(&stream, lines, error_text, next_tag, assign, value, nullptr, true); if (err == ERR_FILE_EOF) { + if (p_load && !path_found && decomp_path_found) { + print_verbose(vformat("No natively supported texture format found for %s, using decompressable format %s.", p_path, decomp_path)); + r_path_and_type.path = decomp_path; + } + return OK; } else if (err != OK) { ERR_PRINT(vformat("ResourceFormatImporter::load - %s.import:%d error: %s.", p_path, lines, error_text)); @@ -84,12 +93,15 @@ Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndTy String feature = assign.get_slicec('.', 1); if (OS::get_singleton()->has_feature(feature)) { r_path_and_type.path = value; - path_found = true; //first match must have priority + path_found = true; // First match must have priority. + } else if (p_load && Image::can_decompress(feature) && !decomp_path_found) { // When loading, check for decompressable formats and use first one found if nothing else is supported. + decomp_path = value; + decomp_path_found = true; // First match must have priority. } } else if (!path_found && assign == "path") { r_path_and_type.path = value; - path_found = true; //first match must have priority + path_found = true; // First match must have priority. } else if (assign == "type") { r_path_and_type.type = ClassDB::get_compatibility_remapped_class(value); } else if (assign == "importer") { @@ -154,7 +166,7 @@ Ref ResourceFormatImporter::load(const String &p_path, const String &p Ref ResourceFormatImporter::load_internal(const String &p_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode, bool p_silence_errors) { PathAndType pat; - Error err = _get_path_and_type(p_path, pat); + Error err = _get_path_and_type(p_path, pat, true); if (err != OK) { if (r_error) { @@ -244,7 +256,7 @@ Error ResourceFormatImporter::get_import_order_threads_and_importer(const String if (FileAccess::exists(p_path + ".import")) { PathAndType pat; - Error err = _get_path_and_type(p_path, pat); + Error err = _get_path_and_type(p_path, pat, false); if (err == OK) { importer = get_importer_by_name(pat.importer); @@ -268,7 +280,7 @@ int ResourceFormatImporter::get_import_order(const String &p_path) const { if (FileAccess::exists(p_path + ".import")) { PathAndType pat; - Error err = _get_path_and_type(p_path, pat); + Error err = _get_path_and_type(p_path, pat, false); if (err == OK) { importer = get_importer_by_name(pat.importer); @@ -300,7 +312,7 @@ bool ResourceFormatImporter::handles_type(const String &p_type) const { String ResourceFormatImporter::get_internal_resource_path(const String &p_path) const { PathAndType pat; - Error err = _get_path_and_type(p_path, pat); + Error err = _get_path_and_type(p_path, pat, false); if (err != OK) { return String(); @@ -354,20 +366,20 @@ void ResourceFormatImporter::get_internal_resource_path_list(const String &p_pat String ResourceFormatImporter::get_import_group_file(const String &p_path) const { bool valid = true; PathAndType pat; - _get_path_and_type(p_path, pat, &valid); + _get_path_and_type(p_path, pat, false, &valid); return valid ? pat.group_file : String(); } bool ResourceFormatImporter::is_import_valid(const String &p_path) const { bool valid = true; PathAndType pat; - _get_path_and_type(p_path, pat, &valid); + _get_path_and_type(p_path, pat, false, &valid); return valid; } String ResourceFormatImporter::get_resource_type(const String &p_path) const { PathAndType pat; - Error err = _get_path_and_type(p_path, pat); + Error err = _get_path_and_type(p_path, pat, false); if (err != OK) { return ""; @@ -378,7 +390,7 @@ String ResourceFormatImporter::get_resource_type(const String &p_path) const { ResourceUID::ID ResourceFormatImporter::get_resource_uid(const String &p_path) const { PathAndType pat; - Error err = _get_path_and_type(p_path, pat); + Error err = _get_path_and_type(p_path, pat, false); if (err != OK) { return ResourceUID::INVALID_ID; @@ -393,7 +405,7 @@ bool ResourceFormatImporter::has_custom_uid_support() const { Error ResourceFormatImporter::get_resource_import_info(const String &p_path, StringName &r_type, ResourceUID::ID &r_uid, String &r_import_group_file) const { PathAndType pat; - Error err = _get_path_and_type(p_path, pat); + Error err = _get_path_and_type(p_path, pat, false); if (err == OK) { r_type = pat.type; @@ -410,7 +422,7 @@ Error ResourceFormatImporter::get_resource_import_info(const String &p_path, Str Variant ResourceFormatImporter::get_resource_metadata(const String &p_path) const { PathAndType pat; - Error err = _get_path_and_type(p_path, pat); + Error err = _get_path_and_type(p_path, pat, false); if (err != OK) { return Variant(); @@ -420,7 +432,7 @@ Variant ResourceFormatImporter::get_resource_metadata(const String &p_path) cons } void ResourceFormatImporter::get_classes_used(const String &p_path, HashSet *r_classes) { PathAndType pat; - Error err = _get_path_and_type(p_path, pat); + Error err = _get_path_and_type(p_path, pat, false); if (err != OK) { return; @@ -431,7 +443,7 @@ void ResourceFormatImporter::get_classes_used(const String &p_path, HashSet *p_dependencies, bool p_add_types) { PathAndType pat; - Error err = _get_path_and_type(p_path, pat); + Error err = _get_path_and_type(p_path, pat, false); if (err != OK) { return; @@ -503,7 +515,7 @@ String ResourceFormatImporter::get_import_base_path(const String &p_for_file) co bool ResourceFormatImporter::are_import_settings_valid(const String &p_path) const { bool valid = true; PathAndType pat; - _get_path_and_type(p_path, pat, &valid); + _get_path_and_type(p_path, pat, false, &valid); if (!valid) { return false; diff --git a/core/io/resource_importer.h b/core/io/resource_importer.h index 4b272602e23..b8788719142 100644 --- a/core/io/resource_importer.h +++ b/core/io/resource_importer.h @@ -48,7 +48,7 @@ class ResourceFormatImporter : public ResourceFormatLoader { ResourceUID::ID uid = ResourceUID::INVALID_ID; }; - Error _get_path_and_type(const String &p_path, PathAndType &r_path_and_type, bool *r_valid = nullptr) const; + Error _get_path_and_type(const String &p_path, PathAndType &r_path_and_type, bool p_load, bool *r_valid = nullptr) const; static ResourceFormatImporter *singleton;