diff options
52 files changed, 599 insertions, 182 deletions
diff --git a/core/variant.cpp b/core/variant.cpp index 8b2051add7..56b272cccf 100644 --- a/core/variant.cpp +++ b/core/variant.cpp @@ -1731,6 +1731,14 @@ Variant::operator RID() const { else if (type == OBJECT && !_get_obj().ref.is_null()) { return _get_obj().ref.get_rid(); } else if (type == OBJECT && _get_obj().obj) { +#ifdef DEBUG_ENABLED + if (ScriptDebugger::get_singleton()) { + if (!ObjectDB::instance_validate(_get_obj().obj)) { + ERR_EXPLAIN("Invalid pointer (object was deleted)"); + ERR_FAIL_V(RID()); + }; + }; +#endif Variant::CallError ce; Variant ret = _get_obj().obj->call(CoreStringNames::get_singleton()->get_rid, NULL, 0, ce); if (ce.error == Variant::CallError::CALL_OK && ret.get_type() == Variant::_RID) { diff --git a/doc/classes/File.xml b/doc/classes/File.xml index 1967349546..6462176c73 100644 --- a/doc/classes/File.xml +++ b/doc/classes/File.xml @@ -48,6 +48,7 @@ </argument> <description> Returns [code]true[/code] if the file exists in the given path. + Note that many resources types are imported (e.g. textures or sound files), and that their source asset will not be included in the exported game, as only the imported version is used (in the [code]res://.import[/code] folder). To check for the existence of such resources while taking into account the remapping to their imported location, use [method ResourceLoader.exists]. Typically, using [code]File.file_exists[/code] on an imported resource would work while you are developing in the editor (the source asset is present in [code]res://[/code], but fail when exported). </description> </method> <method name="get_16" qualifiers="const"> diff --git a/drivers/gles2/rasterizer_scene_gles2.cpp b/drivers/gles2/rasterizer_scene_gles2.cpp index ce2961170a..ae677b606d 100644 --- a/drivers/gles2/rasterizer_scene_gles2.cpp +++ b/drivers/gles2/rasterizer_scene_gles2.cpp @@ -994,6 +994,12 @@ void RasterizerSceneGLES2::_add_geometry_with_material(RasterizerStorageGLES2::G e->depth_layer = e->instance->depth_layer; e->priority = p_material->render_priority; + if (has_alpha && p_material->shader->spatial.depth_draw_mode == RasterizerStorageGLES2::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS) { + //add element to opaque + RenderList::Element *eo = render_list.add_element(); + *eo = *e; + } + int rpsize = e->instance->reflection_probe_instances.size(); if (rpsize > 0) { bool first = true; @@ -3135,7 +3141,7 @@ void RasterizerSceneGLES2::initialize() { } // cubemaps for shadows - if (!storage->config.support_write_depth) { //not going to be used + if (storage->config.support_write_depth) { //not going to be used int max_shadow_cubemap_sampler_size = 512; int cube_size = max_shadow_cubemap_sampler_size; diff --git a/drivers/gles2/rasterizer_storage_gles2.cpp b/drivers/gles2/rasterizer_storage_gles2.cpp index f0deff4791..38fcff3ab2 100644 --- a/drivers/gles2/rasterizer_storage_gles2.cpp +++ b/drivers/gles2/rasterizer_storage_gles2.cpp @@ -4631,7 +4631,7 @@ bool RasterizerStorageGLES2::free(RID p_rid) { Shader *shader = shader_owner.get(p_rid); - if (shader->shader) { + if (shader->shader && shader->custom_code_id) { shader->shader->free_custom_shader(shader->custom_code_id); } diff --git a/drivers/gles2/shader_gles2.cpp b/drivers/gles2/shader_gles2.cpp index 65d4b63bb9..5e259a01f0 100644 --- a/drivers/gles2/shader_gles2.cpp +++ b/drivers/gles2/shader_gles2.cpp @@ -242,6 +242,11 @@ ShaderGLES2::Version *ShaderGLES2::get_current_version() { strings.push_back("#define USE_GLES_OVER_GL\n"); #else strings.push_back("#version 100\n"); +//angle does not like +#ifdef JAVASCRIPT_ENABLED + strings.push_back("#define USE_HIGHP_PRECISION\n"); +#endif + #endif int define_line_ofs = 1; @@ -514,6 +519,10 @@ ShaderGLES2::Version *ShaderGLES2::get_current_version() { glUseProgram(0); v.ok = true; + if (cc) { + cc->versions.insert(conditional_version.version); + } + return &v; } @@ -678,9 +687,28 @@ void ShaderGLES2::set_custom_shader(uint32_t p_code_id) { } void ShaderGLES2::free_custom_shader(uint32_t p_code_id) { + ERR_FAIL_COND(!custom_code_map.has(p_code_id)); - if (conditional_version.code_version == p_code_id) - conditional_version.code_version = 0; + if (conditional_version.code_version == p_code_id) { + conditional_version.code_version = 0; //do not keep using a version that is going away + unbind(); + } + + VersionKey key; + key.code_version = p_code_id; + for (Set<uint32_t>::Element *E = custom_code_map[p_code_id].versions.front(); E; E = E->next()) { + key.version = E->get(); + ERR_CONTINUE(!version_map.has(key)); + Version &v = version_map[key]; + + glDeleteShader(v.vert_id); + glDeleteShader(v.frag_id); + glDeleteProgram(v.id); + memdelete_arr(v.uniform_location); + v.id = 0; + + version_map.erase(key); + } custom_code_map.erase(p_code_id); } diff --git a/drivers/gles2/shader_gles2.h b/drivers/gles2/shader_gles2.h index 5805432d09..d493880d0b 100644 --- a/drivers/gles2/shader_gles2.h +++ b/drivers/gles2/shader_gles2.h @@ -104,6 +104,7 @@ private: Vector<StringName> texture_uniforms; Vector<StringName> custom_uniforms; Vector<CharString> custom_defines; + Set<uint32_t> versions; }; struct Version { diff --git a/drivers/gles2/shaders/canvas.glsl b/drivers/gles2/shaders/canvas.glsl index bc734a6597..c4a8c8b990 100644 --- a/drivers/gles2/shaders/canvas.glsl +++ b/drivers/gles2/shaders/canvas.glsl @@ -6,8 +6,8 @@ #define mediump #define highp #else -precision mediump float; -precision mediump int; +precision highp float; +precision highp int; #endif uniform highp mat4 projection_matrix; @@ -243,9 +243,14 @@ VERTEX_SHADER_CODE #define mediump #define highp #else +#if defined(USE_HIGHP_PRECISION) +precision highp float; +precision highp int; +#else precision mediump float; precision mediump int; #endif +#endif uniform sampler2D color_texture; // texunit:-1 /* clang-format on */ diff --git a/drivers/gles2/shaders/copy.glsl b/drivers/gles2/shaders/copy.glsl index 286ba6b8c0..931b3f3708 100644 --- a/drivers/gles2/shaders/copy.glsl +++ b/drivers/gles2/shaders/copy.glsl @@ -6,8 +6,8 @@ #define mediump #define highp #else -precision mediump float; -precision mediump int; +precision highp float; +precision highp int; #endif attribute highp vec4 vertex_attrib; // attrib:0 @@ -61,9 +61,14 @@ void main() { #define mediump #define highp #else +#if defined(USE_HIGHP_PRECISION) +precision highp float; +precision highp int; +#else precision mediump float; precision mediump int; #endif +#endif #if defined(USE_CUBEMAP) || defined(USE_PANORAMA) varying vec3 cube_interp; diff --git a/drivers/gles2/shaders/cubemap_filter.glsl b/drivers/gles2/shaders/cubemap_filter.glsl index 558c83960e..7643297a14 100644 --- a/drivers/gles2/shaders/cubemap_filter.glsl +++ b/drivers/gles2/shaders/cubemap_filter.glsl @@ -6,8 +6,8 @@ #define mediump #define highp #else -precision mediump float; -precision mediump int; +precision highp float; +precision highp int; #endif attribute highp vec2 vertex; // attrib:0 @@ -51,10 +51,16 @@ void main() { #define mediump #define highp #else +#if defined(USE_HIGHP_PRECISION) +precision highp float; +precision highp int; +#else precision mediump float; precision mediump int; #endif +#endif + #ifdef USE_SOURCE_PANORAMA uniform sampler2D source_panorama; //texunit:0 #else diff --git a/drivers/gles2/shaders/scene.glsl b/drivers/gles2/shaders/scene.glsl index 6aa91df20f..c7f5c97133 100644 --- a/drivers/gles2/shaders/scene.glsl +++ b/drivers/gles2/shaders/scene.glsl @@ -683,8 +683,13 @@ VERTEX_SHADER_CODE #define mediump #define highp #else -precision mediump float; +#if defined(USE_HIGHP_PRECISION) +precision highp float; precision highp int; +#else +precision mediump float; +precision mediump int; +#endif #endif #include "stdlib.glsl" diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index 02dbe096c5..966466d9bc 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -4132,9 +4132,19 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const glDepthFunc(GL_LEQUAL); - state.used_contact_shadows = true; + state.used_contact_shadows = false; - if (!storage->config.no_depth_prepass && storage->frame.current_rt && state.debug_draw != VS::VIEWPORT_DEBUG_DRAW_OVERDRAW) { //detect with state.used_contact_shadows too + for (int i = 0; i < p_light_cull_count; i++) { + + ERR_BREAK(i >= RenderList::MAX_LIGHTS); + + LightInstance *li = light_instance_owner.getptr(p_light_cull_result[i]); + if (li->light_ptr->param[VS::LIGHT_PARAM_CONTACT_SHADOW_SIZE] > CMP_EPSILON) { + state.used_contact_shadows = true; + } + } + + if (!storage->config.no_depth_prepass && storage->frame.current_rt && state.debug_draw != VS::VIEWPORT_DEBUG_DRAW_OVERDRAW && !storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_NO_3D_EFFECTS]) { //detect with state.used_contact_shadows too //pre z pass glDisable(GL_BLEND); diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp index 8b3f1a1b77..70037dfc33 100644 --- a/drivers/gles3/rasterizer_storage_gles3.cpp +++ b/drivers/gles3/rasterizer_storage_gles3.cpp @@ -7486,7 +7486,7 @@ bool RasterizerStorageGLES3::free(RID p_rid) { // delete the texture Shader *shader = shader_owner.get(p_rid); - if (shader->shader) + if (shader->shader && shader->custom_code_id) shader->shader->free_custom_shader(shader->custom_code_id); if (shader->dirty_list.in_list()) diff --git a/drivers/gles3/shader_gles3.cpp b/drivers/gles3/shader_gles3.cpp index edc2a6c054..2db0223edd 100644 --- a/drivers/gles3/shader_gles3.cpp +++ b/drivers/gles3/shader_gles3.cpp @@ -559,6 +559,9 @@ ShaderGLES3::Version *ShaderGLES3::get_current_version() { glUseProgram(0); v.ok = true; + if (cc) { + cc->versions.insert(conditional_version.version); + } return &v; } @@ -741,8 +744,26 @@ void ShaderGLES3::set_custom_shader(uint32_t p_code_id) { void ShaderGLES3::free_custom_shader(uint32_t p_code_id) { ERR_FAIL_COND(!custom_code_map.has(p_code_id)); - if (conditional_version.code_version == p_code_id) - conditional_version.code_version = 0; //bye + if (conditional_version.code_version == p_code_id) { + conditional_version.code_version = 0; //do not keep using a version that is going away + unbind(); + } + + VersionKey key; + key.code_version = p_code_id; + for (Set<uint32_t>::Element *E = custom_code_map[p_code_id].versions.front(); E; E = E->next()) { + key.version = E->get(); + ERR_CONTINUE(!version_map.has(key)); + Version &v = version_map[key]; + + glDeleteShader(v.vert_id); + glDeleteShader(v.frag_id); + glDeleteProgram(v.id); + memdelete_arr(v.uniform_location); + v.id = 0; + + version_map.erase(key); + } custom_code_map.erase(p_code_id); } diff --git a/drivers/gles3/shader_gles3.h b/drivers/gles3/shader_gles3.h index 1f98f4883d..1ed30986bf 100644 --- a/drivers/gles3/shader_gles3.h +++ b/drivers/gles3/shader_gles3.h @@ -117,6 +117,7 @@ private: uint32_t version; Vector<StringName> texture_uniforms; Vector<CharString> custom_defines; + Set<uint32_t> versions; }; struct Version { diff --git a/drivers/windows/dir_access_windows.cpp b/drivers/windows/dir_access_windows.cpp index c32e063736..8ac4e53c65 100644 --- a/drivers/windows/dir_access_windows.cpp +++ b/drivers/windows/dir_access_windows.cpp @@ -354,13 +354,13 @@ String DirAccessWindows::get_filesystem_type() const { String unit = path.substr(0,unit_end+1) + "\\"; print_line("unit: "+unit); - TCHAR szVolumeName[100] = ""; - TCHAR szFileSystemName[10] = ""; + WCHAR szVolumeName[100]; + WCHAR szFileSystemName[10]; DWORD dwSerialNumber = 0; DWORD dwMaxFileNameLength = 0; DWORD dwFileSystemFlags = 0; - if(::GetVolumeInformation(unit.utf8().get_data(), + if(::GetVolumeInformationW(unit.c_str(), szVolumeName, sizeof(szVolumeName), &dwSerialNumber, diff --git a/editor/create_dialog.cpp b/editor/create_dialog.cpp index 205bdc63b9..3c2bfdc04d 100644 --- a/editor/create_dialog.cpp +++ b/editor/create_dialog.cpp @@ -208,7 +208,7 @@ void CreateDialog::add_type(const String &p_type, HashMap<String, TreeItem *> &p if (!can_instance) { item->set_custom_color(0, get_color("disabled_font_color", "Editor")); item->set_selectable(0, false); - } else { + } else if (!(*to_select && (*to_select)->get_text(0) == search_box->get_text())) { bool is_search_subsequence = search_box->get_text().is_subsequence_ofi(p_type); String to_select_type = *to_select ? (*to_select)->get_text(0) : ""; to_select_type = to_select_type.split(" ")[0]; @@ -221,11 +221,11 @@ void CreateDialog::add_type(const String &p_type, HashMap<String, TreeItem *> &p } else { current_item_is_preferred = ed.script_class_is_parent(p_type, preferred_search_result_type) && !ed.script_class_is_parent(to_select_type, preferred_search_result_type) && search_box->get_text() != to_select_type; } - if (*to_select && p_type.length() < (*to_select)->get_text(0).length()) { + if (search_box->get_text() == p_type || (*to_select && p_type.length() < (*to_select)->get_text(0).length())) { current_item_is_preferred = true; } - if (((!*to_select || current_item_is_preferred) && is_search_subsequence) || search_box->get_text() == p_type) { + if (((!*to_select || current_item_is_preferred) && is_search_subsequence)) { *to_select = item; } } diff --git a/editor/editor_audio_buses.cpp b/editor/editor_audio_buses.cpp index 5d0abef4b8..6593eb8f03 100644 --- a/editor/editor_audio_buses.cpp +++ b/editor/editor_audio_buses.cpp @@ -75,9 +75,16 @@ void EditorAudioBus::_notification(int p_what) { disabled_vu = get_icon("BusVuFrozen", "EditorIcons"); + Color solo_color = Color::html(EditorSettings::get_singleton()->is_dark_theme() ? "#ffe337" : "#ffeb70"); + Color mute_color = Color::html(EditorSettings::get_singleton()->is_dark_theme() ? "#ff2929" : "#ff7070"); + Color bypass_color = Color::html(EditorSettings::get_singleton()->is_dark_theme() ? "#22ccff" : "#70deff"); + solo->set_icon(get_icon("AudioBusSolo", "EditorIcons")); + solo->add_color_override("icon_color_pressed", solo_color); mute->set_icon(get_icon("AudioBusMute", "EditorIcons")); + mute->add_color_override("icon_color_pressed", mute_color); bypass->set_icon(get_icon("AudioBusBypass", "EditorIcons")); + bypass->add_color_override("icon_color_pressed", bypass_color); bus_options->set_icon(get_icon("GuiMiniTabMenu", "EditorIcons")); diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp index e660bb2daf..d7e0302478 100644 --- a/editor/editor_inspector.cpp +++ b/editor/editor_inspector.cpp @@ -1899,13 +1899,13 @@ int EditorInspector::get_scroll_offset() const { return get_v_scroll(); } -void EditorInspector::set_use_sub_inspector_bg(bool p_enable) { +void EditorInspector::set_sub_inspector(bool p_enable) { - use_sub_inspector_bg = p_enable; + sub_inspector = p_enable; if (!is_inside_tree()) return; - if (use_sub_inspector_bg) { + if (sub_inspector) { add_style_override("bg", get_stylebox("sub_inspector_bg", "Editor")); } else { add_style_override("bg", get_stylebox("bg", "Tree")); @@ -2126,16 +2126,18 @@ void EditorInspector::_notification(int p_what) { if (p_what == NOTIFICATION_ENTER_TREE) { - get_tree()->connect("node_removed", this, "_node_removed"); - if (use_sub_inspector_bg) { + if (sub_inspector) { add_style_override("bg", get_stylebox("sub_inspector_bg", "Editor")); - } else if (is_inside_tree()) { + } else { add_style_override("bg", get_stylebox("bg", "Tree")); + get_tree()->connect("node_removed", this, "_node_removed"); } } if (p_what == NOTIFICATION_EXIT_TREE) { - get_tree()->disconnect("node_removed", this, "_node_removed"); + if (!sub_inspector) { + get_tree()->disconnect("node_removed", this, "_node_removed"); + } edit(NULL); } @@ -2184,7 +2186,7 @@ void EditorInspector::_notification(int p_what) { if (p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) { - if (use_sub_inspector_bg) { + if (sub_inspector) { add_style_override("bg", get_stylebox("sub_inspector_bg", "Editor")); } else if (is_inside_tree()) { add_style_override("bg", get_stylebox("bg", "Tree")); @@ -2280,7 +2282,7 @@ EditorInspector::EditorInspector() { _prop_edited = "property_edited"; set_process(true); property_focusable = -1; - use_sub_inspector_bg = false; + sub_inspector = false; get_v_scrollbar()->connect("value_changed", this, "_vscroll_changed"); update_scroll_request = -1; diff --git a/editor/editor_inspector.h b/editor/editor_inspector.h index d64a78be57..4fb3198e87 100644 --- a/editor/editor_inspector.h +++ b/editor/editor_inspector.h @@ -281,7 +281,7 @@ class EditorInspector : public ScrollContainer { bool update_all_pending; bool read_only; bool keying; - bool use_sub_inspector_bg; + bool sub_inspector; float refresh_countdown; bool update_tree_pending; @@ -375,7 +375,7 @@ public: void set_object_class(const String &p_class); String get_object_class() const; - void set_use_sub_inspector_bg(bool p_enable); + void set_sub_inspector(bool p_enable); EditorInspector(); }; diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 719130621e..0ff0bca7ee 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -1108,12 +1108,15 @@ void EditorNode::_save_scene(String p_file, int idx) { } } -void EditorNode::save_all_scenes_and_restart() { +void EditorNode::save_all_scenes() { _menu_option_confirm(RUN_STOP, true); - exiting = true; - _save_all_scenes(); +} + +void EditorNode::restart_editor() { + + exiting = true; String to_reopen; if (get_tree()->get_edited_scene_root()) { @@ -2305,7 +2308,8 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { ProjectSettings::get_singleton()->set("rendering/quality/driver/driver_name", video_driver_request); ProjectSettings::get_singleton()->save(); - save_all_scenes_and_restart(); + save_all_scenes(); + restart_editor(); } break; default: { if (p_option >= IMPORT_PLUGIN_BASE) { @@ -4760,6 +4764,8 @@ EditorNode::EditorNode() { ResourceLoader::clear_translation_remaps(); //no remaps using during editor ResourceLoader::clear_path_remaps(); + ImageTexture::set_keep_images_cached(true); + InputDefault *id = Object::cast_to<InputDefault>(Input::get_singleton()); if (id) { diff --git a/editor/editor_node.h b/editor/editor_node.h index 13bebea5f0..a45ea54186 100644 --- a/editor/editor_node.h +++ b/editor/editor_node.h @@ -782,7 +782,8 @@ public: void add_tool_submenu_item(const String &p_name, PopupMenu *p_submenu); void remove_tool_menu_item(const String &p_name); - void save_all_scenes_and_restart(); + void save_all_scenes(); + void restart_editor(); void dim_editor(bool p_dimming); diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp index c5d0f13c60..f19eac6878 100644 --- a/editor/editor_properties.cpp +++ b/editor/editor_properties.cpp @@ -2448,7 +2448,7 @@ void EditorPropertyResource::update_property() { sub_inspector->set_enable_v_scroll(false); sub_inspector->set_use_doc_hints(true); - sub_inspector->set_use_sub_inspector_bg(true); + sub_inspector->set_sub_inspector(true); sub_inspector->set_enable_capitalize_paths(true); sub_inspector->connect("property_keyed", this, "_sub_inspector_property_keyed"); diff --git a/editor/import/editor_scene_importer_gltf.cpp b/editor/import/editor_scene_importer_gltf.cpp index 654dfc62e0..c29e9281fa 100644 --- a/editor/import/editor_scene_importer_gltf.cpp +++ b/editor/import/editor_scene_importer_gltf.cpp @@ -1030,11 +1030,19 @@ Error EditorSceneImporterGLTF::_parse_meshes(GLTFState &state) { int size = src_varr.size(); ERR_FAIL_COND_V(size == 0, ERR_PARSE_ERROR); { + + int max_idx = varr.size(); + varr.resize(size); + PoolVector<Vector3>::Write w_varr = varr.write(); PoolVector<Vector3>::Read r_varr = varr.read(); PoolVector<Vector3>::Read r_src_varr = src_varr.read(); for (int l = 0; l < size; l++) { - w_varr[l] = r_varr[l] + r_src_varr[l]; + if (l < max_idx) { + w_varr[l] = r_varr[l] + r_src_varr[l]; + } else { + w_varr[l] = r_src_varr[l]; + } } } array_copy[Mesh::ARRAY_VERTEX] = varr; @@ -1045,11 +1053,18 @@ Error EditorSceneImporterGLTF::_parse_meshes(GLTFState &state) { int size = src_narr.size(); ERR_FAIL_COND_V(size == 0, ERR_PARSE_ERROR); { + int max_idx = narr.size(); + narr.resize(size); + PoolVector<Vector3>::Write w_narr = narr.write(); PoolVector<Vector3>::Read r_narr = narr.read(); PoolVector<Vector3>::Read r_src_narr = src_narr.read(); for (int l = 0; l < size; l++) { - w_narr[l] = r_narr[l] + r_src_narr[l]; + if (l < max_idx) { + w_narr[l] = r_narr[l] + r_src_narr[l]; + } else { + w_narr[l] = r_src_narr[l]; + } } } array_copy[Mesh::ARRAY_NORMAL] = narr; @@ -1062,6 +1077,8 @@ Error EditorSceneImporterGLTF::_parse_meshes(GLTFState &state) { { + int max_idx = tangents_v3.size(); + int size4 = src_tangents.size(); tangents_v4.resize(size4); PoolVector<float>::Write w4 = tangents_v4.write(); @@ -1071,9 +1088,15 @@ Error EditorSceneImporterGLTF::_parse_meshes(GLTFState &state) { for (int l = 0; l < size4 / 4; l++) { - w4[l * 4 + 0] = r3[l].x + r4[l * 4 + 0]; - w4[l * 4 + 1] = r3[l].y + r4[l * 4 + 1]; - w4[l * 4 + 2] = r3[l].z + r4[l * 4 + 2]; + if (l < max_idx) { + w4[l * 4 + 0] = r3[l].x + r4[l * 4 + 0]; + w4[l * 4 + 1] = r3[l].y + r4[l * 4 + 1]; + w4[l * 4 + 2] = r3[l].z + r4[l * 4 + 2]; + } else { + w4[l * 4 + 0] = r4[l * 4 + 0]; + w4[l * 4 + 1] = r4[l * 4 + 1]; + w4[l * 4 + 2] = r4[l * 4 + 2]; + } w4[l * 4 + 3] = r4[l * 4 + 3]; //copy flip value } } diff --git a/editor/import_dock.cpp b/editor/import_dock.cpp index e59df7c932..40cf02ac9d 100644 --- a/editor/import_dock.cpp +++ b/editor/import_dock.cpp @@ -372,6 +372,63 @@ void ImportDock::clear() { preset->get_popup()->clear(); } +static bool _find_owners(EditorFileSystemDirectory *efsd, const String &p_path) { + + if (!efsd) + return false; + + for (int i = 0; i < efsd->get_subdir_count(); i++) { + + if (_find_owners(efsd->get_subdir(i), p_path)) { + return true; + } + } + + for (int i = 0; i < efsd->get_file_count(); i++) { + + Vector<String> deps = efsd->get_file_deps(i); + if (deps.find(p_path) != -1) + return true; + } + + return false; +} +void ImportDock::_reimport_attempt() { + + bool need_restart = false; + bool used_in_resources = false; + for (int i = 0; i < params->paths.size(); i++) { + Ref<ConfigFile> config; + config.instance(); + Error err = config->load(params->paths[i] + ".import"); + ERR_CONTINUE(err != OK); + + String imported_with = config->get_value("remap", "importer"); + if (imported_with != params->importer->get_importer_name()) { + need_restart = true; + if (_find_owners(EditorFileSystem::get_singleton()->get_filesystem(), params->paths[i])) { + used_in_resources = true; + } + } + } + + if (need_restart) { + label_warning->set_visible(used_in_resources); + reimport_confirm->popup_centered_minsize(); + return; + } + + _reimport(); +} + +void ImportDock::_reimport_and_restart() { + + EditorNode::get_singleton()->save_all_scenes(); + EditorResourcePreview::get_singleton()->stop(); //dont try to re-create previews after import + _reimport(); + EditorNode::get_singleton()->restart_editor(); +} + void ImportDock::_reimport() { for (int i = 0; i < params->paths.size(); i++) { @@ -416,6 +473,7 @@ void ImportDock::_notification(int p_what) { case NOTIFICATION_ENTER_TREE: { import_opts->edit(params); + label_warning->add_color_override("font_color", get_color("warning_color", "Editor")); } break; } } @@ -433,6 +491,8 @@ void ImportDock::_bind_methods() { ClassDB::bind_method(D_METHOD("_preset_selected"), &ImportDock::_preset_selected); ClassDB::bind_method(D_METHOD("_importer_selected"), &ImportDock::_importer_selected); ClassDB::bind_method(D_METHOD("_property_toggled"), &ImportDock::_property_toggled); + ClassDB::bind_method(D_METHOD("_reimport_and_restart"), &ImportDock::_reimport_and_restart); + ClassDB::bind_method(D_METHOD("_reimport_attempt"), &ImportDock::_reimport_attempt); } void ImportDock::initialize_import_options() const { @@ -469,11 +529,22 @@ ImportDock::ImportDock() { add_child(hb); import = memnew(Button); import->set_text(TTR("Reimport")); - import->connect("pressed", this, "_reimport"); + import->connect("pressed", this, "_reimport_attempt"); hb->add_spacer(); hb->add_child(import); hb->add_spacer(); + reimport_confirm = memnew(ConfirmationDialog); + reimport_confirm->get_ok()->set_text(TTR("Save scenes, re-import and restart")); + add_child(reimport_confirm); + reimport_confirm->connect("confirmed", this, "_reimport_and_restart"); + + VBoxContainer *vbc_confirm = memnew(VBoxContainer()); + vbc_confirm->add_child(memnew(Label(TTR("Changing the type of an imported file requires editor restart.")))); + label_warning = memnew(Label(TTR("WARNING: Assets exist that use this resource, they may stop loading properly."))); + vbc_confirm->add_child(label_warning); + reimport_confirm->add_child(vbc_confirm); + params = memnew(ImportDockParameters); } diff --git a/editor/import_dock.h b/editor/import_dock.h index bc992b2f7e..1d43e00b63 100644 --- a/editor/import_dock.h +++ b/editor/import_dock.h @@ -36,6 +36,7 @@ #include "editor/editor_file_system.h" #include "editor/editor_inspector.h" #include "scene/gui/box_container.h" +#include "scene/gui/dialogs.h" #include "scene/gui/menu_button.h" #include "scene/gui/option_button.h" #include "scene/gui/popup_menu.h" @@ -52,6 +53,8 @@ class ImportDock : public VBoxContainer { List<PropertyInfo> properties; Map<StringName, Variant> property_values; + ConfirmationDialog *reimport_confirm; + Label *label_warning; Button *import; ImportDockParameters *params; @@ -61,6 +64,8 @@ class ImportDock : public VBoxContainer { void _update_options(const Ref<ConfigFile> &p_config = Ref<ConfigFile>()); void _property_toggled(const StringName &p_prop, bool p_checked); + void _reimport_attempt(); + void _reimport_and_restart(); void _reimport(); enum { diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 02f6263887..2913c4ce56 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -474,7 +474,7 @@ void CanvasItemEditor::_find_canvas_items_at_pos(const Point2 &p_pos, Node *p_no if (canvas_item && canvas_item->is_visible_in_tree()) { Transform2D xform = (p_parent_xform * p_canvas_xform * canvas_item->get_transform()).affine_inverse(); - const real_t local_grab_distance = xform.basis_xform(Vector2(grab_distance, 0)).length(); + const real_t local_grab_distance = xform.basis_xform(Vector2(grab_distance, 0)).length() / zoom; if (canvas_item->_edit_is_selected_on_click(xform.xform(p_pos), local_grab_distance)) { Node2D *node = Object::cast_to<Node2D>(canvas_item); diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp index b8fb9d4ab0..7ce4029476 100644 --- a/editor/project_manager.cpp +++ b/editor/project_manager.cpp @@ -83,6 +83,8 @@ private: Container *name_container; Container *path_container; Container *install_path_container; + Container *rasterizer_container; + Ref<ButtonGroup> rasterizer_button_group; Label *msg; LineEdit *project_path; LineEdit *project_name; @@ -471,6 +473,13 @@ private: if (mode == MODE_NEW) { ProjectSettings::CustomMap initial_settings; + if (rasterizer_button_group->get_pressed_button()->get_meta("driver_name") == "GLES3") { + initial_settings["rendering/quality/driver/driver_name"] = "GLES3"; + } else { + initial_settings["rendering/quality/driver/driver_name"] = "GLES2"; + initial_settings["rendering/vram_compression/import_etc2"] = false; + initial_settings["rendering/vram_compression/import_etc"] = true; + } initial_settings["application/config/name"] = project_name->get_text(); initial_settings["application/config/icon"] = "res://icon.png"; initial_settings["rendering/environment/default_environment"] = "res://default_env.tres"; @@ -687,6 +696,7 @@ public: msg->hide(); install_path_container->hide(); install_status_rect->hide(); + rasterizer_container->hide(); get_ok()->set_disabled(false); ProjectSettings *current = memnew(ProjectSettings); @@ -738,6 +748,7 @@ public: get_ok()->set_text(TTR("Import & Edit")); name_container->hide(); install_path_container->hide(); + rasterizer_container->hide(); project_path->grab_focus(); } else if (mode == MODE_NEW) { @@ -746,6 +757,7 @@ public: get_ok()->set_text(TTR("Create & Edit")); name_container->show(); install_path_container->hide(); + rasterizer_container->show(); project_name->call_deferred("grab_focus"); project_name->call_deferred("select_all"); @@ -755,13 +767,14 @@ public: get_ok()->set_text(TTR("Install & Edit")); name_container->hide(); install_path_container->hide(); + rasterizer_container->hide(); project_path->grab_focus(); } _test_path(); } - popup_centered(Size2(500, 0) * EDSCALE); + popup_centered_minsize(Size2(500, 0) * EDSCALE); } ProjectDialog() { @@ -840,6 +853,48 @@ public: msg->set_align(Label::ALIGN_CENTER); vb->add_child(msg); + // rasterizer selection + rasterizer_container = memnew(VBoxContainer); + vb->add_child(rasterizer_container); + l = memnew(Label); + l->set_text(TTR("Renderer:")); + rasterizer_container->add_child(l); + Container *rshb = memnew(HBoxContainer); + rasterizer_container->add_child(rshb); + rasterizer_button_group.instance(); + + Container *rvb = memnew(VBoxContainer); + rvb->set_h_size_flags(SIZE_EXPAND_FILL); + rshb->add_child(rvb); + Button *rs_button = memnew(CheckBox); + rs_button->set_button_group(rasterizer_button_group); + rs_button->set_text(TTR("OpenGL ES 3.0")); + rs_button->set_meta("driver_name", "GLES3"); + rs_button->set_pressed(true); + rvb->add_child(rs_button); + l = memnew(Label); + l->set_text(TTR("Higher visual quality\nAll features available\nIncompatible with older hardware\nNot recommended for web games")); + rvb->add_child(l); + + rshb->add_child(memnew(VSeparator)); + + rvb = memnew(VBoxContainer); + rvb->set_h_size_flags(SIZE_EXPAND_FILL); + rshb->add_child(rvb); + rs_button = memnew(CheckBox); + rs_button->set_button_group(rasterizer_button_group); + rs_button->set_text(TTR("OpenGL ES 2.0")); + rs_button->set_meta("driver_name", "GLES2"); + rvb->add_child(rs_button); + l = memnew(Label); + l->set_text(TTR("Lower visual quality\nSome features not available\nWorks on most hardware\nRecommended for web games")); + rvb->add_child(l); + + l = memnew(Label); + l->set_text(TTR("Renderer can be changed later, but scenes may need to be adjusted.")); + l->set_align(Label::ALIGN_CENTER); + rasterizer_container->add_child(l); + fdialog = memnew(FileDialog); fdialog->set_access(FileDialog::ACCESS_FILESYSTEM); fdialog_install = memnew(FileDialog); diff --git a/editor/project_settings_editor.cpp b/editor/project_settings_editor.cpp index dd31853e73..cc33550ac9 100644 --- a/editor/project_settings_editor.cpp +++ b/editor/project_settings_editor.cpp @@ -1606,7 +1606,8 @@ TabContainer *ProjectSettingsEditor::get_tabs() { } void ProjectSettingsEditor::_editor_restart() { - EditorNode::get_singleton()->save_all_scenes_and_restart(); + EditorNode::get_singleton()->save_all_scenes(); + EditorNode::get_singleton()->restart_editor(); } void ProjectSettingsEditor::_editor_restart_request() { diff --git a/editor/script_editor_debugger.cpp b/editor/script_editor_debugger.cpp index acc735d571..5f6459045a 100644 --- a/editor/script_editor_debugger.cpp +++ b/editor/script_editor_debugger.cpp @@ -898,6 +898,10 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da item.name = strings[2]; item.script = strings[0]; item.line = strings[1].to_int(); + } else if (strings.size() == 4) { //Built-in scripts have an :: in their name + item.name = strings[3]; + item.script = strings[0] + "::" + strings[1]; + item.line = strings[2].to_int(); } } else { diff --git a/editor/settings_config_dialog.cpp b/editor/settings_config_dialog.cpp index e4d5573a9a..ecd35cb930 100644 --- a/editor/settings_config_dialog.cpp +++ b/editor/settings_config_dialog.cpp @@ -375,7 +375,8 @@ void EditorSettingsDialog::_focus_current_search_box() { } void EditorSettingsDialog::_editor_restart() { - EditorNode::get_singleton()->save_all_scenes_and_restart(); + EditorNode::get_singleton()->save_all_scenes(); + EditorNode::get_singleton()->restart_editor(); } void EditorSettingsDialog::_editor_restart_request() { diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index ae70525de5..6d85eb3c90 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -223,16 +223,21 @@ void GDScript::_placeholder_erased(PlaceHolderScriptInstance *p_placeholder) { void GDScript::get_script_method_list(List<MethodInfo> *p_list) const { - for (const Map<StringName, GDScriptFunction *>::Element *E = member_functions.front(); E; E = E->next()) { - GDScriptFunction *func = E->get(); - MethodInfo mi; - mi.name = E->key(); - for (int i = 0; i < func->get_argument_count(); i++) { - mi.arguments.push_back(func->get_argument_type(i)); + const GDScript *current = this; + while (current) { + for (const Map<StringName, GDScriptFunction *>::Element *E = member_functions.front(); E; E = E->next()) { + GDScriptFunction *func = E->get(); + MethodInfo mi; + mi.name = E->key(); + for (int i = 0; i < func->get_argument_count(); i++) { + mi.arguments.push_back(func->get_argument_type(i)); + } + + mi.return_val = func->get_return_type(); + p_list->push_back(mi); } - mi.return_val = func->get_return_type(); - p_list->push_back(mi); + current = current->_base; } } diff --git a/platform/javascript/os_javascript.cpp b/platform/javascript/os_javascript.cpp index b92634c8d6..d7ba454051 100644 --- a/platform/javascript/os_javascript.cpp +++ b/platform/javascript/os_javascript.cpp @@ -861,8 +861,21 @@ Error OS_JavaScript::initialize(const VideoMode &p_desired, int p_video_driver, video_driver_index = p_video_driver; video_mode = p_desired; - // Can't fulfill fullscreen request during start-up due to browser security. + // fullscreen_change_callback will correct this if the request is successful. video_mode.fullscreen = false; + // Emscripten only attempts fullscreen requests if the user input callback + // was registered through one its own functions, so request manually for + // start-up fullscreen. + if (p_desired.fullscreen) { + /* clang-format off */ + EM_ASM({ + (canvas.requestFullscreen || canvas.msRequestFullscreen || + canvas.mozRequestFullScreen || canvas.mozRequestFullscreen || + canvas.webkitRequestFullscreen + ).call(canvas); + }); + /* clang-format on */ + } /* clang-format off */ if (EM_ASM_INT_V({ return Module.resizeCanvasOnStart })) { /* clang-format on */ diff --git a/scene/animation/animation_blend_tree.cpp b/scene/animation/animation_blend_tree.cpp index a343a4f0ed..0daa574f72 100644 --- a/scene/animation/animation_blend_tree.cpp +++ b/scene/animation/animation_blend_tree.cpp @@ -141,10 +141,14 @@ void AnimationNodeOneShot::get_parameter_list(List<PropertyInfo> *r_list) const r_list->push_back(PropertyInfo(Variant::BOOL, prev_active, PROPERTY_HINT_NONE, "", 0)); r_list->push_back(PropertyInfo(Variant::REAL, time, PROPERTY_HINT_NONE, "", 0)); r_list->push_back(PropertyInfo(Variant::REAL, remaining, PROPERTY_HINT_NONE, "", 0)); + r_list->push_back(PropertyInfo(Variant::REAL, time_to_restart, PROPERTY_HINT_NONE, "", 0)); } + Variant AnimationNodeOneShot::get_parameter_default_value(const StringName &p_parameter) const { if (p_parameter == active || p_parameter == prev_active) { return false; + } else if (p_parameter == time_to_restart) { + return -1; } else { return 0.0; } @@ -218,13 +222,26 @@ float AnimationNodeOneShot::process(float p_time, bool p_seek) { bool prev_active = get_parameter(this->prev_active); float time = get_parameter(this->time); float remaining = get_parameter(this->remaining); + float time_to_restart = get_parameter(this->time_to_restart); if (!active) { //make it as if this node doesn't exist, pass input 0 by. if (prev_active) { set_parameter(this->prev_active, false); } - return blend_input(0, p_time, p_seek, 1.0, FILTER_IGNORE, !sync); + if (time_to_restart >= 0.0 && !p_seek) { + time_to_restart -= p_time; + if (time_to_restart < 0) { + //restart + set_parameter(this->active, true); + active = true; + } + set_parameter(this->time_to_restart, time_to_restart); + } + + if (!active) { + return blend_input(0, p_time, p_seek, 1.0, FILTER_IGNORE, !sync); + } } bool os_seek = p_seek; @@ -276,6 +293,10 @@ float AnimationNodeOneShot::process(float p_time, bool p_seek) { if (remaining <= 0) { set_parameter(this->active, false); set_parameter(this->prev_active, false); + if (autorestart) { + float restart_sec = autorestart_delay + Math::randf() * autorestart_random_delay; + set_parameter(this->time_to_restart, restart_sec); + } } } @@ -350,6 +371,7 @@ AnimationNodeOneShot::AnimationNodeOneShot() { prev_active = "prev_active"; time = "time"; remaining = "remaining"; + time_to_restart = "time_to_restart"; } //////////////////////////////////////////////// diff --git a/scene/animation/animation_blend_tree.h b/scene/animation/animation_blend_tree.h index e207713134..c16dcb1b8c 100644 --- a/scene/animation/animation_blend_tree.h +++ b/scene/animation/animation_blend_tree.h @@ -91,6 +91,7 @@ private: StringName prev_active; StringName time; StringName remaining; + StringName time_to_restart; protected: static void _bind_methods(); diff --git a/scene/animation/animation_tree.cpp b/scene/animation/animation_tree.cpp index 706717a8e3..dc022bcd70 100644 --- a/scene/animation/animation_tree.cpp +++ b/scene/animation/animation_tree.cpp @@ -685,6 +685,10 @@ bool AnimationTree::_update_caches(AnimationPlayer *player) { track = track_animation; } break; + default: { + ERR_PRINT("Animation corrupted (invalid track type"); + continue; + } } track_cache[path] = track; @@ -853,6 +857,9 @@ void AnimationTree::_process_graph(float p_delta) { for (int i = 0; i < a->get_track_count(); i++) { NodePath path = a->track_get_path(i); + + ERR_CONTINUE(!track_cache.has(path)); + TrackCache *track = track_cache[path]; if (track->type != a->track_get_type(i)) { continue; //may happen should not diff --git a/scene/gui/box_container.cpp b/scene/gui/box_container.cpp index 35e8e984cd..cc37d4cf7d 100644 --- a/scene/gui/box_container.cpp +++ b/scene/gui/box_container.cpp @@ -255,6 +255,10 @@ void BoxContainer::_notification(int p_what) { _resort(); } break; + case NOTIFICATION_THEME_CHANGED: { + + minimum_size_changed(); + } break; } } diff --git a/scene/gui/graph_node.cpp b/scene/gui/graph_node.cpp index 7c879d239c..8c588109d6 100644 --- a/scene/gui/graph_node.cpp +++ b/scene/gui/graph_node.cpp @@ -192,97 +192,104 @@ bool GraphNode::has_point(const Point2 &p_point) const { void GraphNode::_notification(int p_what) { - if (p_what == NOTIFICATION_DRAW) { + switch (p_what) { + case NOTIFICATION_DRAW: { - Ref<StyleBox> sb; + Ref<StyleBox> sb; - if (comment) { - sb = get_stylebox(selected ? "commentfocus" : "comment"); + if (comment) { + sb = get_stylebox(selected ? "commentfocus" : "comment"); - } else { + } else { - sb = get_stylebox(selected ? "selectedframe" : "frame"); - } + sb = get_stylebox(selected ? "selectedframe" : "frame"); + } - //sb=sb->duplicate(); - //sb->call("set_modulate",modulate); - Ref<Texture> port = get_icon("port"); - Ref<Texture> close = get_icon("close"); - Ref<Texture> resizer = get_icon("resizer"); - int close_offset = get_constant("close_offset"); - int close_h_offset = get_constant("close_h_offset"); - Color close_color = get_color("close_color"); - Ref<Font> title_font = get_font("title_font"); - int title_offset = get_constant("title_offset"); - int title_h_offset = get_constant("title_h_offset"); - Color title_color = get_color("title_color"); - Point2i icofs = -port->get_size() * 0.5; - int edgeofs = get_constant("port_offset"); - icofs.y += sb->get_margin(MARGIN_TOP); - - draw_style_box(sb, Rect2(Point2(), get_size())); - - switch (overlay) { - case OVERLAY_DISABLED: { - - } break; - case OVERLAY_BREAKPOINT: { - - draw_style_box(get_stylebox("breakpoint"), Rect2(Point2(), get_size())); - } break; - case OVERLAY_POSITION: { - draw_style_box(get_stylebox("position"), Rect2(Point2(), get_size())); - - } break; - } + //sb=sb->duplicate(); + //sb->call("set_modulate",modulate); + Ref<Texture> port = get_icon("port"); + Ref<Texture> close = get_icon("close"); + Ref<Texture> resizer = get_icon("resizer"); + int close_offset = get_constant("close_offset"); + int close_h_offset = get_constant("close_h_offset"); + Color close_color = get_color("close_color"); + Ref<Font> title_font = get_font("title_font"); + int title_offset = get_constant("title_offset"); + int title_h_offset = get_constant("title_h_offset"); + Color title_color = get_color("title_color"); + Point2i icofs = -port->get_size() * 0.5; + int edgeofs = get_constant("port_offset"); + icofs.y += sb->get_margin(MARGIN_TOP); + + draw_style_box(sb, Rect2(Point2(), get_size())); + + switch (overlay) { + case OVERLAY_DISABLED: { + + } break; + case OVERLAY_BREAKPOINT: { + + draw_style_box(get_stylebox("breakpoint"), Rect2(Point2(), get_size())); + } break; + case OVERLAY_POSITION: { + draw_style_box(get_stylebox("position"), Rect2(Point2(), get_size())); + + } break; + } - int w = get_size().width - sb->get_minimum_size().x; + int w = get_size().width - sb->get_minimum_size().x; - if (show_close) - w -= close->get_width(); + if (show_close) + w -= close->get_width(); - draw_string(title_font, Point2(sb->get_margin(MARGIN_LEFT) + title_h_offset, -title_font->get_height() + title_font->get_ascent() + title_offset), title, title_color, w); - if (show_close) { - Vector2 cpos = Point2(w + sb->get_margin(MARGIN_LEFT) + close_h_offset, -close->get_height() + close_offset); - draw_texture(close, cpos, close_color); - close_rect.position = cpos; - close_rect.size = close->get_size(); - } else { - close_rect = Rect2(); - } + draw_string(title_font, Point2(sb->get_margin(MARGIN_LEFT) + title_h_offset, -title_font->get_height() + title_font->get_ascent() + title_offset), title, title_color, w); + if (show_close) { + Vector2 cpos = Point2(w + sb->get_margin(MARGIN_LEFT) + close_h_offset, -close->get_height() + close_offset); + draw_texture(close, cpos, close_color); + close_rect.position = cpos; + close_rect.size = close->get_size(); + } else { + close_rect = Rect2(); + } - for (Map<int, Slot>::Element *E = slot_info.front(); E; E = E->next()) { - - if (E->key() < 0 || E->key() >= cache_y.size()) - continue; - if (!slot_info.has(E->key())) - continue; - const Slot &s = slot_info[E->key()]; - //left - if (s.enable_left) { - Ref<Texture> p = port; - if (s.custom_slot_left.is_valid()) { - p = s.custom_slot_left; + for (Map<int, Slot>::Element *E = slot_info.front(); E; E = E->next()) { + + if (E->key() < 0 || E->key() >= cache_y.size()) + continue; + if (!slot_info.has(E->key())) + continue; + const Slot &s = slot_info[E->key()]; + //left + if (s.enable_left) { + Ref<Texture> p = port; + if (s.custom_slot_left.is_valid()) { + p = s.custom_slot_left; + } + p->draw(get_canvas_item(), icofs + Point2(edgeofs, cache_y[E->key()]), s.color_left); } - p->draw(get_canvas_item(), icofs + Point2(edgeofs, cache_y[E->key()]), s.color_left); - } - if (s.enable_right) { - Ref<Texture> p = port; - if (s.custom_slot_right.is_valid()) { - p = s.custom_slot_right; + if (s.enable_right) { + Ref<Texture> p = port; + if (s.custom_slot_right.is_valid()) { + p = s.custom_slot_right; + } + p->draw(get_canvas_item(), icofs + Point2(get_size().x - edgeofs, cache_y[E->key()]), s.color_right); } - p->draw(get_canvas_item(), icofs + Point2(get_size().x - edgeofs, cache_y[E->key()]), s.color_right); } - } - if (resizable) { - draw_texture(resizer, get_size() - resizer->get_size()); - } - } + if (resizable) { + draw_texture(resizer, get_size() - resizer->get_size()); + } + } break; + + case NOTIFICATION_SORT_CHILDREN: { + + _resort(); + } break; - if (p_what == NOTIFICATION_SORT_CHILDREN) { + case NOTIFICATION_THEME_CHANGED: { - _resort(); + minimum_size_changed(); + } break; } } diff --git a/scene/gui/grid_container.cpp b/scene/gui/grid_container.cpp index b37d08de71..d0e2edc7b5 100644 --- a/scene/gui/grid_container.cpp +++ b/scene/gui/grid_container.cpp @@ -164,6 +164,10 @@ void GridContainer::_notification(int p_what) { } } break; + case NOTIFICATION_THEME_CHANGED: { + + minimum_size_changed(); + } break; } } diff --git a/scene/gui/margin_container.cpp b/scene/gui/margin_container.cpp index a087b68d25..62ba45c484 100644 --- a/scene/gui/margin_container.cpp +++ b/scene/gui/margin_container.cpp @@ -64,27 +64,33 @@ Size2 MarginContainer::get_minimum_size() const { void MarginContainer::_notification(int p_what) { - if (p_what == NOTIFICATION_SORT_CHILDREN) { + switch (p_what) { + case NOTIFICATION_SORT_CHILDREN: { - int margin_left = get_constant("margin_left"); - int margin_top = get_constant("margin_top"); - int margin_right = get_constant("margin_right"); - int margin_bottom = get_constant("margin_bottom"); + int margin_left = get_constant("margin_left"); + int margin_top = get_constant("margin_top"); + int margin_right = get_constant("margin_right"); + int margin_bottom = get_constant("margin_bottom"); - Size2 s = get_size(); + Size2 s = get_size(); - for (int i = 0; i < get_child_count(); i++) { + for (int i = 0; i < get_child_count(); i++) { - Control *c = Object::cast_to<Control>(get_child(i)); - if (!c) - continue; - if (c->is_set_as_toplevel()) - continue; + Control *c = Object::cast_to<Control>(get_child(i)); + if (!c) + continue; + if (c->is_set_as_toplevel()) + continue; - int w = s.width - margin_left - margin_right; - int h = s.height - margin_top - margin_bottom; - fit_child_in_rect(c, Rect2(margin_left, margin_top, w, h)); - } + int w = s.width - margin_left - margin_right; + int h = s.height - margin_top - margin_bottom; + fit_child_in_rect(c, Rect2(margin_left, margin_top, w, h)); + } + } break; + case NOTIFICATION_THEME_CHANGED: { + + minimum_size_changed(); + } break; } } diff --git a/scene/gui/split_container.cpp b/scene/gui/split_container.cpp index e4cb2a06fc..d6a93238b2 100644 --- a/scene/gui/split_container.cpp +++ b/scene/gui/split_container.cpp @@ -193,6 +193,10 @@ void SplitContainer::_notification(int p_what) { draw_texture(tex, Point2i(middle_sep + (sep - tex->get_width()) / 2, (size.y - tex->get_height()) / 2)); } } break; + case NOTIFICATION_THEME_CHANGED: { + + minimum_size_changed(); + } break; } } diff --git a/scene/gui/tab_container.cpp b/scene/gui/tab_container.cpp index b4fe6b0255..212efa4976 100644 --- a/scene/gui/tab_container.cpp +++ b/scene/gui/tab_container.cpp @@ -338,6 +338,7 @@ void TabContainer::_notification(int p_what) { } } break; case NOTIFICATION_THEME_CHANGED: { + minimum_size_changed(); call_deferred("_on_theme_changed"); //wait until all changed theme } break; } diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp index 5acb157279..f713851090 100644 --- a/scene/main/scene_tree.cpp +++ b/scene/main/scene_tree.cpp @@ -484,6 +484,14 @@ bool SceneTree::iteration(float p_time) { return _quit; } +void SceneTree::_update_font_oversampling(float p_ratio) { + + if (use_font_oversampling) { + DynamicFontAtSize::font_oversampling = p_ratio; + DynamicFont::update_oversampling(); + } +} + bool SceneTree::idle(float p_time) { //print_line("ram: "+itos(OS::get_singleton()->get_static_memory_usage())+" sram: "+itos(OS::get_singleton()->get_dynamic_memory_usage())); @@ -515,12 +523,6 @@ bool SceneTree::idle(float p_time) { last_screen_size = win_size; _update_root_rect(); - - if (use_font_oversampling) { - DynamicFontAtSize::font_oversampling = OS::get_singleton()->get_window_size().width / root->get_visible_rect().size.width; - DynamicFont::update_oversampling(); - } - emit_signal("screen_resized"); } @@ -1133,10 +1135,12 @@ void SceneTree::_update_root_rect() { if (stretch_mode == STRETCH_MODE_DISABLED) { + _update_font_oversampling(1.0); root->set_size((last_screen_size / stretch_shrink).floor()); root->set_attach_to_screen_rect(Rect2(Point2(), last_screen_size)); root->set_size_override_stretch(false); root->set_size_override(false, Size2()); + root->update_canvas_items(); return; //user will take care } @@ -1154,6 +1158,9 @@ void SceneTree::_update_root_rect() { //same aspect or ignore aspect viewport_size = desired_res; screen_size = video_mode; + if (use_font_oversampling) { + WARN_PRINT("Font oversampling only works with the following resize modes 'Keep Width', 'Keep Height', and 'Expand'.") + } } else if (viewport_aspect < video_mode_aspect) { // screen ratio is smaller vertically @@ -1208,21 +1215,30 @@ void SceneTree::_update_root_rect() { switch (stretch_mode) { case STRETCH_MODE_DISABLED: { // Already handled above + _update_font_oversampling(1.0); } break; case STRETCH_MODE_2D: { + _update_font_oversampling(screen_size.x / viewport_size.x); //screen / viewport radio drives oversampling root->set_size((screen_size / stretch_shrink).floor()); root->set_attach_to_screen_rect(Rect2(margin, screen_size)); root->set_size_override_stretch(true); root->set_size_override(true, (viewport_size / stretch_shrink).floor()); + root->update_canvas_items(); //force them to update just in case } break; case STRETCH_MODE_VIEWPORT: { + _update_font_oversampling(1.0); root->set_size((viewport_size / stretch_shrink).floor()); root->set_attach_to_screen_rect(Rect2(margin, screen_size)); root->set_size_override_stretch(false); root->set_size_override(false, Size2()); + root->update_canvas_items(); //force them to update just in case + + if (use_font_oversampling) { + WARN_PRINT("Font oversampling does not work in 'Viewport' stretch mode, only '2D'.") + } } break; } @@ -1925,12 +1941,11 @@ void SceneTree::add_idle_callback(IdleCallback p_callback) { void SceneTree::set_use_font_oversampling(bool p_oversampling) { + if (use_font_oversampling == p_oversampling) + return; + use_font_oversampling = p_oversampling; - if (use_font_oversampling) { - DynamicFontAtSize::font_oversampling = OS::get_singleton()->get_window_size().width / root->get_visible_rect().size.width; - } else { - DynamicFontAtSize::font_oversampling = 1.0; - } + _update_root_rect(); } bool SceneTree::is_using_font_oversampling() const { @@ -1944,6 +1959,7 @@ SceneTree::SceneTree() { accept_quit = true; quit_on_go_back = true; initialized = false; + use_font_oversampling = false; #ifdef DEBUG_ENABLED debug_collisions_hint = false; debug_navigation_hint = false; @@ -2079,8 +2095,6 @@ SceneTree::SceneTree() { live_edit_root = NodePath("/root"); #endif - - use_font_oversampling = false; } SceneTree::~SceneTree() { diff --git a/scene/main/scene_tree.h b/scene/main/scene_tree.h index d6ab8c37b2..3a1ff5cb06 100644 --- a/scene/main/scene_tree.h +++ b/scene/main/scene_tree.h @@ -153,6 +153,7 @@ private: Size2i stretch_min; real_t stretch_shrink; + void _update_font_oversampling(float p_ratio); void _update_root_rect(); List<ObjectID> delete_queue; diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 8df007dcc7..61d6fc7401 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -693,6 +693,13 @@ bool Viewport::use_arvr() { return arvr; } +void Viewport::update_canvas_items() { + if (!is_inside_tree()) + return; + + _update_canvas_items(this); +} + void Viewport::set_size(const Size2 &p_size) { if (size == p_size.floor()) @@ -1128,6 +1135,26 @@ Transform2D Viewport::get_final_transform() const { return stretch_transform * global_canvas_transform; } +void Viewport::_update_canvas_items(Node *p_node) { + if (p_node != this) { + + Viewport *vp = Object::cast_to<Viewport>(p_node); + if (vp) + return; + + CanvasItem *ci = Object::cast_to<CanvasItem>(p_node); + if (ci) { + ci->update(); + } + } + + int cc = p_node->get_child_count(); + + for (int i = 0; i < cc; i++) { + _update_canvas_items(p_node->get_child(i)); + } +} + void Viewport::set_size_override(bool p_enable, const Size2 &p_size, const Vector2 &p_margin) { if (size_override == p_enable && p_size == size_override_size) diff --git a/scene/main/viewport.h b/scene/main/viewport.h index cdb9d4afb5..4d0a4e8c87 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -385,6 +385,8 @@ private: void _drop_mouse_focus(); + void _update_canvas_items(Node *p_node); + protected: void _notification(int p_what); static void _bind_methods(); @@ -403,6 +405,7 @@ public: bool is_audio_listener_2d() const; void set_size(const Size2 &p_size); + void update_canvas_items(); Size2 get_size() const; Rect2 get_visible_rect() const; diff --git a/scene/resources/surface_tool.cpp b/scene/resources/surface_tool.cpp index 1684cbf15f..2116dd0b1e 100644 --- a/scene/resources/surface_tool.cpp +++ b/scene/resources/surface_tool.cpp @@ -1021,8 +1021,6 @@ void SurfaceTool::_bind_methods() { ClassDB::bind_method(D_METHOD("generate_normals", "flip"), &SurfaceTool::generate_normals, DEFVAL(false)); ClassDB::bind_method(D_METHOD("generate_tangents"), &SurfaceTool::generate_tangents); - ClassDB::bind_method(D_METHOD("add_to_format", "flags"), &SurfaceTool::add_to_format); - ClassDB::bind_method(D_METHOD("set_material", "material"), &SurfaceTool::set_material); ClassDB::bind_method(D_METHOD("clear"), &SurfaceTool::clear); diff --git a/scene/resources/surface_tool.h b/scene/resources/surface_tool.h index 754254150d..ef13238c13 100644 --- a/scene/resources/surface_tool.h +++ b/scene/resources/surface_tool.h @@ -118,8 +118,6 @@ public: void generate_normals(bool p_flip = false); void generate_tangents(); - void add_to_format(int p_flags) { format |= p_flags; } - void set_material(const Ref<Material> &p_material); void clear(); diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp index 3870916779..26036c08a9 100644 --- a/scene/resources/texture.cpp +++ b/scene/resources/texture.cpp @@ -178,6 +178,12 @@ void ImageTexture::_reload_hook(const RID &p_hook) { _change_notify(); } +bool ImageTexture::keep_images_cached = false; + +void ImageTexture::set_keep_images_cached(bool p_enable) { + keep_images_cached = p_enable; +} + void ImageTexture::create(int p_width, int p_height, Image::Format p_format, uint32_t p_flags) { flags = p_flags; @@ -198,6 +204,10 @@ void ImageTexture::create_from_image(const Ref<Image> &p_image, uint32_t p_flags VisualServer::get_singleton()->texture_allocate(texture, p_image->get_width(), p_image->get_height(), 0, p_image->get_format(), VS::TEXTURE_TYPE_2D, p_flags); VisualServer::get_singleton()->texture_set_data(texture, p_image); _change_notify(); + + if (keep_images_cached) { + image_cache = p_image; + } } void ImageTexture::set_flags(uint32_t p_flags) { @@ -245,6 +255,10 @@ void ImageTexture::set_data(const Ref<Image> &p_image) { _change_notify(); alpha_cache.unref(); + + if (keep_images_cached) { + image_cache = p_image; + } } void ImageTexture::_resource_path_changed() { @@ -254,7 +268,11 @@ void ImageTexture::_resource_path_changed() { Ref<Image> ImageTexture::get_data() const { - return VisualServer::get_singleton()->texture_get_data(texture); + if (image_cache.is_valid()) { + return image_cache; + } else { + return VisualServer::get_singleton()->texture_get_data(texture); + } } int ImageTexture::get_width() const { diff --git a/scene/resources/texture.h b/scene/resources/texture.h index 2b67ebec62..4b5b504510 100644 --- a/scene/resources/texture.h +++ b/scene/resources/texture.h @@ -111,6 +111,7 @@ private: Size2 size_override; float lossy_storage_quality; mutable Ref<BitMap> alpha_cache; + Ref<Image> image_cache; protected: virtual void reload_from_file(); @@ -125,7 +126,11 @@ protected: void _set_data(Dictionary p_data); + static bool keep_images_cached; + public: + static void set_keep_images_cached(bool p_enable); + void create(int p_width, int p_height, Image::Format p_format, uint32_t p_flags = FLAGS_DEFAULT); void create_from_image(const Ref<Image> &p_image, uint32_t p_flags = FLAGS_DEFAULT); diff --git a/scene/resources/theme.cpp b/scene/resources/theme.cpp index 786a136040..87b40d5447 100644 --- a/scene/resources/theme.cpp +++ b/scene/resources/theme.cpp @@ -622,43 +622,47 @@ void Theme::clear() { void Theme::copy_default_theme() { Ref<Theme> default_theme = get_default(); + copy_theme(default_theme); +} + +void Theme::copy_theme(const Ref<Theme> &p_other) { //these need reconnecting, so add normally { const StringName *K = NULL; - while ((K = default_theme->icon_map.next(K))) { + while ((K = p_other->icon_map.next(K))) { const StringName *L = NULL; - while ((L = default_theme->icon_map[*K].next(L))) { - set_icon(*K, *L, default_theme->icon_map[*K][*L]); + while ((L = p_other->icon_map[*K].next(L))) { + set_icon(*L, *K, p_other->icon_map[*K][*L]); } } } { const StringName *K = NULL; - while ((K = default_theme->style_map.next(K))) { + while ((K = p_other->style_map.next(K))) { const StringName *L = NULL; - while ((L = default_theme->style_map[*K].next(L))) { - set_stylebox(*K, *L, default_theme->style_map[*K][*L]); + while ((L = p_other->style_map[*K].next(L))) { + set_stylebox(*L, *K, p_other->style_map[*K][*L]); } } } { const StringName *K = NULL; - while ((K = default_theme->font_map.next(K))) { + while ((K = p_other->font_map.next(K))) { const StringName *L = NULL; - while ((L = default_theme->font_map[*K].next(L))) { - set_font(*K, *L, default_theme->font_map[*K][*L]); + while ((L = p_other->font_map[*K].next(L))) { + set_font(*L, *K, p_other->font_map[*K][*L]); } } } //these are ok to just copy - color_map = default_theme->color_map; - constant_map = default_theme->constant_map; - shader_map = default_theme->shader_map; + color_map = p_other->color_map; + constant_map = p_other->constant_map; + shader_map = p_other->shader_map; _change_notify(); emit_changed(); @@ -752,6 +756,7 @@ void Theme::_bind_methods() { ClassDB::bind_method(D_METHOD("_emit_theme_changed"), &Theme::_emit_theme_changed); ClassDB::bind_method("copy_default_theme", &Theme::copy_default_theme); + ClassDB::bind_method("copy_theme", &Theme::copy_theme); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "default_font", PROPERTY_HINT_RESOURCE_TYPE, "Font"), "set_default_font", "get_default_font"); } diff --git a/scene/resources/theme.h b/scene/resources/theme.h index 021a2936bd..fb59073cbe 100644 --- a/scene/resources/theme.h +++ b/scene/resources/theme.h @@ -184,6 +184,7 @@ public: void get_type_list(List<StringName> *p_list) const; void copy_default_theme(); + void copy_theme(const Ref<Theme> &p_other); void clear(); Theme(); diff --git a/servers/visual_server.cpp b/servers/visual_server.cpp index 02acf72951..14c9a29ae5 100644 --- a/servers/visual_server.cpp +++ b/servers/visual_server.cpp @@ -2406,7 +2406,7 @@ VisualServer::VisualServer() { GLOBAL_DEF("rendering/quality/shading/force_blinn_over_ggx.mobile", true); GLOBAL_DEF("rendering/quality/depth_prepass/enable", true); - GLOBAL_DEF("rendering/quality/depth_prepass/disable_for_vendors", "PowerVR,Mali,Adreno"); + GLOBAL_DEF("rendering/quality/depth_prepass/disable_for_vendors", "PowerVR,Mali,Adreno,Apple"); GLOBAL_DEF("rendering/quality/filters/use_nearest_mipmap_filter", false); } |