From c2d330fc8f2b327c622899d160bf7a4077aa5252 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20L=C3=BCbe=C3=9F?= Date: Thu, 10 Jul 2025 14:59:37 +0200 Subject: [PATCH] Handle loading error and placeholder shaders --- .../resources/Shaders/PlaceholderError.fx | 28 ++++ .../resources/Shaders/PlaceholderError.fx.ass | 11 ++ .../resources/Shaders/PlaceholderLoading.fx | 28 ++++ .../Shaders/PlaceholderLoading.fx.ass | 11 ++ .../src/EditWindows/ContentBrowserWindow.bf | 121 +++++++++++------- GlitchyEditor/src/EditorContentManager.bf | 40 +++++- .../src/Content/Loaders/MaterialLoader.bf | 5 +- GlitchyEngine/src/Renderer/Renderer2D.bf | 4 +- 8 files changed, 192 insertions(+), 56 deletions(-) create mode 100644 GlitchyEditor/resources/Shaders/PlaceholderError.fx create mode 100644 GlitchyEditor/resources/Shaders/PlaceholderError.fx.ass create mode 100644 GlitchyEditor/resources/Shaders/PlaceholderLoading.fx create mode 100644 GlitchyEditor/resources/Shaders/PlaceholderLoading.fx.ass diff --git a/GlitchyEditor/resources/Shaders/PlaceholderError.fx b/GlitchyEditor/resources/Shaders/PlaceholderError.fx new file mode 100644 index 0000000..45a226f --- /dev/null +++ b/GlitchyEditor/resources/Shaders/PlaceholderError.fx @@ -0,0 +1,28 @@ +#include "GlitchyEngine.hlsl" + +struct VS_IN +{ + float3 Position : POSITION; +}; + +struct PS_IN +{ + float4 Position : SV_POSITION; +}; + +PS_IN VS(VS_IN input) +{ + PS_IN output; + + float4 worldPosition = mul(Transform, float4(input.Position, 1)); + output.Position = mul(ViewProjection, worldPosition); + + return output; +} + +float4 PS(PS_IN input) : SV_TARGET +{ + return float4(1, 0, 1, 1); +} + +#pragma Effect[VS = VS; PS = PS] diff --git a/GlitchyEditor/resources/Shaders/PlaceholderError.fx.ass b/GlitchyEditor/resources/Shaders/PlaceholderError.fx.ass new file mode 100644 index 0000000..36c6906 --- /dev/null +++ b/GlitchyEditor/resources/Shaders/PlaceholderError.fx.ass @@ -0,0 +1,11 @@ +{ + AssetLoader = null, + Config = null, + Importer = "ShaderImporter", + ImporterConfig = null, + Processor = null, + ProcessorConfig = null, + Exporter = null, + ExporterConfig = null, + AssetHandle = 652951988555027469 +} \ No newline at end of file diff --git a/GlitchyEditor/resources/Shaders/PlaceholderLoading.fx b/GlitchyEditor/resources/Shaders/PlaceholderLoading.fx new file mode 100644 index 0000000..d9235e6 --- /dev/null +++ b/GlitchyEditor/resources/Shaders/PlaceholderLoading.fx @@ -0,0 +1,28 @@ +#include "GlitchyEngine.hlsl" + +struct VS_IN +{ + float3 Position : POSITION; +}; + +struct PS_IN +{ + float4 Position : SV_POSITION; +}; + +PS_IN VS(VS_IN input) +{ + PS_IN output; + + float4 worldPosition = mul(Transform, float4(input.Position, 1)); + output.Position = mul(ViewProjection, worldPosition); + + return output; +} + +float4 PS(PS_IN input) : SV_TARGET +{ + return float4(0, 1, 1, 1); +} + +#pragma Effect[VS = VS; PS = PS] diff --git a/GlitchyEditor/resources/Shaders/PlaceholderLoading.fx.ass b/GlitchyEditor/resources/Shaders/PlaceholderLoading.fx.ass new file mode 100644 index 0000000..1069a05 --- /dev/null +++ b/GlitchyEditor/resources/Shaders/PlaceholderLoading.fx.ass @@ -0,0 +1,11 @@ +{ + AssetLoader = null, + Config = null, + Importer = "ShaderImporter", + ImporterConfig = null, + Processor = null, + ProcessorConfig = null, + Exporter = null, + ExporterConfig = null, + AssetHandle = 3052446500956620342 +} \ No newline at end of file diff --git a/GlitchyEditor/src/EditWindows/ContentBrowserWindow.bf b/GlitchyEditor/src/EditWindows/ContentBrowserWindow.bf index 1850e73..15c3b28 100644 --- a/GlitchyEditor/src/EditWindows/ContentBrowserWindow.bf +++ b/GlitchyEditor/src/EditWindows/ContentBrowserWindow.bf @@ -316,8 +316,7 @@ namespace GlitchyEditor.EditWindows { _manager.Update(); - // Show History - if (ImGui.Begin("Debug History")) + /*if (ImGui.Begin("Debug History")) { ImGui.CollapsingHeader("History"); for (String path in _directoryHistory.[Friend]_history) @@ -338,7 +337,7 @@ namespace GlitchyEditor.EditWindows } ImGui.End(); - } + }*/ // Make sure we are in an existing directory. if (!_manager.AssetHierarchy.FileExists(CurrentDirectory)) @@ -745,57 +744,81 @@ namespace GlitchyEditor.EditWindows private ImGui.RectangleSelectionData _rectangleSelection; + enum Modifiers + { + None, + Alt, + Ctrl, + Shift + } + + private void HandleShortcuts() + { + Modifiers modifiers = .None; + + Enum.SetFlagConditionally(ref modifiers, .Alt, Input.IsKeyPressed(.Alt)); + Enum.SetFlagConditionally(ref modifiers, .Ctrl, Input.IsKeyPressed(.Control)); + Enum.SetFlagConditionally(ref modifiers, .Shift, Input.IsKeyPressed(.Shift)); + + // TODO: Come up with a good hotkey system... + if (modifiers == .Alt) + { + if (Input.IsKeyPressing(.Up)) + { + NavigateUp(); + } + + if (Input.IsKeyPressing(.Left)) + { + NavigateBack(); + } + + if (Input .IsKeyPressing(.Right)) + { + NavigateForward(); + } + } + + if (Input.IsMouseButtonPressing(.XButton1)) + { + NavigateBack(); + } + + if (Input.IsMouseButtonPressing(.XButton2)) + { + NavigateForward(); + } + + if (modifiers == .Ctrl) + { + if (Input.IsKeyPressing(.C)) + { + CopySelectedFiles(cutFiles: false); + } + + if (Input.IsKeyPressing(.X)) + { + CopySelectedFiles(cutFiles: true); + } + + if (Input.IsKeyPressing(.V)) + { + PasteFiles(CurrentDirectory); + } + } + + if (modifiers == .Ctrl | .Shift) + { + + } + } + /// Renders the contents of _currentDirectory. Returns the node of the current directory, or null if the browser isn't in a directory. private void DrawCurrentDirectory(TreeNode currentDirectoryNode) { if (ImGui.IsWindowHovered()) { - // TODO: Come up with a good hotkey system... - if (Input.IsKeyPressed(.Alt)) - { - if (Input.IsKeyPressing(.Up)) - { - NavigateUp(); - } - - if (Input.IsKeyPressing(.Left)) - { - NavigateBack(); - } - - if (Input .IsKeyPressing(.Right)) - { - NavigateForward(); - } - } - - if (Input.IsMouseButtonPressing(.XButton1)) - { - NavigateBack(); - } - - if (Input.IsMouseButtonPressing(.XButton2)) - { - NavigateForward(); - } - - if (Input.IsKeyPressed(.Control)) - { - if (Input.IsKeyPressing(.C)) - { - CopySelectedFiles(cutFiles: false); - } - - if (Input.IsKeyPressing(.X)) - { - CopySelectedFiles(cutFiles: true); - } - - if (Input.IsKeyPressing(.V)) - { - PasteFiles(CurrentDirectory); - } - } + HandleShortcuts(); } List> directoryEntries = scope List>(); diff --git a/GlitchyEditor/src/EditorContentManager.bf b/GlitchyEditor/src/EditorContentManager.bf index 4329778..35f456c 100644 --- a/GlitchyEditor/src/EditorContentManager.bf +++ b/GlitchyEditor/src/EditorContentManager.bf @@ -367,7 +367,16 @@ class EditorContentManager : IContentManager if (!_handleToAsset.TryGetValue(handle, out asset)) { - LoadAsset(handle, blocking); + AssetHandle handleAfterLoading = LoadAsset(handle, blocking); + + if (handleAfterLoading == .Invalid) + { + // TODO: If the asset existed at some point, the cache might still know of it. + // Or we store the asset name somewhere else. (For the editor in the asset using it?) + asset = new NewPlaceholderAsset(handle, .Error); + + AssignHandleAndManage(asset, handle); + } } if (var placeholder = asset as PlaceholderAsset) @@ -401,6 +410,8 @@ class EditorContentManager : IContentManager private Asset GetPlaceholderAsset(Type assetType, PlaceholderType placeholderType) { + // TODO: Probably don't hardcode paths here. + // TODO: Probably verify existence at start of application. switch (assetType) { case typeof(Texture2D): @@ -414,6 +425,17 @@ class EditorContentManager : IContentManager AssetHandle handle = LoadAsset("Resources/Textures/ErrorTexture2D.png", true); return GetAsset(null, handle); } + case typeof(Effect): + if (placeholderType == .Loading) + { + AssetHandle handle = LoadAsset("Resources/Shaders/PlaceholderLoading.fx", true); + return GetAsset(null, handle); + } + else if (placeholderType == .Error) + { + AssetHandle handle = LoadAsset("Resources/Shaders/PlaceholderError.fx", true); + return GetAsset(null, handle); + } } return null; @@ -623,6 +645,7 @@ class EditorContentManager : IContentManager using (_finishedEntriesLock.Enter()) { loadedAsset.Identifier = assetNode.Identifier; + // TODO: AssignHandleAndManage loadedAsset.[Friend]_contentManager = this; loadedAsset.[Friend]_handle = handle; @@ -874,14 +897,23 @@ class EditorContentManager : IContentManager // If this happens too often we could use a different random generator } - //_handles.Add(asset.Identifier, handle); + AssignHandleAndManage(asset, handle); + + return handle; + } + + private void AssignHandleAndManage(Asset asset, AssetHandle handle) + { + if (_handleToAsset.TryGetValue(handle, let existingAsset)) + { + existingAsset.ReleaseRef(); + } + _handleToAsset.Add(handle, asset); asset.[Friend]_contentManager = this; asset.[Friend]_handle = handle; asset.AddRef(); - - return handle; } private void SwapAsset(Asset oldAsset, Asset newAsset) diff --git a/GlitchyEngine/src/Content/Loaders/MaterialLoader.bf b/GlitchyEngine/src/Content/Loaders/MaterialLoader.bf index 77a1012..a362080 100644 --- a/GlitchyEngine/src/Content/Loaders/MaterialLoader.bf +++ b/GlitchyEngine/src/Content/Loaders/MaterialLoader.bf @@ -27,7 +27,10 @@ class MaterialLoader : IProcessedAssetLoader String textureName = scope String(textureNameLength); stream.ReadStrSized32(textureNameLength, textureName); - material.SetTexture(textureName, textureHandle); + if (material.SetTexture(textureName, textureHandle) case .Err(let error)) + { + Log.EngineLogger.Error($"Failed to set texture slot {textureName}: {error}"); + } } uint16 bufferCount = Try!(stream.Read()); diff --git a/GlitchyEngine/src/Renderer/Renderer2D.bf b/GlitchyEngine/src/Renderer/Renderer2D.bf index 8308d3c..ade8f22 100644 --- a/GlitchyEngine/src/Renderer/Renderer2D.bf +++ b/GlitchyEngine/src/Renderer/Renderer2D.bf @@ -532,7 +532,7 @@ namespace GlitchyEngine.Renderer s_quadBatchMaterial.SetVariable("ViewProjection", sceneViewProjection); //s_currentQuadEffect.Get()?.Variables["ViewProjection"].SetData(viewProjection); - s_currentCircleEffect.Get()?.Variables["ViewProjection"].SetData(sceneViewProjection); + //s_currentCircleEffect.Get()?.Variables["ViewProjection"].SetData(sceneViewProjection); s_currentLineEffect.Get()?.Variables["ViewProjection"].SetData(sceneViewProjection); s_drawOrder = drawOrder; @@ -574,7 +574,7 @@ namespace GlitchyEngine.Renderer //s_currentQuadEffect.Get()?.Variables["ViewProjection"].SetData(viewProjection); s_quadBatchMaterial.SetVariable("ViewProjection", sceneViewProjection); - s_currentCircleEffect.Get()?.Variables["ViewProjection"].SetData(sceneViewProjection); + //s_currentCircleEffect.Get()?.Variables["ViewProjection"].SetData(sceneViewProjection); s_currentLineEffect.Get()?.Variables["ViewProjection"].SetData(sceneViewProjection); s_drawOrder = drawOrder;