summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore3
-rw-r--r--core/math/expression.cpp4
-rw-r--r--core/ustring.cpp14
-rw-r--r--doc/classes/VisualServer.xml7
-rw-r--r--drivers/gles2/rasterizer_storage_gles2.cpp68
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.cpp74
-rw-r--r--editor/animation_track_editor.cpp5
-rw-r--r--editor/editor_file_dialog.cpp4
-rw-r--r--editor/editor_node.cpp4
-rw-r--r--editor/editor_properties.cpp11
-rw-r--r--editor/filesystem_dock.cpp8
-rw-r--r--editor/plugins/animation_blend_tree_editor_plugin.cpp2
-rw-r--r--editor/plugins/script_editor_plugin.cpp2
-rw-r--r--editor/plugins/script_text_editor.cpp4
-rw-r--r--editor/project_manager.cpp2
-rw-r--r--editor/property_editor.cpp2
-rw-r--r--modules/csg/csg_shape.cpp4
-rw-r--r--platform/android/os_android.cpp8
-rw-r--r--platform/haiku/os_haiku.cpp13
-rw-r--r--platform/iphone/os_iphone.cpp10
-rw-r--r--platform/osx/os_osx.mm1
-rw-r--r--platform/uwp/os_uwp.cpp7
-rw-r--r--platform/windows/os_windows.cpp15
-rw-r--r--platform/x11/os_x11.cpp4
-rw-r--r--scene/gui/popup_menu.cpp18
-rw-r--r--scene/main/canvas_layer.cpp10
-rw-r--r--scene/main/viewport.cpp10
-rw-r--r--scene/resources/dynamic_font.cpp20
-rw-r--r--scene/resources/dynamic_font.h2
-rw-r--r--scene/resources/primitive_meshes.cpp2
-rw-r--r--servers/physics/area_pair_sw.cpp4
-rw-r--r--servers/physics_2d/area_pair_2d_sw.cpp4
-rw-r--r--servers/visual/visual_server_raster.h2
-rw-r--r--servers/visual/visual_server_viewport.cpp10
-rw-r--r--servers/visual/visual_server_viewport.h19
-rw-r--r--servers/visual/visual_server_wrap_mt.h2
-rw-r--r--servers/visual_server.cpp2
-rw-r--r--servers/visual_server.h2
38 files changed, 265 insertions, 118 deletions
diff --git a/.gitignore b/.gitignore
index 3a05ed9e7d..fe504482b3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -311,5 +311,8 @@ platform/windows/godot_res.res
/.vs
/.vscode
+# Visual Studio Code workspace file
+*.code-workspace
+
# Scons progress indicator
.scons_node_count
diff --git a/core/math/expression.cpp b/core/math/expression.cpp
index a16267cf0a..0cfb54234c 100644
--- a/core/math/expression.cpp
+++ b/core/math/expression.cpp
@@ -2120,6 +2120,10 @@ Error Expression::parse(const String &p_expression, const Vector<String> &p_inpu
}
Variant Expression::execute(Array p_inputs, Object *p_base, bool p_show_error) {
+ if (error_set) {
+ ERR_EXPLAIN("There was previously a parse error: " + error_str);
+ ERR_FAIL_V(Variant());
+ }
execution_error = false;
Variant output;
diff --git a/core/ustring.cpp b/core/ustring.cpp
index 1195cd0719..2191bb5e23 100644
--- a/core/ustring.cpp
+++ b/core/ustring.cpp
@@ -2774,16 +2774,13 @@ String String::format(const Variant &values, String placeholder) const {
if (value_arr.size() == 2) {
Variant v_key = value_arr[0];
- String key;
-
- key = v_key.get_construct_string();
+ String key = v_key;
if (key.left(1) == "\"" && key.right(key.length() - 1) == "\"") {
key = key.substr(1, key.length() - 2);
}
Variant v_val = value_arr[1];
- String val;
- val = v_val.get_construct_string();
+ String val = v_val;
if (val.left(1) == "\"" && val.right(val.length() - 1) == "\"") {
val = val.substr(1, val.length() - 2);
@@ -2795,8 +2792,7 @@ String String::format(const Variant &values, String placeholder) const {
}
} else { //Array structure ["RobotGuy","Logis","rookie"]
Variant v_val = values_arr[i];
- String val;
- val = v_val.get_construct_string();
+ String val = v_val;
if (val.left(1) == "\"" && val.right(val.length() - 1) == "\"") {
val = val.substr(1, val.length() - 2);
@@ -2815,8 +2811,8 @@ String String::format(const Variant &values, String placeholder) const {
d.get_key_list(&keys);
for (List<Variant>::Element *E = keys.front(); E; E = E->next()) {
- String key = E->get().get_construct_string();
- String val = d[E->get()].get_construct_string();
+ String key = E->get();
+ String val = d[E->get()];
if (key.left(1) == "\"" && key.right(key.length() - 1) == "\"") {
key = key.substr(1, key.length() - 2);
diff --git a/doc/classes/VisualServer.xml b/doc/classes/VisualServer.xml
index 225a1f2bba..ed6fdacec7 100644
--- a/doc/classes/VisualServer.xml
+++ b/doc/classes/VisualServer.xml
@@ -3613,7 +3613,7 @@
If [code]true[/code] sets the viewport active, else sets it inactive.
</description>
</method>
- <method name="viewport_set_canvas_layer">
+ <method name="viewport_set_canvas_stacking">
<return type="void">
</return>
<argument index="0" name="viewport" type="RID">
@@ -3622,8 +3622,11 @@
</argument>
<argument index="2" name="layer" type="int">
</argument>
+ <argument index="3" name="sublayer" type="int">
+ </argument>
<description>
- Sets the renderlayer for a viewport's canvas.
+ Sets the stacking order for a viewport's canvas.
+ [code]layer[/code] is the actual canvas layer, while [code]sublayer[/code] specifies the stacking order of the canvas among those in the same layer.
</description>
</method>
<method name="viewport_set_canvas_transform">
diff --git a/drivers/gles2/rasterizer_storage_gles2.cpp b/drivers/gles2/rasterizer_storage_gles2.cpp
index d5865064cf..c4c5093540 100644
--- a/drivers/gles2/rasterizer_storage_gles2.cpp
+++ b/drivers/gles2/rasterizer_storage_gles2.cpp
@@ -613,8 +613,72 @@ Ref<Image> RasterizerStorageGLES2::texture_get_data(RID p_texture, int p_layer)
return Ref<Image>(img);
#else
- ERR_EXPLAIN("Sorry, It's not possible to obtain images back in OpenGL ES");
- ERR_FAIL_V(Ref<Image>());
+ Image::Format real_format;
+ GLenum gl_format;
+ GLenum gl_internal_format;
+ GLenum gl_type;
+ bool compressed;
+ _get_gl_image_and_format(Ref<Image>(), texture->format, texture->flags, real_format, gl_format, gl_internal_format, gl_type, compressed);
+
+ PoolVector<uint8_t> data;
+
+ int data_size = Image::get_image_data_size(texture->alloc_width, texture->alloc_height, Image::FORMAT_RGBA8, false);
+
+ data.resize(data_size * 2); //add some memory at the end, just in case for buggy drivers
+ PoolVector<uint8_t>::Write wb = data.write();
+
+ GLuint temp_framebuffer;
+ glGenFramebuffers(1, &temp_framebuffer);
+
+ GLuint temp_color_texture;
+ glGenTextures(1, &temp_color_texture);
+
+ glBindFramebuffer(GL_FRAMEBUFFER, temp_framebuffer);
+
+ glBindTexture(GL_TEXTURE_2D, temp_color_texture);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture->alloc_width, texture->alloc_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, temp_color_texture, 0);
+
+ glDepthMask(GL_FALSE);
+ glDisable(GL_DEPTH_TEST);
+ glDisable(GL_CULL_FACE);
+ glDisable(GL_BLEND);
+ glDepthFunc(GL_LEQUAL);
+ glColorMask(1, 1, 1, 1);
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, texture->tex_id);
+
+ glViewport(0, 0, texture->alloc_width, texture->alloc_height);
+
+ shaders.copy.bind();
+
+ glClearColor(0.0, 0.0, 0.0, 0.0);
+ glClear(GL_COLOR_BUFFER_BIT);
+ bind_quad_array();
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+ glReadPixels(0, 0, texture->alloc_width, texture->alloc_height, GL_RGBA, GL_UNSIGNED_BYTE, &wb[0]);
+
+ glDeleteTextures(1, &temp_color_texture);
+
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ glDeleteFramebuffers(1, &temp_framebuffer);
+
+ wb = PoolVector<uint8_t>::Write();
+
+ data.resize(data_size);
+
+ Image *img = memnew(Image(texture->alloc_width, texture->alloc_height, false, Image::FORMAT_RGBA8, data));
+ if (!texture->compressed) {
+ img->convert(real_format);
+ }
+
+ return Ref<Image>(img);
+
#endif
}
diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp
index 8a73804eec..c06ef805a6 100644
--- a/drivers/gles3/rasterizer_storage_gles3.cpp
+++ b/drivers/gles3/rasterizer_storage_gles3.cpp
@@ -1116,8 +1116,78 @@ Ref<Image> RasterizerStorageGLES3::texture_get_data(RID p_texture, int p_layer)
return Ref<Image>(img);
#else
- ERR_EXPLAIN("Sorry, It's not possible to obtain images back in OpenGL ES");
- ERR_FAIL_V(Ref<Image>());
+ Image::Format real_format;
+ GLenum gl_format;
+ GLenum gl_internal_format;
+ GLenum gl_type;
+ bool compressed;
+ bool srgb;
+ _get_gl_image_and_format(Ref<Image>(), texture->format, texture->flags, real_format, gl_format, gl_internal_format, gl_type, compressed, srgb);
+
+ PoolVector<uint8_t> data;
+
+ int data_size = Image::get_image_data_size(texture->alloc_width, texture->alloc_height, Image::FORMAT_RGBA8, false);
+
+ data.resize(data_size * 2); //add some memory at the end, just in case for buggy drivers
+ PoolVector<uint8_t>::Write wb = data.write();
+
+ GLuint temp_framebuffer;
+ glGenFramebuffers(1, &temp_framebuffer);
+
+ GLuint temp_color_texture;
+ glGenTextures(1, &temp_color_texture);
+
+ glBindFramebuffer(GL_FRAMEBUFFER, temp_framebuffer);
+
+ glBindTexture(GL_TEXTURE_2D, temp_color_texture);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture->alloc_width, texture->alloc_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+
+ print_line(itos(texture->alloc_width) + " xx " + itos(texture->alloc_height) + " -> " + itos(real_format));
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, temp_color_texture, 0);
+
+ glDepthMask(GL_FALSE);
+ glDisable(GL_DEPTH_TEST);
+ glDisable(GL_CULL_FACE);
+ glDisable(GL_BLEND);
+ glDepthFunc(GL_LEQUAL);
+ glColorMask(1, 1, 1, 1);
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, texture->tex_id);
+
+ glViewport(0, 0, texture->alloc_width, texture->alloc_height);
+
+ shaders.copy.bind();
+
+ shaders.copy.set_conditional(CopyShaderGLES3::LINEAR_TO_SRGB, !srgb);
+
+ glClearColor(0.0, 0.0, 0.0, 0.0);
+ glClear(GL_COLOR_BUFFER_BIT);
+ glBindVertexArray(resources.quadie_array);
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+ glBindVertexArray(0);
+
+ glReadPixels(0, 0, texture->alloc_width, texture->alloc_height, GL_RGBA, GL_UNSIGNED_BYTE, &wb[0]);
+
+ shaders.copy.set_conditional(CopyShaderGLES3::LINEAR_TO_SRGB, false);
+
+ glDeleteTextures(1, &temp_color_texture);
+
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ glDeleteFramebuffers(1, &temp_framebuffer);
+
+ wb = PoolVector<uint8_t>::Write();
+
+ data.resize(data_size);
+
+ Image *img = memnew(Image(texture->alloc_width, texture->alloc_height, false, Image::FORMAT_RGBA8, data));
+ if (!texture->compressed) {
+ img->convert(real_format);
+ }
+
+ return Ref<Image>(img);
#endif
}
diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp
index 3997469e95..37d26d8e0f 100644
--- a/editor/animation_track_editor.cpp
+++ b/editor/animation_track_editor.cpp
@@ -1685,15 +1685,10 @@ void AnimationTrackEdit::_zoom_changed() {
}
void AnimationTrackEdit::_path_entered(const String &p_text) {
-
- *block_animation_update_ptr = true;
undo_redo->create_action("Change Track Path");
undo_redo->add_do_method(animation.ptr(), "track_set_path", track, p_text);
undo_redo->add_undo_method(animation.ptr(), "track_set_path", track, animation->track_get_path(track));
undo_redo->commit_action();
- *block_animation_update_ptr = false;
- update();
- path->hide();
}
String AnimationTrackEdit::get_tooltip(const Point2 &p_pos) const {
diff --git a/editor/editor_file_dialog.cpp b/editor/editor_file_dialog.cpp
index 438d7ea306..b39f910182 100644
--- a/editor/editor_file_dialog.cpp
+++ b/editor/editor_file_dialog.cpp
@@ -580,7 +580,7 @@ void EditorFileDialog::_item_list_item_rmb_selected(int p_item, const Vector2 &p
if (single_item_selected) {
item_menu->add_separator();
Dictionary item_meta = item_list->get_item_metadata(p_item);
- String item_text = item_meta["dir"] ? TTR("Open In File Manager") : TTR("Show In File Manager");
+ String item_text = item_meta["dir"] ? TTR("Open in File Manager") : TTR("Show in File Manager");
item_menu->add_icon_item(get_icon("Filesystem", "EditorIcons"), item_text, ITEM_MENU_SHOW_IN_EXPLORER);
}
@@ -605,7 +605,7 @@ void EditorFileDialog::_item_list_rmb_clicked(const Vector2 &p_pos) {
}
item_menu->add_icon_item(get_icon("Reload", "EditorIcons"), TTR("Refresh"), ITEM_MENU_REFRESH, KEY_F5);
item_menu->add_separator();
- item_menu->add_icon_item(get_icon("Filesystem", "EditorIcons"), TTR("Open In File Manager"), ITEM_MENU_SHOW_IN_EXPLORER);
+ item_menu->add_icon_item(get_icon("Filesystem", "EditorIcons"), TTR("Open in File Manager"), ITEM_MENU_SHOW_IN_EXPLORER);
item_menu->set_position(item_list->get_global_position() + p_pos);
item_menu->popup();
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index e9ce2cb8ae..b18e4d0f35 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -3935,7 +3935,7 @@ void EditorNode::_scene_tab_input(const Ref<InputEvent> &p_input) {
scene_tabs_context_menu->add_shortcut(ED_GET_SHORTCUT("editor/save_all_scenes"), FILE_SAVE_ALL_SCENES);
if (scene_tabs->get_hovered_tab() >= 0) {
scene_tabs_context_menu->add_separator();
- scene_tabs_context_menu->add_item(TTR("Show in filesystem"), FILE_SHOW_IN_FILESYSTEM);
+ scene_tabs_context_menu->add_item(TTR("Show in FileSystem"), FILE_SHOW_IN_FILESYSTEM);
scene_tabs_context_menu->add_item(TTR("Play This Scene"), RUN_PLAY_SCENE);
scene_tabs_context_menu->add_item(TTR("Close Tab"), FILE_CLOSE);
}
@@ -5181,7 +5181,7 @@ EditorNode::EditorNode() {
p->add_separator();
p->add_shortcut(ED_SHORTCUT("editor/save_scene", TTR("Save Scene"), KEY_MASK_CMD + KEY_S), FILE_SAVE_SCENE);
p->add_shortcut(ED_SHORTCUT("editor/save_scene_as", TTR("Save Scene As..."), KEY_MASK_SHIFT + KEY_MASK_CMD + KEY_S), FILE_SAVE_AS_SCENE);
- p->add_shortcut(ED_SHORTCUT("editor/save_all_scenes", TTR("Save all Scenes"), KEY_MASK_ALT + KEY_MASK_SHIFT + KEY_MASK_CMD + KEY_S), FILE_SAVE_ALL_SCENES);
+ p->add_shortcut(ED_SHORTCUT("editor/save_all_scenes", TTR("Save All Scenes"), KEY_MASK_ALT + KEY_MASK_SHIFT + KEY_MASK_CMD + KEY_S), FILE_SAVE_ALL_SCENES);
p->add_separator();
p->add_shortcut(ED_SHORTCUT("editor/close_scene", TTR("Close Scene"), KEY_MASK_SHIFT + KEY_MASK_CMD + KEY_W), FILE_CLOSE);
p->add_separator();
diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp
index 5148c12160..b68ec97406 100644
--- a/editor/editor_properties.cpp
+++ b/editor/editor_properties.cpp
@@ -1802,8 +1802,13 @@ void EditorPropertyNodePath::_node_selected(const NodePath &p_path) {
NodePath path = p_path;
Node *base_node = Object::cast_to<Node>(get_edited_object());
- if (base_node == NULL && get_edited_object()->has_method("get_root_path")) {
- base_node = get_edited_object()->call("get_root_path");
+ if (base_node == NULL) {
+ if (Object::cast_to<Resource>(get_edited_object())) {
+ Node *to_node = get_node(p_path);
+ path = get_tree()->get_edited_scene_root()->get_path_to(to_node);
+ } else if (get_edited_object()->has_method("get_root_path")) {
+ base_node = get_edited_object()->call("get_root_path");
+ }
}
if (base_node) { // for AnimationTrackKeyEdit
path = base_node->get_path().rel_path_to(p_path);
@@ -2216,7 +2221,7 @@ void EditorPropertyResource::_update_menu() {
RES r = res;
if (r.is_valid() && r->get_path().is_resource_file()) {
menu->add_separator();
- menu->add_item(TTR("Show in File System"), OBJ_MENU_SHOW_IN_FILE_SYSTEM);
+ menu->add_item(TTR("Show in FileSystem"), OBJ_MENU_SHOW_IN_FILE_SYSTEM);
}
} else {
}
diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp
index 2136211faa..48bfa6fddb 100644
--- a/editor/filesystem_dock.cpp
+++ b/editor/filesystem_dock.cpp
@@ -2117,7 +2117,7 @@ void FileSystemDock::_file_and_folders_fill_popup(PopupMenu *p_popup, Vector<Str
p_popup->add_item(TTR("New Resource..."), FILE_NEW_RESOURCE);
String fpath = p_paths[0];
- String item_text = fpath.ends_with("/") ? TTR("Open In File Manager") : TTR("Show In File Manager");
+ String item_text = fpath.ends_with("/") ? TTR("Open in File Manager") : TTR("Show in File Manager");
p_popup->add_item(item_text, FILE_SHOW_IN_EXPLORER);
}
}
@@ -2128,8 +2128,8 @@ void FileSystemDock::_tree_rmb_select(const Vector2 &p_pos) {
if (paths.size() == 1) {
if (paths[0].ends_with("/")) {
- tree_popup->add_item(TTR("Expand all"), FOLDER_EXPAND_ALL);
- tree_popup->add_item(TTR("Collapse all"), FOLDER_COLLAPSE_ALL);
+ tree_popup->add_item(TTR("Expand All"), FOLDER_EXPAND_ALL);
+ tree_popup->add_item(TTR("Collapse All"), FOLDER_COLLAPSE_ALL);
tree_popup->add_separator();
}
}
@@ -2175,7 +2175,7 @@ void FileSystemDock::_file_list_rmb_pressed(const Vector2 &p_pos) {
file_list_popup->add_item(TTR("New Folder..."), FILE_NEW_FOLDER);
file_list_popup->add_item(TTR("New Script..."), FILE_NEW_SCRIPT);
file_list_popup->add_item(TTR("New Resource..."), FILE_NEW_RESOURCE);
- file_list_popup->add_item(TTR("Show In File Manager"), FILE_SHOW_IN_EXPLORER);
+ file_list_popup->add_item(TTR("Show in File Manager"), FILE_SHOW_IN_EXPLORER);
file_list_popup->set_position(files->get_global_position() + p_pos);
file_list_popup->popup();
}
diff --git a/editor/plugins/animation_blend_tree_editor_plugin.cpp b/editor/plugins/animation_blend_tree_editor_plugin.cpp
index 205458fb1d..b83976270f 100644
--- a/editor/plugins/animation_blend_tree_editor_plugin.cpp
+++ b/editor/plugins/animation_blend_tree_editor_plugin.cpp
@@ -833,8 +833,6 @@ void AnimationNodeBlendTreeEditor::edit(const Ref<AnimationNode> &p_node) {
if (p_node.is_valid()) {
blend_tree = p_node;
- } else {
- blend_tree.unref();
}
if (blend_tree.is_null()) {
diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp
index ac69cc0df1..03b9f7938f 100644
--- a/editor/plugins/script_editor_plugin.cpp
+++ b/editor/plugins/script_editor_plugin.cpp
@@ -2998,7 +2998,7 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) {
file_menu->get_popup()->add_separator();
file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/reload_script_soft", TTR("Soft Reload Script"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_R), FILE_TOOL_RELOAD_SOFT);
file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/copy_path", TTR("Copy Script Path")), FILE_COPY_PATH);
- file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/show_in_file_system", TTR("Show In File System")), SHOW_IN_FILE_SYSTEM);
+ file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/show_in_file_system", TTR("Show in FileSystem")), SHOW_IN_FILE_SYSTEM);
file_menu->get_popup()->add_separator();
file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/history_previous", TTR("History Previous"), KEY_MASK_ALT | KEY_LEFT), WINDOW_PREV);
diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp
index 27f5910d94..0796a93dc3 100644
--- a/editor/plugins/script_text_editor.cpp
+++ b/editor/plugins/script_text_editor.cpp
@@ -1583,8 +1583,8 @@ void ScriptTextEditor::register_editor() {
ED_SHORTCUT("script_text_editor/complete_symbol", TTR("Complete Symbol"), KEY_MASK_CMD | KEY_SPACE);
#endif
ED_SHORTCUT("script_text_editor/trim_trailing_whitespace", TTR("Trim Trailing Whitespace"), KEY_MASK_CMD | KEY_MASK_ALT | KEY_T);
- ED_SHORTCUT("script_text_editor/convert_indent_to_spaces", TTR("Convert Indent To Spaces"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_Y);
- ED_SHORTCUT("script_text_editor/convert_indent_to_tabs", TTR("Convert Indent To Tabs"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_I);
+ ED_SHORTCUT("script_text_editor/convert_indent_to_spaces", TTR("Convert Indent to Spaces"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_Y);
+ ED_SHORTCUT("script_text_editor/convert_indent_to_tabs", TTR("Convert Indent to Tabs"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_I);
ED_SHORTCUT("script_text_editor/auto_indent", TTR("Auto Indent"), KEY_MASK_CMD | KEY_I);
#ifdef OSX_ENABLED
diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp
index 83de5a646a..8c906e5f0b 100644
--- a/editor/project_manager.cpp
+++ b/editor/project_manager.cpp
@@ -1312,7 +1312,7 @@ void ProjectManager::_load_recent_projects() {
show->set_modulate(Color(1, 1, 1, 0.5));
path_hb->add_child(show);
show->connect("pressed", this, "_show_project", varray(path));
- show->set_tooltip(TTR("Show In File Manager"));
+ show->set_tooltip(TTR("Show in File Manager"));
Label *fpath = memnew(Label(path));
fpath->set_name("path");
diff --git a/editor/property_editor.cpp b/editor/property_editor.cpp
index 9ef6e4332c..8da75b7b3f 100644
--- a/editor/property_editor.cpp
+++ b/editor/property_editor.cpp
@@ -968,7 +968,7 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::
RES r = v;
if (r.is_valid() && r->get_path().is_resource_file()) {
menu->add_separator();
- menu->add_item(TTR("Show in File System"), OBJ_MENU_SHOW_IN_FILE_SYSTEM);
+ menu->add_item(TTR("Show in FileSystem"), OBJ_MENU_SHOW_IN_FILE_SYSTEM);
}
} else {
}
diff --git a/modules/csg/csg_shape.cpp b/modules/csg/csg_shape.cpp
index 44044d2750..4eb798de11 100644
--- a/modules/csg/csg_shape.cpp
+++ b/modules/csg/csg_shape.cpp
@@ -598,8 +598,8 @@ CSGBrush *CSGMesh::_build_brush() {
mw[j / 3] = mat;
}
} else {
- int is = vertices.size();
- int as = avertices.size();
+ int as = vertices.size();
+ int is = avertices.size();
vertices.resize(as + is);
smooth.resize((as + is) / 3);
diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp
index 8e050c1d27..96ff226402 100644
--- a/platform/android/os_android.cpp
+++ b/platform/android/os_android.cpp
@@ -39,7 +39,7 @@
#include "file_access_android.h"
#include "main/main.h"
#include "servers/visual/visual_server_raster.h"
-//#include "servers/visual/visual_server_wrap_mt.h"
+#include "servers/visual/visual_server_wrap_mt.h"
#ifdef ANDROID_NATIVE_ACTIVITY
#include "dir_access_android.h"
@@ -183,13 +183,11 @@ Error OS_Android::initialize(const VideoMode &p_desired, int p_video_driver, int
video_driver_index = p_video_driver;
visual_server = memnew(VisualServerRaster);
- /* if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) {
-
+ if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) {
visual_server = memnew(VisualServerWrapMT(visual_server, false));
- };*/
+ }
visual_server->init();
- // visual_server->cursor_set_visible(false, 0);
AudioDriverManager::initialize(p_audio_driver);
diff --git a/platform/haiku/os_haiku.cpp b/platform/haiku/os_haiku.cpp
index c80365f1f3..f9f12af817 100644
--- a/platform/haiku/os_haiku.cpp
+++ b/platform/haiku/os_haiku.cpp
@@ -117,16 +117,13 @@ Error OS_Haiku::initialize(const VideoMode &p_desired, int p_video_driver, int p
#endif
- visual_server = memnew(VisualServerRaster());
-
- ERR_FAIL_COND_V(!visual_server, ERR_UNAVAILABLE);
-
- // TODO: enable multithreaded VS
- /*
+ visual_server = memnew(VisualServerRaster);
+ // FIXME: Reimplement threaded rendering
if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) {
- visual_server = memnew(VisualServerWrapMT(visual_server, get_render_thread_mode() == RENDER_SEPARATE_THREAD));
+ visual_server = memnew(VisualServerWrapMT(visual_server, false));
}
- */
+
+ ERR_FAIL_COND_V(!visual_server, ERR_UNAVAILABLE);
video_driver_index = p_video_driver;
diff --git a/platform/iphone/os_iphone.cpp b/platform/iphone/os_iphone.cpp
index addef61ec7..e996a5905b 100644
--- a/platform/iphone/os_iphone.cpp
+++ b/platform/iphone/os_iphone.cpp
@@ -34,7 +34,7 @@
#include "drivers/gles3/rasterizer_gles3.h"
#include "servers/visual/visual_server_raster.h"
-//#include "servers/visual/visual_server_wrap_mt.h"
+#include "servers/visual/visual_server_wrap_mt.h"
#include "main/main.h"
@@ -107,13 +107,11 @@ Error OSIPhone::initialize(const VideoMode &p_desired, int p_video_driver, int p
RasterizerGLES3::register_config();
RasterizerGLES3::make_current();
- visual_server = memnew(VisualServerRaster());
- /*
- FIXME: Reimplement threaded rendering? Or remove?
+ visual_server = memnew(VisualServerRaster);
+ // FIXME: Reimplement threaded rendering
if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) {
visual_server = memnew(VisualServerWrapMT(visual_server, false));
- };
- */
+ }
visual_server->init();
//visual_server->cursor_set_visible(false, 0);
diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm
index 1a5a56e933..77bf8a8146 100644
--- a/platform/osx/os_osx.mm
+++ b/platform/osx/os_osx.mm
@@ -1385,7 +1385,6 @@ Error OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_a
visual_server = memnew(VisualServerRaster);
if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) {
-
visual_server = memnew(VisualServerWrapMT(visual_server, get_render_thread_mode() == RENDER_SEPARATE_THREAD));
}
diff --git a/platform/uwp/os_uwp.cpp b/platform/uwp/os_uwp.cpp
index 6410378593..2209ecb20e 100644
--- a/platform/uwp/os_uwp.cpp
+++ b/platform/uwp/os_uwp.cpp
@@ -295,13 +295,10 @@ Error OSUWP::initialize(const VideoMode &p_desired, int p_video_driver, int p_au
set_video_mode(vm);
visual_server = memnew(VisualServerRaster);
- // FIXME: Reimplement threaded rendering? Or remove?
- /*
+ // FIXME: Reimplement threaded rendering
if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) {
-
- visual_server = memnew(VisualServerWrapMT(visual_server, get_render_thread_mode() == RENDER_SEPARATE_THREAD));
+ visual_server = memnew(VisualServerWrapMT(visual_server, false));
}
- */
visual_server->init();
input = memnew(InputDefault);
diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp
index 3bbffd8fb7..f8705c4bff 100644
--- a/platform/windows/os_windows.cpp
+++ b/platform/windows/os_windows.cpp
@@ -1334,24 +1334,9 @@ Error OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int
visual_server = memnew(VisualServerRaster);
if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) {
-
visual_server = memnew(VisualServerWrapMT(visual_server, get_render_thread_mode() == RENDER_SEPARATE_THREAD));
}
- /*
- DEVMODE dmScreenSettings; // Device Mode
- memset(&dmScreenSettings,0,sizeof(dmScreenSettings)); // Makes Sure Memory's Cleared
- dmScreenSettings.dmSize=sizeof(dmScreenSettings); // Size Of The Devmode Structure
- dmScreenSettings.dmPelsWidth = width; // Selected Screen Width
- dmScreenSettings.dmPelsHeight = height; // Selected Screen Height
- dmScreenSettings.dmBitsPerPel = bits; // Selected Bits Per Pixel
- dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;
- if (ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL)
-
-
-
-
- */
visual_server->init();
input = memnew(InputDefault);
diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp
index 88c2c8aec6..8ba5833796 100644
--- a/platform/x11/os_x11.cpp
+++ b/platform/x11/os_x11.cpp
@@ -342,12 +342,12 @@ Error OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_a
context_gl->set_use_vsync(current_videomode.use_vsync);
#endif
- visual_server = memnew(VisualServerRaster);
+ visual_server = memnew(VisualServerRaster);
if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) {
-
visual_server = memnew(VisualServerWrapMT(visual_server, get_render_thread_mode() == RENDER_SEPARATE_THREAD));
}
+
if (current_videomode.maximized) {
current_videomode.maximized = false;
set_window_maximized(true);
diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp
index 3239641c2f..f84b75d8d8 100644
--- a/scene/gui/popup_menu.cpp
+++ b/scene/gui/popup_menu.cpp
@@ -557,6 +557,21 @@ void PopupMenu::_notification(int p_what) {
mouse_over = -1;
update();
}
+
+ for (int i = 0; i < items.size(); i++) {
+ if (items[i].submenu == "")
+ continue;
+
+ Node *n = get_node(items[i].submenu);
+ if (!n)
+ continue;
+
+ PopupMenu *pm = Object::cast_to<PopupMenu>(n);
+ if (!pm || !pm->is_visible())
+ continue;
+
+ pm->hide();
+ }
} break;
}
}
@@ -1012,8 +1027,7 @@ bool PopupMenu::activate_item_by_event(const Ref<InputEvent> &p_event, bool p_fo
code |= KEY_MASK_SHIFT;
}
- int il = items.size();
- for (int i = 0; i < il; i++) {
+ for (int i = 0; i < items.size(); i++) {
if (is_item_disabled(i) || items[i].shortcut_is_disabled)
continue;
diff --git a/scene/main/canvas_layer.cpp b/scene/main/canvas_layer.cpp
index a2e890e7a7..0f5fd99281 100644
--- a/scene/main/canvas_layer.cpp
+++ b/scene/main/canvas_layer.cpp
@@ -35,7 +35,7 @@ void CanvasLayer::set_layer(int p_xform) {
layer = p_xform;
if (viewport.is_valid())
- VisualServer::get_singleton()->viewport_set_canvas_layer(viewport, canvas, layer);
+ VisualServer::get_singleton()->viewport_set_canvas_stacking(viewport, canvas, layer, get_position_in_parent());
}
int CanvasLayer::get_layer() const {
@@ -149,7 +149,7 @@ void CanvasLayer::_notification(int p_what) {
viewport = vp->get_viewport_rid();
VisualServer::get_singleton()->viewport_attach_canvas(viewport, canvas);
- VisualServer::get_singleton()->viewport_set_canvas_layer(viewport, canvas, layer);
+ VisualServer::get_singleton()->viewport_set_canvas_stacking(viewport, canvas, layer, get_position_in_parent());
VisualServer::get_singleton()->viewport_set_canvas_transform(viewport, canvas, transform);
} break;
@@ -159,6 +159,10 @@ void CanvasLayer::_notification(int p_what) {
viewport = RID();
} break;
+ case NOTIFICATION_MOVED_IN_PARENT: {
+
+ VisualServer::get_singleton()->viewport_set_canvas_stacking(viewport, canvas, layer, get_position_in_parent());
+ } break;
}
}
@@ -201,7 +205,7 @@ void CanvasLayer::set_custom_viewport(Node *p_viewport) {
viewport = vp->get_viewport_rid();
VisualServer::get_singleton()->viewport_attach_canvas(viewport, canvas);
- VisualServer::get_singleton()->viewport_set_canvas_layer(viewport, canvas, layer);
+ VisualServer::get_singleton()->viewport_set_canvas_stacking(viewport, canvas, layer, get_position_in_parent());
VisualServer::get_singleton()->viewport_set_canvas_transform(viewport, canvas, transform);
}
}
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index 6bf1d12086..a28b6fd6de 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -1839,8 +1839,16 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
MenuButton *popup_menu_parent = NULL;
MenuButton *menu_button = Object::cast_to<MenuButton>(over);
- if (popup_menu)
+ if (popup_menu) {
popup_menu_parent = Object::cast_to<MenuButton>(popup_menu->get_parent());
+ if (!popup_menu_parent) {
+ // Go through the parents to see if there's a MenuButton at the end.
+ while (Object::cast_to<PopupMenu>(popup_menu->get_parent())) {
+ popup_menu = Object::cast_to<PopupMenu>(popup_menu->get_parent());
+ }
+ popup_menu_parent = Object::cast_to<MenuButton>(popup_menu->get_parent());
+ }
+ }
// If the mouse is over a menu button, this menu will open automatically
// if there is already a pop-up menu open at the same hierarchical level.
diff --git a/scene/resources/dynamic_font.cpp b/scene/resources/dynamic_font.cpp
index 458cbf6718..7422c56eee 100644
--- a/scene/resources/dynamic_font.cpp
+++ b/scene/resources/dynamic_font.cpp
@@ -1029,7 +1029,7 @@ void DynamicFont::_bind_methods() {
Mutex *DynamicFont::dynamic_font_mutex = NULL;
-SelfList<DynamicFont>::List DynamicFont::dynamic_fonts;
+SelfList<DynamicFont>::List *DynamicFont::dynamic_fonts = NULL;
DynamicFont::DynamicFont() :
font_list(this) {
@@ -1041,29 +1041,31 @@ DynamicFont::DynamicFont() :
spacing_char = 0;
spacing_space = 0;
outline_color = Color(1, 1, 1);
- if (dynamic_font_mutex)
+ if (dynamic_font_mutex) {
dynamic_font_mutex->lock();
- dynamic_fonts.add(&font_list);
- if (dynamic_font_mutex)
+ dynamic_fonts->add(&font_list);
dynamic_font_mutex->unlock();
+ }
}
DynamicFont::~DynamicFont() {
-
- if (dynamic_font_mutex)
+ if (dynamic_font_mutex) {
dynamic_font_mutex->lock();
- dynamic_fonts.remove(&font_list);
- if (dynamic_font_mutex)
+ dynamic_fonts->remove(&font_list);
dynamic_font_mutex->unlock();
+ }
}
void DynamicFont::initialize_dynamic_fonts() {
+ dynamic_fonts = memnew(SelfList<DynamicFont>::List());
dynamic_font_mutex = Mutex::create();
}
void DynamicFont::finish_dynamic_fonts() {
memdelete(dynamic_font_mutex);
dynamic_font_mutex = NULL;
+ memdelete(dynamic_fonts);
+ dynamic_fonts = NULL;
}
void DynamicFont::update_oversampling() {
@@ -1073,7 +1075,7 @@ void DynamicFont::update_oversampling() {
if (dynamic_font_mutex)
dynamic_font_mutex->lock();
- SelfList<DynamicFont> *E = dynamic_fonts.first();
+ SelfList<DynamicFont> *E = dynamic_fonts->first();
while (E) {
if (E->self()->data_at_size.is_valid()) {
diff --git a/scene/resources/dynamic_font.h b/scene/resources/dynamic_font.h
index afda48a566..bd3f84d62c 100644
--- a/scene/resources/dynamic_font.h
+++ b/scene/resources/dynamic_font.h
@@ -285,7 +285,7 @@ public:
SelfList<DynamicFont> font_list;
static Mutex *dynamic_font_mutex;
- static SelfList<DynamicFont>::List dynamic_fonts;
+ static SelfList<DynamicFont>::List *dynamic_fonts;
static void initialize_dynamic_fonts();
static void finish_dynamic_fonts();
diff --git a/scene/resources/primitive_meshes.cpp b/scene/resources/primitive_meshes.cpp
index 63aa44e1d8..28af3d3220 100644
--- a/scene/resources/primitive_meshes.cpp
+++ b/scene/resources/primitive_meshes.cpp
@@ -1282,7 +1282,7 @@ void PrismMesh::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_subdivide_depth"), &PrismMesh::get_subdivide_depth);
ADD_PROPERTY(PropertyInfo(Variant::REAL, "left_to_right", PROPERTY_HINT_RANGE, "-2.0,2.0,0.1"), "set_left_to_right", "get_left_to_right");
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "size"), "set_size", "get_size");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "size"), "set_size", "get_size");
ADD_PROPERTY(PropertyInfo(Variant::INT, "subdivide_width", PROPERTY_HINT_RANGE, "0,100,1,or_greater"), "set_subdivide_width", "get_subdivide_width");
ADD_PROPERTY(PropertyInfo(Variant::INT, "subdivide_height", PROPERTY_HINT_RANGE, "0,100,1,or_greater"), "set_subdivide_height", "get_subdivide_height");
ADD_PROPERTY(PropertyInfo(Variant::INT, "subdivide_depth", PROPERTY_HINT_RANGE, "0,100,1,or_greater"), "set_subdivide_depth", "get_subdivide_depth");
diff --git a/servers/physics/area_pair_sw.cpp b/servers/physics/area_pair_sw.cpp
index d2fef0ab77..5e295edcd1 100644
--- a/servers/physics/area_pair_sw.cpp
+++ b/servers/physics/area_pair_sw.cpp
@@ -147,10 +147,10 @@ Area2PairSW::~Area2PairSW() {
if (colliding) {
- if (area_b->has_area_monitor_callback() && area_a->is_monitorable())
+ if (area_b->has_area_monitor_callback())
area_b->remove_area_from_query(area_a, shape_a, shape_b);
- if (area_a->has_area_monitor_callback() && area_b->is_monitorable())
+ if (area_a->has_area_monitor_callback())
area_a->remove_area_from_query(area_b, shape_b, shape_a);
}
diff --git a/servers/physics_2d/area_pair_2d_sw.cpp b/servers/physics_2d/area_pair_2d_sw.cpp
index 9d515d2183..cdd35cf657 100644
--- a/servers/physics_2d/area_pair_2d_sw.cpp
+++ b/servers/physics_2d/area_pair_2d_sw.cpp
@@ -147,10 +147,10 @@ Area2Pair2DSW::~Area2Pair2DSW() {
if (colliding) {
- if (area_b->has_area_monitor_callback() && area_a->is_monitorable())
+ if (area_b->has_area_monitor_callback())
area_b->remove_area_from_query(area_a, shape_a, shape_b);
- if (area_a->has_area_monitor_callback() && area_b->is_monitorable())
+ if (area_a->has_area_monitor_callback())
area_a->remove_area_from_query(area_b, shape_b, shape_a);
}
diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h
index 62ba2eab69..fc77dcc562 100644
--- a/servers/visual/visual_server_raster.h
+++ b/servers/visual/visual_server_raster.h
@@ -474,7 +474,7 @@ public:
BIND2(viewport_set_transparent_background, RID, bool)
BIND2(viewport_set_global_canvas_transform, RID, const Transform2D &)
- BIND3(viewport_set_canvas_layer, RID, RID, int)
+ BIND4(viewport_set_canvas_stacking, RID, RID, int, int)
BIND2(viewport_set_shadow_atlas_size, RID, int)
BIND3(viewport_set_shadow_atlas_quadrant_subdivision, RID, int, int)
BIND2(viewport_set_msaa, RID, ViewportMSAA)
diff --git a/servers/visual/visual_server_viewport.cpp b/servers/visual/visual_server_viewport.cpp
index b286533590..571b71db85 100644
--- a/servers/visual/visual_server_viewport.cpp
+++ b/servers/visual/visual_server_viewport.cpp
@@ -137,7 +137,7 @@ void VisualServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface::E
}
}
- canvas_map[Viewport::CanvasKey(E->key(), E->get().layer)] = &E->get();
+ canvas_map[Viewport::CanvasKey(E->key(), E->get().layer, E->get().sublayer)] = &E->get();
}
if (lights_with_shadow) {
@@ -176,7 +176,7 @@ void VisualServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface::E
VSG::rasterizer->restore_render_target();
- if (scenario_draw_canvas_bg && canvas_map.front() && canvas_map.front()->key().layer > scenario_canvas_max_layer) {
+ if (scenario_draw_canvas_bg && canvas_map.front() && canvas_map.front()->key().get_layer() > scenario_canvas_max_layer) {
Ref<ARVRInterface> arvr_interface = ARVRServer::get_singleton()->get_primary_interface();
if (!can_draw_3d) {
@@ -209,7 +209,7 @@ void VisualServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface::E
VSG::canvas->render_canvas(canvas, xform, canvas_lights, lights_with_mask, clip_rect);
i++;
- if (scenario_draw_canvas_bg && E->key().layer >= scenario_canvas_max_layer) {
+ if (scenario_draw_canvas_bg && E->key().get_layer() >= scenario_canvas_max_layer) {
Ref<ARVRInterface> arvr_interface = ARVRServer::get_singleton()->get_primary_interface();
if (!can_draw_3d) {
@@ -496,6 +496,7 @@ void VisualServerViewport::viewport_attach_canvas(RID p_viewport, RID p_canvas)
canvas->viewports.insert(p_viewport);
viewport->canvas_map[p_canvas] = Viewport::CanvasData();
viewport->canvas_map[p_canvas].layer = 0;
+ viewport->canvas_map[p_canvas].sublayer = 0;
viewport->canvas_map[p_canvas].canvas = canvas;
}
@@ -534,13 +535,14 @@ void VisualServerViewport::viewport_set_global_canvas_transform(RID p_viewport,
viewport->global_transform = p_transform;
}
-void VisualServerViewport::viewport_set_canvas_layer(RID p_viewport, RID p_canvas, int p_layer) {
+void VisualServerViewport::viewport_set_canvas_stacking(RID p_viewport, RID p_canvas, int p_layer, int p_sublayer) {
Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND(!viewport);
ERR_FAIL_COND(!viewport->canvas_map.has(p_canvas));
viewport->canvas_map[p_canvas].layer = p_layer;
+ viewport->canvas_map[p_canvas].sublayer = p_sublayer;
}
void VisualServerViewport::viewport_set_shadow_atlas_size(RID p_viewport, int p_size) {
diff --git a/servers/visual/visual_server_viewport.h b/servers/visual/visual_server_viewport.h
index cb7912d6f4..66baa48458 100644
--- a/servers/visual/visual_server_viewport.h
+++ b/servers/visual/visual_server_viewport.h
@@ -78,17 +78,21 @@ public:
struct CanvasKey {
- int layer;
+ int64_t stacking;
RID canvas;
bool operator<(const CanvasKey &p_canvas) const {
- if (layer == p_canvas.layer) return canvas < p_canvas.canvas;
- return layer < p_canvas.layer;
+ if (stacking == p_canvas.stacking)
+ return canvas < p_canvas.canvas;
+ return stacking < p_canvas.stacking;
+ }
+ CanvasKey() {
+ stacking = 0;
}
- CanvasKey() { layer = 0; }
- CanvasKey(const RID &p_canvas, int p_layer) {
+ CanvasKey(const RID &p_canvas, int p_layer, int p_sublayer) {
canvas = p_canvas;
- layer = p_layer;
+ stacking = ((int64_t)p_layer << 32) + p_sublayer;
}
+ int get_layer() const { return stacking >> 32; }
};
struct CanvasData {
@@ -96,6 +100,7 @@ public:
CanvasBase *canvas;
Transform2D transform;
int layer;
+ int sublayer;
};
Transform2D global_transform;
@@ -176,7 +181,7 @@ public:
void viewport_set_transparent_background(RID p_viewport, bool p_enabled);
void viewport_set_global_canvas_transform(RID p_viewport, const Transform2D &p_transform);
- void viewport_set_canvas_layer(RID p_viewport, RID p_canvas, int p_layer);
+ void viewport_set_canvas_stacking(RID p_viewport, RID p_canvas, int p_layer, int p_sublayer);
void viewport_set_shadow_atlas_size(RID p_viewport, int p_size);
void viewport_set_shadow_atlas_quadrant_subdivision(RID p_viewport, int p_quadrant, int p_subdiv);
diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h
index e4d69121f0..0b435a26aa 100644
--- a/servers/visual/visual_server_wrap_mt.h
+++ b/servers/visual/visual_server_wrap_mt.h
@@ -400,7 +400,7 @@ public:
FUNC2(viewport_set_transparent_background, RID, bool)
FUNC2(viewport_set_global_canvas_transform, RID, const Transform2D &)
- FUNC3(viewport_set_canvas_layer, RID, RID, int)
+ FUNC4(viewport_set_canvas_stacking, RID, RID, int, int)
FUNC2(viewport_set_shadow_atlas_size, RID, int)
FUNC3(viewport_set_shadow_atlas_quadrant_subdivision, RID, int, int)
FUNC2(viewport_set_msaa, RID, ViewportMSAA)
diff --git a/servers/visual_server.cpp b/servers/visual_server.cpp
index 164be132b8..b8477daa66 100644
--- a/servers/visual_server.cpp
+++ b/servers/visual_server.cpp
@@ -1890,7 +1890,7 @@ void VisualServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("viewport_set_canvas_transform", "viewport", "canvas", "offset"), &VisualServer::viewport_set_canvas_transform);
ClassDB::bind_method(D_METHOD("viewport_set_transparent_background", "viewport", "enabled"), &VisualServer::viewport_set_transparent_background);
ClassDB::bind_method(D_METHOD("viewport_set_global_canvas_transform", "viewport", "transform"), &VisualServer::viewport_set_global_canvas_transform);
- ClassDB::bind_method(D_METHOD("viewport_set_canvas_layer", "viewport", "canvas", "layer"), &VisualServer::viewport_set_canvas_layer);
+ ClassDB::bind_method(D_METHOD("viewport_set_canvas_stacking", "viewport", "canvas", "layer", "sublayer"), &VisualServer::viewport_set_canvas_stacking);
ClassDB::bind_method(D_METHOD("viewport_set_shadow_atlas_size", "viewport", "size"), &VisualServer::viewport_set_shadow_atlas_size);
ClassDB::bind_method(D_METHOD("viewport_set_shadow_atlas_quadrant_subdivision", "viewport", "quadrant", "subdivision"), &VisualServer::viewport_set_shadow_atlas_quadrant_subdivision);
ClassDB::bind_method(D_METHOD("viewport_set_msaa", "viewport", "msaa"), &VisualServer::viewport_set_msaa);
diff --git a/servers/visual_server.h b/servers/visual_server.h
index 9d98fca21b..4db6a6a39b 100644
--- a/servers/visual_server.h
+++ b/servers/visual_server.h
@@ -644,7 +644,7 @@ public:
virtual void viewport_set_transparent_background(RID p_viewport, bool p_enabled) = 0;
virtual void viewport_set_global_canvas_transform(RID p_viewport, const Transform2D &p_transform) = 0;
- virtual void viewport_set_canvas_layer(RID p_viewport, RID p_canvas, int p_layer) = 0;
+ virtual void viewport_set_canvas_stacking(RID p_viewport, RID p_canvas, int p_layer, int p_sublayer) = 0;
virtual void viewport_set_shadow_atlas_size(RID p_viewport, int p_size) = 0;
virtual void viewport_set_shadow_atlas_quadrant_subdivision(RID p_viewport, int p_quadrant, int p_subdiv) = 0;