diff --git a/compat/image_enum_compat.cpp b/compat/image_enum_compat.cpp index 4aabdc545..6a8a7f07d 100644 --- a/compat/image_enum_compat.cpp +++ b/compat/image_enum_compat.cpp @@ -204,6 +204,15 @@ String ImageEnumCompat::get_v3_format_name(V3Image::Format p_format) { return v3_format_names[p_format]; } +V3Image::Format ImageEnumCompat::get_v3_format_enum_from_name(String p_format) { + for (int i = 0; i < V3Image::FORMAT_MAX; i++) { + if (v3_format_names[i] == p_format) { + return V3Image::Format(i); + } + } + return V3Image::FORMAT_MAX; +} + String ImageEnumCompat::get_v3_format_identifier(V3Image::Format p_format) { ERR_FAIL_INDEX_V(p_format, V3Image::FORMAT_MAX, String()); return v3_format_identifiers[p_format]; diff --git a/compat/image_enum_compat.h b/compat/image_enum_compat.h index 3ff92d807..144ac4398 100644 --- a/compat/image_enum_compat.h +++ b/compat/image_enum_compat.h @@ -82,8 +82,11 @@ class ImageEnumCompat { static String get_v2_format_name(V2Image::Format p_format); static String get_v2_format_identifier(V2Image::Format p_format); static String get_v2_format_identifier_pcfg(V2Image::Format p_format, int p_img_size); + static String get_v3_format_name(V3Image::Format p_format); static String get_v3_format_identifier(V3Image::Format p_format); + static V3Image::Format get_v3_format_enum_from_name(String p_format); + static String get_v4_format_identifier(Image::Format p_format); static Image::Format convert_image_format_enum_v3_to_v4(V3Image::Format fmt); diff --git a/compat/texture_loader_compat.cpp b/compat/texture_loader_compat.cpp index b954f5361..c6cbba632 100644 --- a/compat/texture_loader_compat.cpp +++ b/compat/texture_loader_compat.cpp @@ -1,6 +1,7 @@ #include "texture_loader_compat.h" #include "compat/resource_compat_binary.h" #include "compat/resource_loader_compat.h" +#include "core/error/error_list.h" #include "core/error/error_macros.h" #include "core/io/missing_resource.h" #include "core/variant/dictionary.h" @@ -100,7 +101,15 @@ TextureLoaderCompat::TextureVersionType TextureLoaderCompat::recognize(const Str } return FORMAT_V4_IMAGE_TEXTURE; } else if (type == "AtlasTexture") { - return FORMAT_V2_ATLAS_TEXTURE; + switch (i_info.ver_major) { + case 1: + case 2: + return FORMAT_V2_ATLAS_TEXTURE; + case 3: + return FORMAT_V3_ATLAS_TEXTURE; + default: + return FORMAT_V4_ATLAS_TEXTURE; + } } else if (type == "LargeTexture") { return FORMAT_V2_LARGE_TEXTURE; } else if (type == "CubeMap") { @@ -119,11 +128,13 @@ int TextureLoaderCompat::get_ver_major_from_textype(TextureVersionType type) { case FORMAT_V2_LARGE_TEXTURE: case FORMAT_V2_CUBEMAP: return 2; + case FORMAT_V3_ATLAS_TEXTURE: case FORMAT_V3_IMAGE_TEXTURE: case FORMAT_V3_STREAM_TEXTURE2D: case FORMAT_V3_STREAM_TEXTURE3D: case FORMAT_V3_STREAM_TEXTUREARRAY: return 3; + case FORMAT_V4_ATLAS_TEXTURE: case FORMAT_V4_IMAGE_TEXTURE: case FORMAT_V4_COMPRESSED_TEXTURE2D: case FORMAT_V4_COMPRESSED_TEXTURE3D: @@ -155,12 +166,31 @@ TextureLoaderCompat::TextureType TextureLoaderCompat::get_type_enum_from_version case FORMAT_V4_IMAGE_TEXTURE: return TEXTURE_TYPE_2D; case FORMAT_V2_ATLAS_TEXTURE: + case FORMAT_V3_ATLAS_TEXTURE: + case FORMAT_V4_ATLAS_TEXTURE: return TEXTURE_TYPE_ATLAS; default: return TEXTURE_TYPE_UNKNOWN; } } +bool TextureLoaderCompat::is_binary_resource(TextureVersionType t) { + switch (t) { + case FORMAT_V2_TEXTURE: + case FORMAT_V2_IMAGE_TEXTURE: + case FORMAT_V2_ATLAS_TEXTURE: + case FORMAT_V2_LARGE_TEXTURE: + case FORMAT_V2_CUBEMAP: + case FORMAT_V3_IMAGE_TEXTURE: + case FORMAT_V4_IMAGE_TEXTURE: + case FORMAT_V3_ATLAS_TEXTURE: + case FORMAT_V4_ATLAS_TEXTURE: + return true; + default: + return false; + } +} + String TextureLoaderCompat::get_type_name_from_textype(TextureVersionType type) { switch (type) { case FORMAT_V2_TEXTURE: @@ -170,6 +200,8 @@ String TextureLoaderCompat::get_type_name_from_textype(TextureVersionType type) case FORMAT_V4_IMAGE_TEXTURE: return "ImageTexture"; case FORMAT_V2_ATLAS_TEXTURE: + case FORMAT_V3_ATLAS_TEXTURE: + case FORMAT_V4_ATLAS_TEXTURE: return "AtlasTexture"; case FORMAT_V2_LARGE_TEXTURE: return "LargeTexture"; @@ -685,28 +717,42 @@ Ref ResourceConverterTexture2D::convert(const Ref &re int th = 0; int tw_custom = 0; int th_custom = 0; - int flags; + int flags = 0; Ref image; + Ref image_res; Ref texture; Dictionary compat_dict = (res->get_meta("compat", Dictionary())); String type = res->get_original_class(); - if (type == "Texture" || type == "ImageTexture") { - name = ver_major == 2 ? res->get("resource/name") : res->get("resource_name"); - image = res->get("image"); + + auto convert_image = [&](const Ref &image_res) -> Ref { + Ref image = image_res; + if (image.is_null() && image_res->get_class() == "MissingResource") { + ImageConverterCompat ic; + if (ic.handles_type("Image", ver_major)) { + image = ic.convert(image_res, p_type, ver_major, r_error); + } + } + return image; + }; + if ((type == "Texture" && ver_major == 2) || type == "ImageTexture") { + name = get_resource_name(res, ver_major); + image = convert_image(res->get("image")); + ERR_FAIL_COND_V_MSG(image.is_null(), res, "Cannot load resource '" + name + "'."); + size = res->get("size"); flags = res->get("flags"); + bool mipmaps = flags & 1 || image->has_mipmaps(); - ERR_FAIL_COND_V_MSG(image.is_null(), Ref(), "Cannot load resource '" + name + "'."); image->set_name(name); tw = image->get_width(); th = image->get_height(); - if (tw != size.width) { + if (size.width && tw != size.width) { tw_custom = size.width; } - if (th != size.height) { + if (size.height && th != size.height) { th_custom = size.height; } - texture = ResourceFormatLoaderCompatTexture2D::_set_tex(res->get_path(), p_type, tw, th, tw_custom, th_custom, flags, image); + texture = TextureLoaderCompat::create_image_texture(res->get_path(), p_type, tw, th, tw_custom, th_custom, mipmaps, image); } else if (ver_major >= 3) { if (p_type == ResourceInfo::LoadType::NON_GLOBAL_LOAD) { return res; @@ -715,8 +761,12 @@ Ref ResourceConverterTexture2D::convert(const Ref &re String load_path = res->get("load_path"); ResourceFormatLoaderCompatTexture2D tlc; texture = tlc.custom_load(load_path, p_type, r_error); + } else { + ERR_FAIL_V_MSG(res, "Unsupported type: " + type); + } + if (compat_dict.size() > 0) { + texture->set_meta("compat", compat_dict); } - texture->set_meta("compat", compat_dict); return texture; } @@ -787,7 +837,7 @@ ResourceInfo TextureLoaderCompat::get_resource_info(const String &p_path, Error return ResourceInfo(); } int ver_major = TextureLoaderCompat::get_ver_major_from_textype(t); - if (ver_major == 2 || t == TextureLoaderCompat::FORMAT_V3_IMAGE_TEXTURE || t == TextureLoaderCompat::FORMAT_V4_IMAGE_TEXTURE) { + if (TextureLoaderCompat::is_binary_resource(t)) { ResourceFormatLoaderCompatBinary rlcb; return rlcb.get_resource_info(p_path, r_error); } @@ -813,7 +863,7 @@ Ref ResourceFormatLoaderCompatTexture2D::custom_load(const String &p_p Ref texture; Ref image; bool convert = false; - if (t == TextureLoaderCompat::FORMAT_V2_IMAGE_TEXTURE || t == TextureLoaderCompat::FORMAT_V2_TEXTURE || t == TextureLoaderCompat::FORMAT_V3_IMAGE_TEXTURE || t == TextureLoaderCompat::FORMAT_V4_IMAGE_TEXTURE) { + if (TextureLoaderCompat::is_binary_resource(t)) { convert = true; } else if (t == TextureLoaderCompat::FORMAT_V3_STREAM_TEXTURE2D) { err = TextureLoaderCompat::_load_data_stex2d_v3(p_path, lw, lh, lwc, lhc, lflags, image); @@ -1011,4 +1061,95 @@ Ref ResourceFormatLoaderCompatTextureLayered::custom_load(const String set_res_path(texture, res->get_path(), p_type); return texture; -} \ No newline at end of file +} + +bool ImageConverterCompat::handles_type(const String &p_type, int ver_major) const { + return (p_type == "Image") && ver_major == 3; +} + +Ref ImageConverterCompat::convert(const Ref &res, ResourceInfo::LoadType p_type, int ver_major, Error *r_error) { + String name; + Vector2 size; + Ref image; + Dictionary compat_dict = (res->get_meta("compat", Dictionary())); + String type = res->get_original_class(); + if (type != "Image") { + WARN_PRINT("ImageConverterCompat: Unsupported type: " + type); + return res; + } + name = get_resource_name(res, ver_major); + Dictionary data = res->get("data"); + int tw = data.get("width", 0); + int th = data.get("height", 0); + String format = data.get("format", ""); + auto fmt_enum = ImageEnumCompat::convert_image_format_enum_v3_to_v4(ImageEnumCompat::get_v3_format_enum_from_name(format)); + if (fmt_enum == Image::FORMAT_MAX) { + *r_error = ERR_UNAVAILABLE; + ERR_FAIL_V_MSG(res, "Deprecated v3 image format: " + format); + } + bool mipmaps = data.get("mipmaps", false); + Vector img_data = data.get("data", Vector()); + image = Image::create_from_data(tw, th, mipmaps, fmt_enum, img_data); + image->set_name(name); + if (compat_dict.size() > 0) { + image->set_meta("compat", compat_dict); + } + return image; +} + +class OverrideImageTexture : public ImageTexture { +public: + Ref image; + virtual Ref get_image() const override { + // otherwise, call the parent + return image; + } + virtual String get_save_class() const override { + return "ImageTexture"; + } +}; + +class fakeimagetex : Texture2D { + GDCLASS(fakeimagetex, Texture2D); + +public: + mutable RID texture; + Image::Format format = Image::FORMAT_L8; + bool mipmaps = false; + int w = 0; + int h = 0; + Size2 size_override; + mutable Ref alpha_cache; + bool image_stored = false; +}; +static_assert(sizeof(fakeimagetex) == sizeof(ImageTexture), "fakeimagetex must be the same size as ImageTexture"); + +Ref TextureLoaderCompat::create_image_texture(const String &p_path, ResourceInfo::LoadType p_type, int tw, int th, int tw_custom, int th_custom, bool mipmaps, Ref image) { + Ref texture; + Ref override_texture; + if (p_type != ResourceInfo::LoadType::REAL_LOAD) { + override_texture.instantiate(); + override_texture->image = image; + texture = override_texture; + } else { + texture.instantiate(); + } + fakeimagetex *fake = reinterpret_cast(texture.ptr()); + fake->image_stored = true; + fake->w = tw; + fake->h = th; + fake->format = image->get_format(); + if (tw_custom || th_custom) { + fake->size_override = Size2(tw_custom, th_custom); + } + fake->mipmaps = mipmaps; + bool size_override = tw_custom || th_custom; + if (p_type == ResourceInfo::LoadType::REAL_LOAD) { + RID texture_rid = RS::get_singleton()->texture_2d_create(image); + fake->texture = texture_rid; + if (size_override) { + RS::get_singleton()->texture_set_size_override(texture_rid, fake->w, fake->h); + } + } + return texture; +} diff --git a/compat/texture_loader_compat.h b/compat/texture_loader_compat.h index 69ea806e3..01203fe8a 100644 --- a/compat/texture_loader_compat.h +++ b/compat/texture_loader_compat.h @@ -9,6 +9,7 @@ #include "core/object/ref_counted.h" #include "core/templates/vector.h" #include "scene/resources/compressed_texture.h" +#include "scene/resources/image_texture.h" class TextureLoaderCompat { public: enum TextureVersionType { @@ -18,10 +19,12 @@ class TextureLoaderCompat { FORMAT_V2_ATLAS_TEXTURE, //atex FORMAT_V2_LARGE_TEXTURE, //ltex FORMAT_V2_CUBEMAP, //cbm + FORMAT_V3_ATLAS_TEXTURE, //res FORMAT_V3_IMAGE_TEXTURE, //tex FORMAT_V3_STREAM_TEXTURE2D, //stex FORMAT_V3_STREAM_TEXTURE3D, //tex3d FORMAT_V3_STREAM_TEXTUREARRAY, //texarr + FORMAT_V4_ATLAS_TEXTURE, //res FORMAT_V4_IMAGE_TEXTURE, //tex FORMAT_V4_COMPRESSED_TEXTURE2D, //ctex FORMAT_V4_COMPRESSED_TEXTURE3D, //ctex3d @@ -34,7 +37,6 @@ class TextureLoaderCompat { TEXTURE_TYPE_LAYERED, TEXTURE_TYPE_ATLAS }; - static Error _load_data_ctexlayered_v4(const String &p_path, Vector> &r_data, Image::Format &r_format, int &r_width, int &r_height, int &r_depth, int &r_type, bool &r_mipmaps); static Error _load_layered_texture_v3(const String &p_path, Vector> &r_data, Image::Format &r_format, int &r_width, int &r_height, int &r_depth, bool &r_mipmaps); static ResourceInfo _get_resource_info(TextureLoaderCompat::TextureVersionType t); @@ -43,6 +45,8 @@ class TextureLoaderCompat { static Error _load_data_ctex2d_v4(const String &p_path, int &tw, int &th, int &tw_custom, int &th_custom, Ref &image, int p_size_limit = 0); static Error _load_data_stex2d_v3(const String &p_path, int &tw, int &th, int &tw_custom, int &th_custom, int &flags, Ref &image, int p_size_limit = 0); + static Ref create_image_texture(const String &p_path, ResourceInfo::LoadType p_type, int tw, int th, int tw_custom, int th_custom, bool mipmaps, Ref image); + static bool is_binary_resource(TextureVersionType t); static TextureVersionType recognize(const String &p_path, Error *r_err); static int get_ver_major_from_textype(TextureVersionType type); static TextureType get_type_enum_from_version_type(TextureVersionType type); @@ -60,6 +64,16 @@ class ResourceConverterTexture2D : public ResourceCompatConverter { // static Ref _load_texture2d(const String &p_path, Ref &image, bool &size_override, int ver_major, Error *r_err) const; }; +class ImageConverterCompat : public ResourceCompatConverter { + GDCLASS(ImageConverterCompat, ResourceCompatConverter); + +public: + virtual Ref convert(const Ref &res, ResourceInfo::LoadType p_type, int ver_major, Error *r_error = nullptr) override; + virtual bool handles_type(const String &p_type, int ver_major) const override; + + // static Ref _load_texture2d(const String &p_path, Ref &image, bool &size_override, int ver_major, Error *r_err) const; +}; + class ResourceFormatLoaderCompatTexture2D : public CompatFormatLoader { GDCLASS(ResourceFormatLoaderCompatTexture2D, CompatFormatLoader); diff --git a/exporters/texture_exporter.cpp b/exporters/texture_exporter.cpp index 4d3e8fa0d..2c0cc201b 100644 --- a/exporters/texture_exporter.cpp +++ b/exporters/texture_exporter.cpp @@ -6,11 +6,9 @@ #include "core/io/file_access.h" #include "core/io/image_loader.h" #include "core/io/resource_loader.h" +#include "scene/resources/atlas_texture.h" -bool TextureExporter::handles_import(const String &importer, const String &resource_type) const { - return importer == "image" || importer == "texture" || importer == "bitmap" || resource_type == "BitMap" || resource_type == "CompressedTexture2D" || (resource_type == "Texture2D") || resource_type == "ImageTexture" || resource_type == "StreamTexture" || resource_type == "Texture"; -} - +namespace { bool get_bit(const Vector &bitmask, int width, int p_x, int p_y) { int ofs = width * p_y + p_x; int bbyte = ofs / 8; @@ -18,6 +16,8 @@ bool get_bit(const Vector &bitmask, int width, int p_x, int p_y) { return (bitmask[bbyte] & (1 << bbit)) != 0; } +} //namespace + // Format is the same on V2 - V4 Ref TextureExporter::load_image_from_bitmap(const String p_path, Error *r_err) { Error err; @@ -78,13 +78,24 @@ Error TextureExporter::_convert_bitmap(const String &p_path, const String &dest_ return OK; } +Error decompress_image(const Ref &img) { + Error err; + if (img->is_compressed()) { + err = img->decompress(); + if (err == ERR_UNAVAILABLE) { + return err; + } + ERR_FAIL_COND_V_MSG(err != OK, err, "Failed to decompress image."); + } + return OK; +} + Error TextureExporter::save_image(const String &dest_path, const Ref &img, bool lossy) { String dest_ext = dest_path.get_extension().to_lower(); Error err; if (img->is_compressed()) { err = img->decompress(); if (err == ERR_UNAVAILABLE) { - WARN_PRINT("Decompression not implemented yet for texture format " + Image::get_format_name(img->get_format())); return err; } ERR_FAIL_COND_V_MSG(err != OK, err, "Failed to decompress " + Image::get_format_name(img->get_format()) + " texture " + dest_path); @@ -107,8 +118,7 @@ Error TextureExporter::_convert_tex(const String &p_path, const String &dest_pat Error err; String dst_dir = dest_path.get_base_dir(); Ref tex; - ResourceFormatLoaderCompatTexture2D rlcb; - tex = rlcb.custom_load(p_path, ResourceInfo::LoadType::NON_GLOBAL_LOAD, &err); + tex = ResourceCompatLoader::non_global_load(p_path, "", &err); // deprecated format if (err == ERR_UNAVAILABLE) { // TODO: Not reporting here because we can't get the deprecated format type yet, @@ -135,6 +145,55 @@ Error TextureExporter::_convert_tex(const String &p_path, const String &dest_pat return OK; } +Error TextureExporter::_convert_atex(const String &p_path, const String &dest_path, bool lossy, String &image_format) { + Error err; + String dst_dir = dest_path.get_base_dir(); + // TODO: make gltf_load take in a cache mode + Ref atex = ResourceCompatLoader::gltf_load(p_path, "", &err); + // deprecated format + if (err == ERR_UNAVAILABLE) { + // TODO: Not reporting here because we can't get the deprecated format type yet, + // implement functionality to pass it back + return err; + } + ERR_FAIL_COND_V_MSG(err != OK || atex.is_null(), err, "Failed to load texture " + p_path); + Ref tex = atex->get_atlas(); + ERR_FAIL_COND_V_MSG(tex.is_null(), ERR_PARSE_ERROR, "Failed to load atlas texture " + p_path); + Ref img = tex->get_image(); + + ERR_FAIL_COND_V_MSG(img.is_null(), ERR_PARSE_ERROR, "Failed to load image for texture " + p_path); + ERR_FAIL_COND_V_MSG(img->is_empty(), ERR_FILE_EOF, "Image data is empty for texture " + p_path + ", not saving"); + image_format = Image::get_format_name(img->get_format()); + + img = img->duplicate(); + // resize it according to the properties of the atlas + err = decompress_image(img); + if (err) { + return err; + } + if (img->get_format() != Image::FORMAT_RGBA8) { + img->convert(Image::FORMAT_RGBA8); + } + + auto margin = atex->get_margin(); + auto region = atex->get_region(); + + // now we have to add the margin padding + Ref new_img = Image::create_empty(atex->get_width(), atex->get_height(), false, img->get_format()); + new_img->blit_rect(img, region, Point2i(margin.position.x, margin.position.y)); + + err = gdre::ensure_dir(dst_dir); + ERR_FAIL_COND_V_MSG(err != OK, err, "Failed to create dirs for " + dest_path); + err = save_image(dest_path, new_img, lossy); + if (err == ERR_UNAVAILABLE) { + return err; + } + ERR_FAIL_COND_V_MSG(err != OK, err, "Failed to save image " + dest_path + " from texture " + p_path); + + print_verbose("Converted " + p_path + " to " + dest_path); + return OK; +} + Error TextureExporter::export_file(const String &out_path, const String &res_path) { Error err; auto recognized = TextureLoaderCompat::recognize(res_path, &err); @@ -229,9 +288,12 @@ Ref TextureExporter::export_resource(const String &output_dir, Ref if (iinfo->get_importer() == "image") { ResourceFormatLoaderImage rli; Ref img = rli.load(path, "", &err, false, nullptr, ResourceFormatLoader::CACHE_MODE_IGNORE); - ERR_FAIL_COND_V_MSG(err != OK || img.is_null(), report, "Failed to load image " + path); - img_format = Image::get_format_name(img->get_format()); - err = save_image(dest_path, img, lossy); + if (!err && !img.is_null()) { + img_format = Image::get_format_name(img->get_format()); + err = save_image(dest_path, img, lossy); + } + } else if (iinfo->get_importer() == "texture_atlas") { + err = _convert_atex(path, dest_path, lossy, img_format); } else if (iinfo->get_importer() == "bitmap") { err = _convert_bitmap(path, dest_path, lossy); } else { @@ -272,10 +334,12 @@ void TextureExporter::get_handled_types(List *out) const { out->push_back("StreamTexture"); out->push_back("CompressedTexture2D"); out->push_back("BitMap"); + out->push_back("AtlasTexture"); } void TextureExporter::get_handled_importers(List *out) const { out->push_back("texture"); out->push_back("bitmap"); out->push_back("image"); + out->push_back("texture_atlas"); } \ No newline at end of file diff --git a/exporters/texture_exporter.h b/exporters/texture_exporter.h index c6d76b796..0e3379807 100644 --- a/exporters/texture_exporter.h +++ b/exporters/texture_exporter.h @@ -6,6 +6,7 @@ class TextureExporter : public ResourceExporter { GDCLASS(TextureExporter, ResourceExporter); Error _export_file(const String &out_path, const String &res_path, int ver_major = 0); Error _convert_tex(const String &p_path, const String &p_dst, bool lossy, String &image_format); + Error _convert_atex(const String &p_path, const String &p_dst, bool lossy, String &image_format); Error _convert_bitmap(const String &p_path, const String &p_dst, bool lossy); static Ref load_image_from_bitmap(const String p_path, Error *r_err); @@ -13,7 +14,6 @@ class TextureExporter : public ResourceExporter { static Error save_image(const String &dest_path, const Ref &img, bool lossy); virtual Error export_file(const String &out_path, const String &res_path) override; virtual Ref export_resource(const String &output_dir, Ref import_infos) override; - virtual bool handles_import(const String &importer, const String &resource_type = String()) const override; virtual void get_handled_types(List *out) const override; virtual void get_handled_importers(List *out) const override; }; \ No newline at end of file diff --git a/register_types.cpp b/register_types.cpp index 2d9060185..4a0bd832b 100644 --- a/register_types.cpp +++ b/register_types.cpp @@ -51,6 +51,7 @@ static Ref texture_layered_loader = nu //converters static Ref sample_converter = nullptr; static Ref texture_converter = nullptr; +static Ref image_converter = nullptr; static Ref ogg_converter = nullptr; //exporters @@ -85,6 +86,7 @@ void init_loaders() { texture_layered_loader = memnew(ResourceFormatLoaderCompatTextureLayered); sample_converter = memnew(SampleConverterCompat); texture_converter = memnew(ResourceConverterTexture2D); + image_converter = memnew(ImageConverterCompat); ogg_converter = memnew(OggStreamConverterCompat); ResourceCompatLoader::add_resource_format_loader(binary_loader, true); ResourceCompatLoader::add_resource_format_loader(text_loader, true); @@ -93,6 +95,7 @@ void init_loaders() { ResourceCompatLoader::add_resource_format_loader(texture_layered_loader, true); ResourceCompatLoader::add_resource_object_converter(sample_converter, true); ResourceCompatLoader::add_resource_object_converter(texture_converter, true); + ResourceCompatLoader::add_resource_object_converter(image_converter, true); ResourceCompatLoader::add_resource_object_converter(ogg_converter, true); } @@ -172,6 +175,9 @@ void deinit_loaders() { if (texture_converter.is_valid()) { ResourceCompatLoader::remove_resource_object_converter(texture_converter); } + if (image_converter.is_valid()) { + ResourceCompatLoader::remove_resource_object_converter(image_converter); + } if (ogg_converter.is_valid()) { ResourceCompatLoader::remove_resource_object_converter(ogg_converter); } @@ -182,6 +188,7 @@ void deinit_loaders() { texture_layered_loader = nullptr; sample_converter = nullptr; texture_converter = nullptr; + image_converter = nullptr; ogg_converter = nullptr; } @@ -226,6 +233,7 @@ void initialize_gdsdecomp_module(ModuleInitializationLevel p_level) { ClassDB::register_class(); ClassDB::register_class(); ClassDB::register_class(); + ClassDB::register_class(); ClassDB::register_class(); ClassDB::register_class(); diff --git a/utility/import_info.cpp b/utility/import_info.cpp index 385085011..cae3b965c 100644 --- a/utility/import_info.cpp +++ b/utility/import_info.cpp @@ -594,6 +594,8 @@ Error ImportInfov2::_load(const String &p_path) { new_ext = "wav"; } else if (p_path.get_extension() == "cbm") { new_ext = "cube"; + } else if (type == "AtlasTexture") { + new_ext = "png"; } else { new_ext = "fixme"; } @@ -628,6 +630,8 @@ Error ImportInfov2::_load(const String &p_path) { importer = "bitmask"; } else if (p_path.get_extension() == "cbm") { importer = "cubemap"; + } else if (p_path.get_extension() == "atex") { + importer = "texture_atlas"; } else { importer = "none"; }