Prevent errors when using ViewportTexture

This commit is contained in:
kobewi 2023-04-06 14:47:49 +02:00
parent 491a437df5
commit 1b9802fa8c
6 changed files with 70 additions and 20 deletions

View file

@ -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);