diff options
author | Juan Linietsky <juan@godotengine.org> | 2020-03-03 22:51:12 -0300 |
---|---|---|
committer | Juan Linietsky <reduzio@gmail.com> | 2020-03-26 15:49:38 +0100 |
commit | 9e08742de81b062c30b7984900a55d5150a4bd17 (patch) | |
tree | 6570bbc8bdcc17e0538d0361156f041b24c2614d | |
parent | f8a79a97c7d12da43b111a756f09ee7ad5ea28e9 (diff) |
Added a Window node, and made it the scene root.
Still a lot of work to do.
84 files changed, 1081 insertions, 621 deletions
diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp index 76541c3cd5..8ebf5b0f04 100644 --- a/drivers/vulkan/rendering_device_vulkan.cpp +++ b/drivers/vulkan/rendering_device_vulkan.cpp @@ -5150,12 +5150,12 @@ bool RenderingDeviceVulkan::compute_pipeline_is_valid(RID p_pipeline) { /**** SCREEN ****/ /****************/ -int RenderingDeviceVulkan::screen_get_width(int p_screen) const { +int RenderingDeviceVulkan::screen_get_width(DisplayServer::WindowID p_screen) const { _THREAD_SAFE_METHOD_ return context->window_get_width(p_screen); } -int RenderingDeviceVulkan::screen_get_height(int p_screen) const { +int RenderingDeviceVulkan::screen_get_height(DisplayServer::WindowID p_screen) const { _THREAD_SAFE_METHOD_ return context->window_get_height(p_screen); @@ -5189,7 +5189,7 @@ RenderingDevice::FramebufferFormatID RenderingDeviceVulkan::screen_get_framebuff /**** DRAW LIST ****/ /*******************/ -RenderingDevice::DrawListID RenderingDeviceVulkan::draw_list_begin_for_screen(int p_screen, const Color &p_clear_color) { +RenderingDevice::DrawListID RenderingDeviceVulkan::draw_list_begin_for_screen(DisplayServer::WindowID p_screen, const Color &p_clear_color) { _THREAD_SAFE_METHOD_ diff --git a/drivers/vulkan/rendering_device_vulkan.h b/drivers/vulkan/rendering_device_vulkan.h index 4a224f0ceb..7f1697b2b5 100644 --- a/drivers/vulkan/rendering_device_vulkan.h +++ b/drivers/vulkan/rendering_device_vulkan.h @@ -1052,15 +1052,15 @@ public: /**** SCREEN ****/ /****************/ - virtual int screen_get_width(int p_screen = 0) const; - virtual int screen_get_height(int p_screen = 0) const; + virtual int screen_get_width(DisplayServer::WindowID p_screen = 0) const; + virtual int screen_get_height(DisplayServer::WindowID p_screen = 0) const; virtual FramebufferFormatID screen_get_framebuffer_format() const; /********************/ /**** DRAW LISTS ****/ /********************/ - virtual DrawListID draw_list_begin_for_screen(int p_screen = 0, const Color &p_clear_color = Color()); + virtual DrawListID draw_list_begin_for_screen(DisplayServer::WindowID p_screen = 0, const Color &p_clear_color = Color()); virtual DrawListID draw_list_begin(RID p_framebuffer, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector<Color> &p_clear_color_values = Vector<Color>(), float p_clear_depth = 1.0, uint32_t p_clear_stencil = 0, const Rect2 &p_region = Rect2()); virtual Error draw_list_begin_split(RID p_framebuffer, uint32_t p_splits, DrawListID *r_split_ids, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector<Color> &p_clear_color_values = Vector<Color>(), float p_clear_depth = 1.0, uint32_t p_clear_stencil = 0, const Rect2 &p_region = Rect2()); diff --git a/drivers/vulkan/vulkan_context.cpp b/drivers/vulkan/vulkan_context.cpp index c8ff342713..494c64ff55 100644 --- a/drivers/vulkan/vulkan_context.cpp +++ b/drivers/vulkan/vulkan_context.cpp @@ -696,7 +696,9 @@ Error VulkanContext::_create_semaphores() { return OK; } -int VulkanContext::_window_create(VkSurfaceKHR p_surface, int p_width, int p_height) { +Error VulkanContext::_window_create(DisplayServer::WindowID p_window_id, VkSurfaceKHR p_surface, int p_width, int p_height) { + + ERR_FAIL_COND_V(windows.has(p_window_id), ERR_INVALID_PARAMETER); if (!queues_initialized) { // We use a single GPU, but we need a surface to initialize the @@ -710,39 +712,37 @@ int VulkanContext::_window_create(VkSurfaceKHR p_surface, int p_width, int p_hei window.width = p_width; window.height = p_height; Error err = _update_swap_chain(&window); - ERR_FAIL_COND_V(err != OK, -1); + ERR_FAIL_COND_V(err != OK, ERR_CANT_CREATE); - int id = last_window_id; - windows[id] = window; - last_window_id++; - return id; + windows[p_window_id] = window; + return OK; } -void VulkanContext::window_resize(int p_window, int p_width, int p_height) { +void VulkanContext::window_resize(DisplayServer::WindowID p_window, int p_width, int p_height) { ERR_FAIL_COND(!windows.has(p_window)); windows[p_window].width = p_width; windows[p_window].height = p_height; _update_swap_chain(&windows[p_window]); } -int VulkanContext::window_get_width(int p_window) { +int VulkanContext::window_get_width(DisplayServer::WindowID p_window) { ERR_FAIL_COND_V(!windows.has(p_window), -1); return windows[p_window].width; } -int VulkanContext::window_get_height(int p_window) { +int VulkanContext::window_get_height(DisplayServer::WindowID p_window) { ERR_FAIL_COND_V(!windows.has(p_window), -1); return windows[p_window].height; } -VkRenderPass VulkanContext::window_get_render_pass(int p_window) { +VkRenderPass VulkanContext::window_get_render_pass(DisplayServer::WindowID p_window) { ERR_FAIL_COND_V(!windows.has(p_window), VK_NULL_HANDLE); Window *w = &windows[p_window]; //vulkan use of currentbuffer return w->render_pass; } -VkFramebuffer VulkanContext::window_get_framebuffer(int p_window) { +VkFramebuffer VulkanContext::window_get_framebuffer(DisplayServer::WindowID p_window) { ERR_FAIL_COND_V(!windows.has(p_window), VK_NULL_HANDLE); ERR_FAIL_COND_V(!buffers_prepared, VK_NULL_HANDLE); Window *w = &windows[p_window]; @@ -750,7 +750,7 @@ VkFramebuffer VulkanContext::window_get_framebuffer(int p_window) { return w->swapchain_image_resources[w->current_buffer].framebuffer; } -void VulkanContext::window_destroy(int p_window_id) { +void VulkanContext::window_destroy(DisplayServer::WindowID p_window_id) { ERR_FAIL_COND(!windows.has(p_window_id)); _clean_up_swap_chain(&windows[p_window_id]); vkDestroySurfaceKHR(inst, windows[p_window_id].surface, NULL); @@ -1497,7 +1497,6 @@ VulkanContext::VulkanContext() { buffers_prepared = false; swapchainImageCount = 0; - last_window_id = 0; } VulkanContext::~VulkanContext() { diff --git a/drivers/vulkan/vulkan_context.h b/drivers/vulkan/vulkan_context.h index 458cb6d793..2f10fbfdef 100644 --- a/drivers/vulkan/vulkan_context.h +++ b/drivers/vulkan/vulkan_context.h @@ -34,6 +34,7 @@ #include "core/error_list.h" #include "core/map.h" #include "core/ustring.h" +#include "servers/display_server.h" #include <vulkan/vulkan.h> class VulkanContext { @@ -106,8 +107,7 @@ class VulkanContext { } }; - Map<int, Window> windows; - int last_window_id; + Map<DisplayServer::WindowID, Window> windows; uint32_t swapchainImageCount; //commands @@ -173,7 +173,7 @@ protected: virtual const char *_get_platform_surface_extension() const = 0; // virtual VkResult _create_surface(VkSurfaceKHR *surface, VkInstance p_instance) = 0; - virtual int _window_create(VkSurfaceKHR p_surface, int p_width, int p_height); + virtual Error _window_create(DisplayServer::WindowID p_window_id, VkSurfaceKHR p_surface, int p_width, int p_height); VkInstance _get_instance() { return inst; @@ -187,12 +187,12 @@ public: int get_swapchain_image_count() const; uint32_t get_graphics_queue() const; - void window_resize(int p_window_id, int p_width, int p_height); - int window_get_width(int p_window = 0); - int window_get_height(int p_window = 0); - void window_destroy(int p_window_id); - VkFramebuffer window_get_framebuffer(int p_window = 0); - VkRenderPass window_get_render_pass(int p_window = 0); + void window_resize(DisplayServer::WindowID p_window_id, int p_width, int p_height); + int window_get_width(DisplayServer::WindowID p_window = 0); + int window_get_height(DisplayServer::WindowID p_window = 0); + void window_destroy(DisplayServer::WindowID p_window_id); + VkFramebuffer window_get_framebuffer(DisplayServer::WindowID p_window = 0); + VkRenderPass window_get_render_pass(DisplayServer::WindowID p_window = 0); VkFormat get_screen_format() const; VkPhysicalDeviceLimits get_device_limits() const; diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp index d3205ff147..7a6f43497e 100644 --- a/editor/animation_track_editor.cpp +++ b/editor/animation_track_editor.cpp @@ -37,7 +37,7 @@ #include "editor/plugins/animation_player_editor_plugin.h" #include "editor_node.h" #include "editor_scale.h" -#include "scene/main/viewport.h" +#include "scene/main/window.h" #include "servers/audio/audio_stream.h" class AnimationTrackKeyEdit : public Object { diff --git a/editor/editor_autoload_settings.cpp b/editor/editor_autoload_settings.cpp index 83a1e2fca2..a02346c872 100644 --- a/editor/editor_autoload_settings.cpp +++ b/editor/editor_autoload_settings.cpp @@ -35,7 +35,7 @@ #include "editor_node.h" #include "editor_scale.h" #include "project_settings_editor.h" -#include "scene/main/viewport.h" +#include "scene/main/window.h" #include "scene/resources/packed_scene.h" #define PREVIEW_LIST_MAX_SIZE 10 diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 48cd479fcf..5f00bc59ac 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -169,6 +169,7 @@ #include "editor/register_exporters.h" #include "editor/run_settings_dialog.h" #include "editor/settings_config_dialog.h" +#include "scene/main/window.h" #include "servers/display_server.h" #include <stdio.h> #include <stdlib.h> @@ -346,7 +347,7 @@ void EditorNode::_notification(int p_what) { editor_selection->update(); - scene_root->set_size_override(true, Size2(ProjectSettings::get_singleton()->get("display/window/size/width"), ProjectSettings::get_singleton()->get("display/window/size/height"))); + //scene_root->set_size_override(true, Size2(ProjectSettings::get_singleton()->get("display/window/size/width"), ProjectSettings::get_singleton()->get("display/window/size/height"))); { //TODO should only happen on settings changed int current_filter = GLOBAL_GET("rendering/canvas_textures/default_texture_filter"); @@ -2668,10 +2669,10 @@ void EditorNode::_screenshot(bool p_use_utc) { void EditorNode::_save_screenshot(NodePath p_path) { - Viewport *viewport = EditorInterface::get_singleton()->get_editor_viewport()->get_viewport(); - viewport->set_clear_mode(Viewport::CLEAR_MODE_ONLY_NEXT_FRAME); + SubViewport *viewport = Object::cast_to<SubViewport>(EditorInterface::get_singleton()->get_editor_viewport()->get_viewport()); + viewport->set_clear_mode(SubViewport::CLEAR_MODE_ONLY_NEXT_FRAME); Ref<Image> img = viewport->get_texture()->get_data(); - viewport->set_clear_mode(Viewport::CLEAR_MODE_ALWAYS); + viewport->set_clear_mode(SubViewport::CLEAR_MODE_ALWAYS); Error error = img->save_png(p_path); ERR_FAIL_COND_MSG(error != OK, "Cannot save screenshot to file '" + p_path + "'."); } @@ -5941,7 +5942,7 @@ EditorNode::EditorNode() { srt->add_child(scene_root_parent); scene_root_parent->set_v_size_flags(Control::SIZE_EXPAND_FILL); - scene_root = memnew(Viewport); + scene_root = memnew(SubViewport); //scene_root->set_usage(Viewport::USAGE_2D); canvas BG mode prevents usage of this as 2D VisualServer::get_singleton()->viewport_set_hide_scenario(scene_root->get_viewport_rid(), true); diff --git a/editor/editor_node.h b/editor/editor_node.h index bd285db224..c670d4954b 100644 --- a/editor/editor_node.h +++ b/editor/editor_node.h @@ -84,6 +84,8 @@ class Tabs; class TextureProgress; class ToolButton; class VSplitContainer; +class Window; +class SubViewport; class EditorNode : public Node { @@ -206,7 +208,7 @@ private: TOOL_MENU_BASE = 1000 }; - Viewport *scene_root; //root of the scene being edited + SubViewport *scene_root; //root of the scene being edited PanelContainer *scene_root_parent; Control *theme_base; @@ -724,7 +726,7 @@ public: Node *get_edited_scene() { return editor_data.get_edited_scene_root(); } - Viewport *get_scene_root() { return scene_root; } //root of the scene being edited + SubViewport *get_scene_root() { return scene_root; } //root of the scene being edited void fix_dependencies(const String &p_for_file); void clear_scene() { _cleanup_scene(); } diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp index 9a474ed4af..cc89f1c16a 100644 --- a/editor/editor_properties.cpp +++ b/editor/editor_properties.cpp @@ -35,7 +35,7 @@ #include "editor_node.h" #include "editor_properties_array_dict.h" #include "editor_scale.h" -#include "scene/main/viewport.h" +#include "scene/main/window.h" ///////////////////// NULL ///////////////////////// diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp index 18f0aba030..286ca7b184 100644 --- a/editor/editor_settings.cpp +++ b/editor/editor_settings.cpp @@ -49,7 +49,7 @@ #include "editor/editor_translations.gen.h" #include "scene/main/node.h" #include "scene/main/scene_tree.h" -#include "scene/main/viewport.h" +#include "scene/main/window.h" // PRIVATE METHODS diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index 171bb4105d..d52a7f25be 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -42,7 +42,7 @@ #include "editor_scale.h" #include "editor_settings.h" #include "import_dock.h" -#include "scene/main/viewport.h" +#include "scene/main/window.h" #include "scene/resources/packed_scene.h" #include "servers/display_server.h" diff --git a/editor/plugins/animation_blend_space_2d_editor.cpp b/editor/plugins/animation_blend_space_2d_editor.cpp index dc8f7f3724..156237a452 100644 --- a/editor/plugins/animation_blend_space_2d_editor.cpp +++ b/editor/plugins/animation_blend_space_2d_editor.cpp @@ -40,7 +40,7 @@ #include "scene/animation/animation_player.h" #include "scene/gui/menu_button.h" #include "scene/gui/panel.h" -#include "scene/main/viewport.h" +#include "scene/main/window.h" bool AnimationNodeBlendSpace2DEditor::can_edit(const Ref<AnimationNode> &p_node) { diff --git a/editor/plugins/animation_blend_tree_editor_plugin.cpp b/editor/plugins/animation_blend_tree_editor_plugin.cpp index 931bce65d7..ecc5982fea 100644 --- a/editor/plugins/animation_blend_tree_editor_plugin.cpp +++ b/editor/plugins/animation_blend_tree_editor_plugin.cpp @@ -40,7 +40,7 @@ #include "scene/gui/menu_button.h" #include "scene/gui/panel.h" #include "scene/gui/progress_bar.h" -#include "scene/main/viewport.h" +#include "scene/main/window.h" void AnimationNodeBlendTreeEditor::add_custom_type(const String &p_name, const Ref<Script> &p_script) { diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp index 10d13f0188..dee595c119 100644 --- a/editor/plugins/animation_player_editor_plugin.cpp +++ b/editor/plugins/animation_player_editor_plugin.cpp @@ -40,7 +40,7 @@ #include "editor/editor_settings.h" #include "editor/plugins/canvas_item_editor_plugin.h" // For onion skinning. #include "editor/plugins/spatial_editor_plugin.h" // For onion skinning. -#include "scene/main/viewport.h" +#include "scene/main/window.h" #include "servers/visual_server.h" void AnimationPlayerEditor::_node_removed(Node *p_node) { @@ -1420,7 +1420,7 @@ void AnimationPlayerEditor::_prepare_onion_layers_2() { // Tweak the root viewport to ensure it's rendered before our target. RID root_vp = get_tree()->get_root()->get_viewport_rid(); - Rect2 root_vp_screen_rect = get_tree()->get_root()->get_attach_to_screen_rect(); + Rect2 root_vp_screen_rect = Rect2(Vector2(), get_tree()->get_root()->get_size()); VS::get_singleton()->viewport_attach_to_screen(root_vp, Rect2()); VS::get_singleton()->viewport_set_update_mode(root_vp, VS::VIEWPORT_UPDATE_ALWAYS); diff --git a/editor/plugins/animation_state_machine_editor.cpp b/editor/plugins/animation_state_machine_editor.cpp index 1fe57665eb..3fd0cb94a2 100644 --- a/editor/plugins/animation_state_machine_editor.cpp +++ b/editor/plugins/animation_state_machine_editor.cpp @@ -40,7 +40,7 @@ #include "scene/animation/animation_player.h" #include "scene/gui/menu_button.h" #include "scene/gui/panel.h" -#include "scene/main/viewport.h" +#include "scene/main/window.h" bool AnimationNodeStateMachineEditor::can_edit(const Ref<AnimationNode> &p_node) { diff --git a/editor/plugins/animation_tree_editor_plugin.cpp b/editor/plugins/animation_tree_editor_plugin.cpp index cf99d2ef78..795bd3eb1b 100644 --- a/editor/plugins/animation_tree_editor_plugin.cpp +++ b/editor/plugins/animation_tree_editor_plugin.cpp @@ -44,7 +44,7 @@ #include "scene/animation/animation_player.h" #include "scene/gui/menu_button.h" #include "scene/gui/panel.h" -#include "scene/main/viewport.h" +#include "scene/main/window.h" #include "scene/scene_string_names.h" void AnimationTreeEditor::edit(AnimationTree *p_tree) { diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 13f4979ba2..90d3bf0641 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -50,7 +50,7 @@ #include "scene/gui/nine_patch_rect.h" #include "scene/gui/viewport_container.h" #include "scene/main/canvas_layer.h" -#include "scene/main/viewport.h" +#include "scene/main/window.h" #include "scene/resources/packed_scene.h" #define MIN_ZOOM 0.01 diff --git a/editor/plugins/material_editor_plugin.cpp b/editor/plugins/material_editor_plugin.cpp index d388296927..a13a594d95 100644 --- a/editor/plugins/material_editor_plugin.cpp +++ b/editor/plugins/material_editor_plugin.cpp @@ -114,7 +114,7 @@ MaterialEditor::MaterialEditor() { vc->set_stretch(true); add_child(vc); vc->set_anchors_and_margins_preset(PRESET_WIDE); - viewport = memnew(Viewport); + viewport = memnew(SubViewport); Ref<World> world; world.instance(); viewport->set_world(world); //use own world diff --git a/editor/plugins/material_editor_plugin.h b/editor/plugins/material_editor_plugin.h index 84e69425d0..895c3f80bd 100644 --- a/editor/plugins/material_editor_plugin.h +++ b/editor/plugins/material_editor_plugin.h @@ -48,7 +48,7 @@ class MaterialEditor : public Control { GDCLASS(MaterialEditor, Control); ViewportContainer *vc; - Viewport *viewport; + SubViewport *viewport; MeshInstance *sphere_instance; MeshInstance *box_instance; DirectionalLight *light1; diff --git a/editor/plugins/mesh_editor_plugin.cpp b/editor/plugins/mesh_editor_plugin.cpp index 5a17f0d4f1..c921ca46cd 100644 --- a/editor/plugins/mesh_editor_plugin.cpp +++ b/editor/plugins/mesh_editor_plugin.cpp @@ -115,7 +115,7 @@ void MeshEditor::_bind_methods() { MeshEditor::MeshEditor() { - viewport = memnew(Viewport); + viewport = memnew(SubViewport); Ref<World> world; world.instance(); viewport->set_world(world); //use own world diff --git a/editor/plugins/mesh_editor_plugin.h b/editor/plugins/mesh_editor_plugin.h index 87c4a1776b..6d39d49de1 100644 --- a/editor/plugins/mesh_editor_plugin.h +++ b/editor/plugins/mesh_editor_plugin.h @@ -46,7 +46,7 @@ class MeshEditor : public ViewportContainer { float rot_x; float rot_y; - Viewport *viewport; + SubViewport *viewport; MeshInstance *mesh_instance; Spatial *rotation; DirectionalLight *light1; diff --git a/editor/plugins/mesh_library_editor_plugin.cpp b/editor/plugins/mesh_library_editor_plugin.cpp index 4e63a498b8..f341d9ca86 100644 --- a/editor/plugins/mesh_library_editor_plugin.cpp +++ b/editor/plugins/mesh_library_editor_plugin.cpp @@ -36,7 +36,7 @@ #include "scene/3d/mesh_instance.h" #include "scene/3d/navigation_region.h" #include "scene/3d/physics_body.h" -#include "scene/main/viewport.h" +#include "scene/main/window.h" #include "scene/resources/packed_scene.h" #include "spatial_editor_plugin.h" diff --git a/editor/plugins/root_motion_editor_plugin.cpp b/editor/plugins/root_motion_editor_plugin.cpp index d932305c63..daea2eec6b 100644 --- a/editor/plugins/root_motion_editor_plugin.cpp +++ b/editor/plugins/root_motion_editor_plugin.cpp @@ -30,7 +30,7 @@ #include "root_motion_editor_plugin.h" #include "editor/editor_node.h" -#include "scene/main/viewport.h" +#include "scene/main/window.h" void EditorPropertyRootMotion::_confirmed() { diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index 06d1c664b5..f435856cdf 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -45,7 +45,7 @@ #include "editor/find_in_files.h" #include "editor/node_dock.h" #include "editor/plugins/shader_editor_plugin.h" -#include "scene/main/viewport.h" +#include "scene/main/window.h" #include "scene/scene_string_names.h" #include "script_text_editor.h" #include "servers/display_server.h" diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp index d514b50460..2af64b6ed6 100644 --- a/editor/plugins/spatial_editor_plugin.cpp +++ b/editor/plugins/spatial_editor_plugin.cpp @@ -3834,7 +3834,7 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed c->set_stretch(true); add_child(c); c->set_anchors_and_margins_preset(Control::PRESET_WIDE); - viewport = memnew(Viewport); + viewport = memnew(SubViewport); viewport->set_disable_input(true); c->add_child(viewport); diff --git a/editor/plugins/spatial_editor_plugin.h b/editor/plugins/spatial_editor_plugin.h index b67459b9d0..9dad66b647 100644 --- a/editor/plugins/spatial_editor_plugin.h +++ b/editor/plugins/spatial_editor_plugin.h @@ -262,7 +262,7 @@ private: PopupMenu *display_submenu; Control *surface; - Viewport *viewport; + SubViewport *viewport; Camera *camera; bool transforming; bool orthogonal; @@ -467,7 +467,7 @@ public: AABB *p_preview_bounds, AcceptDialog *p_accept); - Viewport *get_viewport_node() { return viewport; } + SubViewport *get_viewport_node() { return viewport; } Camera *get_camera() { return camera; } // return the default camera object. SpatialEditorViewport(SpatialEditor *p_spatial_editor, EditorNode *p_editor, int p_index); diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index 8070e2b4d5..3b7c4897b2 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -42,7 +42,7 @@ #include "scene/animation/animation_player.h" #include "scene/gui/menu_button.h" #include "scene/gui/panel.h" -#include "scene/main/viewport.h" +#include "scene/main/window.h" #include "scene/resources/visual_shader_nodes.h" #include "servers/display_server.h" #include "servers/visual/shader_types.h" diff --git a/editor/property_editor.cpp b/editor/property_editor.cpp index feef274d33..7ba43d1246 100644 --- a/editor/property_editor.cpp +++ b/editor/property_editor.cpp @@ -53,7 +53,7 @@ #include "editor/multi_node_edit.h" #include "editor/property_selector.h" #include "scene/gui/label.h" -#include "scene/main/viewport.h" +#include "scene/main/window.h" #include "scene/resources/font.h" #include "scene/resources/packed_scene.h" #include "scene/scene_string_names.h" diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index 4382b63747..3df4367b43 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -44,7 +44,7 @@ #include "editor/plugins/canvas_item_editor_plugin.h" #include "editor/plugins/script_editor_plugin.h" #include "editor/plugins/spatial_editor_plugin.h" -#include "scene/main/viewport.h" +#include "scene/main/window.h" #include "scene/resources/packed_scene.h" #include "servers/display_server.h" #include "servers/visual_server.h" diff --git a/editor/scene_tree_editor.cpp b/editor/scene_tree_editor.cpp index 782df12d4b..0f8e748dfb 100644 --- a/editor/scene_tree_editor.cpp +++ b/editor/scene_tree_editor.cpp @@ -37,7 +37,7 @@ #include "editor/plugins/animation_player_editor_plugin.h" #include "editor/plugins/canvas_item_editor_plugin.h" #include "scene/gui/label.h" -#include "scene/main/viewport.h" +#include "scene/main/window.h" #include "scene/resources/packed_scene.h" Node *SceneTreeEditor::get_scene_node() { diff --git a/main/main.cpp b/main/main.cpp index 53bb336b1f..d748aad9a7 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -58,7 +58,7 @@ #include "modules/register_module_types.h" #include "platform/register_platform_apis.h" #include "scene/main/scene_tree.h" -#include "scene/main/viewport.h" +#include "scene/main/window.h" #include "scene/register_scene_types.h" #include "scene/resources/packed_scene.h" #include "servers/arvr_server.h" @@ -1819,25 +1819,26 @@ bool Main::start() { String stretch_mode = GLOBAL_DEF("display/window/stretch/mode", "disabled"); String stretch_aspect = GLOBAL_DEF("display/window/stretch/aspect", "ignore"); Size2i stretch_size = Size2(GLOBAL_DEF("display/window/size/width", 0), GLOBAL_DEF("display/window/size/height", 0)); - real_t stretch_shrink = GLOBAL_DEF("display/window/stretch/shrink", 1.0); - SceneTree::StretchMode sml_sm = SceneTree::STRETCH_MODE_DISABLED; - if (stretch_mode == "2d") - sml_sm = SceneTree::STRETCH_MODE_2D; - else if (stretch_mode == "viewport") - sml_sm = SceneTree::STRETCH_MODE_VIEWPORT; + Window::ContentScaleMode cs_sm = Window::CONTENT_SCALE_MODE_DISABLED; + if (stretch_mode == "objects") + cs_sm = Window::CONTENT_SCALE_MODE_OBJECTS; + else if (stretch_mode == "pixels") + cs_sm = Window::CONTENT_SCALE_MODE_PIXELS; - SceneTree::StretchAspect sml_aspect = SceneTree::STRETCH_ASPECT_IGNORE; + Window::ContentScaleAspect cs_aspect = Window::CONTENT_SCALE_ASPECT_IGNORE; if (stretch_aspect == "keep") - sml_aspect = SceneTree::STRETCH_ASPECT_KEEP; + cs_aspect = Window::CONTENT_SCALE_ASPECT_KEEP; else if (stretch_aspect == "keep_width") - sml_aspect = SceneTree::STRETCH_ASPECT_KEEP_WIDTH; + cs_aspect = Window::CONTENT_SCALE_ASPECT_KEEP_WIDTH; else if (stretch_aspect == "keep_height") - sml_aspect = SceneTree::STRETCH_ASPECT_KEEP_HEIGHT; + cs_aspect = Window::CONTENT_SCALE_ASPECT_KEEP_HEIGHT; else if (stretch_aspect == "expand") - sml_aspect = SceneTree::STRETCH_ASPECT_EXPAND; + cs_aspect = Window::CONTENT_SCALE_ASPECT_EXPAND; - sml->set_screen_stretch(sml_sm, sml_aspect, stretch_size, stretch_shrink); + sml->get_root()->set_content_scale_mode(cs_sm); + sml->get_root()->set_content_scale_aspect(cs_aspect); + sml->get_root()->set_content_scale_size(stretch_size); sml->set_auto_accept_quit(GLOBAL_DEF("application/config/auto_accept_quit", true)); sml->set_quit_on_go_back(GLOBAL_DEF("application/config/quit_on_go_back", true)); @@ -1861,7 +1862,7 @@ bool Main::start() { sml->get_root()->set_snap_controls_to_pixels(snap_controls); bool font_oversampling = GLOBAL_DEF("rendering/quality/dynamic_fonts/use_oversampling", true); - sml->set_use_font_oversampling(font_oversampling); + sml->get_root()->set_use_font_oversampling(font_oversampling); int texture_filter = GLOBAL_DEF("rendering/canvas_textures/default_texture_filter", 1); int texture_repeat = GLOBAL_DEF("rendering/canvas_textures/default_texture_repeat", 0); diff --git a/main/tests/test_gui.cpp b/main/tests/test_gui.cpp index f0b00aeeae..645588529f 100644 --- a/main/tests/test_gui.cpp +++ b/main/tests/test_gui.cpp @@ -54,7 +54,7 @@ #include "scene/main/scene_tree.h" #include "scene/3d/camera.h" -#include "scene/main/viewport.h" +#include "scene/main/window.h" namespace TestGUI { diff --git a/modules/gridmap/grid_map_editor_plugin.cpp b/modules/gridmap/grid_map_editor_plugin.cpp index aa470105e0..bb27f946a2 100644 --- a/modules/gridmap/grid_map_editor_plugin.cpp +++ b/modules/gridmap/grid_map_editor_plugin.cpp @@ -37,6 +37,7 @@ #include "core/math/geometry.h" #include "core/os/keyboard.h" +#include "scene/main/window.h" void GridMapEditor::_node_removed(Node *p_node) { diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp index 14c37bd375..8600dcbbf5 100644 --- a/modules/visual_script/visual_script_editor.cpp +++ b/modules/visual_script/visual_script_editor.cpp @@ -38,7 +38,7 @@ #include "editor/editor_node.h" #include "editor/editor_resource_preview.h" #include "editor/editor_scale.h" -#include "scene/main/viewport.h" +#include "scene/main/window.h" #include "visual_script_expression.h" #include "visual_script_flow_control.h" #include "visual_script_func_nodes.h" diff --git a/modules/visual_script/visual_script_property_selector.cpp b/modules/visual_script/visual_script_property_selector.cpp index d799f19143..6e0d662be9 100644 --- a/modules/visual_script/visual_script_property_selector.cpp +++ b/modules/visual_script/visual_script_property_selector.cpp @@ -39,7 +39,7 @@ #include "modules/visual_script/visual_script_func_nodes.h" #include "modules/visual_script/visual_script_nodes.h" #include "scene/main/node.h" -#include "scene/main/viewport.h" +#include "scene/main/window.h" void VisualScriptPropertySelector::_text_changed(const String &p_newtext) { _update_search(); diff --git a/platform/linuxbsd/display_server_x11.cpp b/platform/linuxbsd/display_server_x11.cpp index ace07a3ac6..0b4a6b19d8 100644 --- a/platform/linuxbsd/display_server_x11.cpp +++ b/platform/linuxbsd/display_server_x11.cpp @@ -47,8 +47,7 @@ #include "servers/visual/rasterizer_rd/rasterizer_rd.h" #endif -#include "servers/visual/visual_server_raster.h" -#include "servers/visual/visual_server_wrap_mt.h" +#include "scene/resources/texture.h" #ifdef HAVE_MNTENT #include <mntent.h> @@ -89,6 +88,8 @@ #include <X11/XKBlib.h> +#include "core/project_settings.h" + // 2.2 is the first release with multitouch #define XINPUT_CLIENT_VERSION_MAJOR 2 #define XINPUT_CLIENT_VERSION_MINOR 2 @@ -641,7 +642,7 @@ void DisplayServerX11::delete_sub_window(WindowID p_id) { #ifdef VULKAN_ENABLED if (rendering_driver == "vulkan") { - context_vulkan->window_destroy(wd.vulkan_window); + context_vulkan->window_destroy(p_id); } #endif XUnmapWindow(x11_display, wd.x11_window); @@ -665,6 +666,13 @@ void DisplayServerX11::window_set_title(const String &p_title, WindowID p_window XChangeProperty(x11_display, wd.x11_window, _net_wm_name, utf8_string, 8, PropModeReplace, (unsigned char *)p_title.utf8().get_data(), p_title.utf8().length()); } +void DisplayServerX11::window_set_resize_callback(const Callable &p_callable, WindowID p_window) { + + ERR_FAIL_COND(!windows.has(p_window)); + WindowData &wd = windows[p_window]; + wd.resize_callback = p_callable; +} + int DisplayServerX11::window_get_current_screen(WindowID p_window) const { ERR_FAIL_COND_V(!windows.has(p_window), -1); const WindowData &wd = windows[p_window]; @@ -2020,9 +2028,17 @@ void DisplayServerX11::_window_changed(XEvent *event) { #if defined(VULKAN_ENABLED) if (rendering_driver == "vulkan") { - context_vulkan->window_resize(wd.vulkan_window, wd.size.width, wd.size.height); + context_vulkan->window_resize(window_id, wd.size.width, wd.size.height); } #endif + + if (!wd.resize_callback.is_null()) { + Variant size = wd.size; + Variant *sizep = &size; + Variant ret; + Callable::CallError ce; + wd.resize_callback.call((const Variant **)&sizep, 1, ret, ce); + } } void DisplayServerX11::process_events() { @@ -2764,8 +2780,8 @@ DisplayServerX11::WindowID DisplayServerX11::_create_window(WindowMode p_mode, c #if defined(VULKAN_ENABLED) if (context_vulkan) { - wd.vulkan_window = context_vulkan->window_create(wd.x11_window, x11_display, p_resolution.width, p_resolution.height); - ERR_FAIL_COND_V_MSG(wd.vulkan_window == -1, INVALID_WINDOW_ID, "Can't create a Vulkan window"); + Error err = context_vulkan->window_create(window_id_counter, wd.x11_window, x11_display, p_resolution.width, p_resolution.height); + ERR_FAIL_COND_V_MSG(err != OK, INVALID_WINDOW_ID, "Can't create a Vulkan window"); } #endif @@ -3295,7 +3311,7 @@ DisplayServerX11::~DisplayServerX11() { for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) { #ifdef VULKAN_ENABLED if (rendering_driver == "vulkan") { - context_vulkan->window_destroy(E->get().vulkan_window); + context_vulkan->window_destroy(E->key()); } #endif diff --git a/platform/linuxbsd/display_server_x11.h b/platform/linuxbsd/display_server_x11.h index 6964447be2..b1ecde30d9 100644 --- a/platform/linuxbsd/display_server_x11.h +++ b/platform/linuxbsd/display_server_x11.h @@ -113,14 +113,13 @@ class DisplayServerX11 : public DisplayServer { struct WindowData { Window x11_window; ::XIC xic; -#if defined(VULKAN_ENABLED) - int vulkan_window; -#endif + Size2i min_size; Size2i max_size; Size2i size; Size2i im_position; bool im_active = false; + Callable resize_callback; //better to guess on the fly, given WM can change it //WindowMode mode; @@ -256,6 +255,7 @@ public: virtual void delete_sub_window(WindowID p_id); virtual void window_set_title(const String &p_title, WindowID p_window = MAIN_WINDOW_ID); + virtual void window_set_resize_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID); virtual int window_get_current_screen(WindowID p_window = MAIN_WINDOW_ID) const; virtual void window_set_current_screen(int p_screen, WindowID p_window = MAIN_WINDOW_ID); diff --git a/platform/linuxbsd/vulkan_context_x11.cpp b/platform/linuxbsd/vulkan_context_x11.cpp index 602dbc77a2..d0e1b1678c 100644 --- a/platform/linuxbsd/vulkan_context_x11.cpp +++ b/platform/linuxbsd/vulkan_context_x11.cpp @@ -35,7 +35,7 @@ const char *VulkanContextX11::_get_platform_surface_extension() const { return VK_KHR_XLIB_SURFACE_EXTENSION_NAME; } -int VulkanContextX11::window_create(::Window p_window, Display *p_display, int p_width, int p_height) { +Error VulkanContextX11::window_create(DisplayServer::WindowID p_window_id, ::Window p_window, Display *p_display, int p_width, int p_height) { VkXlibSurfaceCreateInfoKHR createInfo; createInfo.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR; @@ -46,8 +46,8 @@ int VulkanContextX11::window_create(::Window p_window, Display *p_display, int p VkSurfaceKHR surface; VkResult err = vkCreateXlibSurfaceKHR(_get_instance(), &createInfo, NULL, &surface); - ERR_FAIL_COND_V(err, -1); - return _window_create(surface, p_width, p_height); + ERR_FAIL_COND_V(err, ERR_CANT_CREATE); + return _window_create(p_window_id, surface, p_width, p_height); } VulkanContextX11::VulkanContextX11() { diff --git a/platform/linuxbsd/vulkan_context_x11.h b/platform/linuxbsd/vulkan_context_x11.h index 573f994ea6..6e144ab2d9 100644 --- a/platform/linuxbsd/vulkan_context_x11.h +++ b/platform/linuxbsd/vulkan_context_x11.h @@ -39,7 +39,7 @@ class VulkanContextX11 : public VulkanContext { virtual const char *_get_platform_surface_extension() const; public: - int window_create(::Window p_window, Display *p_display, int p_width, int p_height); + Error window_create(DisplayServer::WindowID p_window_id, ::Window p_window, Display *p_display, int p_width, int p_height); VulkanContextX11(); ~VulkanContextX11(); diff --git a/scene/2d/audio_stream_player_2d.cpp b/scene/2d/audio_stream_player_2d.cpp index 3ef4dfe5f1..df0b17800f 100644 --- a/scene/2d/audio_stream_player_2d.cpp +++ b/scene/2d/audio_stream_player_2d.cpp @@ -32,7 +32,7 @@ #include "core/engine.h" #include "scene/2d/area_2d.h" -#include "scene/main/viewport.h" +#include "scene/main/window.h" void AudioStreamPlayer2D::_mix_audio() { diff --git a/scene/2d/camera_2d.h b/scene/2d/camera_2d.h index 04b5260444..7a106ef79a 100644 --- a/scene/2d/camera_2d.h +++ b/scene/2d/camera_2d.h @@ -32,7 +32,7 @@ #define CAMERA_2D_H #include "scene/2d/node_2d.h" -#include "scene/main/viewport.h" +#include "scene/main/window.h" class Camera2D : public Node2D { diff --git a/scene/2d/canvas_item.cpp b/scene/2d/canvas_item.cpp index 0f93a61b09..959be53028 100644 --- a/scene/2d/canvas_item.cpp +++ b/scene/2d/canvas_item.cpp @@ -34,7 +34,7 @@ #include "core/message_queue.h" #include "core/method_bind_ext.gen.inc" #include "scene/main/canvas_layer.h" -#include "scene/main/viewport.h" +#include "scene/main/window.h" #include "scene/resources/font.h" #include "scene/resources/style_box.h" #include "scene/resources/texture.h" diff --git a/scene/2d/node_2d.cpp b/scene/2d/node_2d.cpp index df21538609..0b0b9820d3 100644 --- a/scene/2d/node_2d.cpp +++ b/scene/2d/node_2d.cpp @@ -32,7 +32,7 @@ #include "core/message_queue.h" #include "scene/gui/control.h" -#include "scene/main/viewport.h" +#include "scene/main/window.h" #include "servers/visual_server.h" #ifdef TOOLS_ENABLED diff --git a/scene/2d/sprite.cpp b/scene/2d/sprite.cpp index 7eaafe5348..a6fb6f7435 100644 --- a/scene/2d/sprite.cpp +++ b/scene/2d/sprite.cpp @@ -32,7 +32,7 @@ #include "core/core_string_names.h" #include "core/os/os.h" -#include "scene/main/viewport.h" +#include "scene/main/window.h" #include "scene/scene_string_names.h" #ifdef TOOLS_ENABLED diff --git a/scene/2d/touch_screen_button.cpp b/scene/2d/touch_screen_button.cpp index 0f79e12275..7efc6479f9 100644 --- a/scene/2d/touch_screen_button.cpp +++ b/scene/2d/touch_screen_button.cpp @@ -33,7 +33,7 @@ #include "core/input/input.h" #include "core/input/input_map.h" #include "core/os/os.h" -#include "scene/main/viewport.h" +#include "scene/main/window.h" void TouchScreenButton::set_texture(const Ref<Texture2D> &p_texture) { diff --git a/scene/2d/visibility_notifier_2d.cpp b/scene/2d/visibility_notifier_2d.cpp index 54511bbe1b..65dabb92b1 100644 --- a/scene/2d/visibility_notifier_2d.cpp +++ b/scene/2d/visibility_notifier_2d.cpp @@ -35,7 +35,7 @@ #include "scene/2d/animated_sprite.h" #include "scene/2d/physics_body_2d.h" #include "scene/animation/animation_player.h" -#include "scene/main/viewport.h" +#include "scene/main/window.h" #include "scene/scene_string_names.h" #ifdef TOOLS_ENABLED diff --git a/scene/3d/audio_stream_player_3d.cpp b/scene/3d/audio_stream_player_3d.cpp index f0a61a905c..f3020d4044 100644 --- a/scene/3d/audio_stream_player_3d.cpp +++ b/scene/3d/audio_stream_player_3d.cpp @@ -33,7 +33,7 @@ #include "scene/3d/area.h" #include "scene/3d/camera.h" #include "scene/3d/listener.h" -#include "scene/main/viewport.h" +#include "scene/main/window.h" // Based on "A Novel Multichannel Panning Method for Standard and Arbitrary Loudspeaker Configurations" by Ramy Sadek and Chris Kyriakakis (2004) // Speaker-Placement Correction Amplitude Panning (SPCAP) diff --git a/scene/3d/camera.h b/scene/3d/camera.h index 6ac3ece798..feb7b39b1e 100644 --- a/scene/3d/camera.h +++ b/scene/3d/camera.h @@ -33,7 +33,7 @@ #include "scene/3d/spatial.h" #include "scene/3d/spatial_velocity_tracker.h" -#include "scene/main/viewport.h" +#include "scene/main/window.h" #include "scene/resources/environment.h" class Camera : public Spatial { diff --git a/scene/3d/listener.h b/scene/3d/listener.h index 287e67f31e..17ff1d9397 100644 --- a/scene/3d/listener.h +++ b/scene/3d/listener.h @@ -32,7 +32,7 @@ #define LISTENER_H #include "scene/3d/spatial.h" -#include "scene/main/viewport.h" +#include "scene/main/window.h" class Listener : public Spatial { diff --git a/scene/3d/spatial.cpp b/scene/3d/spatial.cpp index f1911348ce..c6225dd291 100644 --- a/scene/3d/spatial.cpp +++ b/scene/3d/spatial.cpp @@ -33,7 +33,7 @@ #include "core/engine.h" #include "core/message_queue.h" #include "scene/main/scene_tree.h" -#include "scene/main/viewport.h" +#include "scene/main/window.h" #include "scene/scene_string_names.h" /* diff --git a/scene/3d/world_environment.cpp b/scene/3d/world_environment.cpp index 83a7243906..9276432ba9 100644 --- a/scene/3d/world_environment.cpp +++ b/scene/3d/world_environment.cpp @@ -29,7 +29,7 @@ /*************************************************************************/ #include "world_environment.h" -#include "scene/main/viewport.h" +#include "scene/main/window.h" void WorldEnvironment::_notification(int p_what) { diff --git a/scene/debugger/scene_debugger.cpp b/scene/debugger/scene_debugger.cpp index 7a184adc55..359f936793 100644 --- a/scene/debugger/scene_debugger.cpp +++ b/scene/debugger/scene_debugger.cpp @@ -34,7 +34,7 @@ #include "core/io/marshalls.h" #include "core/script_language.h" #include "scene/main/scene_tree.h" -#include "scene/main/viewport.h" +#include "scene/main/window.h" #include "scene/resources/packed_scene.h" void SceneDebugger::initialize() { diff --git a/scene/gui/base_button.cpp b/scene/gui/base_button.cpp index b2020d44e8..07bc91e7e7 100644 --- a/scene/gui/base_button.cpp +++ b/scene/gui/base_button.cpp @@ -31,7 +31,7 @@ #include "base_button.h" #include "core/os/keyboard.h" -#include "scene/main/viewport.h" +#include "scene/main/window.h" #include "scene/scene_string_names.h" void BaseButton::_unpress_group() { diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp index 29900def80..4959781de4 100644 --- a/scene/gui/color_picker.cpp +++ b/scene/gui/color_picker.cpp @@ -38,7 +38,7 @@ #include "editor/editor_scale.h" #include "editor/editor_settings.h" #endif -#include "scene/main/viewport.h" +#include "scene/main/window.h" void ColorPicker::_notification(int p_what) { diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index 1a231e368b..8f62d9c009 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -38,7 +38,7 @@ #include "scene/gui/label.h" #include "scene/gui/panel.h" #include "scene/main/canvas_layer.h" -#include "scene/main/viewport.h" +#include "scene/main/window.h" #include "scene/scene_string_names.h" #include "servers/visual_server.h" diff --git a/scene/gui/dialogs.cpp b/scene/gui/dialogs.cpp index 6cadd0a63e..290cff6888 100644 --- a/scene/gui/dialogs.cpp +++ b/scene/gui/dialogs.cpp @@ -36,7 +36,7 @@ #ifdef TOOLS_ENABLED #include "editor/editor_node.h" #include "editor/editor_scale.h" -#include "scene/main/viewport.h" // Only used to check for more modals when dimming the editor. +#include "scene/main/window.h" // Only used to check for more modals when dimming the editor. #endif // WindowDialog diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index 8466612c85..41a9905d0b 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -41,7 +41,7 @@ #include "editor/editor_scale.h" #include "editor/editor_settings.h" #endif -#include "scene/main/viewport.h" +#include "scene/main/window.h" static bool _is_text_char(CharType c) { return !is_symbol(c); diff --git a/scene/gui/menu_button.cpp b/scene/gui/menu_button.cpp index 2b163187c5..7f2ea7d3ed 100644 --- a/scene/gui/menu_button.cpp +++ b/scene/gui/menu_button.cpp @@ -31,7 +31,7 @@ #include "menu_button.h" #include "core/os/keyboard.h" -#include "scene/main/viewport.h" +#include "scene/main/window.h" void MenuButton::_unhandled_key_input(Ref<InputEvent> p_event) { diff --git a/scene/gui/scroll_bar.cpp b/scene/gui/scroll_bar.cpp index 4750853c3b..7fc83703c3 100644 --- a/scene/gui/scroll_bar.cpp +++ b/scene/gui/scroll_bar.cpp @@ -33,7 +33,7 @@ #include "core/os/keyboard.h" #include "core/os/os.h" #include "core/print_string.h" -#include "scene/main/viewport.h" +#include "scene/main/window.h" bool ScrollBar::focus_by_default = false; diff --git a/scene/gui/scroll_container.cpp b/scene/gui/scroll_container.cpp index 8bd741f4d8..32943e04e0 100644 --- a/scene/gui/scroll_container.cpp +++ b/scene/gui/scroll_container.cpp @@ -30,7 +30,7 @@ #include "scroll_container.h" #include "core/os/os.h" -#include "scene/main/viewport.h" +#include "scene/main/window.h" bool ScrollContainer::clips_input() const { diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index dd535ba76f..09878f07cf 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -36,7 +36,7 @@ #include "core/os/os.h" #include "core/project_settings.h" #include "core/script_language.h" -#include "scene/main/viewport.h" +#include "scene/main/window.h" #ifdef TOOLS_ENABLED #include "editor/editor_scale.h" diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index cecfb07edb..74b394e51c 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -36,7 +36,7 @@ #include "core/os/os.h" #include "core/print_string.h" #include "core/project_settings.h" -#include "scene/main/viewport.h" +#include "scene/main/window.h" #ifdef TOOLS_ENABLED #include "editor/editor_scale.h" diff --git a/scene/gui/viewport_container.cpp b/scene/gui/viewport_container.cpp index a76f2924d3..7ce1d9e551 100644 --- a/scene/gui/viewport_container.cpp +++ b/scene/gui/viewport_container.cpp @@ -40,7 +40,7 @@ Size2 ViewportContainer::get_minimum_size() const { Size2 ms; for (int i = 0; i < get_child_count(); i++) { - Viewport *c = Object::cast_to<Viewport>(get_child(i)); + SubViewport *c = Object::cast_to<SubViewport>(get_child(i)); if (!c) continue; @@ -77,7 +77,7 @@ void ViewportContainer::set_stretch_shrink(int p_shrink) { for (int i = 0; i < get_child_count(); i++) { - Viewport *c = Object::cast_to<Viewport>(get_child(i)); + SubViewport *c = Object::cast_to<SubViewport>(get_child(i)); if (!c) continue; @@ -101,7 +101,7 @@ void ViewportContainer::_notification(int p_what) { for (int i = 0; i < get_child_count(); i++) { - Viewport *c = Object::cast_to<Viewport>(get_child(i)); + SubViewport *c = Object::cast_to<SubViewport>(get_child(i)); if (!c) continue; @@ -113,14 +113,14 @@ void ViewportContainer::_notification(int p_what) { for (int i = 0; i < get_child_count(); i++) { - Viewport *c = Object::cast_to<Viewport>(get_child(i)); + SubViewport *c = Object::cast_to<SubViewport>(get_child(i)); if (!c) continue; if (is_visible_in_tree()) - c->set_update_mode(Viewport::UPDATE_ALWAYS); + c->set_update_mode(SubViewport::UPDATE_ALWAYS); else - c->set_update_mode(Viewport::UPDATE_DISABLED); + c->set_update_mode(SubViewport::UPDATE_DISABLED); c->set_handle_input_locally(false); //do not handle input locally here } @@ -130,7 +130,7 @@ void ViewportContainer::_notification(int p_what) { for (int i = 0; i < get_child_count(); i++) { - Viewport *c = Object::cast_to<Viewport>(get_child(i)); + SubViewport *c = Object::cast_to<SubViewport>(get_child(i)); if (!c) continue; @@ -159,7 +159,7 @@ void ViewportContainer::_input(const Ref<InputEvent> &p_event) { for (int i = 0; i < get_child_count(); i++) { - Viewport *c = Object::cast_to<Viewport>(get_child(i)); + SubViewport *c = Object::cast_to<SubViewport>(get_child(i)); if (!c || c->is_input_disabled()) continue; @@ -184,7 +184,7 @@ void ViewportContainer::_unhandled_input(const Ref<InputEvent> &p_event) { for (int i = 0; i < get_child_count(); i++) { - Viewport *c = Object::cast_to<Viewport>(get_child(i)); + SubViewport *c = Object::cast_to<SubViewport>(get_child(i)); if (!c || c->is_input_disabled()) continue; diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp index b0708b70b8..77eb445afa 100644 --- a/scene/main/scene_tree.cpp +++ b/scene/main/scene_tree.cpp @@ -51,7 +51,7 @@ #include "servers/navigation_server.h" #include "servers/physics_2d_server.h" #include "servers/physics_server.h" -#include "viewport.h" +#include "window.h" #include <stdio.h> @@ -494,14 +494,6 @@ bool SceneTree::iteration(float p_time) { return _quit; } -void SceneTree::_update_font_oversampling(float p_ratio) { - - if (use_font_oversampling) { - DynamicFontAtSize::font_oversampling = p_ratio; - DynamicFont::update_oversampling(); - } -} - bool SceneTree::idle(float p_time) { //print_line("ram: "+itos(OS::get_singleton()->get_static_memory_usage())+" sram: "+itos(OS::get_singleton()->get_dynamic_memory_usage())); @@ -527,15 +519,6 @@ bool SceneTree::idle(float p_time) { _notify_group_pause("idle_process_internal", Node::NOTIFICATION_INTERNAL_PROCESS); _notify_group_pause("idle_process", Node::NOTIFICATION_PROCESS); - Size2 win_size = Size2(DisplayServer::get_singleton()->window_get_size().width, DisplayServer::get_singleton()->window_get_size().height); - - if (win_size != last_screen_size) { - - last_screen_size = win_size; - _update_root_rect(); - emit_signal("screen_resized"); - } - _flush_ugc(); MessageQueue::get_singleton()->flush(); //small little hack flush_transform_notifications(); //transforms after world update, to avoid unnecessary enter/exit notifications @@ -1130,129 +1113,6 @@ int SceneTree::get_node_count() const { return node_count; } -void SceneTree::_update_root_rect() { - - if (stretch_mode == STRETCH_MODE_DISABLED) { - - _update_font_oversampling(1.0); - root->set_size((last_screen_size / stretch_shrink).floor()); - root->set_attach_to_screen_rect(Rect2(Point2(), last_screen_size)); - root->set_size_override_stretch(false); - root->set_size_override(false, Size2()); - root->update_canvas_items(); - return; //user will take care - } - - //actual screen video mode - Size2 video_mode = Size2(DisplayServer::get_singleton()->window_get_size().width, DisplayServer::get_singleton()->window_get_size().height); - Size2 desired_res = stretch_min; - - Size2 viewport_size; - Size2 screen_size; - - float viewport_aspect = desired_res.aspect(); - float video_mode_aspect = video_mode.aspect(); - - if (use_font_oversampling && stretch_aspect == STRETCH_ASPECT_IGNORE) { - WARN_PRINT("Font oversampling only works with the resize modes 'Keep Width', 'Keep Height', and 'Expand'."); - } - - if (stretch_aspect == STRETCH_ASPECT_IGNORE || Math::is_equal_approx(viewport_aspect, video_mode_aspect)) { - //same aspect or ignore aspect - viewport_size = desired_res; - screen_size = video_mode; - } else if (viewport_aspect < video_mode_aspect) { - // screen ratio is smaller vertically - - if (stretch_aspect == STRETCH_ASPECT_KEEP_HEIGHT || stretch_aspect == STRETCH_ASPECT_EXPAND) { - - //will stretch horizontally - viewport_size.x = desired_res.y * video_mode_aspect; - viewport_size.y = desired_res.y; - screen_size = video_mode; - - } else { - //will need black bars - viewport_size = desired_res; - screen_size.x = video_mode.y * viewport_aspect; - screen_size.y = video_mode.y; - } - } else { - //screen ratio is smaller horizontally - if (stretch_aspect == STRETCH_ASPECT_KEEP_WIDTH || stretch_aspect == STRETCH_ASPECT_EXPAND) { - - //will stretch horizontally - viewport_size.x = desired_res.x; - viewport_size.y = desired_res.x / video_mode_aspect; - screen_size = video_mode; - - } else { - //will need black bars - viewport_size = desired_res; - screen_size.x = video_mode.x; - screen_size.y = video_mode.x / viewport_aspect; - } - } - - screen_size = screen_size.floor(); - viewport_size = viewport_size.floor(); - - Size2 margin; - Size2 offset; - //black bars and margin - if (stretch_aspect != STRETCH_ASPECT_EXPAND && screen_size.x < video_mode.x) { - margin.x = Math::round((video_mode.x - screen_size.x) / 2.0); - VisualServer::get_singleton()->black_bars_set_margins(margin.x, 0, margin.x, 0); - offset.x = Math::round(margin.x * viewport_size.y / screen_size.y); - } else if (stretch_aspect != STRETCH_ASPECT_EXPAND && screen_size.y < video_mode.y) { - margin.y = Math::round((video_mode.y - screen_size.y) / 2.0); - VisualServer::get_singleton()->black_bars_set_margins(0, margin.y, 0, margin.y); - offset.y = Math::round(margin.y * viewport_size.x / screen_size.x); - } else { - VisualServer::get_singleton()->black_bars_set_margins(0, 0, 0, 0); - } - - switch (stretch_mode) { - case STRETCH_MODE_DISABLED: { - // Already handled above - _update_font_oversampling(1.0); - } break; - case STRETCH_MODE_2D: { - - _update_font_oversampling(screen_size.x / viewport_size.x); //screen / viewport radio drives oversampling - root->set_size((screen_size / stretch_shrink).floor()); - root->set_attach_to_screen_rect(Rect2(margin, screen_size)); - root->set_size_override_stretch(true); - root->set_size_override(true, (viewport_size / stretch_shrink).floor()); - root->update_canvas_items(); //force them to update just in case - - } break; - case STRETCH_MODE_VIEWPORT: { - - _update_font_oversampling(1.0); - root->set_size((viewport_size / stretch_shrink).floor()); - root->set_attach_to_screen_rect(Rect2(margin, screen_size)); - root->set_size_override_stretch(false); - root->set_size_override(false, Size2()); - root->update_canvas_items(); //force them to update just in case - - if (use_font_oversampling) { - WARN_PRINT("Font oversampling does not work in 'Viewport' stretch mode, only '2D'."); - } - - } break; - } -} - -void SceneTree::set_screen_stretch(StretchMode p_mode, StretchAspect p_aspect, const Size2 &p_minsize, real_t p_shrink) { - - stretch_mode = p_mode; - stretch_aspect = p_aspect; - stretch_min = p_minsize; - stretch_shrink = p_shrink; - _update_root_rect(); -} - void SceneTree::set_edited_scene_root(Node *p_node) { #ifdef TOOLS_ENABLED edited_scene_root = p_node; @@ -1479,8 +1339,6 @@ void SceneTree::_bind_methods() { ClassDB::bind_method(D_METHOD("get_frame"), &SceneTree::get_frame); ClassDB::bind_method(D_METHOD("quit", "exit_code"), &SceneTree::quit, DEFVAL(-1)); - ClassDB::bind_method(D_METHOD("set_screen_stretch", "mode", "aspect", "minsize", "shrink"), &SceneTree::set_screen_stretch, DEFVAL(1)); - ClassDB::bind_method(D_METHOD("queue_delete", "obj"), &SceneTree::queue_delete); MethodInfo mi; @@ -1530,15 +1388,11 @@ void SceneTree::_bind_methods() { ClassDB::bind_method(D_METHOD("set_refuse_new_network_connections", "refuse"), &SceneTree::set_refuse_new_network_connections); ClassDB::bind_method(D_METHOD("is_refusing_new_network_connections"), &SceneTree::is_refusing_new_network_connections); - ClassDB::bind_method(D_METHOD("set_use_font_oversampling", "enable"), &SceneTree::set_use_font_oversampling); - ClassDB::bind_method(D_METHOD("is_using_font_oversampling"), &SceneTree::is_using_font_oversampling); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "debug_collisions_hint"), "set_debug_collisions_hint", "is_debugging_collisions_hint"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "debug_navigation_hint"), "set_debug_navigation_hint", "is_debugging_navigation_hint"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "paused"), "set_pause", "is_paused"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "refuse_new_network_connections"), "set_refuse_new_network_connections", "is_refusing_new_network_connections"); ADD_PROPERTY_DEFAULT("refuse_new_network_connections", false); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_font_oversampling"), "set_use_font_oversampling", "is_using_font_oversampling"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "edited_scene_root", PROPERTY_HINT_RESOURCE_TYPE, "Node", 0), "set_edited_scene_root", "get_edited_scene_root"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "current_scene", PROPERTY_HINT_RESOURCE_TYPE, "Node", 0), "set_current_scene", "get_current_scene"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "network_peer", PROPERTY_HINT_RESOURCE_TYPE, "NetworkedMultiplayerPeer", 0), "set_network_peer", "get_network_peer"); @@ -1550,7 +1404,6 @@ void SceneTree::_bind_methods() { ADD_SIGNAL(MethodInfo("node_added", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_RESOURCE_TYPE, "Node"))); ADD_SIGNAL(MethodInfo("node_removed", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_RESOURCE_TYPE, "Node"))); ADD_SIGNAL(MethodInfo("node_renamed", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_RESOURCE_TYPE, "Node"))); - ADD_SIGNAL(MethodInfo("screen_resized")); ADD_SIGNAL(MethodInfo("node_configuration_warning_changed", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_RESOURCE_TYPE, "Node"))); ADD_SIGNAL(MethodInfo("idle_frame")); @@ -1568,16 +1421,6 @@ void SceneTree::_bind_methods() { BIND_ENUM_CONSTANT(GROUP_CALL_REVERSE); BIND_ENUM_CONSTANT(GROUP_CALL_REALTIME); BIND_ENUM_CONSTANT(GROUP_CALL_UNIQUE); - - BIND_ENUM_CONSTANT(STRETCH_MODE_DISABLED); - BIND_ENUM_CONSTANT(STRETCH_MODE_2D); - BIND_ENUM_CONSTANT(STRETCH_MODE_VIEWPORT); - - BIND_ENUM_CONSTANT(STRETCH_ASPECT_IGNORE); - BIND_ENUM_CONSTANT(STRETCH_ASPECT_KEEP); - BIND_ENUM_CONSTANT(STRETCH_ASPECT_KEEP_WIDTH); - BIND_ENUM_CONSTANT(STRETCH_ASPECT_KEEP_HEIGHT); - BIND_ENUM_CONSTANT(STRETCH_ASPECT_EXPAND); } SceneTree *SceneTree::singleton = NULL; @@ -1597,19 +1440,6 @@ void SceneTree::add_idle_callback(IdleCallback p_callback) { idle_callbacks[idle_callback_count++] = p_callback; } -void SceneTree::set_use_font_oversampling(bool p_oversampling) { - - if (use_font_oversampling == p_oversampling) - return; - - use_font_oversampling = p_oversampling; - _update_root_rect(); -} - -bool SceneTree::is_using_font_oversampling() const { - return use_font_oversampling; -} - void SceneTree::get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const { if (p_function == "change_scene") { @@ -1649,7 +1479,6 @@ SceneTree::SceneTree() { accept_quit = true; quit_on_go_back = true; initialized = false; - use_font_oversampling = false; #ifdef DEBUG_ENABLED debug_collisions_hint = false; debug_navigation_hint = false; @@ -1681,7 +1510,7 @@ SceneTree::SceneTree() { //create with mainloop - root = memnew(Viewport); + root = memnew(Window); root->set_name("root"); root->set_handle_input_locally(false); if (!root->get_world().is_valid()) @@ -1731,13 +1560,6 @@ SceneTree::SceneTree() { } } - stretch_mode = STRETCH_MODE_DISABLED; - stretch_aspect = STRETCH_ASPECT_IGNORE; - stretch_shrink = 1; - - last_screen_size = Size2(DisplayServer::get_singleton()->window_get_size().width, DisplayServer::get_singleton()->window_get_size().height); - _update_root_rect(); - root->set_physics_object_picking(GLOBAL_DEF("physics/common/enable_object_picking", true)); #ifdef TOOLS_ENABLED diff --git a/scene/main/scene_tree.h b/scene/main/scene_tree.h index 2f805d074f..c51214b676 100644 --- a/scene/main/scene_tree.h +++ b/scene/main/scene_tree.h @@ -39,9 +39,11 @@ #include "scene/resources/world.h" #include "scene/resources/world_2d.h" +#undef Window + class PackedScene; class Node; -class Viewport; +class Window; class Material; class Mesh; class SceneDebugger; @@ -76,22 +78,6 @@ class SceneTree : public MainLoop { public: typedef void (*IdleCallback)(); - enum StretchMode { - - STRETCH_MODE_DISABLED, - STRETCH_MODE_2D, - STRETCH_MODE_VIEWPORT, - }; - - enum StretchAspect { - - STRETCH_ASPECT_IGNORE, - STRETCH_ASPECT_KEEP, - STRETCH_ASPECT_KEEP_WIDTH, - STRETCH_ASPECT_KEEP_HEIGHT, - STRETCH_ASPECT_EXPAND, - }; - private: struct Group { @@ -101,7 +87,7 @@ private: Group() { changed = false; }; }; - Viewport *root; + Window *root; uint64_t tree_version; float physics_process_time; @@ -121,13 +107,11 @@ private: bool initialized; bool input_handled; - Size2 last_screen_size; StringName tree_changed_name; StringName node_added_name; StringName node_removed_name; StringName node_renamed_name; - bool use_font_oversampling; int64_t current_frame; int64_t current_event; int node_count; @@ -147,14 +131,6 @@ private: int call_lock; Set<Node *> call_skip; //skip erased nodes - StretchMode stretch_mode; - StretchAspect stretch_aspect; - Size2i stretch_min; - real_t stretch_shrink; - - void _update_font_oversampling(float p_ratio); - void _update_root_rect(); - List<ObjectID> delete_queue; Map<UGCall, Vector<Variant>> unique_group_calls; @@ -249,7 +225,7 @@ public: GROUP_CALL_MULTILEVEL = 8, }; - _FORCE_INLINE_ Viewport *get_root() const { return root; } + _FORCE_INLINE_ Window *get_root() const { return root; } void call_group_flags(uint32_t p_call_flags, const StringName &p_group, const StringName &p_function, VARIANT_ARG_LIST); void notify_group_flags(uint32_t p_call_flags, const StringName &p_group, int p_notification); @@ -335,11 +311,6 @@ public: void get_nodes_in_group(const StringName &p_group, List<Node *> *p_list); bool has_group(const StringName &p_identifier) const; - void set_screen_stretch(StretchMode p_mode, StretchAspect p_aspect, const Size2 &p_minsize, real_t p_shrink = 1); - - void set_use_font_oversampling(bool p_oversampling); - bool is_using_font_oversampling() const; - //void change_scene(const String& p_path); //Node *get_loaded_scene(); @@ -388,8 +359,6 @@ public: ~SceneTree(); }; -VARIANT_ENUM_CAST(SceneTree::StretchMode); -VARIANT_ENUM_CAST(SceneTree::StretchAspect); VARIANT_ENUM_CAST(SceneTree::GroupCallFlags); #endif diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 20587f49b9..66faaf51b3 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -142,7 +142,7 @@ 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); - ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "viewport_path", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Viewport", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_NODE_PATH_FROM_SCENE_ROOT), "set_viewport_path_in_scene", "get_viewport_path_in_scene"); + ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "viewport_path", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "SubViewport", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_NODE_PATH_FROM_SCENE_ROOT), "set_viewport_path_in_scene", "get_viewport_path_in_scene"); } ViewportTexture::ViewportTexture() { @@ -185,6 +185,8 @@ public: Viewport::GUI::GUI() { + embed_subwindows_hint = false; + dragging = false; mouse_focus = NULL; mouse_click_grabber = NULL; @@ -201,23 +203,6 @@ Viewport::GUI::GUI() { ///////////////////////////////////// -void Viewport::_update_stretch_transform() { - - if (size_override_stretch && size_override) { - - stretch_transform = Transform2D(); - Size2 scale = size / (size_override_size + size_override_margin * 2); - stretch_transform.scale(scale); - stretch_transform.elements[2] = size_override_margin * scale; - - } else { - - stretch_transform = Transform2D(); - } - - _update_global_transform(); -} - void Viewport::update_worlds() { if (!is_inside_tree()) @@ -409,7 +394,7 @@ void Viewport::_notification(int p_what) { VS::get_singleton()->multimesh_set_visible_instances(contact_3d_debug_multimesh, point_count); } - if (physics_object_picking && (to_screen_rect == Rect2() || Input::get_singleton()->get_mouse_mode() != Input::MOUSE_MODE_CAPTURED)) { + if (physics_object_picking && (to_screen_rect == Rect2i() || Input::get_singleton()->get_mouse_mode() != Input::MOUSE_MODE_CAPTURED)) { #ifndef _3D_DISABLED Vector2 last_pos(1e20, 1e20); @@ -699,16 +684,6 @@ RID Viewport::get_viewport_rid() const { return viewport; } -void Viewport::set_use_arvr(bool p_use_arvr) { - arvr = p_use_arvr; - - VS::get_singleton()->viewport_set_use_arvr(viewport, arvr); -} - -bool Viewport::use_arvr() { - return arvr; -} - void Viewport::update_canvas_items() { if (!is_inside_tree()) return; @@ -716,18 +691,35 @@ void Viewport::update_canvas_items() { _update_canvas_items(this); } -void Viewport::set_size(const Size2 &p_size) { +void Viewport::_set_size(const Size2i &p_size, const Size2i &p_size_override, const Rect2i &p_to_screen_rect, const Transform2D &p_stretch_transform, bool p_allocated) { - if (size == p_size.floor()) + if (size == p_size && size_allocated == p_allocated && stretch_transform == p_stretch_transform && p_size_override == size_override && to_screen_rect != p_to_screen_rect) return; - size = p_size.floor(); - VS::get_singleton()->viewport_set_size(viewport, size.width, size.height); + size = p_size; + size_allocated = p_allocated; + size_override = p_size_override; + stretch_transform = p_stretch_transform; + to_screen_rect = p_to_screen_rect; + + if (p_allocated) { + VS::get_singleton()->viewport_set_size(viewport, size.width, size.height); + } else { + VS::get_singleton()->viewport_set_size(viewport, 0, 0); + } + _update_global_transform(); - _update_stretch_transform(); + update_canvas_items(); emit_signal("size_changed"); } +Size2i Viewport::_get_size() const { + return size; +} +bool Viewport::_is_size_allocated() const { + return size_allocated; +} + Rect2 Viewport::get_visible_rect() const { Rect2 r; @@ -738,18 +730,13 @@ Rect2 Viewport::get_visible_rect() const { r = Rect2(Point2(), size); } - if (size_override) { - r.size = size_override_size; + if (size_override != Size2i()) { + r.size = size_override; } return r; } -Size2 Viewport::get_size() const { - - return size; -} - void Viewport::_update_listener() { /* if (is_inside_tree() && audio_listener && (camera || listener) && (!get_parent() || (Object::cast_to<Control>(get_parent()) && Object::cast_to<Control>(get_parent())->is_visible_in_tree()))) { @@ -1279,70 +1266,11 @@ void Viewport::_update_canvas_items(Node *p_node) { } } -void Viewport::set_size_override(bool p_enable, const Size2 &p_size, const Vector2 &p_margin) { - - if (size_override == p_enable && p_size == size_override_size) - return; - - size_override = p_enable; - if (p_size.x >= 0 || p_size.y >= 0) { - size_override_size = p_size; - } - size_override_margin = p_margin; - - _update_stretch_transform(); - emit_signal("size_changed"); -} - -Size2 Viewport::get_size_override() const { - - return size_override_size; -} -bool Viewport::is_size_override_enabled() const { - - return size_override; -} -void Viewport::set_size_override_stretch(bool p_enable) { - - if (p_enable == size_override_stretch) - return; - - size_override_stretch = p_enable; - - _update_stretch_transform(); -} - -bool Viewport::is_size_override_stretch_enabled() const { - - return size_override_stretch; -} - -void Viewport::set_update_mode(UpdateMode p_mode) { - - update_mode = p_mode; - VS::get_singleton()->viewport_set_update_mode(viewport, VS::ViewportUpdateMode(p_mode)); -} -Viewport::UpdateMode Viewport::get_update_mode() const { - - return update_mode; -} - Ref<ViewportTexture> Viewport::get_texture() const { return default_texture; } -void Viewport::set_clear_mode(ClearMode p_mode) { - - clear_mode = p_mode; - VS::get_singleton()->viewport_set_clear_mode(viewport, VS::ViewportClearMode(p_mode)); -} - -Viewport::ClearMode Viewport::get_clear_mode() const { - - return clear_mode; -} - void Viewport::set_shadow_atlas_size(int p_size) { if (shadow_atlas_size == p_size) @@ -1380,7 +1308,7 @@ Transform2D Viewport::_get_input_pre_xform() const { Transform2D pre_xf; - if (to_screen_rect != Rect2()) { + if (to_screen_rect != Rect2i()) { pre_xf.elements[2] = -to_screen_rect.position; pre_xf.scale(size / to_screen_rect.size); @@ -1423,8 +1351,12 @@ void Viewport::_vp_input(const Ref<InputEvent> &p_ev) { } #endif - if (to_screen_rect == Rect2()) - return; //if render target, can't get input events + Ref<InputEventFromWindow> window_event = p_ev; + if (window_event.is_valid()) { + if (window_event->get_window_id() != get_window_id()) { + return; + } + } //this one handles system input, p_ev are in system coordinates //they are converted to viewport coordinates @@ -1448,8 +1380,12 @@ void Viewport::_vp_unhandled_input(const Ref<InputEvent> &p_ev) { return; */ - if (to_screen_rect == Rect2()) - return; //if render target, can't get input events + Ref<InputEventFromWindow> window_event = p_ev; + if (window_event.is_valid()) { + if (window_event->get_window_id() != get_window_id()) { + return; + } + } //this one handles system input, p_ev are in system coordinates //they are converted to viewport coordinates @@ -2878,30 +2814,6 @@ bool Viewport::is_using_own_world() const { return own_world.is_valid(); } -void Viewport::set_attach_to_screen_rect(const Rect2 &p_rect) { - - VS::get_singleton()->viewport_attach_to_screen(viewport, p_rect); - to_screen_rect = p_rect; -} - -Rect2 Viewport::get_attach_to_screen_rect() const { - - return to_screen_rect; -} - -void Viewport::set_use_render_direct_to_screen(bool p_render_direct_to_screen) { - - if (p_render_direct_to_screen == render_direct_to_screen) - return; - - render_direct_to_screen = p_render_direct_to_screen; - VS::get_singleton()->viewport_set_render_direct_to_screen(viewport, p_render_direct_to_screen); -} - -bool Viewport::is_using_render_direct_to_screen() const { - return render_direct_to_screen; -} - void Viewport::set_physics_object_picking(bool p_enable) { physics_object_picking = p_enable; @@ -3091,13 +3003,27 @@ DisplayServer::WindowID Viewport::get_window_id() const { return DisplayServer::MAIN_WINDOW_ID; } -void Viewport::_bind_methods() { +Viewport *Viewport::get_parent_viewport() const { + ERR_FAIL_COND_V(!is_inside_tree(), nullptr); + if (!get_parent()) { + return nullptr; //root viewport + } + + return get_parent()->get_viewport(); +} - ClassDB::bind_method(D_METHOD("set_use_arvr", "use"), &Viewport::set_use_arvr); - ClassDB::bind_method(D_METHOD("use_arvr"), &Viewport::use_arvr); +void Viewport::set_embed_subwindows_hint(bool p_embed) { + gui.embed_subwindows_hint = p_embed; +} +bool Viewport::get_embed_subwindows_hint() const { + return gui.embed_subwindows_hint; +} +bool Viewport::is_embedding_subwindows() const { + return gui.embed_subwindows_hint; +} + +void Viewport::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_size", "size"), &Viewport::set_size); - ClassDB::bind_method(D_METHOD("get_size"), &Viewport::get_size); ClassDB::bind_method(D_METHOD("set_world_2d", "world_2d"), &Viewport::set_world_2d); ClassDB::bind_method(D_METHOD("get_world_2d"), &Viewport::get_world_2d); ClassDB::bind_method(D_METHOD("find_world_2d"), &Viewport::find_world_2d); @@ -3120,18 +3046,6 @@ void Viewport::_bind_methods() { ClassDB::bind_method(D_METHOD("_vp_input_text", "text"), &Viewport::_vp_input_text); ClassDB::bind_method(D_METHOD("_vp_unhandled_input"), &Viewport::_vp_unhandled_input); - ClassDB::bind_method(D_METHOD("set_size_override", "enable", "size", "margin"), &Viewport::set_size_override, DEFVAL(Size2(-1, -1)), DEFVAL(Size2(0, 0))); - ClassDB::bind_method(D_METHOD("get_size_override"), &Viewport::get_size_override); - ClassDB::bind_method(D_METHOD("is_size_override_enabled"), &Viewport::is_size_override_enabled); - ClassDB::bind_method(D_METHOD("set_size_override_stretch", "enabled"), &Viewport::set_size_override_stretch); - ClassDB::bind_method(D_METHOD("is_size_override_stretch_enabled"), &Viewport::is_size_override_stretch_enabled); - - ClassDB::bind_method(D_METHOD("set_clear_mode", "mode"), &Viewport::set_clear_mode); - ClassDB::bind_method(D_METHOD("get_clear_mode"), &Viewport::get_clear_mode); - - ClassDB::bind_method(D_METHOD("set_update_mode", "mode"), &Viewport::set_update_mode); - ClassDB::bind_method(D_METHOD("get_update_mode"), &Viewport::get_update_mode); - ClassDB::bind_method(D_METHOD("set_msaa", "msaa"), &Viewport::set_msaa); ClassDB::bind_method(D_METHOD("get_msaa"), &Viewport::get_msaa); @@ -3161,9 +3075,6 @@ void Viewport::_bind_methods() { ClassDB::bind_method(D_METHOD("set_as_audio_listener_2d", "enable"), &Viewport::set_as_audio_listener_2d); ClassDB::bind_method(D_METHOD("is_audio_listener_2d"), &Viewport::is_audio_listener_2d); - ClassDB::bind_method(D_METHOD("set_attach_to_screen_rect", "rect"), &Viewport::set_attach_to_screen_rect); - ClassDB::bind_method(D_METHOD("set_use_render_direct_to_screen", "enable"), &Viewport::set_use_render_direct_to_screen); - ClassDB::bind_method(D_METHOD("is_using_render_direct_to_screen"), &Viewport::is_using_render_direct_to_screen); ClassDB::bind_method(D_METHOD("get_mouse_position"), &Viewport::get_mouse_position); ClassDB::bind_method(D_METHOD("warp_mouse", "to_position"), &Viewport::warp_mouse); @@ -3199,13 +3110,13 @@ void Viewport::_bind_methods() { ClassDB::bind_method(D_METHOD("set_default_canvas_item_texture_filter", "mode"), &Viewport::set_default_canvas_item_texture_filter); ClassDB::bind_method(D_METHOD("get_default_canvas_item_texture_filter"), &Viewport::get_default_canvas_item_texture_filter); + ClassDB::bind_method(D_METHOD("set_embed_subwindows_hint", "enable"), &Viewport::set_embed_subwindows_hint); + ClassDB::bind_method(D_METHOD("get_embed_subwindows_hint"), &Viewport::get_embed_subwindows_hint); + ClassDB::bind_method(D_METHOD("is_embedding_subwindows"), &Viewport::is_embedding_subwindows); + ClassDB::bind_method(D_METHOD("set_default_canvas_item_texture_repeat", "mode"), &Viewport::set_default_canvas_item_texture_repeat); ClassDB::bind_method(D_METHOD("get_default_canvas_item_texture_repeat"), &Viewport::get_default_canvas_item_texture_repeat); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "arvr"), "set_use_arvr", "use_arvr"); - - ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "size"), "set_size", "get_size"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "size_override_stretch"), "set_size_override_stretch", "is_size_override_stretch_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "own_world"), "set_use_own_world", "is_using_own_world"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "world", PROPERTY_HINT_RESOURCE_TYPE, "World"), "set_world", "get_world"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "world_2d", PROPERTY_HINT_RESOURCE_TYPE, "World2D", 0), "set_world_2d", "get_world_2d"); @@ -3213,11 +3124,7 @@ void Viewport::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "handle_input_locally"), "set_handle_input_locally", "is_handling_input_locally"); ADD_GROUP("Rendering", ""); ADD_PROPERTY(PropertyInfo(Variant::INT, "msaa", PROPERTY_HINT_ENUM, "Disabled,2x,4x,8x,16x,AndroidVR 2x,AndroidVR 4x"), "set_msaa", "get_msaa"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "render_direct_to_screen"), "set_use_render_direct_to_screen", "is_using_render_direct_to_screen"); ADD_PROPERTY(PropertyInfo(Variant::INT, "debug_draw", PROPERTY_HINT_ENUM, "Disabled,Unshaded,Overdraw,Wireframe"), "set_debug_draw", "get_debug_draw"); - ADD_GROUP("Render Target", "render_target_"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "render_target_clear_mode", PROPERTY_HINT_ENUM, "Always,Never,Next Frame"), "set_clear_mode", "get_clear_mode"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "render_target_update_mode", PROPERTY_HINT_ENUM, "Disabled,Once,When Visible,Always"), "set_update_mode", "get_update_mode"); ADD_GROUP("Canvas Items", "canvas_item_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "canvas_item_default_texture_filter", PROPERTY_HINT_ENUM, "Nearest,Linear,MipmapLinear,MipmapNearest"), "set_default_canvas_item_texture_filter", "get_default_canvas_item_texture_filter"); ADD_PROPERTY(PropertyInfo(Variant::INT, "canvas_item_default_texture_repeat", PROPERTY_HINT_ENUM, "Disabled,Enabled,Mirror"), "set_default_canvas_item_texture_repeat", "get_default_canvas_item_texture_repeat"); @@ -3229,6 +3136,7 @@ void Viewport::_bind_methods() { ADD_GROUP("GUI", "gui_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "gui_disable_input"), "set_disable_input", "is_input_disabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "gui_snap_controls_to_pixels"), "set_snap_controls_to_pixels", "is_snap_controls_to_pixels_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "gui_embed_subwindows"), "set_embed_subwindows_hint", "get_embed_subwindows_hint"); ADD_GROUP("Shadow Atlas", "shadow_atlas_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "shadow_atlas_size"), "set_shadow_atlas_size", "get_shadow_atlas_size"); ADD_PROPERTYI(PropertyInfo(Variant::INT, "shadow_atlas_quad_0", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"), "set_shadow_atlas_quadrant_subdiv", "get_shadow_atlas_quadrant_subdiv", 0); @@ -3241,11 +3149,6 @@ void Viewport::_bind_methods() { ADD_SIGNAL(MethodInfo("size_changed")); ADD_SIGNAL(MethodInfo("gui_focus_changed", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_RESOURCE_TYPE, "Control"))); - BIND_ENUM_CONSTANT(UPDATE_DISABLED); - BIND_ENUM_CONSTANT(UPDATE_ONCE); - BIND_ENUM_CONSTANT(UPDATE_WHEN_VISIBLE); - BIND_ENUM_CONSTANT(UPDATE_ALWAYS); - BIND_ENUM_CONSTANT(SHADOW_ATLAS_QUADRANT_SUBDIV_DISABLED); BIND_ENUM_CONSTANT(SHADOW_ATLAS_QUADRANT_SUBDIV_1); BIND_ENUM_CONSTANT(SHADOW_ATLAS_QUADRANT_SUBDIV_4); @@ -3282,10 +3185,6 @@ void Viewport::_bind_methods() { BIND_ENUM_CONSTANT(MSAA_8X); BIND_ENUM_CONSTANT(MSAA_16X); - BIND_ENUM_CONSTANT(CLEAR_MODE_ALWAYS); - BIND_ENUM_CONSTANT(CLEAR_MODE_NEVER); - BIND_ENUM_CONSTANT(CLEAR_MODE_ONLY_NEXT_FRAME); - BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_NEAREST); BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_LINEAR); BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS); @@ -3312,8 +3211,6 @@ Viewport::Viewport() { viewport = VisualServer::get_singleton()->viewport_create(); texture_rid = VisualServer::get_singleton()->viewport_get_texture(viewport); - render_direct_to_screen = false; - default_texture.instance(); default_texture->vp = const_cast<Viewport *>(this); viewport_textures.insert(default_texture.ptr()); @@ -3329,14 +3226,10 @@ Viewport::Viewport() { camera = NULL; override_canvas_transform = false; canvas_layers.insert(NULL); // This eases picking code (interpreted as the canvas of the Viewport) - arvr = false; - size_override = false; - size_override_stretch = false; - size_override_size = Size2(1, 1); + gen_mipmaps = false; //clear=true; - update_mode = UPDATE_WHEN_VISIBLE; physics_object_picking = false; physics_has_last_mousepos = false; @@ -3378,7 +3271,6 @@ Viewport::Viewport() { msaa = MSAA_DISABLED; debug_draw = DEBUG_DRAW_DISABLED; - clear_mode = CLEAR_MODE_ALWAYS; snap_controls_to_pixels = true; physics_last_mouse_state.alt = false; @@ -3389,6 +3281,8 @@ Viewport::Viewport() { local_input_handled = false; handle_input_locally = true; + size_allocated = false; + default_canvas_item_texture_filter = DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_LINEAR; default_canvas_item_texture_repeat = DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_DISABLED; } @@ -3403,3 +3297,84 @@ Viewport::~Viewport() { //SpatialSoundServer::get_singleton()->free(internal_listener); //SpatialSound2DServer::get_singleton()->free(internal_listener_2d); } + +///////////////////////////////// + +void SubViewport::set_use_arvr(bool p_use_arvr) { + arvr = p_use_arvr; + + VS::get_singleton()->viewport_set_use_arvr(get_viewport_rid(), arvr); +} + +bool SubViewport::is_using_arvr() { + return arvr; +} + +void SubViewport::set_size(const Size2i &p_size) { + _set_size(p_size, Size2i(), Rect2i(), Transform2D(), true); +} +Size2i SubViewport::get_size() const { + return _get_size(); +} + +void SubViewport::set_update_mode(UpdateMode p_mode) { + + update_mode = p_mode; + VS::get_singleton()->viewport_set_update_mode(get_viewport_rid(), VS::ViewportUpdateMode(p_mode)); +} +SubViewport::UpdateMode SubViewport::get_update_mode() const { + + return update_mode; +} + +void SubViewport::set_clear_mode(ClearMode p_mode) { + + clear_mode = p_mode; + VS::get_singleton()->viewport_set_clear_mode(get_viewport_rid(), VS::ViewportClearMode(p_mode)); +} + +SubViewport::ClearMode SubViewport::get_clear_mode() const { + + return clear_mode; +} + +DisplayServer::WindowID SubViewport::get_window_id() const { + return DisplayServer::INVALID_WINDOW_ID; +} + +void SubViewport::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_use_arvr", "use"), &SubViewport::set_use_arvr); + ClassDB::bind_method(D_METHOD("is_using_arvr"), &SubViewport::is_using_arvr); + + ClassDB::bind_method(D_METHOD("set_size", "size"), &SubViewport::set_size); + ClassDB::bind_method(D_METHOD("get_size"), &SubViewport::get_size); + + ClassDB::bind_method(D_METHOD("set_update_mode", "mode"), &SubViewport::set_update_mode); + ClassDB::bind_method(D_METHOD("get_update_mode"), &SubViewport::get_update_mode); + + ClassDB::bind_method(D_METHOD("set_clear_mode", "mode"), &SubViewport::set_clear_mode); + ClassDB::bind_method(D_METHOD("get_clear_mode"), &SubViewport::get_clear_mode); + + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "arvr"), "set_use_arvr", "is_using_arvr"); + ADD_GROUP("Render Target", "render_target_"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "render_target_clear_mode", PROPERTY_HINT_ENUM, "Always,Never,Next Frame"), "set_clear_mode", "get_clear_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "render_target_update_mode", PROPERTY_HINT_ENUM, "Disabled,Once,When Visible,Always"), "set_update_mode", "get_update_mode"); + + BIND_ENUM_CONSTANT(UPDATE_DISABLED); + BIND_ENUM_CONSTANT(UPDATE_ONCE); + BIND_ENUM_CONSTANT(UPDATE_WHEN_VISIBLE); + BIND_ENUM_CONSTANT(UPDATE_ALWAYS); + + BIND_ENUM_CONSTANT(CLEAR_MODE_ALWAYS); + BIND_ENUM_CONSTANT(CLEAR_MODE_NEVER); + BIND_ENUM_CONSTANT(CLEAR_MODE_ONLY_NEXT_FRAME); +} + +SubViewport::SubViewport() { + arvr = false; + update_mode = UPDATE_WHEN_VISIBLE; + clear_mode = CLEAR_MODE_ALWAYS; +} + +SubViewport::~SubViewport() { +} diff --git a/scene/main/viewport.h b/scene/main/viewport.h index b2a25fe0e9..1fa08e6cd0 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -89,13 +89,6 @@ class Viewport : public Node { GDCLASS(Viewport, Node); public: - enum UpdateMode { - UPDATE_DISABLED, - UPDATE_ONCE, //then goes to disabled - UPDATE_WHEN_VISIBLE, // default - UPDATE_ALWAYS - }; - enum ShadowAtlasQuadrantSubdiv { SHADOW_ATLAS_QUADRANT_SUBDIV_DISABLED, SHADOW_ATLAS_QUADRANT_SUBDIV_1, @@ -143,13 +136,6 @@ public: DEBUG_DRAW_ROUGHNESS_LIMITER }; - enum ClearMode { - - CLEAR_MODE_ALWAYS, - CLEAR_MODE_NEVER, - CLEAR_MODE_ONLY_NEXT_FRAME - }; - enum DefaultCanvasItemTextureFilter { DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_NEAREST, DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_LINEAR, @@ -173,8 +159,6 @@ private: Listener *listener; Set<Listener *> listeners; - bool arvr; - struct CameraOverrideData { Transform transform; enum Projection { @@ -213,23 +197,17 @@ private: Transform2D global_canvas_transform; Transform2D stretch_transform; - Size2 size; - Rect2 to_screen_rect; - bool render_direct_to_screen; + Size2i size; + Size2i size_override; + bool size_allocated; RID contact_2d_debug; RID contact_3d_debug_multimesh; RID contact_3d_debug_instance; - bool size_override; - bool size_override_stretch; - Size2 size_override_size; - Size2 size_override_margin; - Rect2 last_vp_rect; bool transparent_bg; - ClearMode clear_mode; bool filter; bool gen_mipmaps; @@ -265,6 +243,7 @@ private: Ref<World> world; Ref<World> own_world; + Rect2i to_screen_rect; StringName input_group; StringName gui_input_group; StringName unhandled_input_group; @@ -277,10 +256,8 @@ private: void _propagate_exit_world(Node *p_node); void _propagate_viewport_notification(Node *p_node, int p_what); - void _update_stretch_transform(); void _update_global_transform(); - UpdateMode update_mode; RID texture_rid; DebugDraw debug_draw; @@ -323,6 +300,7 @@ private: List<Control *> roots; int canvas_sort_index; //for sorting items with canvas as root bool dragging; + bool embed_subwindows_hint; GUI(); } gui; @@ -422,6 +400,11 @@ private: void _own_world_changed(); protected: + void _set_size(const Size2i &p_size, const Size2i &p_size_override, const Rect2i &p_to_screen_rect, const Transform2D &p_stretch_transform, bool p_allocated); + + Size2i _get_size() const; + bool _is_size_allocated() const; + void _notification(int p_what); static void _bind_methods(); virtual void _validate_property(PropertyInfo &property) const; @@ -439,19 +422,14 @@ public: void set_camera_override_perspective(float p_fovy_degrees, float p_z_near, float p_z_far); void set_camera_override_orthogonal(float p_size, float p_z_near, float p_z_far); - void set_use_arvr(bool p_use_arvr); - bool use_arvr(); - void set_as_audio_listener(bool p_enable); bool is_audio_listener() const; void set_as_audio_listener_2d(bool p_enable); bool is_audio_listener_2d() const; - void set_size(const Size2 &p_size); void update_canvas_items(); - Size2 get_size() const; Rect2 get_visible_rect() const; RID get_viewport_rid() const; @@ -480,18 +458,6 @@ public: void set_transparent_background(bool p_enable); bool has_transparent_background() const; - void set_size_override(bool p_enable, const Size2 &p_size = Size2(-1, -1), const Vector2 &p_margin = Vector2()); - Size2 get_size_override() const; - - bool is_size_override_enabled() const; - void set_size_override_stretch(bool p_enable); - bool is_size_override_stretch_enabled() const; - - void set_clear_mode(ClearMode p_mode); - ClearMode get_clear_mode() const; - - void set_update_mode(UpdateMode p_mode); - UpdateMode get_update_mode() const; Ref<ViewportTexture> get_texture() const; void set_shadow_atlas_size(int p_size); @@ -515,12 +481,6 @@ public: void set_disable_input(bool p_disable); bool is_input_disabled() const; - void set_attach_to_screen_rect(const Rect2 &p_rect); - Rect2 get_attach_to_screen_rect() const; - - void set_use_render_direct_to_screen(bool p_render_direct_to_screen); - bool is_using_render_direct_to_screen() const; - Vector2 get_mouse_position() const; void warp_mouse(const Vector2 &p_pos); @@ -561,17 +521,66 @@ public: void set_default_canvas_item_texture_repeat(DefaultCanvasItemTextureRepeat p_repeat); DefaultCanvasItemTextureRepeat get_default_canvas_item_texture_repeat() const; - DisplayServer::WindowID get_window_id() const; + virtual DisplayServer::WindowID get_window_id() const = 0; + + void set_embed_subwindows_hint(bool p_embed); + bool get_embed_subwindows_hint() const; + bool is_embedding_subwindows() const; + Viewport *get_parent_viewport() const; Viewport(); ~Viewport(); }; -VARIANT_ENUM_CAST(Viewport::UpdateMode); +class SubViewport : public Viewport { + + GDCLASS(SubViewport, Viewport); + +public: + enum ClearMode { + + CLEAR_MODE_ALWAYS, + CLEAR_MODE_NEVER, + CLEAR_MODE_ONLY_NEXT_FRAME + }; + + enum UpdateMode { + UPDATE_DISABLED, + UPDATE_ONCE, //then goes to disabled + UPDATE_WHEN_VISIBLE, // default + UPDATE_ALWAYS + }; + +private: + UpdateMode update_mode; + ClearMode clear_mode; + bool arvr; + +protected: + static void _bind_methods(); + virtual DisplayServer::WindowID get_window_id() const; + +public: + void set_size(const Size2i &p_size); + Size2i get_size() const; + + void set_use_arvr(bool p_use_arvr); + bool is_using_arvr(); + + void set_update_mode(UpdateMode p_mode); + UpdateMode get_update_mode() const; + + void set_clear_mode(ClearMode p_mode); + ClearMode get_clear_mode() const; + + SubViewport(); + ~SubViewport(); +}; +VARIANT_ENUM_CAST(SubViewport::UpdateMode); VARIANT_ENUM_CAST(Viewport::ShadowAtlasQuadrantSubdiv); VARIANT_ENUM_CAST(Viewport::MSAA); VARIANT_ENUM_CAST(Viewport::DebugDraw); -VARIANT_ENUM_CAST(Viewport::ClearMode); +VARIANT_ENUM_CAST(SubViewport::ClearMode); VARIANT_ENUM_CAST(Viewport::RenderInfo); VARIANT_ENUM_CAST(Viewport::DefaultCanvasItemTextureFilter); VARIANT_ENUM_CAST(Viewport::DefaultCanvasItemTextureRepeat); diff --git a/scene/main/window.cpp b/scene/main/window.cpp new file mode 100644 index 0000000000..21e7450b9f --- /dev/null +++ b/scene/main/window.cpp @@ -0,0 +1,489 @@ +/*************************************************************************/ +/* window.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "window.h" + +#include "scene/resources/dynamic_font.h" + +void Window::set_title(const String &p_title) { + title = p_title; + if (window_id == DisplayServer::INVALID_WINDOW_ID) + return; + DisplayServer::get_singleton()->window_set_title(p_title, window_id); +} +String Window::get_title() const { + return title; +} + +void Window::set_current_screen(int p_screen) { + current_screen = p_screen; + if (window_id == DisplayServer::INVALID_WINDOW_ID) + return; + DisplayServer::get_singleton()->window_set_current_screen(p_screen, window_id); +} +int Window::get_current_screen() const { + if (window_id != DisplayServer::INVALID_WINDOW_ID) { + current_screen = DisplayServer::get_singleton()->window_get_current_screen(window_id); + } + return current_screen; +} + +void Window::set_position(const Point2i &p_position) { + + position = p_position; + if (window_id == DisplayServer::INVALID_WINDOW_ID) + return; + DisplayServer::get_singleton()->window_set_position(p_position, window_id); +} +Point2i Window::get_position() const { + if (window_id != DisplayServer::INVALID_WINDOW_ID) { + position = DisplayServer::get_singleton()->window_get_position(window_id); + } + return position; +} + +void Window::set_size(const Size2i &p_size) { + size = p_size; + if (window_id == DisplayServer::INVALID_WINDOW_ID) { + DisplayServer::get_singleton()->window_set_size(p_size, window_id); + } + _update_size(); +} +Size2i Window::get_size() const { + if (window_id != DisplayServer::INVALID_WINDOW_ID) { + size = DisplayServer::get_singleton()->window_get_size(window_id); + } + return size; +} + +Size2i Window::get_real_size() const { + + if (window_id != DisplayServer::INVALID_WINDOW_ID) { + return DisplayServer::get_singleton()->window_get_real_size(window_id); + } + return size; +} + +void Window::set_max_size(const Size2i &p_max_size) { + max_size = p_max_size; + if (window_id == DisplayServer::INVALID_WINDOW_ID) + return; + DisplayServer::get_singleton()->window_set_max_size(p_max_size, window_id); +} +Size2i Window::get_max_size() const { + if (window_id != DisplayServer::INVALID_WINDOW_ID) { + max_size = DisplayServer::get_singleton()->window_get_max_size(window_id); + } + return max_size; +} + +void Window::set_min_size(const Size2i &p_min_size) { + min_size = p_min_size; + if (window_id == DisplayServer::INVALID_WINDOW_ID) + return; + DisplayServer::get_singleton()->window_set_min_size(p_min_size, window_id); +} +Size2i Window::get_min_size() const { + if (window_id != DisplayServer::INVALID_WINDOW_ID) { + min_size = DisplayServer::get_singleton()->window_get_min_size(window_id); + } + return min_size; +} + +void Window::set_mode(Mode p_mode) { + + mode = p_mode; + if (window_id == DisplayServer::INVALID_WINDOW_ID) + return; + DisplayServer::get_singleton()->window_set_mode(DisplayServer::WindowMode(p_mode), window_id); +} + +Window::Mode Window::get_mode() const { + + if (window_id != DisplayServer::INVALID_WINDOW_ID) { + mode = (Mode)DisplayServer::get_singleton()->window_get_mode(window_id); + } + return mode; +} + +void Window::set_flag(Flags p_flag, bool p_enabled) { + ERR_FAIL_INDEX(p_flag, FLAG_MAX); + flags[p_flag] = p_enabled; + if (window_id == DisplayServer::INVALID_WINDOW_ID) + return; + DisplayServer::get_singleton()->window_set_flag(DisplayServer::WindowFlags(p_flag), p_enabled, window_id); +} + +bool Window::get_flag(Flags p_flag) const { + ERR_FAIL_INDEX_V(p_flag, FLAG_MAX, false); + if (window_id != DisplayServer::INVALID_WINDOW_ID) { + flags[p_flag] = DisplayServer::get_singleton()->window_get_flag(DisplayServer::WindowFlags(p_flag), window_id); + } + return flags[p_flag]; +} + +bool Window::is_maximize_allowed() const { + if (window_id != DisplayServer::INVALID_WINDOW_ID) { + return DisplayServer::get_singleton()->window_is_maximize_allowed(window_id); + } + return true; +} + +void Window::request_attention() { + if (window_id != DisplayServer::INVALID_WINDOW_ID) { + DisplayServer::get_singleton()->window_request_attention(window_id); + } +} +void Window::move_to_foreground() { + if (window_id != DisplayServer::INVALID_WINDOW_ID) { + DisplayServer::get_singleton()->window_move_to_foreground(window_id); + } +} + +bool Window::can_draw() const { + if (!is_inside_tree()) { + return false; + } + if (window_id != DisplayServer::INVALID_WINDOW_ID) { + return DisplayServer::get_singleton()->window_can_draw(window_id); + } + + return true; +} + +void Window::set_ime_active(bool p_active) { + if (window_id != DisplayServer::INVALID_WINDOW_ID) { + DisplayServer::get_singleton()->window_set_ime_active(p_active, window_id); + } +} +void Window::set_ime_position(const Point2i &p_pos) { + if (window_id != DisplayServer::INVALID_WINDOW_ID) { + DisplayServer::get_singleton()->window_set_ime_position(p_pos, window_id); + } +} + +bool Window::is_embedded() const { + ERR_FAIL_COND_V(!is_inside_tree(), false); + if (get_parent_viewport()) { + return get_parent_viewport()->is_embedding_subwindows(); + } else { + return false; + } +} + +void Window::_make_window() { + ERR_FAIL_COND(window_id != DisplayServer::INVALID_WINDOW_ID); + + uint32_t f = 0; + for (int i = 0; i < FLAG_MAX; i++) { + if (flags[i]) { + f |= (1 << i); + } + } + window_id = DisplayServer::get_singleton()->create_sub_window(DisplayServer::WindowMode(mode), f, Rect2i(position, size)); + ERR_FAIL_COND(window_id == DisplayServer::INVALID_WINDOW_ID); + DisplayServer::get_singleton()->window_set_current_screen(current_screen, window_id); + DisplayServer::get_singleton()->window_set_max_size(max_size, window_id); + DisplayServer::get_singleton()->window_set_min_size(min_size, window_id); + DisplayServer::get_singleton()->window_set_title(title, window_id); + + _update_size(); +} +void Window::_update_from_window() { + + ERR_FAIL_COND(window_id == DisplayServer::INVALID_WINDOW_ID); + mode = (Mode)DisplayServer::get_singleton()->window_get_mode(window_id); + for (int i = 0; i < FLAG_MAX; i++) { + flags[i] = DisplayServer::get_singleton()->window_get_flag(DisplayServer::WindowFlags(i), window_id); + } + position = DisplayServer::get_singleton()->window_get_position(window_id); + size = DisplayServer::get_singleton()->window_get_size(window_id); + max_size = DisplayServer::get_singleton()->window_get_max_size(window_id); + min_size = DisplayServer::get_singleton()->window_get_min_size(window_id); +} + +void Window::_clear_window() { + ERR_FAIL_COND(window_id == DisplayServer::INVALID_WINDOW_ID); + _update_from_window(); + DisplayServer::get_singleton()->delete_sub_window(window_id); + window_id = DisplayServer::INVALID_WINDOW_ID; + _update_size(); +} + +void Window::_resize_callback(const Size2i &p_callback) { + size = p_callback; + _update_size(); +} + +void Window::set_visible(bool p_visible) { + if (visible == p_visible) { + return; + } + + if (!is_inside_tree()) { + return; + } + + bool subwindow = get_parent() && get_parent()->get_viewport()->is_embedding_subwindows(); + + visible = p_visible; + + if (!subwindow) { + if (p_visible && window_id != DisplayServer::INVALID_WINDOW_ID) { + _clear_window(); + } + if (!p_visible && window_id == DisplayServer::INVALID_WINDOW_ID) { + _make_window(); + } + } else { + _update_size(); + } +} +bool Window::is_visible() const { + return visible; +} + +void Window::_update_size() { + + Size2i final_size; + Size2i final_size_override; + Rect2i attach_to_screen_rect(Point2i(), size); + Transform2D stretch_transform; + float font_oversampling = 1.0; + + if (content_scale_mode == CONTENT_SCALE_MODE_DISABLED || content_scale_size.x == 0 || content_scale_size.y == 0) { + + stretch_transform = Transform2D(); + final_size = size; + + } else { + + //actual screen video mode + Size2 video_mode = size; + Size2 desired_res = content_scale_size; + + Size2 viewport_size; + Size2 screen_size; + + float viewport_aspect = desired_res.aspect(); + float video_mode_aspect = video_mode.aspect(); + + if (content_scale_aspect == CONTENT_SCALE_ASPECT_IGNORE || Math::is_equal_approx(viewport_aspect, video_mode_aspect)) { + //same aspect or ignore aspect + viewport_size = desired_res; + screen_size = video_mode; + } else if (viewport_aspect < video_mode_aspect) { + // screen ratio is smaller vertically + + if (content_scale_aspect == CONTENT_SCALE_ASPECT_KEEP_HEIGHT || content_scale_aspect == CONTENT_SCALE_ASPECT_EXPAND) { + + //will stretch horizontally + viewport_size.x = desired_res.y * video_mode_aspect; + viewport_size.y = desired_res.y; + screen_size = video_mode; + + } else { + //will need black bars + viewport_size = desired_res; + screen_size.x = video_mode.y * viewport_aspect; + screen_size.y = video_mode.y; + } + } else { + //screen ratio is smaller horizontally + if (content_scale_aspect == CONTENT_SCALE_ASPECT_KEEP_WIDTH || content_scale_aspect == CONTENT_SCALE_ASPECT_EXPAND) { + + //will stretch horizontally + viewport_size.x = desired_res.x; + viewport_size.y = desired_res.x / video_mode_aspect; + screen_size = video_mode; + + } else { + //will need black bars + viewport_size = desired_res; + screen_size.x = video_mode.x; + screen_size.y = video_mode.x / viewport_aspect; + } + } + + screen_size = screen_size.floor(); + viewport_size = viewport_size.floor(); + + Size2 margin; + Size2 offset; + //black bars and margin + if (content_scale_aspect != CONTENT_SCALE_ASPECT_EXPAND && screen_size.x < video_mode.x) { + margin.x = Math::round((video_mode.x - screen_size.x) / 2.0); + //VisualServer::get_singleton()->black_bars_set_margins(margin.x, 0, margin.x, 0); + offset.x = Math::round(margin.x * viewport_size.y / screen_size.y); + } else if (content_scale_aspect != CONTENT_SCALE_ASPECT_EXPAND && screen_size.y < video_mode.y) { + margin.y = Math::round((video_mode.y - screen_size.y) / 2.0); + //VisualServer::get_singleton()->black_bars_set_margins(0, margin.y, 0, margin.y); + offset.y = Math::round(margin.y * viewport_size.x / screen_size.x); + } else { + //VisualServer::get_singleton()->black_bars_set_margins(0, 0, 0, 0); + } + + switch (content_scale_mode) { + case CONTENT_SCALE_MODE_DISABLED: { + // Already handled above + //_update_font_oversampling(1.0); + } break; + case CONTENT_SCALE_MODE_OBJECTS: { + + final_size = screen_size; + final_size_override = viewport_size; + attach_to_screen_rect = Rect2(margin, screen_size); + font_oversampling = screen_size.x / viewport_size.x; + } break; + case CONTENT_SCALE_MODE_PIXELS: { + + final_size = viewport_size; + attach_to_screen_rect = Rect2(margin, screen_size); + + } break; + } + + Size2 scale = size / (Vector2(final_size) + margin * 2); + stretch_transform.scale(scale); + stretch_transform.elements[2] = margin * scale; + } + + bool allocate = is_inside_tree() && visible && (window_id != DisplayServer::INVALID_WINDOW_ID || (get_parent() && get_parent()->get_viewport()->is_embedding_subwindows())); + + _set_size(final_size, final_size_override, attach_to_screen_rect, stretch_transform, allocate); + + if (window_id != DisplayServer::INVALID_WINDOW_ID) { + VisualServer::get_singleton()->viewport_attach_to_screen(get_viewport_rid(), attach_to_screen_rect, window_id); + } else { + VisualServer::get_singleton()->viewport_attach_to_screen(get_viewport_rid(), Rect2i(), DisplayServer::INVALID_WINDOW_ID); + } + + if (window_id == DisplayServer::MAIN_WINDOW_ID) { + + if (!use_font_oversampling) { + font_oversampling = 1.0; + } + if (DynamicFontAtSize::font_oversampling != font_oversampling) { + + DynamicFontAtSize::font_oversampling = font_oversampling; + DynamicFont::update_oversampling(); + } + } +} + +void Window::_notification(int p_what) { + if (p_what == NOTIFICATION_ENTER_TREE) { + if (is_embedded()) { + //create as embedded + _update_size(); + } else { + if (get_parent() == nullptr) { + //it's the root window! + window_id = DisplayServer::MAIN_WINDOW_ID; + _update_from_window(); + _update_size(); + DisplayServer::get_singleton()->window_set_resize_callback(callable_mp(this, &Window::_resize_callback), window_id); + } else { + //create + _make_window(); + DisplayServer::get_singleton()->window_set_resize_callback(callable_mp(this, &Window::_resize_callback), window_id); + } + } + } + + if (p_what == NOTIFICATION_EXIT_TREE) { + if (!is_embedded() && window_id != DisplayServer::INVALID_WINDOW_ID) { + + if (window_id == DisplayServer::MAIN_WINDOW_ID) { + + DisplayServer::get_singleton()->window_set_resize_callback(Callable(), window_id); + } else { + _clear_window(); + } + } else { + _update_size(); + } + } +} + +void Window::set_content_scale_size(const Size2i &p_size) { + ERR_FAIL_COND(p_size.x < 0); + ERR_FAIL_COND(p_size.y < 0); + content_scale_size = p_size; + _update_size(); +} + +Size2i Window::get_content_scale_size() const { + return content_scale_size; +} + +void Window::set_content_scale_mode(const ContentScaleMode &p_mode) { + content_scale_mode = p_mode; + _update_size(); +} +Window::ContentScaleMode Window::get_content_scale_mode() const { + return content_scale_mode; +} + +void Window::set_content_scale_aspect(const ContentScaleAspect &p_aspect) { + content_scale_aspect = p_aspect; + _update_size(); +} +Window::ContentScaleAspect Window::get_content_scale_aspect() const { + return content_scale_aspect; +} + +void Window::set_use_font_oversampling(bool p_oversampling) { + if (is_inside_tree() && window_id != DisplayServer::MAIN_WINDOW_ID) { + ERR_FAIL_MSG("Only the root window can set and use font oversampling."); + } + use_font_oversampling = p_oversampling; + _update_size(); +} +bool Window::is_using_font_oversampling() const { + return use_font_oversampling; +} + +DisplayServer::WindowID Window::get_window_id() const { + return window_id; +} + +void Window::_bind_methods() { +} + +Window::Window() { + for (int i = 0; i < FLAG_MAX; i++) { + flags[i] = false; + } + content_scale_mode = CONTENT_SCALE_MODE_DISABLED; + content_scale_aspect = CONTENT_SCALE_ASPECT_IGNORE; +} +Window::~Window() { +} diff --git a/scene/main/window.h b/scene/main/window.h new file mode 100644 index 0000000000..2fd6d993a9 --- /dev/null +++ b/scene/main/window.h @@ -0,0 +1,169 @@ +/*************************************************************************/ +/* window.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef WINDOW_H +#define WINDOW_H + +#include "scene/main/viewport.h" +#include "servers/display_server.h" + +class Window : public Viewport { + GDCLASS(Window, Viewport) +public: + enum Mode { + MODE_WINDOWED = DisplayServer::WINDOW_MODE_WINDOWED, + MODE_MINIMIZED = DisplayServer::WINDOW_MODE_MINIMIZED, + MODE_MAXIMIZED = DisplayServer::WINDOW_MODE_MAXIMIZED, + MODE_FULLSCREEN = DisplayServer::WINDOW_MODE_FULLSCREEN + }; + + enum Flags { + FLAG_RESIZE_DISABLED = DisplayServer::WINDOW_FLAG_RESIZE_DISABLED, + FLAG_BORDERLESS = DisplayServer::WINDOW_FLAG_BORDERLESS, + FLAG_ALWAYS_ON_TOP = DisplayServer::WINDOW_FLAG_ALWAYS_ON_TOP, + FLAG_TRANSPARENT = DisplayServer::WINDOW_FLAG_TRANSPARENT, + FLAG_MAX = DisplayServer::WINDOW_FLAG_MAX, + }; + + enum ContentScaleMode { + CONTENT_SCALE_MODE_DISABLED, + CONTENT_SCALE_MODE_OBJECTS, + CONTENT_SCALE_MODE_PIXELS, + + }; + + enum ContentScaleAspect { + CONTENT_SCALE_ASPECT_IGNORE, + CONTENT_SCALE_ASPECT_KEEP, + CONTENT_SCALE_ASPECT_KEEP_WIDTH, + CONTENT_SCALE_ASPECT_KEEP_HEIGHT, + CONTENT_SCALE_ASPECT_EXPAND, + + }; + enum { + DEFAULT_WINDOW_SIZE = 100 + }; + +private: + DisplayServer::WindowID window_id = DisplayServer::INVALID_WINDOW_ID; + + String title; + mutable int current_screen = 0; + mutable Vector2i position; + mutable Size2i size = Size2i(DEFAULT_WINDOW_SIZE, DEFAULT_WINDOW_SIZE); + mutable Size2i min_size; + mutable Size2i max_size; + mutable Mode mode = MODE_WINDOWED; + mutable bool flags[FLAG_MAX]; + bool visible = true; + + bool use_font_oversampling = false; + + Size2i content_scale_size; + ContentScaleMode content_scale_mode; + ContentScaleAspect content_scale_aspect; + + void _make_window(); + void _clear_window(); + void _update_from_window(); + + void _resize_callback(const Size2i &p_callback); + + void _update_size(); + + virtual DisplayServer::WindowID get_window_id() const; + +protected: + static void _bind_methods(); + void _notification(int p_what); + +public: + void set_title(const String &p_title); + String get_title() const; + + void set_current_screen(int p_screen); + int get_current_screen() const; + + void set_position(const Point2i &p_position); + Point2i get_position() const; + + void set_size(const Size2i &p_size); + Size2i get_size() const; + + Size2i get_real_size() const; + + void set_max_size(const Size2i &p_max_size); + Size2i get_max_size() const; + + void set_min_size(const Size2i &p_min_size); + Size2i get_min_size() const; + + void set_mode(Mode p_mode); + Mode get_mode() const; + + void set_flag(Flags p_flag, bool p_enabled); + bool get_flag(Flags p_flag) const; + + bool is_maximize_allowed() const; + + void request_attention(); + void move_to_foreground(); + + void set_visible(bool p_visible); + bool is_visible() const; + + bool can_draw() const; + + void set_ime_active(bool p_active); + void set_ime_position(const Point2i &p_pos); + + bool is_embedded() const; + + void set_content_scale_size(const Size2i &p_size); + Size2i get_content_scale_size() const; + + void set_content_scale_mode(const ContentScaleMode &p_mode); + ContentScaleMode get_content_scale_mode() const; + + void set_content_scale_aspect(const ContentScaleAspect &p_aspect); + ContentScaleAspect get_content_scale_aspect() const; + + void set_use_font_oversampling(bool p_oversampling); + bool is_using_font_oversampling() const; + Window(); + ~Window(); +}; + +VARIANT_ENUM_CAST(Window::Window::Mode); +VARIANT_ENUM_CAST(Window::Window::Flags); +VARIANT_ENUM_CAST(Window::ContentScaleMode); +VARIANT_ENUM_CAST(Window::ContentScaleAspect); + +#endif // WINDOW_H diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index 5b33277fa0..8c4bff16a0 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -128,6 +128,7 @@ #include "scene/main/scene_tree.h" #include "scene/main/timer.h" #include "scene/main/viewport.h" +#include "scene/main/window.h" #include "scene/resources/audio_stream_sample.h" #include "scene/resources/bit_map.h" #include "scene/resources/box_shape.h" @@ -267,13 +268,14 @@ void register_scene_types() { ClassDB::register_class<Node>(); ClassDB::register_virtual_class<InstancePlaceholder>(); - ClassDB::register_class<Viewport>(); + ClassDB::register_virtual_class<Viewport>(); ClassDB::register_class<ViewportTexture>(); ClassDB::register_class<HTTPRequest>(); ClassDB::register_class<Timer>(); ClassDB::register_class<CanvasLayer>(); ClassDB::register_class<CanvasModulate>(); ClassDB::register_class<ResourcePreloader>(); + ClassDB::register_class<Window>(); /* REGISTER GUI */ ClassDB::register_class<ButtonGroup>(); diff --git a/scene/resources/world_2d.cpp b/scene/resources/world_2d.cpp index 6bdc4cf6f0..75bdeeac07 100644 --- a/scene/resources/world_2d.cpp +++ b/scene/resources/world_2d.cpp @@ -33,7 +33,7 @@ #include "core/project_settings.h" #include "scene/2d/camera_2d.h" #include "scene/2d/visibility_notifier_2d.h" -#include "scene/main/viewport.h" +#include "scene/main/window.h" #include "servers/physics_2d_server.h" #include "servers/visual_server.h" diff --git a/servers/arvr/arvr_interface.h b/servers/arvr/arvr_interface.h index f33ddb2411..861061cbf5 100644 --- a/servers/arvr/arvr_interface.h +++ b/servers/arvr/arvr_interface.h @@ -33,7 +33,7 @@ #include "core/math/camera_matrix.h" #include "core/os/thread_safe.h" -#include "scene/main/viewport.h" +#include "scene/main/window.h" #include "servers/arvr_server.h" /** diff --git a/servers/display_server.cpp b/servers/display_server.cpp index b1ace561df..598d1734ad 100644 --- a/servers/display_server.cpp +++ b/servers/display_server.cpp @@ -93,7 +93,7 @@ bool DisplayServer::screen_is_kept_on() const { return false; } -DisplayServer::WindowID DisplayServer::create_sub_window(WindowMode p_mode, uint32_t p_flags, const Rect2i) { +DisplayServer::WindowID DisplayServer::create_sub_window(WindowMode p_mode, uint32_t p_flags, const Rect2i &) { ERR_FAIL_V_MSG(INVALID_WINDOW_ID, "Sub-windows not supported by this display server."); } void DisplayServer::delete_sub_window(WindowID p_id) { @@ -274,6 +274,7 @@ void DisplayServer::_bind_methods() { ClassDB::bind_method(D_METHOD("window_get_size", "window_id"), &DisplayServer::window_get_size, DEFVAL(MAIN_WINDOW_ID)); ClassDB::bind_method(D_METHOD("window_set_size", "size", "window_id"), &DisplayServer::window_set_size, DEFVAL(MAIN_WINDOW_ID)); + ClassDB::bind_method(D_METHOD("window_set_resize_callback", "callback", "window_id"), &DisplayServer::window_set_resize_callback, DEFVAL(MAIN_WINDOW_ID)); ClassDB::bind_method(D_METHOD("window_get_max_size", "window_id"), &DisplayServer::window_get_max_size, DEFVAL(MAIN_WINDOW_ID)); ClassDB::bind_method(D_METHOD("window_set_max_size", "max_size", "window_id"), &DisplayServer::window_set_max_size, DEFVAL(MAIN_WINDOW_ID)); diff --git a/servers/display_server.h b/servers/display_server.h index 94848153ce..8dc2497762 100644 --- a/servers/display_server.h +++ b/servers/display_server.h @@ -31,6 +31,7 @@ #ifndef DISPLAY_SERVER_H #define DISPLAY_SERVER_H +#include "core/callable.h" #include "core/input/input.h" #include "core/os/os.h" #include "core/resource.h" @@ -177,9 +178,10 @@ public: WINDOW_FLAG_TRANSPARENT_BIT = (1 << WINDOW_FLAG_TRANSPARENT) }; - virtual WindowID create_sub_window(WindowMode p_mode, uint32_t p_flags, const Rect2i = Rect2i()); + virtual WindowID create_sub_window(WindowMode p_mode, uint32_t p_flags, const Rect2i & = Rect2i()); virtual void delete_sub_window(WindowID p_id); + virtual void window_set_resize_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID) = 0; virtual void window_set_title(const String &p_title, WindowID p_window = MAIN_WINDOW_ID) = 0; virtual int window_get_current_screen(WindowID p_window = MAIN_WINDOW_ID) const = 0; diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h index 84eda2d80c..d5d32c8d47 100644 --- a/servers/visual/rasterizer.h +++ b/servers/visual/rasterizer.h @@ -1294,7 +1294,7 @@ public: }; virtual void prepare_for_blitting_render_targets() = 0; - virtual void blit_render_targets_to_screen(int p_screen, const BlitToScreen *p_render_targets, int p_amount) = 0; + virtual void blit_render_targets_to_screen(DisplayServer::WindowID p_screen, const BlitToScreen *p_render_targets, int p_amount) = 0; virtual void end_frame(bool p_swap_buffers) = 0; virtual void finalize() = 0; diff --git a/servers/visual/rasterizer_rd/rasterizer_rd.cpp b/servers/visual/rasterizer_rd/rasterizer_rd.cpp index 206320376b..9c54f0caae 100644 --- a/servers/visual/rasterizer_rd/rasterizer_rd.cpp +++ b/servers/visual/rasterizer_rd/rasterizer_rd.cpp @@ -34,7 +34,7 @@ void RasterizerRD::prepare_for_blitting_render_targets() { RD::get_singleton()->prepare_screen_for_drawing(); } -void RasterizerRD::blit_render_targets_to_screen(int p_screen, const BlitToScreen *p_render_targets, int p_amount) { +void RasterizerRD::blit_render_targets_to_screen(DisplayServer::WindowID p_screen, const BlitToScreen *p_render_targets, int p_amount) { RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin_for_screen(p_screen); diff --git a/servers/visual/rasterizer_rd/rasterizer_rd.h b/servers/visual/rasterizer_rd/rasterizer_rd.h index d14e9fb36e..bbcf9bfefe 100644 --- a/servers/visual/rasterizer_rd/rasterizer_rd.h +++ b/servers/visual/rasterizer_rd/rasterizer_rd.h @@ -66,7 +66,7 @@ public: void initialize(); void begin_frame(double frame_step); void prepare_for_blitting_render_targets(); - void blit_render_targets_to_screen(int p_screen, const BlitToScreen *p_render_targets, int p_amount); + void blit_render_targets_to_screen(DisplayServer::WindowID p_screen, const BlitToScreen *p_render_targets, int p_amount); void end_frame(bool p_swap_buffers); void finalize(); diff --git a/servers/visual/rendering_device.h b/servers/visual/rendering_device.h index ed55afd961..4705bcaa75 100644 --- a/servers/visual/rendering_device.h +++ b/servers/visual/rendering_device.h @@ -32,6 +32,7 @@ #define RENDERING_DEVICE_H #include "core/object.h" +#include "servers/display_server.h" class RenderingDevice : public Object { GDCLASS(RenderingDevice, Object) @@ -896,8 +897,8 @@ public: /**** SCREEN ****/ /****************/ - virtual int screen_get_width(int p_screen = 0) const = 0; - virtual int screen_get_height(int p_screen = 0) const = 0; + virtual int screen_get_width(DisplayServer::WindowID p_screen = 0) const = 0; + virtual int screen_get_height(DisplayServer::WindowID p_screen = 0) const = 0; virtual FramebufferFormatID screen_get_framebuffer_format() const = 0; /********************/ @@ -920,7 +921,7 @@ public: typedef int64_t DrawListID; - virtual DrawListID draw_list_begin_for_screen(int p_screen = 0, const Color &p_clear_color = Color()) = 0; + virtual DrawListID draw_list_begin_for_screen(DisplayServer::WindowID p_screen = 0, const Color &p_clear_color = Color()) = 0; virtual DrawListID draw_list_begin(RID p_framebuffer, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector<Color> &p_clear_color_values = Vector<Color>(), float p_clear_depth = 1.0, uint32_t p_clear_stencil = 0, const Rect2 &p_region = Rect2()) = 0; virtual Error draw_list_begin_split(RID p_framebuffer, uint32_t p_splits, DrawListID *r_split_ids, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector<Color> &p_clear_color_values = Vector<Color>(), float p_clear_depth = 1.0, uint32_t p_clear_stencil = 0, const Rect2 &p_region = Rect2()) = 0; diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h index b6afbbff93..1a40fc96a2 100644 --- a/servers/visual/visual_server_raster.h +++ b/servers/visual/visual_server_raster.h @@ -466,7 +466,6 @@ public: BIND3(viewport_attach_to_screen, RID, const Rect2 &, int) BIND2(viewport_set_render_direct_to_screen, RID, bool) - BIND1(viewport_detach, RID) BIND2(viewport_set_update_mode, RID, ViewportUpdateMode) BIND2(viewport_set_vflip, RID, bool) diff --git a/servers/visual/visual_server_viewport.cpp b/servers/visual/visual_server_viewport.cpp index 43262042cc..aca96d6552 100644 --- a/servers/visual/visual_server_viewport.cpp +++ b/servers/visual/visual_server_viewport.cpp @@ -312,7 +312,7 @@ void VisualServerViewport::draw_viewports() { //sort viewports active_viewports.sort_custom<ViewportSort>(); - Map<int, Vector<Rasterizer::BlitToScreen>> blit_to_screen_list; + Map<DisplayServer::WindowID, Vector<Rasterizer::BlitToScreen>> blit_to_screen_list; //draw viewports RENDER_TIMESTAMP(">Render Viewports"); @@ -389,11 +389,16 @@ void VisualServerViewport::draw_viewports() { vp->render_info[VS::VIEWPORT_RENDER_INFO_SURFACE_CHANGES_IN_FRAME] = VSG::storage->get_captured_render_info(VS::INFO_SURFACE_CHANGES_IN_FRAME); vp->render_info[VS::VIEWPORT_RENDER_INFO_DRAW_CALLS_IN_FRAME] = VSG::storage->get_captured_render_info(VS::INFO_DRAW_CALLS_IN_FRAME); - if (vp->viewport_to_screen_rect != Rect2() && (!vp->viewport_render_direct_to_screen || !VSG::rasterizer->is_low_end())) { + if (vp->viewport_to_screen != DisplayServer::INVALID_WINDOW_ID && (!vp->viewport_render_direct_to_screen || !VSG::rasterizer->is_low_end())) { //copy to screen if set as such Rasterizer::BlitToScreen blit; blit.render_target = vp->render_target; - blit.rect = vp->viewport_to_screen_rect; + if (vp->viewport_to_screen_rect != Rect2()) { + blit.rect = vp->viewport_to_screen_rect; + } else { + blit.rect.position = Vector2(); + blit.rect.size = vp->size; + } if (!blit_to_screen_list.has(vp->viewport_to_screen)) { blit_to_screen_list[vp->viewport_to_screen] = Vector<Rasterizer::BlitToScreen>(); @@ -450,13 +455,15 @@ void VisualServerViewport::viewport_set_size(RID p_viewport, int p_width, int p_ Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); - // if (viewport->size.width == p_width && viewport->size.height == p_height) { - // return; //nothing to do - // } viewport->size = Size2(p_width, p_height); VSG::storage->render_target_set_size(viewport->render_target, p_width, p_height); if (viewport->render_buffers.is_valid()) { - VSG::scene_render->render_buffers_configure(viewport->render_buffers, viewport->render_target, viewport->size.width, viewport->size.height, viewport->msaa); + if (p_width == 0 || p_height == 0) { + VSG::scene_render->free(viewport->render_buffers); + viewport->render_buffers = RID(); + } else { + VSG::scene_render->render_buffers_configure(viewport->render_buffers, viewport->render_target, viewport->size.width, viewport->size.height, viewport->msaa); + } } } @@ -489,21 +496,34 @@ void VisualServerViewport::viewport_set_clear_mode(RID p_viewport, VS::ViewportC viewport->clear_mode = p_clear_mode; } -void VisualServerViewport::viewport_attach_to_screen(RID p_viewport, const Rect2 &p_rect, int p_screen) { +void VisualServerViewport::viewport_attach_to_screen(RID p_viewport, const Rect2 &p_rect, DisplayServer::WindowID p_screen) { Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); - // If using GLES2 we can optimize this operation by rendering directly to system_fbo - // instead of rendering to fbo and copying to system_fbo after - if (VSG::rasterizer->is_low_end() && viewport->viewport_render_direct_to_screen) { + if (p_screen != DisplayServer::INVALID_WINDOW_ID) { + // If using GLES2 we can optimize this operation by rendering directly to system_fbo + // instead of rendering to fbo and copying to system_fbo after + if (VSG::rasterizer->is_low_end() && viewport->viewport_render_direct_to_screen) { - VSG::storage->render_target_set_size(viewport->render_target, p_rect.size.x, p_rect.size.y); - VSG::storage->render_target_set_position(viewport->render_target, p_rect.position.x, p_rect.position.y); - } + VSG::storage->render_target_set_size(viewport->render_target, p_rect.size.x, p_rect.size.y); + VSG::storage->render_target_set_position(viewport->render_target, p_rect.position.x, p_rect.position.y); + } + + viewport->viewport_to_screen_rect = p_rect; + viewport->viewport_to_screen = p_screen; + } else { + + // if render_direct_to_screen was used, reset size and position + if (VSG::rasterizer->is_low_end() && viewport->viewport_render_direct_to_screen) { + + VSG::storage->render_target_set_position(viewport->render_target, 0, 0); + VSG::storage->render_target_set_size(viewport->render_target, viewport->size.x, viewport->size.y); + } - viewport->viewport_to_screen_rect = p_rect; - viewport->viewport_to_screen = p_screen; + viewport->viewport_to_screen_rect = Rect2(); + viewport->viewport_to_screen = DisplayServer::INVALID_WINDOW_ID; + } } void VisualServerViewport::viewport_set_render_direct_to_screen(RID p_viewport, bool p_enable) { @@ -531,22 +551,6 @@ void VisualServerViewport::viewport_set_render_direct_to_screen(RID p_viewport, } } -void VisualServerViewport::viewport_detach(RID p_viewport) { - - Viewport *viewport = viewport_owner.getornull(p_viewport); - ERR_FAIL_COND(!viewport); - - // if render_direct_to_screen was used, reset size and position - if (VSG::rasterizer->is_low_end() && viewport->viewport_render_direct_to_screen) { - - VSG::storage->render_target_set_position(viewport->render_target, 0, 0); - VSG::storage->render_target_set_size(viewport->render_target, viewport->size.x, viewport->size.y); - } - - viewport->viewport_to_screen_rect = Rect2(); - viewport->viewport_to_screen = 0; -} - void VisualServerViewport::viewport_set_update_mode(RID p_viewport, VS::ViewportUpdateMode p_mode) { Viewport *viewport = viewport_owner.getornull(p_viewport); diff --git a/servers/visual/visual_server_viewport.h b/servers/visual/visual_server_viewport.h index 30b53f3935..38983d5e8a 100644 --- a/servers/visual/visual_server_viewport.h +++ b/servers/visual/visual_server_viewport.h @@ -60,7 +60,7 @@ public: VS::ViewportMSAA msaa; - int viewport_to_screen; + DisplayServer::WindowID viewport_to_screen; Rect2 viewport_to_screen_rect; bool viewport_render_direct_to_screen; @@ -117,7 +117,7 @@ public: clear_mode = VS::VIEWPORT_CLEAR_ALWAYS; transparent_bg = false; disable_environment = false; - viewport_to_screen = 0; + viewport_to_screen = DisplayServer::INVALID_WINDOW_ID; shadow_atlas_size = 0; keep_3d_linear = false; debug_draw = VS::VIEWPORT_DEBUG_DRAW_DISABLED; @@ -158,9 +158,8 @@ public: void viewport_set_size(RID p_viewport, int p_width, int p_height); - void viewport_attach_to_screen(RID p_viewport, const Rect2 &p_rect = Rect2(), int p_screen = 0); + void viewport_attach_to_screen(RID p_viewport, const Rect2 &p_rect = Rect2(), DisplayServer::WindowID p_screen = DisplayServer::MAIN_WINDOW_ID); void viewport_set_render_direct_to_screen(RID p_viewport, bool p_enable); - void viewport_detach(RID p_viewport); void viewport_set_active(RID p_viewport, bool p_active); void viewport_set_parent_viewport(RID p_viewport, RID p_parent_viewport); diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h index 0d4683e43d..e043ac5214 100644 --- a/servers/visual/visual_server_wrap_mt.h +++ b/servers/visual/visual_server_wrap_mt.h @@ -379,9 +379,8 @@ public: FUNC2(viewport_set_clear_mode, RID, ViewportClearMode) - FUNC3(viewport_attach_to_screen, RID, const Rect2 &, int) + FUNC3(viewport_attach_to_screen, RID, const Rect2 &, DisplayServer::WindowID) FUNC2(viewport_set_render_direct_to_screen, RID, bool) - FUNC1(viewport_detach, RID) FUNC2(viewport_set_update_mode, RID, ViewportUpdateMode) diff --git a/servers/visual_server.cpp b/servers/visual_server.cpp index b50ad89b1e..62c3704f5b 100644 --- a/servers/visual_server.cpp +++ b/servers/visual_server.cpp @@ -1769,9 +1769,9 @@ void VisualServer::_bind_methods() { ClassDB::bind_method(D_METHOD("viewport_set_size", "viewport", "width", "height"), &VisualServer::viewport_set_size); ClassDB::bind_method(D_METHOD("viewport_set_active", "viewport", "active"), &VisualServer::viewport_set_active); ClassDB::bind_method(D_METHOD("viewport_set_parent_viewport", "viewport", "parent_viewport"), &VisualServer::viewport_set_parent_viewport); - ClassDB::bind_method(D_METHOD("viewport_attach_to_screen", "viewport", "rect", "screen"), &VisualServer::viewport_attach_to_screen, DEFVAL(Rect2()), DEFVAL(0)); + ClassDB::bind_method(D_METHOD("viewport_attach_to_screen", "viewport", "rect", "screen"), &VisualServer::viewport_attach_to_screen, DEFVAL(Rect2()), DEFVAL(DisplayServer::MAIN_WINDOW_ID)); ClassDB::bind_method(D_METHOD("viewport_set_render_direct_to_screen", "viewport", "enabled"), &VisualServer::viewport_set_render_direct_to_screen); - ClassDB::bind_method(D_METHOD("viewport_detach", "viewport"), &VisualServer::viewport_detach); + ClassDB::bind_method(D_METHOD("viewport_set_update_mode", "viewport", "update_mode"), &VisualServer::viewport_set_update_mode); ClassDB::bind_method(D_METHOD("viewport_set_clear_mode", "viewport", "clear_mode"), &VisualServer::viewport_set_clear_mode); ClassDB::bind_method(D_METHOD("viewport_get_texture", "viewport"), &VisualServer::viewport_get_texture); diff --git a/servers/visual_server.h b/servers/visual_server.h index dfe5e7feed..d41c80dfa1 100644 --- a/servers/visual_server.h +++ b/servers/visual_server.h @@ -37,6 +37,7 @@ #include "core/object.h" #include "core/rid.h" #include "core/variant.h" +#include "servers/display_server.h" class VisualServer : public Object { @@ -584,9 +585,8 @@ public: virtual void viewport_set_active(RID p_viewport, bool p_active) = 0; virtual void viewport_set_parent_viewport(RID p_viewport, RID p_parent_viewport) = 0; - virtual void viewport_attach_to_screen(RID p_viewport, const Rect2 &p_rect = Rect2(), int p_screen = 0) = 0; + virtual void viewport_attach_to_screen(RID p_viewport, const Rect2 &p_rect = Rect2(), DisplayServer::WindowID p_screen = DisplayServer::MAIN_WINDOW_ID) = 0; virtual void viewport_set_render_direct_to_screen(RID p_viewport, bool p_enable) = 0; - virtual void viewport_detach(RID p_viewport) = 0; enum ViewportUpdateMode { VIEWPORT_UPDATE_DISABLED, |