From fdb94e340960061bdc38ef9a2ce0cd84bbfc5e3e Mon Sep 17 00:00:00 2001 From: Anish Bhobe Date: Sat, 9 Mar 2019 17:06:37 +0530 Subject: [PATCH 01/18] Fixes physic_fps=0 bug. Added a condition to check if the loop exited without iteration being run by checking the return value from idle(). Fixes: #26321 (cherry picked from commit 3c27980a178ce26e584b36ea4bf2fc3f661c903b) --- main/main.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/main/main.cpp b/main/main.cpp index e8504d67680..efcfb1a749e 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -1876,7 +1876,9 @@ bool Main::iteration() { uint64_t idle_begin = OS::get_singleton()->get_ticks_usec(); - OS::get_singleton()->get_main_loop()->idle(step * time_scale); + if (OS::get_singleton()->get_main_loop()->idle(step * time_scale)) { + exit = true; + } message_queue->flush(); VisualServer::get_singleton()->sync(); //sync if still drawing from previous frames. From 6b07e4b535b7b1bfcac9cc42644a128bf86ccbfc Mon Sep 17 00:00:00 2001 From: xDGameStudios Date: Mon, 11 Mar 2019 11:29:44 +0000 Subject: [PATCH 02/18] Fixed optional idx argument in add_item (OptionMeny & PopupMenu) (cherry picked from commit ffc5f360e8578140b9b43d6b4f6483931ee7aaeb) --- scene/gui/popup_menu.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp index 01cec6fd31a..23c61f37d6b 100644 --- a/scene/gui/popup_menu.cpp +++ b/scene/gui/popup_menu.cpp @@ -594,7 +594,7 @@ void PopupMenu::add_item(const String &p_label, int p_ID, uint32_t p_accel) { item.text = p_label; item.xl_text = tr(p_label); item.accel = p_accel; - item.ID = p_ID; + item.ID = p_ID == -1 ? items.size() : p_ID; items.push_back(item); update(); minimum_size_changed(); @@ -632,7 +632,7 @@ void PopupMenu::add_check_item(const String &p_label, int p_ID, uint32_t p_accel item.text = p_label; item.xl_text = tr(p_label); item.accel = p_accel; - item.ID = p_ID; + item.ID = p_ID == -1 ? items.size() : p_ID; item.checkable_type = Item::CHECKABLE_TYPE_CHECK_BOX; items.push_back(item); update(); From c6ee986f53521372987ead32b528c70565947872 Mon Sep 17 00:00:00 2001 From: Shinryuuji Date: Sat, 22 Dec 2018 15:10:18 +0100 Subject: [PATCH 03/18] Add support for 8bpp bmp files (cherry picked from commit b9578b8f4662ac4de7e4381b384d5e9ec9a3587b) --- modules/bmp/image_loader_bmp.cpp | 62 +++++++++++++++++++------------- modules/bmp/image_loader_bmp.h | 22 +++++++----- 2 files changed, 50 insertions(+), 34 deletions(-) diff --git a/modules/bmp/image_loader_bmp.cpp b/modules/bmp/image_loader_bmp.cpp index a8172c7f520..509b30c7e61 100644 --- a/modules/bmp/image_loader_bmp.cpp +++ b/modules/bmp/image_loader_bmp.cpp @@ -46,11 +46,11 @@ Error ImageLoaderBMP::convert_to_image(Ref p_image, size_t height = (size_t)p_header.bmp_info_header.bmp_height; size_t bits_per_pixel = (size_t)p_header.bmp_info_header.bmp_bit_count; - if (p_header.bmp_info_header.bmp_compression != 0) { + if (p_header.bmp_info_header.bmp_compression != BI_RGB) { err = FAILED; } - if (!(bits_per_pixel == 24 || bits_per_pixel == 32)) { + if (!(bits_per_pixel == 8 || bits_per_pixel == 24 || bits_per_pixel == 32)) { err = FAILED; } @@ -67,11 +67,26 @@ Error ImageLoaderBMP::convert_to_image(Ref p_image, PoolVector::Write image_data_w = image_data.write(); uint8_t *write_buffer = image_data_w.ptr(); + const uint32_t color_index_max = p_header.bmp_info_header.bmp_colors_used - 1; const uint8_t *line = p_buffer + (line_width * (height - 1)); for (unsigned int i = 0; i < height; i++) { const uint8_t *line_ptr = line; for (unsigned int j = 0; j < width; j++) { switch (bits_per_pixel) { + case 8: { + uint8_t color_index = CLAMP(*line_ptr, 0, color_index_max); + uint32_t color = 0x000000; + + if (p_color_buffer != NULL) + color = ((uint32_t *)p_color_buffer)[color_index]; + + write_buffer[index + 2] = color & 0xff; + write_buffer[index + 1] = (color >> 8) & 0xff; + write_buffer[index + 0] = (color >> 16) & 0xff; + write_buffer[index + 3] = 0xff; + index += 4; + line_ptr += 1; + } break; case 24: { uint32_t color = *((uint32_t *)line_ptr); @@ -108,7 +123,12 @@ Error ImageLoaderBMP::load_image(Ref p_image, FileAccess *f, bmp_header_s bmp_header; Error err = ERR_INVALID_DATA; - if (f->get_len() > sizeof(bmp_header)) { + static const size_t FILE_HEADER_SIZE = 14; + static const size_t INFO_HEADER_SIZE = 40; + + // A valid bmp file should always at least have a + // file header and a minimal info header + if (f->get_len() > FILE_HEADER_SIZE + INFO_HEADER_SIZE) { // File Header bmp_header.bmp_file_header.bmp_signature = f->get_16(); if (bmp_header.bmp_file_header.bmp_signature == BITMAP_SIGNATURE) { @@ -129,35 +149,27 @@ Error ImageLoaderBMP::load_image(Ref p_image, FileAccess *f, bmp_header.bmp_info_header.bmp_colors_used = f->get_32(); bmp_header.bmp_info_header.bmp_important_colors = f->get_32(); - bmp_header.bmp_info_header.bmp_red_mask = f->get_32(); - bmp_header.bmp_info_header.bmp_green_mask = f->get_32(); - bmp_header.bmp_info_header.bmp_blue_mask = f->get_32(); - bmp_header.bmp_info_header.bmp_alpha_mask = f->get_32(); - bmp_header.bmp_info_header.bmp_cs_type = f->get_32(); - for (int i = 0; i < 9; i++) - bmp_header.bmp_info_header.bmp_endpoints[i] = f->get_32(); + // Compressed bitmaps not supported, stop parsing + if (bmp_header.bmp_info_header.bmp_compression != BI_RGB) { + ERR_EXPLAIN("Unsupported bmp file: " + f->get_path()); + f->close(); + ERR_FAIL_V(err) + } - bmp_header.bmp_info_header.bmp_gamma_red = f->get_32(); - bmp_header.bmp_info_header.bmp_gamma_green = f->get_32(); - bmp_header.bmp_info_header.bmp_gamma_blue = f->get_32(); - - f->seek(sizeof(bmp_header.bmp_file_header) + + f->seek(FILE_HEADER_SIZE + bmp_header.bmp_info_header.bmp_header_size); - uint32_t color_table_size = 0; - if (bmp_header.bmp_info_header.bmp_bit_count == 1) - color_table_size = 2; - else if (bmp_header.bmp_info_header.bmp_bit_count == 4) - color_table_size = 16; - else if (bmp_header.bmp_info_header.bmp_bit_count == 8) - color_table_size = 256; + if (bmp_header.bmp_info_header.bmp_bit_count < 16 && bmp_header.bmp_info_header.bmp_colors_used == 0) + bmp_header.bmp_info_header.bmp_colors_used = 1 << bmp_header.bmp_info_header.bmp_bit_count; + + // Color table is usually 4 bytes per color -> [B][G][R][0] + uint32_t color_table_size = bmp_header.bmp_info_header.bmp_colors_used * 4; PoolVector bmp_color_table; if (color_table_size > 0) { - err = bmp_color_table.resize(color_table_size * 4); + err = bmp_color_table.resize(color_table_size); PoolVector::Write bmp_color_table_w = bmp_color_table.write(); - f->get_buffer(bmp_color_table_w.ptr(), - bmp_header.bmp_info_header.bmp_colors_used * 4); + f->get_buffer(bmp_color_table_w.ptr(), color_table_size); } f->seek(bmp_header.bmp_file_header.bmp_file_offset); diff --git a/modules/bmp/image_loader_bmp.h b/modules/bmp/image_loader_bmp.h index d6899061d07..b27a47d4026 100644 --- a/modules/bmp/image_loader_bmp.h +++ b/modules/bmp/image_loader_bmp.h @@ -37,6 +37,19 @@ class ImageLoaderBMP : public ImageFormatLoader { protected: static const unsigned BITMAP_SIGNATURE = 0x4d42; + enum bmp_compression_s { + BI_RGB = 0x00, + BI_RLE8 = 0x01, + BI_RLE4 = 0x02, + BI_BITFIELDS = 0x03, + BI_JPEG = 0x04, + BI_PNG = 0x05, + BI_ALPHABITFIELDS = 0x06, + BI_CMYK = 0x0b, + BI_CMYKRLE8 = 0x0c, + BI_CMYKRLE4 = 0x0d + }; + struct bmp_header_s { struct bmp_file_header_s { uint16_t bmp_signature; @@ -57,15 +70,6 @@ protected: uint32_t bmp_pixels_per_meter_y; uint32_t bmp_colors_used; uint32_t bmp_important_colors; - uint32_t bmp_red_mask; - uint32_t bmp_green_mask; - uint32_t bmp_blue_mask; - uint32_t bmp_alpha_mask; - uint32_t bmp_cs_type; - uint32_t bmp_endpoints[9]; - uint32_t bmp_gamma_red; - uint32_t bmp_gamma_green; - uint32_t bmp_gamma_blue; } bmp_info_header; }; From 5dd3d3dadfa8b927d148dff8d9567a6056db5404 Mon Sep 17 00:00:00 2001 From: "Andrii Doroshenko (Xrayez)" Date: Sun, 21 Apr 2019 15:49:49 +0300 Subject: [PATCH 04/18] Import 4/1 bit bmp images Add some sanity checks according to bmp specification. Read color table and index data within the same scope and then simply extend the color palette. This particular implementation has one limitation: not all 4/1 bit images can be imported as it requires bit unpacking (size dimensions must be a multiple of 8 for 1-bit and 2 (even) for 4-bit images). (cherry picked from commit 6484da572117eaee88567f7b167ab261e28e7873) --- modules/bmp/image_loader_bmp.cpp | 172 ++++++++++++++++++++++++------- modules/bmp/image_loader_bmp.h | 4 + 2 files changed, 138 insertions(+), 38 deletions(-) diff --git a/modules/bmp/image_loader_bmp.cpp b/modules/bmp/image_loader_bmp.cpp index 509b30c7e61..bcc992db241 100644 --- a/modules/bmp/image_loader_bmp.cpp +++ b/modules/bmp/image_loader_bmp.cpp @@ -33,6 +33,7 @@ Error ImageLoaderBMP::convert_to_image(Ref p_image, const uint8_t *p_buffer, const uint8_t *p_color_buffer, + const uint32_t color_table_size, const bmp_header_s &p_header) { Error err = OK; @@ -49,42 +50,82 @@ Error ImageLoaderBMP::convert_to_image(Ref p_image, if (p_header.bmp_info_header.bmp_compression != BI_RGB) { err = FAILED; } + // Check whether we can load it - if (!(bits_per_pixel == 8 || bits_per_pixel == 24 || bits_per_pixel == 32)) { - err = FAILED; + if (bits_per_pixel == 1) { + // Requires bit unpacking... + ERR_FAIL_COND_V(width % 8 != 0, ERR_UNAVAILABLE); + ERR_FAIL_COND_V(height % 8 != 0, ERR_UNAVAILABLE); + + } else if (bits_per_pixel == 4) { + // Requires bit unpacking... + ERR_FAIL_COND_V(width % 2 != 0, ERR_UNAVAILABLE); + ERR_FAIL_COND_V(height % 2 != 0, ERR_UNAVAILABLE); + + } else if (bits_per_pixel == 16) { + + ERR_FAIL_V(ERR_UNAVAILABLE); } - if (err == OK) { - uint32_t line_width = ((p_header.bmp_info_header.bmp_width * - p_header.bmp_info_header.bmp_bit_count / 8) + - 3) & - ~3; + // Image data (might be indexed) + PoolVector data; + int data_len = 0; - PoolVector image_data; - err = image_data.resize(width * height * 4); + if (bits_per_pixel <= 8) { // indexed + data_len = width * height; + } else { // color + data_len = width * height * 4; + } + ERR_FAIL_COND_V(data_len == 0, ERR_BUG); + err = data.resize(data_len); - PoolVector::Write image_data_w = image_data.write(); - uint8_t *write_buffer = image_data_w.ptr(); + PoolVector::Write data_w = data.write(); + uint8_t *write_buffer = data_w.ptr(); - const uint32_t color_index_max = p_header.bmp_info_header.bmp_colors_used - 1; + const uint32_t width_bytes = width * bits_per_pixel / 8; + const uint32_t line_width = (width_bytes + 3) & ~3; + + // The actual data traversal is determined by + // the data width in case of 8/4/1 bit images + const uint32_t w = bits_per_pixel >= 24 ? width : width_bytes; const uint8_t *line = p_buffer + (line_width * (height - 1)); + for (unsigned int i = 0; i < height; i++) { const uint8_t *line_ptr = line; - for (unsigned int j = 0; j < width; j++) { + + for (unsigned int j = 0; j < w; j++) { switch (bits_per_pixel) { + case 1: { + uint8_t color_index = *line_ptr; + + write_buffer[index + 0] = (color_index >> 7) & 1; + write_buffer[index + 1] = (color_index >> 6) & 1; + write_buffer[index + 2] = (color_index >> 5) & 1; + write_buffer[index + 3] = (color_index >> 4) & 1; + write_buffer[index + 4] = (color_index >> 3) & 1; + write_buffer[index + 5] = (color_index >> 2) & 1; + write_buffer[index + 6] = (color_index >> 1) & 1; + write_buffer[index + 7] = (color_index >> 0) & 1; + + index += 8; + line_ptr += 1; + } break; + case 4: { + uint8_t color_index = *line_ptr; + + write_buffer[index + 0] = (color_index >> 4) & 0x0f; + write_buffer[index + 1] = color_index & 0x0f; + + index += 2; + line_ptr += 1; + } break; case 8: { - uint8_t color_index = CLAMP(*line_ptr, 0, color_index_max); - uint32_t color = 0x000000; + uint8_t color_index = *line_ptr; - if (p_color_buffer != NULL) - color = ((uint32_t *)p_color_buffer)[color_index]; + write_buffer[index] = color_index; - write_buffer[index + 2] = color & 0xff; - write_buffer[index + 1] = (color >> 8) & 0xff; - write_buffer[index + 0] = (color >> 16) & 0xff; - write_buffer[index + 3] = 0xff; - index += 4; + index += 1; line_ptr += 1; } break; case 24: { @@ -94,6 +135,7 @@ Error ImageLoaderBMP::convert_to_image(Ref p_image, write_buffer[index + 1] = (color >> 8) & 0xff; write_buffer[index + 0] = (color >> 16) & 0xff; write_buffer[index + 3] = 0xff; + index += 4; line_ptr += 3; } break; @@ -104,6 +146,7 @@ Error ImageLoaderBMP::convert_to_image(Ref p_image, write_buffer[index + 1] = (color >> 8) & 0xff; write_buffer[index + 0] = (color >> 16) & 0xff; write_buffer[index + 3] = color >> 24; + index += 4; line_ptr += 4; } break; @@ -111,7 +154,51 @@ Error ImageLoaderBMP::convert_to_image(Ref p_image, } line -= line_width; } - p_image->create(width, height, 0, Image::FORMAT_RGBA8, image_data); + + if (p_color_buffer == NULL || color_table_size == 0) { // regular pixels + + p_image->create(width, height, 0, Image::FORMAT_RGBA8, data); + + } else { // data is in indexed format, extend it + + // Palette data + PoolVector palette_data; + palette_data.resize(color_table_size * 4); + + PoolVector::Write palette_data_w = palette_data.write(); + uint8_t *pal = palette_data_w.ptr(); + + const uint8_t *cb = p_color_buffer; + + for (unsigned int i = 0; i < color_table_size; ++i) { + uint32_t color = *((uint32_t *)cb); + + pal[i * 4 + 0] = (color >> 16) & 0xff; + pal[i * 4 + 1] = (color >> 8) & 0xff; + pal[i * 4 + 2] = (color)&0xff; + pal[i * 4 + 3] = 0xff; + + cb += 4; + } + // Extend palette to image + PoolVector extended_data; + extended_data.resize(data.size() * 4); + + PoolVector::Write ex_w = extended_data.write(); + uint8_t *dest = ex_w.ptr(); + + const int num_pixels = width * height; + + for (int i = 0; i < num_pixels; i++) { + dest[0] = pal[write_buffer[i] * 4 + 0]; + dest[1] = pal[write_buffer[i] * 4 + 1]; + dest[2] = pal[write_buffer[i] * 4 + 2]; + dest[3] = pal[write_buffer[i] * 4 + 3]; + + dest += 4; + } + p_image->create(width, height, 0, Image::FORMAT_RGBA8, extended_data); + } } } return err; @@ -123,12 +210,9 @@ Error ImageLoaderBMP::load_image(Ref p_image, FileAccess *f, bmp_header_s bmp_header; Error err = ERR_INVALID_DATA; - static const size_t FILE_HEADER_SIZE = 14; - static const size_t INFO_HEADER_SIZE = 40; - // A valid bmp file should always at least have a // file header and a minimal info header - if (f->get_len() > FILE_HEADER_SIZE + INFO_HEADER_SIZE) { + if (f->get_len() > BITMAP_FILE_HEADER_SIZE + BITMAP_INFO_HEADER_MIN_SIZE) { // File Header bmp_header.bmp_file_header.bmp_signature = f->get_16(); if (bmp_header.bmp_file_header.bmp_signature == BITMAP_SIGNATURE) { @@ -138,9 +222,14 @@ Error ImageLoaderBMP::load_image(Ref p_image, FileAccess *f, // Info Header bmp_header.bmp_info_header.bmp_header_size = f->get_32(); + ERR_FAIL_COND_V(bmp_header.bmp_info_header.bmp_header_size < BITMAP_INFO_HEADER_MIN_SIZE, ERR_FILE_CORRUPT); + bmp_header.bmp_info_header.bmp_width = f->get_32(); bmp_header.bmp_info_header.bmp_height = f->get_32(); + bmp_header.bmp_info_header.bmp_planes = f->get_16(); + ERR_FAIL_COND_V(bmp_header.bmp_info_header.bmp_planes != 1, ERR_FILE_CORRUPT); + bmp_header.bmp_info_header.bmp_bit_count = f->get_16(); bmp_header.bmp_info_header.bmp_compression = f->get_32(); bmp_header.bmp_info_header.bmp_size_image = f->get_32(); @@ -153,23 +242,30 @@ Error ImageLoaderBMP::load_image(Ref p_image, FileAccess *f, if (bmp_header.bmp_info_header.bmp_compression != BI_RGB) { ERR_EXPLAIN("Unsupported bmp file: " + f->get_path()); f->close(); - ERR_FAIL_V(err) + ERR_FAIL_V(ERR_UNAVAILABLE); } + // Don't rely on sizeof(bmp_file_header) as structure padding + // adds 2 bytes offset leading to misaligned color table reading + uint32_t ct_offset = BITMAP_FILE_HEADER_SIZE + + bmp_header.bmp_info_header.bmp_header_size; + f->seek(ct_offset); - f->seek(FILE_HEADER_SIZE + - bmp_header.bmp_info_header.bmp_header_size); + uint32_t color_table_size = 0; - if (bmp_header.bmp_info_header.bmp_bit_count < 16 && bmp_header.bmp_info_header.bmp_colors_used == 0) - bmp_header.bmp_info_header.bmp_colors_used = 1 << bmp_header.bmp_info_header.bmp_bit_count; - - // Color table is usually 4 bytes per color -> [B][G][R][0] - uint32_t color_table_size = bmp_header.bmp_info_header.bmp_colors_used * 4; + // bmp_colors_used may report 0 despite having a color table + // for 4 and 1 bit images, so don't rely on this information + if (bmp_header.bmp_info_header.bmp_bit_count <= 8) { + // Support 256 colors max + color_table_size = 1 << bmp_header.bmp_info_header.bmp_bit_count; + } + ERR_FAIL_COND_V(color_table_size == 0, ERR_BUG); PoolVector bmp_color_table; if (color_table_size > 0) { - err = bmp_color_table.resize(color_table_size); + // Color table is usually 4 bytes per color -> [B][G][R][0] + err = bmp_color_table.resize(color_table_size * 4); PoolVector::Write bmp_color_table_w = bmp_color_table.write(); - f->get_buffer(bmp_color_table_w.ptr(), color_table_size); + f->get_buffer(bmp_color_table_w.ptr(), color_table_size * 4); } f->seek(bmp_header.bmp_file_header.bmp_file_offset); @@ -186,7 +282,7 @@ Error ImageLoaderBMP::load_image(Ref p_image, FileAccess *f, PoolVector::Read bmp_buffer_r = bmp_buffer.read(); PoolVector::Read bmp_color_table_r = bmp_color_table.read(); err = convert_to_image(p_image, bmp_buffer_r.ptr(), - bmp_color_table_r.ptr(), bmp_header); + bmp_color_table_r.ptr(), color_table_size, bmp_header); } f->close(); } diff --git a/modules/bmp/image_loader_bmp.h b/modules/bmp/image_loader_bmp.h index b27a47d4026..0082cf778a8 100644 --- a/modules/bmp/image_loader_bmp.h +++ b/modules/bmp/image_loader_bmp.h @@ -37,6 +37,9 @@ class ImageLoaderBMP : public ImageFormatLoader { protected: static const unsigned BITMAP_SIGNATURE = 0x4d42; + static const unsigned BITMAP_FILE_HEADER_SIZE = 14; // bmp_file_header_s + static const unsigned BITMAP_INFO_HEADER_MIN_SIZE = 40; // bmp_info_header_s + enum bmp_compression_s { BI_RGB = 0x00, BI_RLE8 = 0x01, @@ -76,6 +79,7 @@ protected: static Error convert_to_image(Ref p_image, const uint8_t *p_buffer, const uint8_t *p_color_buffer, + const uint32_t color_table_size, const bmp_header_s &p_header); public: From f8dce7ade942bbd7f4e024d80e2f93579ad16708 Mon Sep 17 00:00:00 2001 From: "Andrii Doroshenko (Xrayez)" Date: Wed, 17 Jul 2019 01:43:33 +0300 Subject: [PATCH 05/18] Fix BMP loader incorrectly interpreting color table size Color table should exist for images with bit count <= 8. Importing 16-bit BMP images could also likely have a color table but they're not currently supported in Godot. (cherry picked from commit d5c5aabbf28bdae7e7b5e2be0b66f640a0cd62cf) --- modules/bmp/image_loader_bmp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/bmp/image_loader_bmp.cpp b/modules/bmp/image_loader_bmp.cpp index bcc992db241..904dd1b7d9d 100644 --- a/modules/bmp/image_loader_bmp.cpp +++ b/modules/bmp/image_loader_bmp.cpp @@ -257,8 +257,8 @@ Error ImageLoaderBMP::load_image(Ref p_image, FileAccess *f, if (bmp_header.bmp_info_header.bmp_bit_count <= 8) { // Support 256 colors max color_table_size = 1 << bmp_header.bmp_info_header.bmp_bit_count; + ERR_FAIL_COND_V(color_table_size == 0, ERR_BUG); } - ERR_FAIL_COND_V(color_table_size == 0, ERR_BUG); PoolVector bmp_color_table; if (color_table_size > 0) { From 9114357bc50246192ba7e93a86a28b4aaaab7277 Mon Sep 17 00:00:00 2001 From: "Andrii Doroshenko (Xrayez)" Date: Wed, 17 Jul 2019 20:28:35 +0300 Subject: [PATCH 06/18] Fix BMP loader to distinguish between compression types Some of the values in compression enumeration represent uncompressed formats: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-wmf/4e588f70-bd92-4a6f-b77f-35d0feaf7a57 This allows the loader to proceed with uncompressed formats. Note that loading compressed BMP's is still not supported. (cherry picked from commit 422a8ffe02c5b914739bbc8ad07057c323ba11e8) --- modules/bmp/image_loader_bmp.cpp | 18 ++++++++++-------- modules/bmp/image_loader_bmp.h | 8 ++++---- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/modules/bmp/image_loader_bmp.cpp b/modules/bmp/image_loader_bmp.cpp index 904dd1b7d9d..224d058c0a8 100644 --- a/modules/bmp/image_loader_bmp.cpp +++ b/modules/bmp/image_loader_bmp.cpp @@ -47,9 +47,6 @@ Error ImageLoaderBMP::convert_to_image(Ref p_image, size_t height = (size_t)p_header.bmp_info_header.bmp_height; size_t bits_per_pixel = (size_t)p_header.bmp_info_header.bmp_bit_count; - if (p_header.bmp_info_header.bmp_compression != BI_RGB) { - err = FAILED; - } // Check whether we can load it if (bits_per_pixel == 1) { @@ -238,11 +235,16 @@ Error ImageLoaderBMP::load_image(Ref p_image, FileAccess *f, bmp_header.bmp_info_header.bmp_colors_used = f->get_32(); bmp_header.bmp_info_header.bmp_important_colors = f->get_32(); - // Compressed bitmaps not supported, stop parsing - if (bmp_header.bmp_info_header.bmp_compression != BI_RGB) { - ERR_EXPLAIN("Unsupported bmp file: " + f->get_path()); - f->close(); - ERR_FAIL_V(ERR_UNAVAILABLE); + switch (bmp_header.bmp_info_header.bmp_compression) { + case BI_RLE8: + case BI_RLE4: + case BI_CMYKRLE8: + case BI_CMYKRLE4: { + // Stop parsing + ERR_EXPLAIN("Compressed BMP files are not supported: " + f->get_path()); + f->close(); + ERR_FAIL_V(ERR_UNAVAILABLE); + } break; } // Don't rely on sizeof(bmp_file_header) as structure padding // adds 2 bytes offset leading to misaligned color table reading diff --git a/modules/bmp/image_loader_bmp.h b/modules/bmp/image_loader_bmp.h index 0082cf778a8..2debb19a1cf 100644 --- a/modules/bmp/image_loader_bmp.h +++ b/modules/bmp/image_loader_bmp.h @@ -42,15 +42,15 @@ protected: enum bmp_compression_s { BI_RGB = 0x00, - BI_RLE8 = 0x01, - BI_RLE4 = 0x02, + BI_RLE8 = 0x01, // compressed + BI_RLE4 = 0x02, // compressed BI_BITFIELDS = 0x03, BI_JPEG = 0x04, BI_PNG = 0x05, BI_ALPHABITFIELDS = 0x06, BI_CMYK = 0x0b, - BI_CMYKRLE8 = 0x0c, - BI_CMYKRLE4 = 0x0d + BI_CMYKRLE8 = 0x0c, // compressed + BI_CMYKRLE4 = 0x0d // compressed }; struct bmp_header_s { From 41f6a800bd690829c95fb5723e218e5249b1fa72 Mon Sep 17 00:00:00 2001 From: AnthonyYoManz Date: Thu, 25 Apr 2019 21:59:07 +0100 Subject: [PATCH 07/18] Fix Crash On Close When 3D Is Disabled (cherry picked from commit fc65cc64b92d1663cf858f3c6cf4f039c2da67e8) --- scene/register_scene_types.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index 22a317060fc..3a823d3afe2 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -762,7 +762,11 @@ void unregister_scene_types() { ResourceLoader::remove_resource_format_loader(resource_loader_bmfont); resource_loader_bmfont.unref(); + //SpatialMaterial is not initialised when 3D is disabled, so it shouldn't be cleaned up either +#ifndef _3D_DISABLED SpatialMaterial::finish_shaders(); +#endif // _3D_DISABLED + ParticlesMaterial::finish_shaders(); CanvasItemMaterial::finish_shaders(); SceneStringNames::free(); From d585b1a5b16c5559daa43dddefaebcc279b2a00e Mon Sep 17 00:00:00 2001 From: XiaoLongHan Date: Sat, 27 Apr 2019 22:50:26 +0800 Subject: [PATCH 08/18] fix file system not refresh on exFAT (cherry picked from commit 9d309096c9999b7c3da02781e4a6adda5933dbb3) --- editor/editor_file_system.cpp | 6 +++--- editor/editor_file_system.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp index 3d9d5e26be4..286db917a83 100644 --- a/editor/editor_file_system.cpp +++ b/editor/editor_file_system.cpp @@ -837,7 +837,7 @@ void EditorFileSystem::_scan_fs_changes(EditorFileSystemDirectory *p_dir, const bool updated_dir = false; String cd = p_dir->get_path(); - if (current_mtime != p_dir->modified_time || using_fat_32) { + if (current_mtime != p_dir->modified_time || using_fat32_or_exfat) { updated_dir = true; p_dir->modified_time = current_mtime; @@ -1855,8 +1855,8 @@ EditorFileSystem::EditorFileSystem() { if (da->change_dir("res://.import") != OK) { da->make_dir("res://.import"); } - //this should probably also work on Unix and use the string it returns for FAT32 - using_fat_32 = da->get_filesystem_type() == "FAT32"; + // This should probably also work on Unix and use the string it returns for FAT32 or exFAT + using_fat32_or_exfat = (da->get_filesystem_type() == "FAT32" || da->get_filesystem_type() == "exFAT"); memdelete(da); scan_total = 0; diff --git a/editor/editor_file_system.h b/editor/editor_file_system.h index 2a9e3254543..3dae06fb3b6 100644 --- a/editor/editor_file_system.h +++ b/editor/editor_file_system.h @@ -234,7 +234,7 @@ class EditorFileSystem : public Node { static Error _resource_import(const String &p_path); - bool using_fat_32; //workaround for projects in FAT32 filesystem (pendrives, most of the time) + bool using_fat32_or_exfat; // Workaround for projects in FAT32 or exFAT filesystem (pendrives, most of the time) protected: void _notification(int p_what); From f1fdaf32f3c612a3eb25bae767609f0381511569 Mon Sep 17 00:00:00 2001 From: MJacred Date: Mon, 29 Apr 2019 15:40:48 +0200 Subject: [PATCH 09/18] Fix application window not listed in taskbar (X11) * for executable * for editor and exported executable (on older Cinnamon versions) (cherry picked from commit 1d86929dcb349330e54fc7450f6c72601bc9d477) --- platform/x11/context_gl_x11.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/platform/x11/context_gl_x11.cpp b/platform/x11/context_gl_x11.cpp index aadf7ee36de..9718b031643 100644 --- a/platform/x11/context_gl_x11.cpp +++ b/platform/x11/context_gl_x11.cpp @@ -191,6 +191,7 @@ Error ContextGL_X11::initialize() { swa.colormap = XCreateColormap(x11_display, RootWindow(x11_display, vi->screen), vi->visual, AllocNone); x11_window = XCreateWindow(x11_display, RootWindow(x11_display, vi->screen), 0, 0, OS::get_singleton()->get_video_mode().width, OS::get_singleton()->get_video_mode().height, 0, vi->depth, InputOutput, vi->visual, valuemask, &swa); + XStoreName(x11_display, x11_window, "Godot Engine"); ERR_FAIL_COND_V(!x11_window, ERR_UNCONFIGURED); set_class_hint(x11_display, x11_window); From 123dc78f2b36af563e92df1d108855d96d39f877 Mon Sep 17 00:00:00 2001 From: Maxime Leroy Date: Wed, 1 May 2019 20:47:38 +0200 Subject: [PATCH 10/18] Fixing Curve2D/3D baked interpolated values If bake interval is a multiple of the curve length, the curve would return NaN for some offset values (when `frac == 0.0`, it matches the start and end of the curve segment so `fmod == 0.0`, `frac` becomes NaN) ``` # Godot 3.1.1 var c = Curve3D.new() c.add_point(Vector3()) c.add_point(Vector3(0.5,0,0)) c.add_point(Vector3(1,0,0)) c.bake_interval = 0.5 c.interpolate_baked(0.5) == Vector3(NAN, NAN, NAN) ``` (cherry picked from commit 6bd271139d8192bdac9c9cf0e5fd2d007b967598) --- scene/resources/curve.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/scene/resources/curve.cpp b/scene/resources/curve.cpp index ece8ad4bb06..950518aa6e0 100644 --- a/scene/resources/curve.cpp +++ b/scene/resources/curve.cpp @@ -782,7 +782,8 @@ Vector2 Curve2D::interpolate_baked(float p_offset, bool p_cubic) const { if (idx >= bpc - 1) { return r[bpc - 1]; } else if (idx == bpc - 2) { - frac /= Math::fmod(baked_max_ofs, bake_interval); + if (frac > 0) + frac /= Math::fmod(baked_max_ofs, bake_interval); } else { frac /= bake_interval; } @@ -1352,7 +1353,8 @@ Vector3 Curve3D::interpolate_baked(float p_offset, bool p_cubic) const { if (idx >= bpc - 1) { return r[bpc - 1]; } else if (idx == bpc - 2) { - frac /= Math::fmod(baked_max_ofs, bake_interval); + if (frac > 0) + frac /= Math::fmod(baked_max_ofs, bake_interval); } else { frac /= bake_interval; } @@ -1396,7 +1398,8 @@ float Curve3D::interpolate_baked_tilt(float p_offset) const { if (idx >= bpc - 1) { return r[bpc - 1]; } else if (idx == bpc - 2) { - frac /= Math::fmod(baked_max_ofs, bake_interval); + if (frac > 0) + frac /= Math::fmod(baked_max_ofs, bake_interval); } else { frac /= bake_interval; } From 759b488b226593d3787b275fbc3e30930c2ac76f Mon Sep 17 00:00:00 2001 From: Hugo Locurcio Date: Thu, 2 May 2019 00:45:34 +0200 Subject: [PATCH 11/18] Add a property hint for DynamicFont size This caps its size to reasonable values in the Inspector. This closes #22581. (cherry picked from commit 818f756d9034abe8b1ab4ecc014666893fcb00b6) --- scene/resources/dynamic_font.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scene/resources/dynamic_font.cpp b/scene/resources/dynamic_font.cpp index fd7b67a2181..8ee98790556 100644 --- a/scene/resources/dynamic_font.cpp +++ b/scene/resources/dynamic_font.cpp @@ -1008,7 +1008,7 @@ void DynamicFont::_bind_methods() { ClassDB::bind_method(D_METHOD("get_fallback_count"), &DynamicFont::get_fallback_count); ADD_GROUP("Settings", ""); - ADD_PROPERTY(PropertyInfo(Variant::INT, "size"), "set_size", "get_size"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "size", PROPERTY_HINT_RANGE, "1,255,1"), "set_size", "get_size"); ADD_PROPERTY(PropertyInfo(Variant::INT, "outline_size", PROPERTY_HINT_RANGE, "0,255,1"), "set_outline_size", "get_outline_size"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "outline_color"), "set_outline_color", "get_outline_color"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_mipmaps"), "set_use_mipmaps", "get_use_mipmaps"); From 33b2d65f980a96cb354a46d8f688fb4234346dfd Mon Sep 17 00:00:00 2001 From: Bojidar Marinov Date: Thu, 2 May 2019 17:13:45 +0300 Subject: [PATCH 12/18] Fix slight issues with autocompletion and member lists in GDScript Fixes #27152 Fixes #28591 (cherry picked from commit f9d95309024c7b7dac5c12b891cb90982f566565) --- modules/gdscript/gdscript.cpp | 2 +- modules/gdscript/gdscript_editor.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index 0676317f6ea..a8b51f699cb 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -226,7 +226,7 @@ void GDScript::get_script_method_list(List *p_list) const { const GDScript *current = this; while (current) { - for (const Map::Element *E = member_functions.front(); E; E = E->next()) { + for (const Map::Element *E = current->member_functions.front(); E; E = E->next()) { GDScriptFunction *func = E->get(); MethodInfo mi; mi.name = E->key(); diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp index dd9ffede765..54be37d9aca 100644 --- a/modules/gdscript/gdscript_editor.cpp +++ b/modules/gdscript/gdscript_editor.cpp @@ -1947,7 +1947,7 @@ static void _find_identifiers_in_base(const GDScriptCompletionContext &p_context } else { base_type.has_type = script->get_instance_base_type() != StringName(); base_type.kind = GDScriptParser::DataType::NATIVE; - base_type.script_type = script->get_instance_base_type(); + base_type.native_type = script->get_instance_base_type(); } } else { return; From cd1bb5d3dbf38d6568e0b485b679ab74d8b22314 Mon Sep 17 00:00:00 2001 From: Michael Alexsander Silva Dias Date: Fri, 3 May 2019 14:52:36 -0300 Subject: [PATCH 13/18] Make 'TabContainer' update when icon/title is changed Fixes #28655. (cherry picked from commit 37f4d51a755f8afb053544e1e63249f8659f6a2e) --- scene/gui/tab_container.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scene/gui/tab_container.cpp b/scene/gui/tab_container.cpp index 212efa49765..e78990c8436 100644 --- a/scene/gui/tab_container.cpp +++ b/scene/gui/tab_container.cpp @@ -719,6 +719,7 @@ void TabContainer::set_tab_title(int p_tab, const String &p_title) { Control *child = _get_tab(p_tab); ERR_FAIL_COND(!child); child->set_meta("_tab_name", p_title); + update(); } String TabContainer::get_tab_title(int p_tab) const { @@ -736,6 +737,7 @@ void TabContainer::set_tab_icon(int p_tab, const Ref &p_icon) { Control *child = _get_tab(p_tab); ERR_FAIL_COND(!child); child->set_meta("_tab_icon", p_icon); + update(); } Ref TabContainer::get_tab_icon(int p_tab) const { From c70a3671b059e27d75d44a76d918375ae8fde0c0 Mon Sep 17 00:00:00 2001 From: Anish Date: Sat, 4 May 2019 00:34:58 +0530 Subject: [PATCH 14/18] Fixes VideostreamGDNative crash on audio_channel=0. Added an if case to check if the mix_callback exists before running any of the audio code. Fixes: #28644 (cherry picked from commit f0757f31a44144b1d8c8a527d63f67645a4141fb) --- .../videodecoder/video_stream_gdnative.cpp | 34 ++++++++++--------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/modules/gdnative/videodecoder/video_stream_gdnative.cpp b/modules/gdnative/videodecoder/video_stream_gdnative.cpp index 9bb11862699..be131c54021 100644 --- a/modules/gdnative/videodecoder/video_stream_gdnative.cpp +++ b/modules/gdnative/videodecoder/video_stream_gdnative.cpp @@ -146,23 +146,25 @@ void VideoStreamPlaybackGDNative::update(float p_delta) { ERR_FAIL_COND(interface == NULL); interface->update(data_struct, p_delta); - if (pcm_write_idx >= 0) { - // Previous remains - int mixed = mix_callback(mix_udata, pcm, samples_decoded); - if (mixed == samples_decoded) { - pcm_write_idx = -1; - } else { - samples_decoded -= mixed; - pcm_write_idx += mixed; + if (mix_callback) { + if (pcm_write_idx >= 0) { + // Previous remains + int mixed = mix_callback(mix_udata, pcm, samples_decoded); + if (mixed == samples_decoded) { + pcm_write_idx = -1; + } else { + samples_decoded -= mixed; + pcm_write_idx += mixed; + } } - } - if (pcm_write_idx < 0) { - samples_decoded = interface->get_audioframe(data_struct, pcm, AUX_BUFFER_SIZE); - pcm_write_idx = mix_callback(mix_udata, pcm, samples_decoded); - if (pcm_write_idx == samples_decoded) { - pcm_write_idx = -1; - } else { - samples_decoded -= pcm_write_idx; + if (pcm_write_idx < 0) { + samples_decoded = interface->get_audioframe(data_struct, pcm, AUX_BUFFER_SIZE); + pcm_write_idx = mix_callback(mix_udata, pcm, samples_decoded); + if (pcm_write_idx == samples_decoded) { + pcm_write_idx = -1; + } else { + samples_decoded -= pcm_write_idx; + } } } From abf19bdab28f2394de19031ae1e1a6ae39d2209f Mon Sep 17 00:00:00 2001 From: Colin Redman <20376935+credman0@users.noreply.github.com> Date: Sat, 4 May 2019 10:08:49 -0700 Subject: [PATCH 15/18] Fix ParallaxBackground breaking when moving it out the scene tree (cherry picked from commit 359d7f178c9c64365355db10fa41492c903558b9) --- scene/2d/parallax_layer.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/scene/2d/parallax_layer.cpp b/scene/2d/parallax_layer.cpp index baf5b5967b2..9a6b63b9a34 100644 --- a/scene/2d/parallax_layer.cpp +++ b/scene/2d/parallax_layer.cpp @@ -105,6 +105,11 @@ void ParallaxLayer::_notification(int p_what) { orig_scale = get_scale(); _update_mirroring(); } break; + case NOTIFICATION_EXIT_TREE: { + + set_position(orig_offset); + set_scale(orig_scale); + } break; } } From 3689ac6c6bfc276be9eb76f6865e619a456b6d60 Mon Sep 17 00:00:00 2001 From: clayjohn Date: Fri, 14 Jun 2019 13:22:19 -0700 Subject: [PATCH 16/18] fix CPU particles bug with local_coords and transform (cherry picked from commit 52696e98b4dbba07ffb642bf675798acf312ae92) --- scene/2d/cpu_particles_2d.cpp | 45 ++++++++++++++++++++++++---- scene/2d/cpu_particles_2d.h | 2 ++ scene/3d/cpu_particles.cpp | 56 ++++++++++++++++++++++++++++++----- scene/3d/cpu_particles.h | 4 ++- 4 files changed, 93 insertions(+), 14 deletions(-) diff --git a/scene/2d/cpu_particles_2d.cpp b/scene/2d/cpu_particles_2d.cpp index 05c2253a5b0..5741084d14e 100644 --- a/scene/2d/cpu_particles_2d.cpp +++ b/scene/2d/cpu_particles_2d.cpp @@ -84,7 +84,9 @@ void CPUParticles2D::set_randomness_ratio(float p_ratio) { void CPUParticles2D::set_use_local_coordinates(bool p_enable) { local_coords = p_enable; + set_notify_transform(!p_enable); } + void CPUParticles2D::set_speed_scale(float p_scale) { speed_scale = p_scale; @@ -864,11 +866,6 @@ void CPUParticles2D::_update_particle_data_buffer() { PoolVector::Read r = particles.read(); float *ptr = w.ptr(); - Transform2D un_transform; - if (!local_coords) { - un_transform = get_global_transform().affine_inverse(); - } - if (draw_order != DRAW_ORDER_INDEX) { ow = particle_order.write(); order = ow.ptr(); @@ -890,7 +887,7 @@ void CPUParticles2D::_update_particle_data_buffer() { Transform2D t = r[idx].transform; if (!local_coords) { - t = un_transform * t; + t = inv_emission_transform * t; } if (r[idx].active) { @@ -1059,6 +1056,42 @@ void CPUParticles2D::_notification(int p_what) { _update_particle_data_buffer(); } + + if (p_what == NOTIFICATION_TRANSFORM_CHANGED) { + + inv_emission_transform = get_global_transform().affine_inverse(); + + if (!local_coords) { + + int pc = particles.size(); + + PoolVector::Write w = particle_data.write(); + PoolVector::Read r = particles.read(); + float *ptr = w.ptr(); + + for (int i = 0; i < pc; i++) { + + Transform2D t = inv_emission_transform * r[i].transform; + + if (r[i].active) { + + ptr[0] = t.elements[0][0]; + ptr[1] = t.elements[1][0]; + ptr[2] = 0; + ptr[3] = t.elements[2][0]; + ptr[4] = t.elements[0][1]; + ptr[5] = t.elements[1][1]; + ptr[6] = 0; + ptr[7] = t.elements[2][1]; + + } else { + zeromem(ptr, sizeof(float) * 8); + } + + ptr += 13; + } + } + } } void CPUParticles2D::convert_from_particles(Node *p_particles) { diff --git a/scene/2d/cpu_particles_2d.h b/scene/2d/cpu_particles_2d.h index 23d25863312..2ec7badd76c 100644 --- a/scene/2d/cpu_particles_2d.h +++ b/scene/2d/cpu_particles_2d.h @@ -142,6 +142,8 @@ private: int fixed_fps; bool fractional_delta; + Transform2D inv_emission_transform; + DrawOrder draw_order; Ref texture; diff --git a/scene/3d/cpu_particles.cpp b/scene/3d/cpu_particles.cpp index 85bc2dd5290..2b6a76ec152 100644 --- a/scene/3d/cpu_particles.cpp +++ b/scene/3d/cpu_particles.cpp @@ -909,11 +909,6 @@ void CPUParticles::_update_particle_data_buffer() { PoolVector::Read r = particles.read(); float *ptr = w.ptr(); - Transform un_transform; - if (!local_coords) { - un_transform = get_global_transform().affine_inverse(); - } - if (draw_order != DRAW_ORDER_INDEX) { ow = particle_order.write(); order = ow.ptr(); @@ -931,7 +926,12 @@ void CPUParticles::_update_particle_data_buffer() { Vector3 dir = c->get_global_transform().basis.get_axis(2); //far away to close if (local_coords) { - dir = un_transform.basis.xform(dir).normalized(); + + // will look different from Particles in editor as this is based on the camera in the scenetree + // and not the editor camera + dir = inv_emission_transform.xform(dir).normalized(); + } else { + dir = dir.normalized(); } SortArray sorter; @@ -949,7 +949,7 @@ void CPUParticles::_update_particle_data_buffer() { Transform t = r[idx].transform; if (!local_coords) { - t = un_transform * t; + t = inv_emission_transform * t; } if (r[idx].active) { @@ -1114,6 +1114,46 @@ void CPUParticles::_notification(int p_what) { _update_particle_data_buffer(); } } + + if (p_what == NOTIFICATION_TRANSFORM_CHANGED) { + + inv_emission_transform = get_global_transform().affine_inverse(); + + if (!local_coords) { + + int pc = particles.size(); + + PoolVector::Write w = particle_data.write(); + PoolVector::Read r = particles.read(); + float *ptr = w.ptr(); + + for (int i = 0; i < pc; i++) { + + Transform t = inv_emission_transform * r[i].transform; + + if (r[i].active) { + ptr[0] = t.basis.elements[0][0]; + ptr[1] = t.basis.elements[0][1]; + ptr[2] = t.basis.elements[0][2]; + ptr[3] = t.origin.x; + ptr[4] = t.basis.elements[1][0]; + ptr[5] = t.basis.elements[1][1]; + ptr[6] = t.basis.elements[1][2]; + ptr[7] = t.origin.y; + ptr[8] = t.basis.elements[2][0]; + ptr[9] = t.basis.elements[2][1]; + ptr[10] = t.basis.elements[2][2]; + ptr[11] = t.origin.z; + } else { + zeromem(ptr, sizeof(float) * 12); + } + + ptr += 17; + } + + can_update = true; + } + } } void CPUParticles::convert_from_particles(Node *p_particles) { @@ -1391,6 +1431,8 @@ CPUParticles::CPUParticles() { cycle = 0; redraw = false; + set_notify_transform(true); + multimesh = VisualServer::get_singleton()->multimesh_create(); set_base(multimesh); diff --git a/scene/3d/cpu_particles.h b/scene/3d/cpu_particles.h index b863a3cb3fc..6784d49e92c 100644 --- a/scene/3d/cpu_particles.h +++ b/scene/3d/cpu_particles.h @@ -116,7 +116,7 @@ private: const Particle *particles; bool operator()(int p_a, int p_b) const { - return particles[p_a].time < particles[p_b].time; + return particles[p_a].time > particles[p_b].time; } }; @@ -142,6 +142,8 @@ private: int fixed_fps; bool fractional_delta; + Transform inv_emission_transform; + volatile bool can_update; DrawOrder draw_order; From 61ef8e98ba79db2152087b580c895b4d7bd2d1ec Mon Sep 17 00:00:00 2001 From: clayjohn Date: Sun, 28 Jul 2019 18:31:52 -0700 Subject: [PATCH 17/18] toggle CPUParticles2D visibility when redrawing (cherry picked from commit cb4d145c22379a7ffd40965b4ba182854708c218) --- scene/2d/cpu_particles_2d.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/scene/2d/cpu_particles_2d.cpp b/scene/2d/cpu_particles_2d.cpp index 5741084d14e..7e0a42180b4 100644 --- a/scene/2d/cpu_particles_2d.cpp +++ b/scene/2d/cpu_particles_2d.cpp @@ -936,9 +936,13 @@ void CPUParticles2D::_set_redraw(bool p_redraw) { if (redraw) { VS::get_singleton()->connect("frame_pre_draw", this, "_update_render_thread"); VS::get_singleton()->canvas_item_set_update_when_visible(get_canvas_item(), true); + + VS::get_singleton()->multimesh_set_visible_instances(multimesh, -1); } else { VS::get_singleton()->disconnect("frame_pre_draw", this, "_update_render_thread"); VS::get_singleton()->canvas_item_set_update_when_visible(get_canvas_item(), false); + + VS::get_singleton()->multimesh_set_visible_instances(multimesh, 0); } #ifndef NO_THREADS update_mutex->unlock(); From 5acb21dd7bfc2800f469b03814853501076b6ace Mon Sep 17 00:00:00 2001 From: clayjohn Date: Sun, 18 Aug 2019 21:50:33 -0700 Subject: [PATCH 18/18] check if skeleton texture is already allocated before reallocating (cherry picked from commit 99de3906ba1a42f1279634bc23258ce39828c5f6) --- drivers/gles2/rasterizer_storage_gles2.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gles2/rasterizer_storage_gles2.cpp b/drivers/gles2/rasterizer_storage_gles2.cpp index bbae657cefb..1cf5c119345 100644 --- a/drivers/gles2/rasterizer_storage_gles2.cpp +++ b/drivers/gles2/rasterizer_storage_gles2.cpp @@ -3466,6 +3466,8 @@ RID RasterizerStorageGLES2::skeleton_create() { Skeleton *skeleton = memnew(Skeleton); + glGenTextures(1, &skeleton->tex_id); + return skeleton_owner.make_rid(skeleton); } @@ -3483,7 +3485,6 @@ void RasterizerStorageGLES2::skeleton_allocate(RID p_skeleton, int p_bones, bool skeleton->use_2d = p_2d_skeleton; if (config.float_texture_supported) { - glGenTextures(1, &skeleton->tex_id); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, skeleton->tex_id);