summaryrefslogtreecommitdiffstats
path: root/scene/main/viewport.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'scene/main/viewport.cpp')
-rw-r--r--scene/main/viewport.cpp113
1 files changed, 89 insertions, 24 deletions
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index c8d2d71c2a..26128a08ab 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -54,7 +54,6 @@
#include "scene/resources/mesh.h"
#include "scene/resources/text_line.h"
#include "scene/resources/world_2d.h"
-#include "scene/scene_string_names.h"
#include "servers/audio_server.h"
#include "servers/rendering/rendering_server_globals.h"
@@ -81,7 +80,7 @@ void ViewportTexture::setup_local_to_scene() {
if (loc_scene->is_ready()) {
_setup_local_to_scene(loc_scene);
} else {
- loc_scene->connect(SNAME("ready"), callable_mp(this, &ViewportTexture::_setup_local_to_scene).bind(loc_scene), CONNECT_ONE_SHOT);
+ loc_scene->connect(SceneStringName(ready), callable_mp(this, &ViewportTexture::_setup_local_to_scene).bind(loc_scene), CONNECT_ONE_SHOT);
vp_pending = true;
}
}
@@ -688,6 +687,18 @@ void Viewport::_process_picking() {
physics_picking_events.clear();
return;
}
+#ifndef _3D_DISABLED
+ if (use_xr) {
+ if (XRServer::get_singleton() != nullptr) {
+ Ref<XRInterface> xr_interface = XRServer::get_singleton()->get_primary_interface();
+ if (xr_interface.is_valid() && xr_interface->is_initialized() && xr_interface->get_view_count() > 1) {
+ WARN_PRINT_ONCE("Object picking can't be used when stereo rendering, this will be turned off!");
+ physics_object_picking = false; // don't try again.
+ return;
+ }
+ }
+ }
+#endif
_drop_physics_mouseover(true);
@@ -856,9 +867,10 @@ void Viewport::_process_picking() {
if (send_event) {
co->_input_event_call(this, ev, res[i].shape);
- if (physics_object_picking_first_only) {
- break;
- }
+ }
+
+ if (physics_object_picking_first_only) {
+ break;
}
}
}
@@ -970,7 +982,7 @@ void Viewport::_set_size(const Size2i &p_size, const Size2i &p_size_2d_override,
stretch_transform_new.scale(scale);
}
- Size2i new_size = p_size.max(Size2i(2, 2));
+ Size2i new_size = p_size.maxi(2);
if (size == new_size && size_allocated == p_allocated && stretch_transform == stretch_transform_new && p_size_2d_override == size_2d_override) {
return;
}
@@ -1452,7 +1464,7 @@ void Viewport::_gui_show_tooltip() {
gui.tooltip_label->set_theme_type_variation(SNAME("TooltipLabel"));
gui.tooltip_label->set_text(gui.tooltip_text);
base_tooltip = gui.tooltip_label;
- panel->connect("mouse_entered", callable_mp(this, &Viewport::_gui_cancel_tooltip));
+ panel->connect(SceneStringName(mouse_entered), callable_mp(this, &Viewport::_gui_cancel_tooltip));
}
base_tooltip->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
@@ -1461,6 +1473,8 @@ void Viewport::_gui_show_tooltip() {
panel->set_flag(Window::FLAG_NO_FOCUS, true);
panel->set_flag(Window::FLAG_POPUP, false);
panel->set_flag(Window::FLAG_MOUSE_PASSTHROUGH, true);
+ // A non-embedded tooltip window will only be transparent if per_pixel_transparency is allowed in the main Viewport.
+ panel->set_flag(Window::FLAG_TRANSPARENT, true);
panel->set_wrap_controls(true);
panel->add_child(base_tooltip);
panel->gui_parent = this;
@@ -1469,17 +1483,25 @@ void Viewport::_gui_show_tooltip() {
tooltip_owner->add_child(gui.tooltip_popup);
+ Window *window = Object::cast_to<Window>(gui.tooltip_popup->get_embedder());
+ if (!window) { // Not embedded.
+ window = gui.tooltip_popup->get_parent_visible_window();
+ }
+ float win_scale = window->content_scale_factor;
Point2 tooltip_offset = GLOBAL_GET("display/mouse_cursor/tooltip_position_offset");
+ if (!gui.tooltip_popup->is_embedded()) {
+ tooltip_offset *= win_scale;
+ }
Rect2 r(gui.tooltip_pos + tooltip_offset, gui.tooltip_popup->get_contents_minimum_size());
- r.size = r.size.min(panel->get_max_size());
-
- Window *window = gui.tooltip_popup->get_parent_visible_window();
Rect2i vr;
if (gui.tooltip_popup->is_embedded()) {
vr = gui.tooltip_popup->get_embedder()->get_visible_rect();
} else {
+ panel->content_scale_factor = win_scale;
+ r.size *= win_scale;
vr = window->get_usable_parent_rect();
}
+ r.size = r.size.min(panel->get_max_size());
if (r.size.x + r.position.x > vr.size.x + vr.position.x) {
// Place it in the opposite direction. If it fails, just hug the border.
@@ -1705,12 +1727,12 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
Point2 mpos = mb->get_position();
if (mb->is_pressed()) {
- if (!gui.mouse_focus_mask.is_empty()) {
- // Do not steal mouse focus and stuff while a focus mask exists.
- gui.mouse_focus_mask.set_flag(mouse_button_to_mask(mb->get_button_index()));
+ MouseButtonMask button_mask = mouse_button_to_mask(mb->get_button_index());
+ if (!gui.mouse_focus_mask.is_empty() && !gui.mouse_focus_mask.has_flag(button_mask)) {
+ // Do not steal mouse focus and stuff while a focus mask without the current mouse button exists.
+ gui.mouse_focus_mask.set_flag(button_mask);
} else {
gui.mouse_focus = gui_find_control(mpos);
- gui.last_mouse_focus = gui.mouse_focus;
if (!gui.mouse_focus) {
return;
@@ -2295,6 +2317,7 @@ void Viewport::_gui_force_drag(Control *p_base, const Variant &p_data, Control *
gui.dragging = true;
gui.drag_data = p_data;
gui.mouse_focus = nullptr;
+ gui.mouse_focus_mask.clear();
if (p_control) {
_gui_set_drag_preview(p_base, p_control);
@@ -2350,7 +2373,7 @@ void Viewport::_gui_hide_control(Control *p_control) {
if (gui.key_focus == p_control) {
gui_release_focus();
}
- if (gui.mouse_over == p_control || gui.mouse_over_hierarchy.find(p_control) >= 0) {
+ if (gui.mouse_over == p_control || gui.mouse_over_hierarchy.has(p_control)) {
_drop_mouse_over(p_control->get_parent_control());
}
if (gui.drag_mouse_over == p_control) {
@@ -2367,13 +2390,10 @@ void Viewport::_gui_remove_control(Control *p_control) {
gui.forced_mouse_focus = false;
gui.mouse_focus_mask.clear();
}
- if (gui.last_mouse_focus == p_control) {
- gui.last_mouse_focus = nullptr;
- }
if (gui.key_focus == p_control) {
gui.key_focus = nullptr;
}
- if (gui.mouse_over == p_control || gui.mouse_over_hierarchy.find(p_control) >= 0) {
+ if (gui.mouse_over == p_control || gui.mouse_over_hierarchy.has(p_control)) {
_drop_mouse_over(p_control->get_parent_control());
}
if (gui.drag_mouse_over == p_control) {
@@ -2747,8 +2767,7 @@ bool Viewport::_sub_windows_forward_input(const Ref<InputEvent> &p_event) {
Size2i min_size = gui.currently_dragged_subwindow->get_min_size();
Size2i min_size_clamped = gui.currently_dragged_subwindow->get_clamped_minimum_size();
- min_size_clamped.x = MAX(min_size_clamped.x, 1);
- min_size_clamped.y = MAX(min_size_clamped.y, 1);
+ min_size_clamped = min_size_clamped.maxi(1);
Rect2i r = gui.subwindow_resize_from_rect;
@@ -2809,8 +2828,7 @@ bool Viewport::_sub_windows_forward_input(const Ref<InputEvent> &p_event) {
Size2i max_size = gui.currently_dragged_subwindow->get_max_size();
if ((max_size.x > 0 || max_size.y > 0) && (max_size.x >= min_size.x && max_size.y >= min_size.y)) {
- max_size.x = MAX(max_size.x, 1);
- max_size.y = MAX(max_size.y, 1);
+ max_size = max_size.maxi(1);
if (r.size.x > max_size.x) {
r.size.x = max_size.x;
@@ -3569,6 +3587,13 @@ bool Viewport::gui_is_drag_successful() const {
return gui.drag_successful;
}
+void Viewport::gui_cancel_drag() {
+ ERR_MAIN_THREAD_GUARD;
+ if (gui_is_dragging()) {
+ _perform_drop();
+ }
+}
+
void Viewport::set_input_as_handled() {
ERR_MAIN_THREAD_GUARD;
if (!handle_input_locally) {
@@ -3709,6 +3734,28 @@ Viewport::VRSMode Viewport::get_vrs_mode() const {
return vrs_mode;
}
+void Viewport::set_vrs_update_mode(VRSUpdateMode p_vrs_update_mode) {
+ ERR_MAIN_THREAD_GUARD;
+
+ vrs_update_mode = p_vrs_update_mode;
+ switch (p_vrs_update_mode) {
+ case VRS_UPDATE_ONCE: {
+ RS::get_singleton()->viewport_set_vrs_update_mode(viewport, RS::VIEWPORT_VRS_UPDATE_ONCE);
+ } break;
+ case VRS_UPDATE_ALWAYS: {
+ RS::get_singleton()->viewport_set_vrs_update_mode(viewport, RS::VIEWPORT_VRS_UPDATE_ALWAYS);
+ } break;
+ default: {
+ RS::get_singleton()->viewport_set_vrs_update_mode(viewport, RS::VIEWPORT_VRS_UPDATE_DISABLED);
+ } break;
+ }
+}
+
+Viewport::VRSUpdateMode Viewport::get_vrs_update_mode() const {
+ ERR_READ_THREAD_GUARD_V(VRS_UPDATE_DISABLED);
+ return vrs_update_mode;
+}
+
void Viewport::set_vrs_texture(Ref<Texture2D> p_texture) {
ERR_MAIN_THREAD_GUARD;
vrs_texture = p_texture;
@@ -4488,6 +4535,10 @@ void Viewport::set_use_xr(bool p_use_xr) {
} else {
RS::get_singleton()->viewport_set_size(viewport, 0, 0);
}
+
+ // Reset render target override textures.
+ RID rt = RS::get_singleton()->viewport_get_render_target(viewport);
+ RSG::texture_storage->render_target_set_override(rt, RID(), RID(), RID());
}
}
}
@@ -4745,6 +4796,9 @@ void Viewport::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_vrs_mode", "mode"), &Viewport::set_vrs_mode);
ClassDB::bind_method(D_METHOD("get_vrs_mode"), &Viewport::get_vrs_mode);
+ ClassDB::bind_method(D_METHOD("set_vrs_update_mode", "mode"), &Viewport::set_vrs_update_mode);
+ ClassDB::bind_method(D_METHOD("get_vrs_update_mode"), &Viewport::get_vrs_update_mode);
+
ClassDB::bind_method(D_METHOD("set_vrs_texture", "texture"), &Viewport::set_vrs_texture);
ClassDB::bind_method(D_METHOD("get_vrs_texture"), &Viewport::get_vrs_texture);
@@ -4777,6 +4831,7 @@ void Viewport::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fsr_sharpness", PROPERTY_HINT_RANGE, "0,2,0.1"), "set_fsr_sharpness", "get_fsr_sharpness");
ADD_GROUP("Variable Rate Shading", "vrs_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "vrs_mode", PROPERTY_HINT_ENUM, "Disabled,Texture,Depth buffer,XR"), "set_vrs_mode", "get_vrs_mode");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "vrs_update_mode", PROPERTY_HINT_ENUM, "Disabled,Once,Always"), "set_vrs_update_mode", "get_vrs_update_mode");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "vrs_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_vrs_texture", "get_vrs_texture");
#endif
ADD_GROUP("Canvas Items", "canvas_item_");
@@ -4843,6 +4898,7 @@ void Viewport::_bind_methods() {
BIND_ENUM_CONSTANT(RENDER_INFO_TYPE_VISIBLE);
BIND_ENUM_CONSTANT(RENDER_INFO_TYPE_SHADOW);
+ BIND_ENUM_CONSTANT(RENDER_INFO_TYPE_CANVAS);
BIND_ENUM_CONSTANT(RENDER_INFO_TYPE_MAX);
BIND_ENUM_CONSTANT(DEBUG_DRAW_DISABLED);
@@ -4899,12 +4955,21 @@ void Viewport::_bind_methods() {
BIND_ENUM_CONSTANT(VRS_TEXTURE);
BIND_ENUM_CONSTANT(VRS_XR);
BIND_ENUM_CONSTANT(VRS_MAX);
+
+ BIND_ENUM_CONSTANT(VRS_UPDATE_DISABLED);
+ BIND_ENUM_CONSTANT(VRS_UPDATE_ONCE);
+ BIND_ENUM_CONSTANT(VRS_UPDATE_ALWAYS);
+ BIND_ENUM_CONSTANT(VRS_UPDATE_MAX);
}
void Viewport::_validate_property(PropertyInfo &p_property) const {
if (vrs_mode != VRS_TEXTURE && (p_property.name == "vrs_texture")) {
p_property.usage = PROPERTY_USAGE_NO_EDITOR;
}
+
+ if (vrs_mode == VRS_DISABLED && (p_property.name == "vrs_update_mode")) {
+ p_property.usage = PROPERTY_USAGE_NO_EDITOR;
+ }
}
Viewport::Viewport() {
@@ -4940,7 +5005,7 @@ Viewport::Viewport() {
unhandled_key_input_group = "_vp_unhandled_key_input" + id;
// Window tooltip.
- gui.tooltip_delay = GLOBAL_DEF(PropertyInfo(Variant::FLOAT, "gui/timers/tooltip_delay_sec", PROPERTY_HINT_RANGE, "0,5,0.01,or_greater"), 0.5);
+ gui.tooltip_delay = GLOBAL_GET("gui/timers/tooltip_delay_sec");
#ifndef _3D_DISABLED
set_scaling_3d_mode((Viewport::Scaling3DMode)(int)GLOBAL_GET("rendering/scaling_3d/mode"));