Prevent errors when using ViewportTexture
This commit is contained in:
parent
491a437df5
commit
1b9802fa8c
@ -500,6 +500,13 @@
|
||||
Returns [code]true[/code] if the local system is the multiplayer authority of this node.
|
||||
</description>
|
||||
</method>
|
||||
<method name="is_node_ready" qualifiers="const">
|
||||
<return type="bool" />
|
||||
<description>
|
||||
Returns [code]true[/code] if the node is ready, i.e. it's inside scene tree and all its children are initialized.
|
||||
[method request_ready] resets it back to [code]false[/code].
|
||||
</description>
|
||||
</method>
|
||||
<method name="is_physics_processing" qualifiers="const">
|
||||
<return type="bool" />
|
||||
<description>
|
||||
|
@ -6,7 +6,7 @@
|
||||
<description>
|
||||
Displays the content of a [Viewport] node as a dynamic [Texture2D]. This can be used to mix controls, 2D, and 3D elements in the same scene.
|
||||
To create a ViewportTexture in code, use the [method Viewport.get_texture] method on the target viewport.
|
||||
[b]Note:[/b] When local to scene, this texture uses [method Resource.setup_local_to_scene] to set the proxy texture and flags in the local viewport.
|
||||
[b]Note:[/b] When local to scene, this texture uses [method Resource.setup_local_to_scene] to set the proxy texture and flags in the local viewport. Local to scene viewport textures will return incorrect data until the scene root is ready (see [signal Node.ready]).
|
||||
</description>
|
||||
<tutorials>
|
||||
<link title="GUI in 3D Demo">https://godotengine.org/asset-library/asset/127</link>
|
||||
|
@ -2786,6 +2786,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;
|
||||
}
|
||||
@ -2932,6 +2936,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);
|
||||
|
@ -500,6 +500,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();
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user