From d389348260f3b3b56a18bb82de188ed14aa7c9a3 Mon Sep 17 00:00:00 2001 From: Wiktor Kocielski Date: Tue, 12 Sep 2023 21:38:26 +0300 Subject: [PATCH] Add View Layers button & Reset/Disable/Copy/Paste buttons to View Flags/Debug View & Camera RenderFlags/RenderView addition --- Source/Editor/Viewport/EditorViewport.cs | 120 +++++++++++++++++++++++ Source/Engine/Graphics/RenderView.cpp | 2 + Source/Engine/Graphics/RenderView.cs | 2 + Source/Engine/Level/Actors/Camera.cpp | 4 + Source/Engine/Level/Actors/Camera.h | 13 +++ 5 files changed, 141 insertions(+) diff --git a/Source/Editor/Viewport/EditorViewport.cs b/Source/Editor/Viewport/EditorViewport.cs index ad7e06ba5..f5ef17ecb 100644 --- a/Source/Editor/Viewport/EditorViewport.cs +++ b/Source/Editor/Viewport/EditorViewport.cs @@ -2,6 +2,7 @@ using System; using System.Linq; +using FlaxEditor.Content.Settings; using FlaxEditor.GUI.ContextMenu; using FlaxEditor.GUI.Input; using FlaxEditor.Options; @@ -9,6 +10,9 @@ using FlaxEditor.Viewport.Cameras; using FlaxEditor.Viewport.Widgets; using FlaxEngine; using FlaxEngine.GUI; +using FlaxEngine.Utilities; +using Newtonsoft.Json; +using JsonSerializer = FlaxEngine.Json.JsonSerializer; namespace FlaxEditor.Viewport { @@ -483,10 +487,89 @@ namespace FlaxEditor.Viewport } } + // View Layers + { + var viewLayers = ViewWidgetButtonMenu.AddChildMenu("View Layers").ContextMenu; + viewLayers.AddButton("Copy layers", () => Clipboard.Text = JsonSerializer.Serialize(Task.View.RenderLayersMask)); + viewLayers.AddButton("Paste layers", () => + { + object obj; + try + { + obj = JsonConvert.DeserializeObject(Clipboard.Text, typeof(LayersMask), JsonSerializer.Settings); + } + catch + { + obj = null; + } + if (obj != null && obj is LayersMask layer) + { + RenderView view = Task.View; + view.RenderLayersMask = layer; + Task.View = view; + } + }); + viewLayers.AddButton("Reset layers", () => + { + RenderView view = Task.View; + view.RenderLayersMask = LayersMask.Default; + Task.View = view; + }).Icon = Editor.Instance.Icons.Rotate32; + viewLayers.AddButton("Disable layers", () => + { + RenderView view = Task.View; + view.RenderLayersMask = new LayersMask(0); + Task.View = view; + }).Icon = Editor.Instance.Icons.Rotate32; + viewLayers.AddSeparator(); + var layers = LayersAndTagsSettings.GetCurrentLayers(); + if (layers != null && layers.Length > 0) + { + for (int i = 0; i < layers.Length; i++) + { + var layer = layers[i]; + var button = viewLayers.AddButton(layer); + button.CloseMenuOnClick = false; + button.Tag = 1 << i; + } + } + viewLayers.ButtonClicked += button => + { + if (button.Tag != null) + { + int layerIndex = (int)button.Tag; + LayersMask mask = new LayersMask(layerIndex); + RenderView view = Task.View; + view.RenderLayersMask ^= mask; + Task.View = view; + button.Icon = (Task.View.RenderLayersMask & mask) != 0 ? Style.Current.CheckBoxTick : SpriteHandle.Invalid; + } + }; + viewLayers.VisibleChanged += WidgetViewLayersShowHide; + } + // View Flags { var viewFlags = ViewWidgetButtonMenu.AddChildMenu("View Flags").ContextMenu; + viewFlags.AddButton("Copy flags", () => Clipboard.Text = JsonSerializer.Serialize(Task.ViewFlags)); + viewFlags.AddButton("Paste flags", () => + { + object obj; + try + { + obj = JsonConvert.DeserializeObject(Clipboard.Text, typeof(ViewFlags), JsonSerializer.Settings); + } + catch + { + obj = null; + } + if (obj != null && obj is ViewFlags flags) + { + Task.ViewFlags = flags; + } + }); viewFlags.AddButton("Reset flags", () => Task.ViewFlags = ViewFlags.DefaultEditor).Icon = Editor.Instance.Icons.Rotate32; + viewFlags.AddButton("Disable flags", () => Task.ViewFlags = ViewFlags.None).Icon = Editor.Instance.Icons.Rotate32; viewFlags.AddSeparator(); for (int i = 0; i < EditorViewportViewFlagsValues.Length; i++) { @@ -510,6 +593,24 @@ namespace FlaxEditor.Viewport // Debug View { var debugView = ViewWidgetButtonMenu.AddChildMenu("Debug View").ContextMenu; + debugView.AddButton("Copy view", () => Clipboard.Text = JsonSerializer.Serialize(Task.ViewMode)); + debugView.AddButton("Paste view", () => + { + object obj; + try + { + obj = JsonConvert.DeserializeObject(Clipboard.Text, typeof(ViewMode), JsonSerializer.Settings); + } + catch + { + obj = null; + } + if (obj != null && obj is ViewMode mode) + { + Task.ViewMode = mode; + } + }); + debugView.AddSeparator(); for (int i = 0; i < EditorViewportViewModeValues.Length; i++) { ref var v = ref EditorViewportViewModeValues[i]; @@ -1561,6 +1662,25 @@ namespace FlaxEditor.Viewport } } + private void WidgetViewLayersShowHide(Control cm) + { + if (cm.Visible == false) + return; + + var ccm = (ContextMenu)cm; + foreach (var e in ccm.Items) + { + if (e is ContextMenuButton b && b != null && b.Tag != null) + { + int layerIndex = (int)b.Tag; + LayersMask mask = new LayersMask(layerIndex); + b.Icon = (Task.View.RenderLayersMask & mask) != 0 + ? Style.Current.CheckBoxTick + : SpriteHandle.Invalid; + } + } + } + private float GetGamepadAxis(GamepadAxis axis) { var value = FlaxEngine.Input.GetGamepadAxis(InputGamepadIndex.All, axis); diff --git a/Source/Engine/Graphics/RenderView.cpp b/Source/Engine/Graphics/RenderView.cpp index 46766c34d..c84351bdc 100644 --- a/Source/Engine/Graphics/RenderView.cpp +++ b/Source/Engine/Graphics/RenderView.cpp @@ -192,6 +192,8 @@ void RenderView::CopyFrom(Camera* camera, Viewport* viewport) Frustum.GetInvMatrix(IVP); CullingFrustum = Frustum; RenderLayersMask = camera->RenderLayersMask; + Flags = camera->RenderFlags; + Mode = camera->RenderView; } void RenderView::GetWorldMatrix(const Transform& transform, Matrix& world) const diff --git a/Source/Engine/Graphics/RenderView.cs b/Source/Engine/Graphics/RenderView.cs index 091661514..0d35bd360 100644 --- a/Source/Engine/Graphics/RenderView.cs +++ b/Source/Engine/Graphics/RenderView.cs @@ -102,6 +102,8 @@ namespace FlaxEngine NonJitteredProjection = Projection; TemporalAAJitter = Float4.Zero; RenderLayersMask = camera.RenderLayersMask; + Flags = camera.RenderFlags; + Mode = camera.RenderView; UpdateCachedData(); } diff --git a/Source/Engine/Level/Actors/Camera.cpp b/Source/Engine/Level/Actors/Camera.cpp index f2625ca3b..2a5c44a7e 100644 --- a/Source/Engine/Level/Actors/Camera.cpp +++ b/Source/Engine/Level/Actors/Camera.cpp @@ -415,6 +415,8 @@ void Camera::Serialize(SerializeStream& stream, const void* otherObj) SERIALIZE_MEMBER(Far, _far); SERIALIZE_MEMBER(OrthoScale, _orthoScale); SERIALIZE(RenderLayersMask); + SERIALIZE(RenderFlags); + SERIALIZE(RenderView); } void Camera::Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) @@ -429,6 +431,8 @@ void Camera::Deserialize(DeserializeStream& stream, ISerializeModifier* modifier DESERIALIZE_MEMBER(Far, _far); DESERIALIZE_MEMBER(OrthoScale, _orthoScale); DESERIALIZE(RenderLayersMask); + DESERIALIZE(RenderFlags); + DESERIALIZE(RenderView); } void Camera::OnEnable() diff --git a/Source/Engine/Level/Actors/Camera.h b/Source/Engine/Level/Actors/Camera.h index 5a0bece33..21f13665f 100644 --- a/Source/Engine/Level/Actors/Camera.h +++ b/Source/Engine/Level/Actors/Camera.h @@ -7,6 +7,7 @@ #include "Engine/Core/Math/Viewport.h" #include "Engine/Core/Math/Ray.h" #include "Engine/Core/Types/LayersMask.h" +#include "Engine/Graphics/Enums.h" #include "Engine/Scripting/ScriptingObjectReference.h" #if USE_EDITOR #include "Engine/Content/AssetReference.h" @@ -134,6 +135,18 @@ public: API_FIELD(Attributes="EditorOrder(100), EditorDisplay(\"Camera\")") LayersMask RenderLayersMask; + /// + /// Frame rendering flags used to switch between graphics features for this camera. + /// + API_FIELD(Attributes = "EditorOrder(110), EditorDisplay(\"Camera\")") + ViewFlags RenderFlags = ViewFlags::DefaultGame; + + /// + /// Describes frame rendering modes for this camera. + /// + API_FIELD(Attributes = "EditorOrder(120), EditorDisplay(\"Camera\")") + ViewMode RenderView = ViewMode::Default; + public: /// /// Projects the point from 3D world-space to game window coordinates (in screen pixels for default viewport calculated from ).