Path: blob/master/scene/resources/camera_texture.cpp
10278 views
/**************************************************************************/1/* camera_texture.cpp */2/**************************************************************************/3/* This file is part of: */4/* GODOT ENGINE */5/* https://godotengine.org */6/**************************************************************************/7/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */8/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */9/* */10/* Permission is hereby granted, free of charge, to any person obtaining */11/* a copy of this software and associated documentation files (the */12/* "Software"), to deal in the Software without restriction, including */13/* without limitation the rights to use, copy, modify, merge, publish, */14/* distribute, sublicense, and/or sell copies of the Software, and to */15/* permit persons to whom the Software is furnished to do so, subject to */16/* the following conditions: */17/* */18/* The above copyright notice and this permission notice shall be */19/* included in all copies or substantial portions of the Software. */20/* */21/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */22/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */23/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */24/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */25/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */26/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */27/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */28/**************************************************************************/2930#include "camera_texture.h"3132#include "servers/camera/camera_feed.h"3334void CameraTexture::_bind_methods() {35ClassDB::bind_method(D_METHOD("set_camera_feed_id", "feed_id"), &CameraTexture::set_camera_feed_id);36ClassDB::bind_method(D_METHOD("get_camera_feed_id"), &CameraTexture::get_camera_feed_id);3738ClassDB::bind_method(D_METHOD("set_which_feed", "which_feed"), &CameraTexture::set_which_feed);39ClassDB::bind_method(D_METHOD("get_which_feed"), &CameraTexture::get_which_feed);4041ClassDB::bind_method(D_METHOD("set_camera_active", "active"), &CameraTexture::set_camera_active);42ClassDB::bind_method(D_METHOD("get_camera_active"), &CameraTexture::get_camera_active);4344ADD_PROPERTY(PropertyInfo(Variant::INT, "camera_feed_id"), "set_camera_feed_id", "get_camera_feed_id");45ADD_PROPERTY(PropertyInfo(Variant::INT, "which_feed"), "set_which_feed", "get_which_feed");46ADD_PROPERTY(PropertyInfo(Variant::BOOL, "camera_is_active"), "set_camera_active", "get_camera_active");47ADD_PROPERTY_DEFAULT("camera_is_active", false);48}4950void CameraTexture::_on_format_changed() {51// FIXME: `emit_changed` is more appropriate, but causes errors for some reason.52callable_mp((Resource *)this, &Resource::emit_changed).call_deferred();53}5455int CameraTexture::get_width() const {56Ref<CameraFeed> feed = CameraServer::get_singleton()->get_feed_by_id(camera_feed_id);57if (feed.is_valid()) {58return feed->get_base_width();59} else {60return 0;61}62}6364int CameraTexture::get_height() const {65Ref<CameraFeed> feed = CameraServer::get_singleton()->get_feed_by_id(camera_feed_id);66if (feed.is_valid()) {67return feed->get_base_height();68} else {69return 0;70}71}7273bool CameraTexture::has_alpha() const {74return false;75}7677RID CameraTexture::get_rid() const {78Ref<CameraFeed> feed = CameraServer::get_singleton()->get_feed_by_id(camera_feed_id);79if (feed.is_valid()) {80return feed->get_texture(which_feed);81} else {82if (_texture.is_null()) {83_texture = RenderingServer::get_singleton()->texture_2d_placeholder_create();84}85return _texture;86}87}8889Ref<Image> CameraTexture::get_image() const {90return RenderingServer::get_singleton()->texture_2d_get(get_rid());91}9293void CameraTexture::set_camera_feed_id(int p_new_id) {94Ref<CameraFeed> feed = CameraServer::get_singleton()->get_feed_by_id(camera_feed_id);95if (feed.is_valid()) {96if (feed->is_connected("format_changed", callable_mp(this, &CameraTexture::_on_format_changed))) {97feed->disconnect("format_changed", callable_mp(this, &CameraTexture::_on_format_changed));98}99}100101camera_feed_id = p_new_id;102103feed = CameraServer::get_singleton()->get_feed_by_id(camera_feed_id);104if (feed.is_valid()) {105feed->connect("format_changed", callable_mp(this, &CameraTexture::_on_format_changed));106}107108notify_property_list_changed();109callable_mp((Resource *)this, &Resource::emit_changed).call_deferred();110}111112int CameraTexture::get_camera_feed_id() const {113return camera_feed_id;114}115116void CameraTexture::set_which_feed(CameraServer::FeedImage p_which) {117which_feed = p_which;118notify_property_list_changed();119callable_mp((Resource *)this, &Resource::emit_changed).call_deferred();120}121122CameraServer::FeedImage CameraTexture::get_which_feed() const {123return which_feed;124}125126void CameraTexture::set_camera_active(bool p_active) {127Ref<CameraFeed> feed = CameraServer::get_singleton()->get_feed_by_id(camera_feed_id);128if (feed.is_valid()) {129feed->set_active(p_active);130notify_property_list_changed();131callable_mp((Resource *)this, &Resource::emit_changed).call_deferred();132}133}134135bool CameraTexture::get_camera_active() const {136Ref<CameraFeed> feed = CameraServer::get_singleton()->get_feed_by_id(camera_feed_id);137if (feed.is_valid()) {138return feed->is_active();139} else {140return false;141}142}143144CameraTexture::CameraTexture() {145// Note: When any CameraTexture is created, we need to automatically activate monitoring146// of camera feeds. This may incur a small lag spike, so it may be preferable to147// enable it manually before creating the camera texture.148CameraServer::get_singleton()->set_monitoring_feeds(true);149}150151CameraTexture::~CameraTexture() {152if (_texture.is_valid()) {153ERR_FAIL_NULL(RenderingServer::get_singleton());154RenderingServer::get_singleton()->free(_texture);155}156}157158159