diff options
Diffstat (limited to 'scene/main')
-rw-r--r-- | scene/main/multiplayer_peer.cpp | 4 | ||||
-rw-r--r-- | scene/main/node.cpp | 5 | ||||
-rw-r--r-- | scene/main/node.h | 1 | ||||
-rw-r--r-- | scene/main/viewport.cpp | 118 | ||||
-rw-r--r-- | scene/main/viewport.h | 5 |
5 files changed, 111 insertions, 22 deletions
diff --git a/scene/main/multiplayer_peer.cpp b/scene/main/multiplayer_peer.cpp index f3e56a1455..8c9eeea027 100644 --- a/scene/main/multiplayer_peer.cpp +++ b/scene/main/multiplayer_peer.cpp @@ -201,6 +201,9 @@ void MultiplayerPeerExtension::_bind_methods() { GDVIRTUAL_BIND(_get_packet_script) GDVIRTUAL_BIND(_put_packet_script, "p_buffer"); + GDVIRTUAL_BIND(_get_packet_channel); + GDVIRTUAL_BIND(_get_packet_mode); + GDVIRTUAL_BIND(_set_transfer_channel, "p_channel"); GDVIRTUAL_BIND(_get_transfer_channel); @@ -217,6 +220,7 @@ void MultiplayerPeerExtension::_bind_methods() { GDVIRTUAL_BIND(_get_unique_id); GDVIRTUAL_BIND(_set_refuse_new_connections, "p_enable"); GDVIRTUAL_BIND(_is_refusing_new_connections); + GDVIRTUAL_BIND(_is_server_relay_supported); GDVIRTUAL_BIND(_get_connection_status); ADD_PROPERTY_DEFAULT("transfer_mode", TRANSFER_MODE_RELIABLE); diff --git a/scene/main/node.cpp b/scene/main/node.cpp index 52c1df8110..057fd15f1b 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -2759,6 +2759,10 @@ bool Node::is_displayed_folded() const { return data.display_folded; } +bool Node::is_ready() const { + return !data.ready_first; +} + void Node::request_ready() { data.ready_first = true; } @@ -2897,6 +2901,7 @@ void Node::_bind_methods() { ClassDB::bind_method(D_METHOD("queue_free"), &Node::queue_free); ClassDB::bind_method(D_METHOD("request_ready"), &Node::request_ready); + ClassDB::bind_method(D_METHOD("is_node_ready"), &Node::is_ready); ClassDB::bind_method(D_METHOD("set_multiplayer_authority", "id", "recursive"), &Node::set_multiplayer_authority, DEFVAL(true)); ClassDB::bind_method(D_METHOD("get_multiplayer_authority"), &Node::get_multiplayer_authority); diff --git a/scene/main/node.h b/scene/main/node.h index 493578bc5b..4a606538a8 100644 --- a/scene/main/node.h +++ b/scene/main/node.h @@ -455,6 +455,7 @@ public: bool can_process_notification(int p_what) const; bool is_enabled() const; + bool is_ready() const; void request_ready(); static void print_orphan_nodes(); diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 8cd57536bf..4aaa2e8f5b 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -61,6 +61,10 @@ #include "servers/rendering/rendering_server_globals.h" void ViewportTexture::setup_local_to_scene() { + if (vp_pending) { + return; + } + Node *loc_scene = get_local_scene(); if (!loc_scene) { return; @@ -68,26 +72,14 @@ void ViewportTexture::setup_local_to_scene() { if (vp) { vp->viewport_textures.erase(this); + vp = nullptr; } - vp = nullptr; - - Node *vpn = loc_scene->get_node(path); - ERR_FAIL_COND_MSG(!vpn, "ViewportTexture: Path to node is invalid."); - - vp = Object::cast_to<Viewport>(vpn); - - ERR_FAIL_COND_MSG(!vp, "ViewportTexture: Path to node does not point to a viewport."); - - vp->viewport_textures.insert(this); - - ERR_FAIL_NULL(RenderingServer::get_singleton()); - if (proxy_ph.is_valid()) { - RS::get_singleton()->texture_proxy_update(proxy, vp->texture_rid); - RS::get_singleton()->free(proxy_ph); + if (loc_scene->is_ready()) { + _setup_local_to_scene(loc_scene); } else { - ERR_FAIL_COND(proxy.is_valid()); // Should be invalid. - proxy = RS::get_singleton()->texture_proxy_create(vp->texture_rid); + loc_scene->connect(SNAME("ready"), callable_mp(this, &ViewportTexture::_setup_local_to_scene).bind(loc_scene), CONNECT_ONE_SHOT); + vp_pending = true; } } @@ -98,8 +90,24 @@ void ViewportTexture::set_viewport_path_in_scene(const NodePath &p_path) { path = p_path; - if (get_local_scene()) { + if (vp) { + vp->viewport_textures.erase(this); + vp = nullptr; + } + + if (proxy_ph.is_valid()) { + RS::get_singleton()->free(proxy_ph); + } + if (proxy.is_valid()) { + RS::get_singleton()->free(proxy); + } + proxy_ph = RID(); + proxy = RID(); + + if (get_local_scene() && !path.is_empty()) { setup_local_to_scene(); + } else { + emit_changed(); } } @@ -108,17 +116,32 @@ NodePath ViewportTexture::get_viewport_path_in_scene() const { } int ViewportTexture::get_width() const { - ERR_FAIL_COND_V_MSG(!vp, 0, "Viewport Texture must be set to use it."); + if (!vp) { + if (!vp_pending) { + ERR_PRINT("Viewport Texture must be set to use it."); + } + return 0; + } return vp->size.width; } int ViewportTexture::get_height() const { - ERR_FAIL_COND_V_MSG(!vp, 0, "Viewport Texture must be set to use it."); + if (!vp) { + if (!vp_pending) { + ERR_PRINT("Viewport Texture must be set to use it."); + } + return 0; + } return vp->size.height; } Size2 ViewportTexture::get_size() const { - ERR_FAIL_COND_V_MSG(!vp, Size2(), "Viewport Texture must be set to use it."); + if (!vp) { + if (!vp_pending) { + ERR_PRINT("Viewport Texture must be set to use it."); + } + return Size2(); + } return vp->size; } @@ -135,10 +158,38 @@ bool ViewportTexture::has_alpha() const { } Ref<Image> ViewportTexture::get_image() const { - ERR_FAIL_COND_V_MSG(!vp, Ref<Image>(), "Viewport Texture must be set to use it."); + if (!vp) { + if (!vp_pending) { + ERR_PRINT("Viewport Texture must be set to use it."); + } + return Ref<Image>(); + } return RS::get_singleton()->texture_2d_get(vp->texture_rid); } +void ViewportTexture::_setup_local_to_scene(const Node *p_loc_scene) { + Node *vpn = p_loc_scene->get_node(path); + ERR_FAIL_COND_MSG(!vpn, "ViewportTexture: Path to node is invalid."); + + vp = Object::cast_to<Viewport>(vpn); + + ERR_FAIL_COND_MSG(!vp, "ViewportTexture: Path to node does not point to a viewport."); + + vp->viewport_textures.insert(this); + + ERR_FAIL_NULL(RenderingServer::get_singleton()); + if (proxy_ph.is_valid()) { + RS::get_singleton()->texture_proxy_update(proxy, vp->texture_rid); + RS::get_singleton()->free(proxy_ph); + } else { + ERR_FAIL_COND(proxy.is_valid()); // Should be invalid. + proxy = RS::get_singleton()->texture_proxy_create(vp->texture_rid); + } + vp_pending = false; + + emit_changed(); +} + void ViewportTexture::_bind_methods() { ClassDB::bind_method(D_METHOD("set_viewport_path_in_scene", "path"), &ViewportTexture::set_viewport_path_in_scene); ClassDB::bind_method(D_METHOD("get_viewport_path_in_scene"), &ViewportTexture::get_viewport_path_in_scene); @@ -374,9 +425,28 @@ int Viewport::_sub_window_find(Window *p_window) { return -1; } +void Viewport::_update_viewport_path() { + if (viewport_textures.is_empty()) { + return; + } + + Node *scene_root = get_scene_file_path().is_empty() ? get_owner() : this; + if (!scene_root && is_inside_tree()) { + scene_root = get_tree()->get_edited_scene_root(); + } + if (scene_root && (scene_root == this || scene_root->is_ancestor_of(this))) { + NodePath path_in_scene = scene_root->get_path_to(this); + for (ViewportTexture *E : viewport_textures) { + E->path = path_in_scene; + } + } +} + void Viewport::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: { + _update_viewport_path(); + if (get_parent()) { parent = get_parent()->get_viewport(); RenderingServer::get_singleton()->viewport_set_parent_viewport(viewport, parent->get_viewport_rid()); @@ -469,6 +539,10 @@ void Viewport::_notification(int p_what) { RenderingServer::get_singleton()->viewport_set_parent_viewport(viewport, RID()); } break; + case NOTIFICATION_PATH_RENAMED: { + _update_viewport_path(); + } break; + case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { if (!get_tree()) { return; diff --git a/scene/main/viewport.h b/scene/main/viewport.h index 5213c0db01..de0abec052 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -59,6 +59,9 @@ class ViewportTexture : public Texture2D { friend class Viewport; Viewport *vp = nullptr; + bool vp_pending = false; + + void _setup_local_to_scene(const Node *p_loc_scene); mutable RID proxy_ph; mutable RID proxy; @@ -314,6 +317,8 @@ private: Ref<ViewportTexture> default_texture; HashSet<ViewportTexture *> viewport_textures; + void _update_viewport_path(); + SDFOversize sdf_oversize = SDF_OVERSIZE_120_PERCENT; SDFScale sdf_scale = SDF_SCALE_50_PERCENT; |