diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp index 2ea55843ad..4ad5f2a506 100644 --- a/scene/resources/texture.cpp +++ b/scene/resources/texture.cpp @@ -2587,7 +2587,10 @@ RID CameraTexture::get_rid() const { if (feed.is_valid()) { return feed->get_texture(which_feed); } else { - return RID(); + if (_texture.is_null()) { + _texture = RenderingServer::get_singleton()->texture_2d_placeholder_create(); + } + return _texture; } } @@ -2643,5 +2646,7 @@ bool CameraTexture::get_camera_active() const { CameraTexture::CameraTexture() {} CameraTexture::~CameraTexture() { - // nothing to do here yet + if (_texture.is_valid()) { + RenderingServer::get_singleton()->free(_texture); + } } diff --git a/scene/resources/texture.h b/scene/resources/texture.h index 98aa61138d..2e97c2deb1 100644 --- a/scene/resources/texture.h +++ b/scene/resources/texture.h @@ -812,6 +812,7 @@ class CameraTexture : public Texture2D { GDCLASS(CameraTexture, Texture2D); private: + mutable RID _texture; int camera_feed_id = 0; CameraServer::FeedImage which_feed = CameraServer::FEED_RGBA_IMAGE; diff --git a/servers/camera/camera_feed.cpp b/servers/camera/camera_feed.cpp index 13afc803e4..9f8e8a8106 100644 --- a/servers/camera/camera_feed.cpp +++ b/servers/camera/camera_feed.cpp @@ -138,11 +138,15 @@ RID CameraFeed::get_texture(CameraServer::FeedImage p_which) { CameraFeed::CameraFeed() { // initialize our feed id = CameraServer::get_singleton()->get_free_id(); + base_width = 0; + base_height = 0; name = "???"; active = false; datatype = CameraFeed::FEED_RGB; position = CameraFeed::FEED_UNSPECIFIED; transform = Transform2D(1.0, 0.0, 0.0, -1.0, 0.0, 1.0); + texture[CameraServer::FEED_Y_IMAGE] = RenderingServer::get_singleton()->texture_2d_placeholder_create(); + texture[CameraServer::FEED_CBCR_IMAGE] = RenderingServer::get_singleton()->texture_2d_placeholder_create(); } CameraFeed::CameraFeed(String p_name, FeedPosition p_position) { @@ -155,16 +159,14 @@ CameraFeed::CameraFeed(String p_name, FeedPosition p_position) { datatype = CameraFeed::FEED_NOIMAGE; position = p_position; transform = Transform2D(1.0, 0.0, 0.0, -1.0, 0.0, 1.0); + texture[CameraServer::FEED_Y_IMAGE] = RenderingServer::get_singleton()->texture_2d_placeholder_create(); + texture[CameraServer::FEED_CBCR_IMAGE] = RenderingServer::get_singleton()->texture_2d_placeholder_create(); } CameraFeed::~CameraFeed() { // Free our textures - if (texture[CameraServer::FEED_Y_IMAGE].is_valid()) { - RenderingServer::get_singleton()->free(texture[CameraServer::FEED_Y_IMAGE]); - } - if (texture[CameraServer::FEED_CBCR_IMAGE].is_valid()) { - RenderingServer::get_singleton()->free(texture[CameraServer::FEED_CBCR_IMAGE]); - } + RenderingServer::get_singleton()->free(texture[CameraServer::FEED_Y_IMAGE]); + RenderingServer::get_singleton()->free(texture[CameraServer::FEED_CBCR_IMAGE]); } void CameraFeed::set_RGB_img(const Ref &p_rgb_img) { @@ -177,12 +179,9 @@ void CameraFeed::set_RGB_img(const Ref &p_rgb_img) { // We're assuming here that our camera image doesn't change around formats etc, allocate the whole lot... base_width = new_width; base_height = new_height; - if (texture[CameraServer::FEED_RGBA_IMAGE].is_null()) { - texture[CameraServer::FEED_RGBA_IMAGE] = RenderingServer::get_singleton()->texture_2d_create(p_rgb_img); - } else { - RID new_texture = RenderingServer::get_singleton()->texture_2d_create(p_rgb_img); - RenderingServer::get_singleton()->texture_replace(texture[CameraServer::FEED_RGBA_IMAGE], new_texture); - } + + RID new_texture = RenderingServer::get_singleton()->texture_2d_create(p_rgb_img); + RenderingServer::get_singleton()->texture_replace(texture[CameraServer::FEED_RGBA_IMAGE], new_texture); } else { RenderingServer::get_singleton()->texture_2d_update(texture[CameraServer::FEED_RGBA_IMAGE], p_rgb_img); } @@ -201,12 +200,9 @@ void CameraFeed::set_YCbCr_img(const Ref &p_ycbcr_img) { // We're assuming here that our camera image doesn't change around formats etc, allocate the whole lot... base_width = new_width; base_height = new_height; - if (texture[CameraServer::FEED_RGBA_IMAGE].is_null()) { - texture[CameraServer::FEED_RGBA_IMAGE] = RenderingServer::get_singleton()->texture_2d_create(p_ycbcr_img); - } else { - RID new_texture = RenderingServer::get_singleton()->texture_2d_create(p_ycbcr_img); - RenderingServer::get_singleton()->texture_replace(texture[CameraServer::FEED_RGBA_IMAGE], new_texture); - } + + RID new_texture = RenderingServer::get_singleton()->texture_2d_create(p_ycbcr_img); + RenderingServer::get_singleton()->texture_replace(texture[CameraServer::FEED_RGBA_IMAGE], new_texture); } else { RenderingServer::get_singleton()->texture_2d_update(texture[CameraServer::FEED_RGBA_IMAGE], p_ycbcr_img); } @@ -230,16 +226,11 @@ void CameraFeed::set_YCbCr_imgs(const Ref &p_y_img, const Ref &p_c // We're assuming here that our camera image doesn't change around formats etc, allocate the whole lot... base_width = new_y_width; base_height = new_y_height; - if (texture[CameraServer::FEED_Y_IMAGE].is_null()) { - texture[CameraServer::FEED_Y_IMAGE] = RenderingServer::get_singleton()->texture_2d_create(p_y_img); - } else { + { RID new_texture = RenderingServer::get_singleton()->texture_2d_create(p_y_img); RenderingServer::get_singleton()->texture_replace(texture[CameraServer::FEED_Y_IMAGE], new_texture); } - - if (texture[CameraServer::FEED_CBCR_IMAGE].is_null()) { - texture[CameraServer::FEED_CBCR_IMAGE] = RenderingServer::get_singleton()->texture_2d_create(p_cbcr_img); - } else { + { RID new_texture = RenderingServer::get_singleton()->texture_2d_create(p_cbcr_img); RenderingServer::get_singleton()->texture_replace(texture[CameraServer::FEED_CBCR_IMAGE], new_texture); }