diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/image.cpp | 191 | ||||
-rw-r--r-- | core/image.h | 56 | ||||
-rw-r--r-- | core/io/config_file.cpp | 3 |
3 files changed, 177 insertions, 73 deletions
diff --git a/core/image.cpp b/core/image.cpp index 6283b93f25..7e7c8d1607 100644 --- a/core/image.cpp +++ b/core/image.cpp @@ -79,6 +79,8 @@ const char *Image::format_names[Image::FORMAT_MAX] = { "ETC2_RGB8", "ETC2_RGBA8", "ETC2_RGB8A1", + "ETC2_RA_AS_RG", + "FORMAT_DXT5_RA_AS_RG", }; @@ -115,7 +117,7 @@ int Image::get_format_pixel_size(Format p_format) { case FORMAT_RGB8: return 3; case FORMAT_RGBA8: return 4; case FORMAT_RGBA4444: return 2; - case FORMAT_RGBA5551: return 2; + case FORMAT_RGB565: return 2; case FORMAT_RF: return 4; //float case FORMAT_RGF: return 8; @@ -159,6 +161,8 @@ int Image::get_format_pixel_size(Format p_format) { case FORMAT_ETC2_RGB8: return 1; case FORMAT_ETC2_RGBA8: return 1; case FORMAT_ETC2_RGB8A1: return 1; + case FORMAT_ETC2_RA_AS_RG: return 1; + case FORMAT_DXT5_RA_AS_RG: return 1; case FORMAT_MAX: { } } @@ -207,7 +211,9 @@ void Image::get_format_min_pixel_size(Format p_format, int &r_w, int &r_h) { case FORMAT_ETC2_RG11S: case FORMAT_ETC2_RGB8: case FORMAT_ETC2_RGBA8: - case FORMAT_ETC2_RGB8A1: { + case FORMAT_ETC2_RGB8A1: + case FORMAT_ETC2_RA_AS_RG: + case FORMAT_DXT5_RA_AS_RG: { r_w = 4; r_h = 4; @@ -268,7 +274,11 @@ int Image::get_format_block_size(Format p_format) { case FORMAT_ETC2_RG11S: case FORMAT_ETC2_RGB8: case FORMAT_ETC2_RGBA8: - case FORMAT_ETC2_RGB8A1: { + case FORMAT_ETC2_RGB8A1: + case FORMAT_ETC2_RA_AS_RG: //used to make basis universal happy + case FORMAT_DXT5_RA_AS_RG: //used to make basis universal happy + + { return 4; } @@ -1937,13 +1947,24 @@ int Image::get_image_mipmap_offset(int p_width, int p_height, Format p_format, i return _get_dst_image_size(p_width, p_height, p_format, mm, p_mipmap - 1); } +int Image::get_image_mipmap_offset_and_dimensions(int p_width, int p_height, Format p_format, int p_mipmap, int &r_w, int &r_h) { + + if (p_mipmap <= 0) { + r_w = p_width; + r_h = p_height; + return 0; + } + int mm; + return _get_dst_image_size(p_width, p_height, p_format, mm, p_mipmap - 1, &r_w, &r_h); +} + bool Image::is_compressed() const { return format > FORMAT_RGBE9995; } Error Image::decompress() { - if (format >= FORMAT_DXT1 && format <= FORMAT_RGTC_RG && _image_decompress_bc) + if (((format >= FORMAT_DXT1 && format <= FORMAT_RGTC_RG) || (format == FORMAT_DXT5_RA_AS_RG)) && _image_decompress_bc) _image_decompress_bc(this); else if (format >= FORMAT_BPTC_RGBA && format <= FORMAT_BPTC_RGBFU && _image_decompress_bptc) _image_decompress_bptc(this); @@ -1951,7 +1972,7 @@ Error Image::decompress() { _image_decompress_pvrtc(this); else if (format == FORMAT_ETC && _image_decompress_etc1) _image_decompress_etc1(this); - else if (format >= FORMAT_ETC2_R11 && format <= FORMAT_ETC2_RGB8A1 && _image_decompress_etc2) + else if (format >= FORMAT_ETC2_R11 && format <= FORMAT_ETC2_RA_AS_RG && _image_decompress_etc2) _image_decompress_etc2(this); else return ERR_UNAVAILABLE; @@ -1960,12 +1981,16 @@ Error Image::decompress() { Error Image::compress(CompressMode p_mode, CompressSource p_source, float p_lossy_quality) { + return compress_from_channels(p_mode, detect_used_channels(p_source), p_lossy_quality); +} +Error Image::compress_from_channels(CompressMode p_mode, UsedChannels p_channels, float p_lossy_quality) { + switch (p_mode) { case COMPRESS_S3TC: { ERR_FAIL_COND_V(!_image_compress_bc_func, ERR_UNAVAILABLE); - _image_compress_bc_func(this, p_lossy_quality, p_source); + _image_compress_bc_func(this, p_lossy_quality, p_channels); } break; case COMPRESS_PVRTC2: { @@ -1985,12 +2010,12 @@ Error Image::compress(CompressMode p_mode, CompressSource p_source, float p_loss case COMPRESS_ETC2: { ERR_FAIL_COND_V(!_image_compress_etc2_func, ERR_UNAVAILABLE); - _image_compress_etc2_func(this, p_lossy_quality, p_source); + _image_compress_etc2_func(this, p_lossy_quality, p_channels); } break; case COMPRESS_BPTC: { ERR_FAIL_COND_V(!_image_compress_bptc_func, ERR_UNAVAILABLE); - _image_compress_bptc_func(this, p_lossy_quality, p_source); + _image_compress_bptc_func(this, p_lossy_quality, p_channels); } break; } @@ -2029,7 +2054,7 @@ Image::Image(int p_width, int p_height, bool p_mipmaps, Format p_format, const P Rect2 Image::get_used_rect() const { - if (format != FORMAT_LA8 && format != FORMAT_RGBA8 && format != FORMAT_RGBAF && format != FORMAT_RGBAH && format != FORMAT_RGBA4444 && format != FORMAT_RGBA5551) + if (format != FORMAT_LA8 && format != FORMAT_RGBA8 && format != FORMAT_RGBAF && format != FORMAT_RGBAH && format != FORMAT_RGBA4444 && format != FORMAT_RGB565) return Rect2(Point2(), Size2(width, height)); int len = data.size(); @@ -2331,12 +2356,12 @@ ImageMemLoadFunc Image::_png_mem_loader_func = NULL; ImageMemLoadFunc Image::_jpg_mem_loader_func = NULL; ImageMemLoadFunc Image::_webp_mem_loader_func = NULL; -void (*Image::_image_compress_bc_func)(Image *, float, Image::CompressSource) = NULL; -void (*Image::_image_compress_bptc_func)(Image *, float, Image::CompressSource) = NULL; +void (*Image::_image_compress_bc_func)(Image *, float, Image::UsedChannels) = NULL; +void (*Image::_image_compress_bptc_func)(Image *, float, Image::UsedChannels) = NULL; void (*Image::_image_compress_pvrtc2_func)(Image *) = NULL; void (*Image::_image_compress_pvrtc4_func)(Image *) = NULL; void (*Image::_image_compress_etc1_func)(Image *, float) = NULL; -void (*Image::_image_compress_etc2_func)(Image *, float, Image::CompressSource) = NULL; +void (*Image::_image_compress_etc2_func)(Image *, float, Image::UsedChannels) = NULL; void (*Image::_image_decompress_pvrtc)(Image *) = NULL; void (*Image::_image_decompress_bc)(Image *) = NULL; void (*Image::_image_decompress_bptc)(Image *) = NULL; @@ -2347,6 +2372,8 @@ PoolVector<uint8_t> (*Image::lossy_packer)(const Ref<Image> &, float) = NULL; Ref<Image> (*Image::lossy_unpacker)(const PoolVector<uint8_t> &) = NULL; PoolVector<uint8_t> (*Image::lossless_packer)(const Ref<Image> &) = NULL; Ref<Image> (*Image::lossless_unpacker)(const PoolVector<uint8_t> &) = NULL; +PoolVector<uint8_t> (*Image::basis_universal_packer)(const Ref<Image> &, Image::UsedChannels) = NULL; +Ref<Image> (*Image::basis_universal_unpacker)(const PoolVector<uint8_t> &) = NULL; void Image::_set_data(const Dictionary &p_data) { @@ -2455,14 +2482,13 @@ Color Image::get_pixel(int p_x, int p_y) const { float a = (u & 0xF) / 15.0; return Color(r, g, b, a); } - case FORMAT_RGBA5551: { + case FORMAT_RGB565: { uint16_t u = ((uint16_t *)ptr)[ofs]; - float r = ((u >> 11) & 0x1F) / 15.0; - float g = ((u >> 6) & 0x1F) / 15.0; - float b = ((u >> 1) & 0x1F) / 15.0; - float a = (u & 0x1) / 1.0; - return Color(r, g, b, a); + float r = (u & 0x1F) / 31.0; + float g = ((u >> 5) & 0x3F) / 63.0; + float b = ((u >> 11) & 0x1F) / 31.0; + return Color(r, g, b, 1.0); } case FORMAT_RF: { @@ -2583,14 +2609,13 @@ void Image::set_pixel(int p_x, int p_y, const Color &p_color) { ((uint16_t *)ptr)[ofs] = rgba; } break; - case FORMAT_RGBA5551: { + case FORMAT_RGB565: { uint16_t rgba = 0; - rgba = uint16_t(CLAMP(p_color.r * 31.0, 0, 31)) << 11; - rgba |= uint16_t(CLAMP(p_color.g * 31.0, 0, 31)) << 6; - rgba |= uint16_t(CLAMP(p_color.b * 31.0, 0, 31)) << 1; - rgba |= uint16_t(p_color.a > 0.5 ? 1 : 0); + rgba = uint16_t(CLAMP(p_color.r * 31.0, 0, 31)); + rgba |= uint16_t(CLAMP(p_color.g * 63.0, 0, 33)) << 5; + rgba |= uint16_t(CLAMP(p_color.b * 31.0, 0, 31)) << 11; ((uint16_t *)ptr)[ofs] = rgba; @@ -2650,10 +2675,10 @@ void Image::set_pixel(int p_x, int p_y, const Color &p_color) { } } -Image::DetectChannels Image::get_detected_channels() { +Image::UsedChannels Image::detect_used_channels(CompressSource p_source) { - ERR_FAIL_COND_V(data.size() == 0, DETECTED_RGBA); - ERR_FAIL_COND_V(is_compressed(), DETECTED_RGBA); + ERR_FAIL_COND_V(data.size() == 0, USED_CHANNELS_RGBA); + ERR_FAIL_COND_V(is_compressed(), USED_CHANNELS_RGBA); bool r = false, g = false, b = false, a = false, c = false; lock(); for (int i = 0; i < width; i++) { @@ -2678,31 +2703,42 @@ Image::DetectChannels Image::get_detected_channels() { unlock(); - if (!c && !a) - return DETECTED_L; - if (!c && a) - return DETECTED_LA; + UsedChannels used_channels; - if (r && !g && !b && !a) - return DETECTED_R; + if (!c && !a) + used_channels = USED_CHANNELS_L; + else if (!c && a) + used_channels = USED_CHANNELS_LA; + else if (r && !g && !b && !a) + used_channels = USED_CHANNELS_R; + else if (r && g && !b && !a) + used_channels = USED_CHANNELS_RG; + else if (r && g && b && !a) + used_channels = USED_CHANNELS_RGB; + else + used_channels = USED_CHANNELS_RGBA; - if (r && g && !b && !a) - return DETECTED_RG; + if (p_source == COMPRESS_SOURCE_SRGB && (used_channels == USED_CHANNELS_R || used_channels == USED_CHANNELS_RG)) { + //R and RG do not support SRGB + used_channels = USED_CHANNELS_RGB; + } - if (r && g && b && !a) - return DETECTED_RGB; + if (p_source == COMPRESS_SOURCE_NORMAL) { + //use RG channels only for normal + used_channels = USED_CHANNELS_RG; + } - return DETECTED_RGBA; + return used_channels; } void Image::optimize_channels() { - switch (get_detected_channels()) { - case DETECTED_L: convert(FORMAT_L8); break; - case DETECTED_LA: convert(FORMAT_LA8); break; - case DETECTED_R: convert(FORMAT_R8); break; - case DETECTED_RG: convert(FORMAT_RG8); break; - case DETECTED_RGB: convert(FORMAT_RGB8); break; - case DETECTED_RGBA: convert(FORMAT_RGBA8); break; + switch (detect_used_channels()) { + case USED_CHANNELS_L: convert(FORMAT_L8); break; + case USED_CHANNELS_LA: convert(FORMAT_LA8); break; + case USED_CHANNELS_R: convert(FORMAT_R8); break; + case USED_CHANNELS_RG: convert(FORMAT_RG8); break; + case USED_CHANNELS_RGB: convert(FORMAT_RGB8); break; + case USED_CHANNELS_RGBA: convert(FORMAT_RGBA8); break; } } @@ -2742,7 +2778,9 @@ void Image::_bind_methods() { ClassDB::bind_method(D_METHOD("detect_alpha"), &Image::detect_alpha); ClassDB::bind_method(D_METHOD("is_invisible"), &Image::is_invisible); - ClassDB::bind_method(D_METHOD("compress", "mode", "source", "lossy_quality"), &Image::compress); + ClassDB::bind_method(D_METHOD("detect_used_channels", "source"), &Image::detect_used_channels, DEFVAL(COMPRESS_SOURCE_GENERIC)); + ClassDB::bind_method(D_METHOD("compress", "mode", "source", "lossy_quality"), &Image::compress, DEFVAL(COMPRESS_SOURCE_GENERIC), DEFVAL(0.7)); + ClassDB::bind_method(D_METHOD("compress_from_channels", "mode", "channels", "lossy_quality"), &Image::compress, DEFVAL(0.7)); ClassDB::bind_method(D_METHOD("decompress"), &Image::decompress); ClassDB::bind_method(D_METHOD("is_compressed"), &Image::is_compressed); @@ -2790,7 +2828,7 @@ void Image::_bind_methods() { BIND_ENUM_CONSTANT(FORMAT_RGB8); BIND_ENUM_CONSTANT(FORMAT_RGBA8); BIND_ENUM_CONSTANT(FORMAT_RGBA4444); - BIND_ENUM_CONSTANT(FORMAT_RGBA5551); + BIND_ENUM_CONSTANT(FORMAT_RGB565); BIND_ENUM_CONSTANT(FORMAT_RF); //float BIND_ENUM_CONSTANT(FORMAT_RGF); BIND_ENUM_CONSTANT(FORMAT_RGBF); @@ -2820,6 +2858,8 @@ void Image::_bind_methods() { BIND_ENUM_CONSTANT(FORMAT_ETC2_RGB8); BIND_ENUM_CONSTANT(FORMAT_ETC2_RGBA8); BIND_ENUM_CONSTANT(FORMAT_ETC2_RGB8A1); + BIND_ENUM_CONSTANT(FORMAT_ETC2_RA_AS_RG); + BIND_ENUM_CONSTANT(FORMAT_DXT5_RA_AS_RG); BIND_ENUM_CONSTANT(FORMAT_MAX); BIND_ENUM_CONSTANT(INTERPOLATE_NEAREST); @@ -2838,17 +2878,24 @@ void Image::_bind_methods() { BIND_ENUM_CONSTANT(COMPRESS_ETC); BIND_ENUM_CONSTANT(COMPRESS_ETC2); + BIND_ENUM_CONSTANT(USED_CHANNELS_L); + BIND_ENUM_CONSTANT(USED_CHANNELS_LA); + BIND_ENUM_CONSTANT(USED_CHANNELS_R); + BIND_ENUM_CONSTANT(USED_CHANNELS_RG); + BIND_ENUM_CONSTANT(USED_CHANNELS_RGB); + BIND_ENUM_CONSTANT(USED_CHANNELS_RGBA); + BIND_ENUM_CONSTANT(COMPRESS_SOURCE_GENERIC); BIND_ENUM_CONSTANT(COMPRESS_SOURCE_SRGB); BIND_ENUM_CONSTANT(COMPRESS_SOURCE_NORMAL); } -void Image::set_compress_bc_func(void (*p_compress_func)(Image *, float, CompressSource)) { +void Image::set_compress_bc_func(void (*p_compress_func)(Image *, float, UsedChannels)) { _image_compress_bc_func = p_compress_func; } -void Image::set_compress_bptc_func(void (*p_compress_func)(Image *, float, CompressSource)) { +void Image::set_compress_bptc_func(void (*p_compress_func)(Image *, float, UsedChannels)) { _image_compress_bptc_func = p_compress_func; } @@ -2904,6 +2951,29 @@ Ref<Image> Image::rgbe_to_srgb() { return new_image; } +Ref<Image> Image::get_image_from_mipmap(int p_mipamp) const { + + int ofs, size, w, h; + get_mipmap_offset_size_and_dimensions(p_mipamp, ofs, size, w, h); + + PoolVector<uint8_t> new_data; + new_data.resize(size); + { + PoolVector<uint8_t>::Write wr = new_data.write(); + PoolVector<uint8_t>::Read rd = data.read(); + copymem(wr.ptr(), rd.ptr() + ofs, size); + } + + Ref<Image> image; + image.instance(); + image->width = w; + image->height = h; + image->format = format; + image->data = new_data; + image->mipmaps = false; + return image; +} + void Image::bumpmap_to_normalmap(float bump_scale) { ERR_FAIL_COND(!_can_modify(format)); convert(Image::FORMAT_RF); @@ -3092,6 +3162,31 @@ Error Image::load_webp_from_buffer(const PoolVector<uint8_t> &p_array) { return _load_from_buffer(p_array, _webp_mem_loader_func); } +void Image::convert_rg_to_ra_rgba8() { + ERR_FAIL_COND(format != FORMAT_RGBA8); + ERR_FAIL_COND(!data.size()); + + int s = data.size(); + PoolVector<uint8_t>::Write w = data.write(); + for (int i = 0; i < s; i += 4) { + w[i + 3] = w[i + 1]; + w[i + 1] = 0; + w[i + 2] = 0; + } +} +void Image::convert_ra_rgba8_to_rg() { + ERR_FAIL_COND(format != FORMAT_RGBA8); + ERR_FAIL_COND(!data.size()); + + int s = data.size(); + PoolVector<uint8_t>::Write w = data.write(); + for (int i = 0; i < s; i += 4) { + w[i + 1] = w[i + 3]; + w[i + 2] = 0; + w[i + 3] = 255; + } +} + Error Image::_load_from_buffer(const PoolVector<uint8_t> &p_array, ImageMemLoadFunc p_loader) { int buffer_size = p_array.size(); diff --git a/core/image.h b/core/image.h index 87387ec38e..cf1ebfad9f 100644 --- a/core/image.h +++ b/core/image.h @@ -72,7 +72,7 @@ public: FORMAT_RGB8, FORMAT_RGBA8, FORMAT_RGBA4444, - FORMAT_RGBA5551, + FORMAT_RGB565, FORMAT_RF, //float FORMAT_RGF, FORMAT_RGBF, @@ -102,6 +102,8 @@ public: FORMAT_ETC2_RGB8, FORMAT_ETC2_RGBA8, FORMAT_ETC2_RGB8A1, + FORMAT_ETC2_RA_AS_RG, //used to make basis universal happy + FORMAT_DXT5_RA_AS_RG, //used to make basis universal happy FORMAT_MAX }; @@ -117,25 +119,27 @@ public: /* INTERPOLATE GAUSS */ }; - enum CompressSource { - COMPRESS_SOURCE_GENERIC, - COMPRESS_SOURCE_SRGB, - COMPRESS_SOURCE_NORMAL, - COMPRESS_SOURCE_LAYERED, + //this is used for compression + enum UsedChannels { + USED_CHANNELS_L, + USED_CHANNELS_LA, + USED_CHANNELS_R, + USED_CHANNELS_RG, + USED_CHANNELS_RGB, + USED_CHANNELS_RGBA, }; - //some functions provided by something else static ImageMemLoadFunc _png_mem_loader_func; static ImageMemLoadFunc _jpg_mem_loader_func; static ImageMemLoadFunc _webp_mem_loader_func; - static void (*_image_compress_bc_func)(Image *, float, CompressSource p_source); - static void (*_image_compress_bptc_func)(Image *, float p_lossy_quality, CompressSource p_source); + static void (*_image_compress_bc_func)(Image *, float, UsedChannels p_channels); + static void (*_image_compress_bptc_func)(Image *, float p_lossy_quality, UsedChannels p_channels); static void (*_image_compress_pvrtc2_func)(Image *); static void (*_image_compress_pvrtc4_func)(Image *); static void (*_image_compress_etc1_func)(Image *, float); - static void (*_image_compress_etc2_func)(Image *, float, CompressSource p_source); + static void (*_image_compress_etc2_func)(Image *, float, UsedChannels p_channels); static void (*_image_decompress_pvrtc)(Image *); static void (*_image_decompress_bc)(Image *); @@ -147,6 +151,8 @@ public: static Ref<Image> (*lossy_unpacker)(const PoolVector<uint8_t> &p_buffer); static PoolVector<uint8_t> (*lossless_packer)(const Ref<Image> &p_image); static Ref<Image> (*lossless_unpacker)(const PoolVector<uint8_t> &p_buffer); + static PoolVector<uint8_t> (*basis_universal_packer)(const Ref<Image> &p_image, UsedChannels p_channels); + static Ref<Image> (*basis_universal_unpacker)(const PoolVector<uint8_t> &p_buffer); PoolVector<uint8_t>::Write write_lock; @@ -292,6 +298,7 @@ public: static int get_image_required_mipmaps(int p_width, int p_height, Format p_format); static Size2i get_image_mipmap_size(int p_width, int p_height, Format p_format, int p_mipmap); static int get_image_mipmap_offset(int p_width, int p_height, Format p_format, int p_mipmap); + static int get_image_mipmap_offset_and_dimensions(int p_width, int p_height, Format p_format, int p_mipmap, int &r_w, int &r_h); enum CompressMode { COMPRESS_S3TC, @@ -301,8 +308,14 @@ public: COMPRESS_ETC2, COMPRESS_BPTC }; + enum CompressSource { + COMPRESS_SOURCE_GENERIC, + COMPRESS_SOURCE_SRGB, + COMPRESS_SOURCE_NORMAL + }; - Error compress(CompressMode p_mode = COMPRESS_S3TC, CompressSource p_source = COMPRESS_SOURCE_GENERIC, float p_lossy_quality = 0.7); + Error compress(CompressMode p_mode, CompressSource p_source = COMPRESS_SOURCE_GENERIC, float p_lossy_quality = 0.7); + Error compress_from_channels(CompressMode p_mode, UsedChannels p_channels, float p_lossy_quality = 0.7); Error decompress(); bool is_compressed() const; @@ -311,6 +324,7 @@ public: void srgb_to_linear(); void normalmap_to_xy(); Ref<Image> rgbe_to_srgb(); + Ref<Image> get_image_from_mipmap(int p_mipamp) const; void bumpmap_to_normalmap(float bump_scale = 1.0); void blit_rect(const Ref<Image> &p_src, const Rect2 &p_src_rect, const Point2 &p_dest); @@ -322,14 +336,17 @@ public: Rect2 get_used_rect() const; Ref<Image> get_rect(const Rect2 &p_area) const; - static void set_compress_bc_func(void (*p_compress_func)(Image *, float, CompressSource)); - static void set_compress_bptc_func(void (*p_compress_func)(Image *, float, CompressSource)); + static void set_compress_bc_func(void (*p_compress_func)(Image *, float, UsedChannels)); + static void set_compress_bptc_func(void (*p_compress_func)(Image *, float, UsedChannels)); static String get_format_name(Format p_format); Error load_png_from_buffer(const PoolVector<uint8_t> &p_array); Error load_jpg_from_buffer(const PoolVector<uint8_t> &p_array); Error load_webp_from_buffer(const PoolVector<uint8_t> &p_array); + void convert_rg_to_ra_rgba8(); + void convert_ra_rgba8_to_rg(); + Image(const uint8_t *p_mem_png_jpg, int p_len = -1); Image(const char **p_xpm); @@ -338,17 +355,7 @@ public: void lock(); void unlock(); - //this is used for compression - enum DetectChannels { - DETECTED_L, - DETECTED_LA, - DETECTED_R, - DETECTED_RG, - DETECTED_RGB, - DETECTED_RGBA, - }; - - DetectChannels get_detected_channels(); + UsedChannels detect_used_channels(CompressSource p_source = COMPRESS_SOURCE_GENERIC); void optimize_channels(); Color get_pixelv(const Point2 &p_src) const; @@ -372,6 +379,7 @@ VARIANT_ENUM_CAST(Image::Format) VARIANT_ENUM_CAST(Image::Interpolation) VARIANT_ENUM_CAST(Image::CompressMode) VARIANT_ENUM_CAST(Image::CompressSource) +VARIANT_ENUM_CAST(Image::UsedChannels) VARIANT_ENUM_CAST(Image::AlphaMode) #endif diff --git a/core/io/config_file.cpp b/core/io/config_file.cpp index 74e85d0cc0..5968972143 100644 --- a/core/io/config_file.cpp +++ b/core/io/config_file.cpp @@ -86,9 +86,10 @@ void ConfigFile::set_value(const String &p_section, const String &p_key, const V Variant ConfigFile::get_value(const String &p_section, const String &p_key, Variant p_default) const { if (!values.has(p_section) || !values[p_section].has(p_key)) { - ERR_FAIL_COND_V_MSG(p_default.get_type() == Variant::NIL, p_default, "Couldn't find the given section/key and no default was given."); + ERR_FAIL_COND_V_MSG(p_default.get_type() == Variant::NIL, Variant(), "Couldn't find the given section '" + p_section + "', key '" + p_key + "' and no default was given."); return p_default; } + return values[p_section][p_key]; } |