diff options
Diffstat (limited to 'modules/pvr/texture_loader_pvr.cpp')
-rw-r--r-- | modules/pvr/texture_loader_pvr.cpp | 156 |
1 files changed, 55 insertions, 101 deletions
diff --git a/modules/pvr/texture_loader_pvr.cpp b/modules/pvr/texture_loader_pvr.cpp index a8e8a9a2f1..83f032ca2b 100644 --- a/modules/pvr/texture_loader_pvr.cpp +++ b/modules/pvr/texture_loader_pvr.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -29,16 +29,12 @@ /*************************************************************************/ #include "texture_loader_pvr.h" -#include "PvrTcEncoder.h" -#include "RgbaBitmap.h" + #include "core/os/file_access.h" -#include <string.h> -#include <new> static void _pvrtc_decompress(Image *p_img); enum PVRFLags { - PVR_HAS_MIPMAPS = 0x00000100, PVR_TWIDDLED = 0x00000200, PVR_NORMAL_MAP = 0x00000400, @@ -48,25 +44,26 @@ enum PVRFLags { PVR_VOLUME_TEXTURES = 0x00004000, PVR_HAS_ALPHA = 0x00008000, PVR_VFLIP = 0x00010000 - }; -RES ResourceFormatPVR::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { - - if (r_error) +RES ResourceFormatPVR::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { + if (r_error) { *r_error = ERR_CANT_OPEN; + } Error err; FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err); - if (!f) + if (!f) { return RES(); + } FileAccessRef faref(f); ERR_FAIL_COND_V(err, RES()); - if (r_error) + if (r_error) { *r_error = ERR_FILE_CORRUPT; + } uint32_t hsize = f->get_32(); @@ -109,11 +106,14 @@ RES ResourceFormatPVR::load(const String &p_path, const String &p_original_path, Image::Format format = Image::FORMAT_MAX; switch (flags & 0xFF) { - case 0x18: - case 0xC: format = (flags & PVR_HAS_ALPHA) ? Image::FORMAT_PVRTC2A : Image::FORMAT_PVRTC2; break; + case 0xC: + format = (flags & PVR_HAS_ALPHA) ? Image::FORMAT_PVRTC1_2A : Image::FORMAT_PVRTC1_2; + break; case 0x19: - case 0xD: format = (flags & PVR_HAS_ALPHA) ? Image::FORMAT_PVRTC4A : Image::FORMAT_PVRTC4; break; + case 0xD: + format = (flags & PVR_HAS_ALPHA) ? Image::FORMAT_PVRTC1_4A : Image::FORMAT_PVRTC1_4; + break; case 0x16: format = Image::FORMAT_L8; break; @@ -153,79 +153,35 @@ RES ResourceFormatPVR::load(const String &p_path, const String &p_original_path, } Ref<Image> image = memnew(Image(width, height, mipmaps, format, data)); - ERR_FAIL_COND_V(image->empty(), RES()); + ERR_FAIL_COND_V(image->is_empty(), RES()); Ref<ImageTexture> texture = memnew(ImageTexture); texture->create_from_image(image); - if (r_error) + if (r_error) { *r_error = OK; + } return texture; } void ResourceFormatPVR::get_recognized_extensions(List<String> *p_extensions) const { - p_extensions->push_back("pvr"); } -bool ResourceFormatPVR::handles_type(const String &p_type) const { +bool ResourceFormatPVR::handles_type(const String &p_type) const { return ClassDB::is_parent_class(p_type, "Texture2D"); } -String ResourceFormatPVR::get_resource_type(const String &p_path) const { - if (p_path.get_extension().to_lower() == "pvr") +String ResourceFormatPVR::get_resource_type(const String &p_path) const { + if (p_path.get_extension().to_lower() == "pvr") { return "Texture2D"; - return ""; -} - -static void _compress_pvrtc4(Image *p_img) { - - Ref<Image> img = p_img->duplicate(); - - bool make_mipmaps = false; - if (!img->is_size_po2() || img->get_width() != img->get_height()) { - make_mipmaps = img->has_mipmaps(); - img->resize_to_po2(true); } - img->convert(Image::FORMAT_RGBA8); - if (!img->has_mipmaps() && make_mipmaps) - img->generate_mipmaps(); - - bool use_alpha = img->detect_alpha(); - - Ref<Image> new_img; - new_img.instance(); - new_img->create(img->get_width(), img->get_height(), img->has_mipmaps(), use_alpha ? Image::FORMAT_PVRTC4A : Image::FORMAT_PVRTC4); - - Vector<uint8_t> data = new_img->get_data(); - { - uint8_t *wr = data.ptrw(); - const uint8_t *r = img->get_data().ptr(); - - for (int i = 0; i <= new_img->get_mipmap_count(); i++) { - - int ofs, size, w, h; - img->get_mipmap_offset_size_and_dimensions(i, ofs, size, w, h); - Javelin::RgbaBitmap bm(w, h); - for (int j = 0; j < size / 4; j++) { - Javelin::ColorRgba<unsigned char> *dp = bm.GetData(); - /* red and Green colors are swapped. */ - new (dp) Javelin::ColorRgba<unsigned char>(r[ofs + 4 * j + 2], r[ofs + 4 * j + 1], r[ofs + 4 * j], r[ofs + 4 * j + 3]); - } - new_img->get_mipmap_offset_size_and_dimensions(i, ofs, size, w, h); - Javelin::PvrTcEncoder::EncodeRgba4Bpp(&wr[ofs], bm); - } - } - - p_img->create(new_img->get_width(), new_img->get_height(), new_img->has_mipmaps(), new_img->get_format(), data); + return ""; } ResourceFormatPVR::ResourceFormatPVR() { - Image::_image_decompress_pvrtc = _pvrtc_decompress; - Image::_image_compress_pvrtc4_func = _compress_pvrtc4; - Image::_image_compress_pvrtc2_func = _compress_pvrtc4; } ///////////////////////////////////////////////////////// @@ -251,35 +207,32 @@ ResourceFormatPVR::ResourceFormatPVR() { struct PVRTCBlock { //blocks are 64 bits - uint32_t data[2]; + uint32_t data[2] = {}; }; _FORCE_INLINE_ bool is_po2(uint32_t p_input) { - - if (p_input == 0) - return 0; + if (p_input == 0) { + return false; + } uint32_t minus1 = p_input - 1; - return ((p_input | minus1) == (p_input ^ minus1)) ? 1 : 0; + return ((p_input | minus1) == (p_input ^ minus1)) ? true : false; } static void unpack_5554(const PVRTCBlock *p_block, int p_ab_colors[2][4]) { - uint32_t raw_bits[2]; raw_bits[0] = p_block->data[1] & (0xFFFE); raw_bits[1] = p_block->data[1] >> 16; for (int i = 0; i < 2; i++) { - if (raw_bits[i] & (1 << 15)) { - p_ab_colors[i][0] = (raw_bits[i] >> 10) & 0x1F; p_ab_colors[i][1] = (raw_bits[i] >> 5) & 0x1F; p_ab_colors[i][2] = raw_bits[i] & 0x1F; - if (i == 0) + if (i == 0) { p_ab_colors[0][2] |= p_ab_colors[0][2] >> 4; + } p_ab_colors[i][3] = 0xF; } else { - p_ab_colors[i][0] = (raw_bits[i] >> (8 - 1)) & 0x1E; p_ab_colors[i][1] = (raw_bits[i] >> (4 - 1)) & 0x1E; @@ -288,10 +241,11 @@ static void unpack_5554(const PVRTCBlock *p_block, int p_ab_colors[2][4]) { p_ab_colors[i][2] = (raw_bits[i] & 0xF) << 1; - if (i == 0) + if (i == 0) { p_ab_colors[0][2] |= p_ab_colors[0][2] >> 3; - else + } else { p_ab_colors[0][2] |= p_ab_colors[0][2] >> 4; + } p_ab_colors[i][3] = (raw_bits[i] >> 11) & 0xE; } @@ -299,15 +253,12 @@ static void unpack_5554(const PVRTCBlock *p_block, int p_ab_colors[2][4]) { } static void unpack_modulations(const PVRTCBlock *p_block, const int p_2bit, int p_modulation[8][16], int p_modulation_modes[8][16], int p_x, int p_y) { - int block_mod_mode = p_block->data[1] & 1; uint32_t modulation_bits = p_block->data[0]; if (p_2bit && block_mod_mode) { - for (int y = 0; y < BLK_Y_SIZE; y++) { for (int x = 0; x < BLK_X_2BPP; x++) { - p_modulation_modes[y + p_y][x + p_x] = block_mod_mode; if (((x ^ y) & 1) == 0) { @@ -318,15 +269,15 @@ static void unpack_modulations(const PVRTCBlock *p_block, const int p_2bit, int } } else if (p_2bit) { - for (int y = 0; y < BLK_Y_SIZE; y++) { for (int x = 0; x < BLK_X_2BPP; x++) { p_modulation_modes[y + p_y][x + p_x] = block_mod_mode; - if (modulation_bits & 1) + if (modulation_bits & 1) { p_modulation[y + p_y][x + p_x] = 0x3; - else + } else { p_modulation[y + p_y][x + p_x] = 0x0; + } modulation_bits >>= 1; } @@ -361,10 +312,11 @@ static void interpolate_colors(const int p_colorp[4], const int p_colorq[4], con v = (y & 0x3) | ((~y & 0x2) << 1); - if (p_2bit) + if (p_2bit) { u = (x & 0x7) | ((~x & 0x4) << 1); - else + } else { u = (x & 0x3) | ((~x & 0x2) << 1); + } v = v - BLK_Y_SIZE / 2; @@ -420,19 +372,20 @@ static void get_modulation_value(int x, int y, const int p_2bit, const int p_mod y = (y & 0x3) | ((~y & 0x2) << 1); - if (p_2bit) + if (p_2bit) { x = (x & 0x7) | ((~x & 0x4) << 1); - else + } else { x = (x & 0x3) | ((~x & 0x2) << 1); + } *p_dopt = 0; if (p_modulation_modes[y][x] == 0) { mod_val = rep_vals0[p_modulation[y][x]]; } else if (p_2bit) { - if (((x ^ y) & 1) == 0) + if (((x ^ y) & 1) == 0) { mod_val = rep_vals0[p_modulation[y][x]]; - else if (p_modulation_modes[y][x] == 1) { + } else if (p_modulation_modes[y][x] == 1) { mod_val = (rep_vals0[p_modulation[y - 1][x]] + rep_vals0[p_modulation[y + 1][x]] + rep_vals0[p_modulation[y][x - 1]] + @@ -459,7 +412,6 @@ static void get_modulation_value(int x, int y, const int p_2bit, const int p_mod static int disable_twiddling = 0; static uint32_t twiddle_uv(uint32_t p_height, uint32_t p_width, uint32_t p_y, uint32_t p_x) { - uint32_t twiddled; uint32_t min_dimension; @@ -484,8 +436,9 @@ static uint32_t twiddle_uv(uint32_t p_height, uint32_t p_width, uint32_t p_y, ui max_value = p_y; } - if (disable_twiddling) + if (disable_twiddling) { return (p_y * p_width + p_x); + } scr_bit_pos = 1; dst_bit_pos = 1; @@ -545,17 +498,17 @@ static void decompress_pvrtc(PVRTCBlock *p_comp_img, const int p_2bit, const int int r_result[4]; - if (p_2bit) + if (p_2bit) { x_block_size = BLK_X_2BPP; - else + } else { x_block_size = BLK_X_4BPP; + } block_width = MAX(2, p_width / x_block_size); block_height = MAX(2, p_height / BLK_Y_SIZE); for (y = 0; y < p_height; y++) { for (x = 0; x < p_width; x++) { - block_x = (x - x_block_size / 2); blk_y = (y - BLK_Y_SIZE / 2); @@ -620,8 +573,9 @@ static void decompress_pvrtc(PVRTCBlock *p_comp_img, const int p_2bit, const int r_result[i] >>= 3; } - if (DoPT) + if (DoPT) { r_result[3] = 0; + } u_pos = (x + y * p_width) << 2; p_dst[u_pos + 0] = (uint8_t)r_result[0]; @@ -633,10 +587,9 @@ static void decompress_pvrtc(PVRTCBlock *p_comp_img, const int p_2bit, const int } static void _pvrtc_decompress(Image *p_img) { + ERR_FAIL_COND(p_img->get_format() != Image::FORMAT_PVRTC1_2 && p_img->get_format() != Image::FORMAT_PVRTC1_2A && p_img->get_format() != Image::FORMAT_PVRTC1_4 && p_img->get_format() != Image::FORMAT_PVRTC1_4A); - ERR_FAIL_COND(p_img->get_format() != Image::FORMAT_PVRTC2 && p_img->get_format() != Image::FORMAT_PVRTC2A && p_img->get_format() != Image::FORMAT_PVRTC4 && p_img->get_format() != Image::FORMAT_PVRTC4A); - - bool _2bit = (p_img->get_format() == Image::FORMAT_PVRTC2 || p_img->get_format() == Image::FORMAT_PVRTC2A); + bool _2bit = (p_img->get_format() == Image::FORMAT_PVRTC1_2 || p_img->get_format() == Image::FORMAT_PVRTC1_2A); Vector<uint8_t> data = p_img->get_data(); const uint8_t *r = data.ptr(); @@ -649,6 +602,7 @@ static void _pvrtc_decompress(Image *p_img) { bool make_mipmaps = p_img->has_mipmaps(); p_img->create(p_img->get_width(), p_img->get_height(), false, Image::FORMAT_RGBA8, newdata); - if (make_mipmaps) + if (make_mipmaps) { p_img->generate_mipmaps(); + } } |