-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
This commit is contained in:
@ -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) {
|
||||
|
||||
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_DXT1)
|
||||
return; //do not compress, already compressed
|
||||
|
||||
int shift = 0;
|
||||
int squish_comp = squish::kColourRangeFit; // TODO: use lossy quality setting to determine the quality
|
||||
Image::Format target_format;
|
||||
int w = p_image->get_width();
|
||||
int h = p_image->get_height();
|
||||
|
||||
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) {
|
||||
if (p_image->get_format() <= Image::FORMAT_RGBA8) {
|
||||
|
||||
target_format = Image::FORMAT_DXT3;
|
||||
squish_comp |= squish::kDxt3;
|
||||
} else {
|
||||
target_format = Image::FORMAT_DXT1;
|
||||
shift = 1;
|
||||
squish_comp |= squish::kDxt1;
|
||||
int squish_comp = squish::kColourRangeFit;
|
||||
Image::Format target_format;
|
||||
|
||||
Image::DetectChannels dc = p_image->get_detected_channels();
|
||||
|
||||
p_image->convert(Image::FORMAT_RGBA8); //still uses RGBA to convert
|
||||
|
||||
switch (dc) {
|
||||
case Image::DETECTED_L: {
|
||||
|
||||
target_format = Image::FORMAT_LATC_L;
|
||||
squish_comp |= squish::kBc4;
|
||||
} break;
|
||||
case Image::DETECTED_LA: {
|
||||
|
||||
target_format = Image::FORMAT_LATC_LA;
|
||||
squish_comp |= squish::kBc5;
|
||||
} break;
|
||||
case Image::DETECTED_R: {
|
||||
|
||||
target_format = Image::FORMAT_RGTC_R;
|
||||
squish_comp |= squish::kBc4;
|
||||
} break;
|
||||
case Image::DETECTED_RG: {
|
||||
|
||||
target_format = Image::FORMAT_RGTC_RG;
|
||||
squish_comp |= squish::kBc5;
|
||||
} break;
|
||||
case Image::DETECTED_RGB: {
|
||||
|
||||
target_format = Image::FORMAT_DXT1;
|
||||
squish_comp |= squish::kDxt1;
|
||||
} break;
|
||||
case Image::DETECTED_RGBA: {
|
||||
|
||||
//TODO, should convert both, then measure which one does a better job
|
||||
target_format = Image::FORMAT_DXT5;
|
||||
squish_comp |= squish::kDxt5;
|
||||
|
||||
} break;
|
||||
}
|
||||
|
||||
PoolVector<uint8_t> 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<uint8_t>::Read rb = p_image->get_data().read();
|
||||
PoolVector<uint8_t>::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<uint8_t>::Read();
|
||||
wb = PoolVector<uint8_t>::Write();
|
||||
|
||||
p_image->create(p_image->get_width(), p_image->get_height(), p_image->has_mipmaps(), target_format, data);
|
||||
}
|
||||
|
||||
p_image->convert(Image::FORMAT_RGBA8); //always expects rgba
|
||||
|
||||
PoolVector<uint8_t> 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);
|
||||
|
||||
PoolVector<uint8_t>::Read rb = p_image->get_data().read();
|
||||
PoolVector<uint8_t>::Write wb = data.write();
|
||||
|
||||
int dst_ofs = 0;
|
||||
|
||||
for (int i = 0; i <= mm_count; i++) {
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
rb = PoolVector<uint8_t>::Read();
|
||||
wb = PoolVector<uint8_t>::Write();
|
||||
|
||||
p_image->create(p_image->get_width(), p_image->get_height(), p_image->has_mipmaps(), target_format, data);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user