From 1e342cfdf68ab0245a9e42df4bbf013eddee449b Mon Sep 17 00:00:00 2001 From: "K. S. Ernest (iFire) Lee" Date: Fri, 24 May 2024 13:05:07 -0700 Subject: [PATCH] Fix Texture3D import not working Fix Texture3D import not working when texture has fully opaque and (partly or fully) transparent slices. For better style make cases of detect_alpha check against the exact enums rather than the enum 0. --- drivers/png/png_driver_common.cpp | 2 +- .../resource_importer_layered_texture.cpp | 3 ++- modules/webp/webp_common.cpp | 2 +- scene/resources/compressed_texture.cpp | 22 +++++++++---------- 4 files changed, 15 insertions(+), 14 deletions(-) diff --git a/drivers/png/png_driver_common.cpp b/drivers/png/png_driver_common.cpp index a789d5c5b3e9..0ee5781f24c5 100644 --- a/drivers/png/png_driver_common.cpp +++ b/drivers/png/png_driver_common.cpp @@ -153,7 +153,7 @@ Error image_to_png(const Ref &p_image, Vector &p_buffer) { png_img.format = PNG_FORMAT_RGBA; break; default: - if (source_image->detect_alpha()) { + if (source_image->detect_alpha() != Image::ALPHA_NONE) { source_image->convert(Image::FORMAT_RGBA8); png_img.format = PNG_FORMAT_RGBA; } else { diff --git a/editor/import/resource_importer_layered_texture.cpp b/editor/import/resource_importer_layered_texture.cpp index 0d0c89425d09..ecca3014f694 100644 --- a/editor/import/resource_importer_layered_texture.cpp +++ b/editor/import/resource_importer_layered_texture.cpp @@ -343,7 +343,7 @@ Error ResourceImporterLayeredTexture::import(ResourceUID::ID p_source_id, const //if using video ram, optimize if (channel_pack == 0) { //remove alpha if not needed, so compression is more efficient - if (image->get_format() == Image::FORMAT_RGBA8 && !image->detect_alpha()) { + if (image->get_format() == Image::FORMAT_RGBA8 && image->detect_alpha() == Image::ALPHA_NONE) { image->convert(Image::FORMAT_RGB8); } } else if (image->get_format() < Image::FORMAT_RGBA8) { @@ -487,6 +487,7 @@ ResourceImporterLayeredTexture::~ResourceImporterLayeredTexture() { void ResourceImporterLayeredTexture::_check_compress_ctex(const String &p_source_file, Ref r_texture_import) { 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); diff --git a/modules/webp/webp_common.cpp b/modules/webp/webp_common.cpp index 0284eec574b3..7552c4ca0033 100644 --- a/modules/webp/webp_common.cpp +++ b/modules/webp/webp_common.cpp @@ -63,7 +63,7 @@ Vector _webp_packer(const Ref &p_image, float p_quality, bool p_ Error error = img->decompress(); ERR_FAIL_COND_V_MSG(error != OK, Vector(), "Couldn't decompress image."); } - if (img->detect_alpha()) { + if (img->detect_alpha() != Image::ALPHA_NONE) { img->convert(Image::FORMAT_RGBA8); } else { img->convert(Image::FORMAT_RGB8); diff --git a/scene/resources/compressed_texture.cpp b/scene/resources/compressed_texture.cpp index 588a2b967b15..a9a261d491c4 100644 --- a/scene/resources/compressed_texture.cpp +++ b/scene/resources/compressed_texture.cpp @@ -313,8 +313,6 @@ Ref CompressedTexture2D::load_image_from_file(Ref f, int p_si Vector> mipmap_images; uint64_t total_size = 0; - bool first = true; - for (uint32_t i = 0; i < mipmaps + 1; i++) { uint32_t size = f->get_32(); @@ -339,18 +337,20 @@ Ref CompressedTexture2D::load_image_from_file(Ref f, int p_si } else if (data_format == DATA_FORMAT_WEBP && Image::webp_unpacker) { img = Image::webp_unpacker(pv); } - if (img.is_null() || img->is_empty()) { ERR_FAIL_COND_V(img.is_null() || img->is_empty(), Ref()); } - - if (first) { - //format will actually be the format of the first image, - //as it may have changed on compression - format = img->get_format(); - first = false; - } else if (img->get_format() != format) { - img->convert(format); //all needs to be the same format + // If the image is compressed and its format doesn't match the desired format, return an empty reference. + // This is done to avoid recompressing the image on load. + ERR_FAIL_COND_V(img->is_compressed() && format != img->get_format(), Ref()); + + // The format will actually be the format of the header, + // as it may have changed on compression. + if (!img->is_compressed() && format != img->get_format()) { + // Convert the image to the desired format. + // Note: We are not decompressing the image here, just changing its format. + // It's important that all images in the texture array share the same format for correct rendering. + img->convert(format); } total_size += img->get_data().size();