summaryrefslogtreecommitdiff
path: root/scene/main
diff options
context:
space:
mode:
authorkobewi <kobewi4e@gmail.com>2023-04-06 14:47:49 +0200
committerRĂ©mi Verschelde <rverschelde@gmail.com>2023-05-12 12:31:22 +0200
commit1146172b302a68393e4f97b47e6460d78db75518 (patch)
tree6b2cfc2e2ac14f2e6aa177ea561c569630c11f73 /scene/main
parent2a8501e1a26b12dadd4f6fcbed799e319cd77027 (diff)
Prevent errors when using ViewportTexture
(cherry picked from commit 1b9802fa8cb45e876cd90d6a174b95b270a7f934)
Diffstat (limited to 'scene/main')
-rw-r--r--scene/main/node.cpp5
-rw-r--r--scene/main/node.h1
-rw-r--r--scene/main/viewport.cpp72
-rw-r--r--scene/main/viewport.h3
4 files changed, 62 insertions, 19 deletions
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..8bdcd9302f 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;
@@ -72,22 +76,11 @@ void ViewportTexture::setup_local_to_scene() {
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;
}
}
@@ -108,17 +101,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 +143,36 @@ 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;
+}
+
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);
diff --git a/scene/main/viewport.h b/scene/main/viewport.h
index 5213c0db01..e88e0628dd 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;