From f89641907f8b45941f5e67891936ee8050a3ef92 Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Fri, 26 May 2017 21:49:49 -0300 Subject: -Added EXR supprot for HDR (no BC6 compression yet though) -Improvements to texture importer -Proper detection of S3TC compression modes, and added all modes to Image -Fixes to non-power of 2 compressed textures, which should all be supported by GLES3 --- modules/squish/image_compress_squish.cpp | 109 ++++++++++++++++++------------- 1 file changed, 65 insertions(+), 44 deletions(-) (limited to 'modules/squish') diff --git a/modules/squish/image_compress_squish.cpp b/modules/squish/image_compress_squish.cpp index 5c53492034..2427dac8a7 100644 --- a/modules/squish/image_compress_squish.cpp +++ b/modules/squish/image_compress_squish.cpp @@ -59,9 +59,9 @@ void image_decompress_squish(Image *p_image) { squish_flags = squish::kDxt3; } else if (p_image->get_format() == Image::FORMAT_DXT5) { squish_flags = squish::kDxt5; - } else if (p_image->get_format() == Image::FORMAT_ATI1) { + } else if (p_image->get_format() == Image::FORMAT_LATC_L || p_image->get_format() == Image::FORMAT_RGTC_R) { squish_flags = squish::kBc4; - } else if (p_image->get_format() == Image::FORMAT_ATI2) { + } else if (p_image->get_format() == Image::FORMAT_LATC_LA || p_image->get_format() == Image::FORMAT_RGTC_RG) { squish_flags = squish::kBc5; } else { ERR_FAIL_COND(true); @@ -81,61 +81,82 @@ void image_decompress_squish(Image *p_image) { void image_compress_squish(Image *p_image) { + if (p_image->get_format() >= Image::FORMAT_DXT1) + return; //do not compress, already compressed + int w = p_image->get_width(); int h = p_image->get_height(); - if (!p_image->has_mipmaps()) { - ERR_FAIL_COND(!w || w % 4 != 0); - ERR_FAIL_COND(!h || h % 4 != 0); - } else { - ERR_FAIL_COND(!w || w != nearest_power_of_2(w)); - ERR_FAIL_COND(!h || h != nearest_power_of_2(h)); - }; + if (p_image->get_format() <= Image::FORMAT_RGBA8) { - if (p_image->get_format() >= Image::FORMAT_DXT1) - return; //do not compress, already compressed + int squish_comp = squish::kColourRangeFit; + Image::Format target_format; - int shift = 0; - int squish_comp = squish::kColourRangeFit; // TODO: use lossy quality setting to determine the quality - Image::Format target_format; + Image::DetectChannels dc = p_image->get_detected_channels(); - if (p_image->get_format() == Image::FORMAT_LA8) { - //compressed normalmap - target_format = Image::FORMAT_DXT5; - squish_comp |= squish::kDxt5; - } else if (p_image->detect_alpha() != Image::ALPHA_NONE) { + p_image->convert(Image::FORMAT_RGBA8); //still uses RGBA to convert - target_format = Image::FORMAT_DXT3; - squish_comp |= squish::kDxt3; - } else { - target_format = Image::FORMAT_DXT1; - shift = 1; - squish_comp |= squish::kDxt1; - } + switch (dc) { + case Image::DETECTED_L: { - p_image->convert(Image::FORMAT_RGBA8); //always expects rgba + target_format = Image::FORMAT_LATC_L; + squish_comp |= squish::kBc4; + } break; + case Image::DETECTED_LA: { - PoolVector data; - int target_size = Image::get_image_data_size(w, h, target_format, p_image->has_mipmaps() ? -1 : 0); - int mm_count = p_image->has_mipmaps() ? Image::get_image_required_mipmaps(w, h, target_format) : 0; - data.resize(target_size); + target_format = Image::FORMAT_LATC_LA; + squish_comp |= squish::kBc5; + } break; + case Image::DETECTED_R: { - PoolVector::Read rb = p_image->get_data().read(); - PoolVector::Write wb = data.write(); + target_format = Image::FORMAT_RGTC_R; + squish_comp |= squish::kBc4; + } break; + case Image::DETECTED_RG: { - int dst_ofs = 0; + target_format = Image::FORMAT_RGTC_RG; + squish_comp |= squish::kBc5; + } break; + case Image::DETECTED_RGB: { - for (int i = 0; i <= mm_count; i++) { + target_format = Image::FORMAT_DXT1; + squish_comp |= squish::kDxt1; + } break; + case Image::DETECTED_RGBA: { - int src_ofs = p_image->get_mipmap_offset(i); - squish::CompressImage(&rb[src_ofs], w, h, &wb[dst_ofs], squish_comp); - dst_ofs += (MAX(4, w) * MAX(4, h)) >> shift; - w >>= 1; - h >>= 1; - } + //TODO, should convert both, then measure which one does a better job + target_format = Image::FORMAT_DXT5; + squish_comp |= squish::kDxt5; - rb = PoolVector::Read(); - wb = PoolVector::Write(); + } break; + } - p_image->create(p_image->get_width(), p_image->get_height(), p_image->has_mipmaps(), target_format, data); + PoolVector data; + int target_size = Image::get_image_data_size(w, h, target_format, p_image->has_mipmaps() ? -1 : 0); + int mm_count = p_image->has_mipmaps() ? Image::get_image_required_mipmaps(w, h, target_format) : 0; + data.resize(target_size); + int shift = Image::get_format_pixel_rshift(target_format); + + PoolVector::Read rb = p_image->get_data().read(); + PoolVector::Write wb = data.write(); + + int dst_ofs = 0; + + for (int i = 0; i <= mm_count; i++) { + + int bw = w % 4 != 0 ? w + (4 - w % 4) : w; + int bh = h % 4 != 0 ? h + (4 - h % 4) : h; + + int src_ofs = p_image->get_mipmap_offset(i); + squish::CompressImage(&rb[src_ofs], bw, bh, &wb[dst_ofs], squish_comp); + dst_ofs += (MAX(4, w) * MAX(4, h)) >> shift; + w >>= 1; + h >>= 1; + } + + rb = PoolVector::Read(); + wb = PoolVector::Write(); + + p_image->create(p_image->get_width(), p_image->get_height(), p_image->has_mipmaps(), target_format, data); + } } -- cgit v1.2.3