From bff4418b847835ef58ef94c2894b65f7088125c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20L=C3=BCbe=C3=9F?= Date: Mon, 25 Jul 2022 17:03:28 +0200 Subject: [PATCH] Content browser --- .../content/Textures/EditorIcons.dds | Bin 32896 -> 65664 bytes .../content/Textures/EditorIcons.psd | Bin 9434 -> 16300 bytes .../src/EditWindows/ContentBrowserWindow.bf | 272 ++++++++++++++++++ .../src/EditWindows/SceneViewportWindow.bf | 19 +- GlitchyEditor/src/Editor.bf | 5 + GlitchyEditor/src/EditorIcons.bf | 52 ++++ GlitchyEditor/src/EditorLayer.bf | 59 ++-- GlitchyEngine/src/Collections/TreeNode.bf | 22 ++ GlitchyEngine/src/ImGui/ImGuiExtension.bf | 23 ++ GlitchyEngine/src/Math/Vector2.bf | 2 +- GlitchyEngine/src/Math/Vector3.bf | 2 +- GlitchyEngine/src/Math/Vector4.bf | 2 +- .../src/Platform/DX11/ImGui/ImGui.bf | 14 +- .../src/Platform/DX11/Renderer/Dx11Texture.bf | 4 +- .../DX11/Renderer/Dx11TextureViewBinding.bf | 2 +- GlitchyEngine/src/Renderer/Effect.bf | 29 +- GlitchyEngine/src/Renderer/Material.bf | 4 +- GlitchyEngine/src/Renderer/RenderCommand.bf | 4 +- .../src/Renderer/ShaderTextureCollection.bf | 2 +- .../src/Renderer/TextureViewBinding.bf | 4 +- GlitchyEngine/src/World/Scene.bf | 4 +- 21 files changed, 481 insertions(+), 44 deletions(-) create mode 100644 GlitchyEditor/src/EditWindows/ContentBrowserWindow.bf create mode 100644 GlitchyEditor/src/EditorIcons.bf diff --git a/GlitchyEditor/content/Textures/EditorIcons.dds b/GlitchyEditor/content/Textures/EditorIcons.dds index 25dc22d60d41b57f642e8c47ce8c0f369576efda..c2de4251e24b772361feec0f4b60c09a2b614a35 100644 GIT binary patch literal 65664 zcmeHJQL^MT417@hvq#`4P_;MUI@}$sU&W-~Rgg z`ug?T&tJcn``1t9`sLpnEs@V}1^h>Cp!MIh=Kp-7!uxp>coTRNxIclv>*szYuYxy$ zH-XFq+Oyy8nX}(nrUbVCIhv4bfS#szjnr;Z(VqKuze&bBR!@MQCFIgs=BvnTj-8+Q zcBUrKp8IxB9sUj*C9pqJ?fW^q7or{OwLY8GtJm2hU+?)M3CQnq5m}H7>7nfrlGY>d z2uBcBeXga>RrVzV())g#65!vf6Xk)1^V9lp=(OQ8oG3RM&f8n}X7>8{S&t+5jLX>9 zW#;}~*ozA+s;=Nj{`1aqh@MIOd*+?Bs}A{$ap^d-d$jMhxpd~c?^=g5u7x`gO@m@UUcup;pNA`gIfH+Q*7<}I1DJ%Sq5v< zkO0-!C=)!Zzy0Y1Yom1S%}4xKIeEX-%l8e(YjRB(S>t;vN5duExx`Crvfr*tM4jf! z9~n(&`aMSpp0_+TcUOaMoL)SQkM37FWk2WUYXryp_!{Am*x)^v>9Q_*_xAv;JwKH@ zG7?X@E?fzo_dGSh`{7NCEKS-Rs!7{DT48&4*VFl@yLo@T_LXjj4c> zBJb1ICv9q(_p1QsBAxeTO_V>w6SnoCGs7mx5f>Iu#U))d{4;Q2IC@^*U24rVi8 z6sJq8hEoFIz{7_J2O#+>bXM-=z9Jmvpq{IS2mP?7=!OK(gGkPgy}X}K$Ui|nX$n0! zG~R$3D%A~Nyue)46OaL?gf&GsBzWfj&1-Mp=D`U-tGAvM4~`zc)0tJKJFe)5IjP6V z_ZbbWDY_xS^H~96b@^OZb#SMO@JabM{!Tsw6;V^9`Y7}LyQDakJZ>DPL8~NpWt~I)mhi@>RV>a&`gz)fk2Yzp>kiYU@wkJ}^;0QF|Aeg@b?ptspB zBBy3kA7T*1PHBp43ifM?C(>V!+awME^=7Sp2H4ylEF=Cl+eP2hZ0a+5n}JPfifjt@ zJIpB3n}vHQ&1S{-At+B{gW1=HZ^cbYvjzxI_|$Y)AZWO&78HrVfrJMu%^fcFTYleGEi$@6mC|}Y+sZQ4_@i1?KSRp zHn?l8X|+QpXkNcr@k5gh#_C1R5 zvw;P5KJ}b<@hYoxWwGiYEnyeUto)a}N$sOOA2z~9pI^~(r8nBw3_s$BV>{~^8E!pA z7tBRH9X}pNu%^fcFTYleGC*rz6mC|}Y+sZQ4_@+Q<&pkR_Ex$O9AIakPd)WIv2?k- z&st#->~$E{-5Cr88Uc6v$e#a%Sc=A}Sg6nFZw5A{DXJ;h>oA`vUsm3sKqJ69??=Hs zA(o6i%qY4!KF35!4y;LmoXPmZB5RpL&e`W?-c6{?StRl`T4C|EVEj3Y}{eZqckYo&C@0d}_8 zgzp(~I&=4Vl`zToAwI78a4^{LK5ac{KOFP^!@|i~j3Og^lAa24B zym%Z#nlivizW3}jPy1og!drvJ_q3XfzNcSeJNq6@=vmPO@e{t|!|MprlmSliz2&F* z@d_5@@zkPmJ*{?@pXTEXtJJmjlv>dO%^|#^-@8OJK6KUD+garLV{j?ddF2-SIhh?h zbinSVN#l81trwN_(!+`~*_yU5I-psE7uut?kgjNOhHuTo)o>f97f<7(JIcv>pSreq zZr&`|g4zDIw4Urc%||{}uhH5i7$PeaTRp?Scf`GB0O{ATl2gMVHOWVNq@S=F$5U#E zS0J11`M)a~bS~kM94=s&`B_AJ){I`rZEuyl`@w~Ubl98yGC zhk0v0L%}FO6M}N|@RGlWMb9KR?X4VI@9H(Hw*cJ!oJM3+^qRl70B=3Y-FMXp?>+O1 z$Vuw!g)wusGQZTe@_r`!pq|4s;E`F;x$5)p5#b@P>h(&^L(|T|zrVfcxZwP>cBI~^ z_>8>>EO`HFYrw`GQ1y3=W>|!W{4VYYikvr)%w`);srWB?GDXcqfc9_yqx@Csm_YZPQ0BbPzhl@dQN7RqO5esZT0Y(f%P4z=xF+yE|E_VqWN!kG aOQ5|29w+=2{3h@w@Fwsk@Fwu^1pWd3c~oxz delta 1117 zcmah}KS.u%1!mPC3E4GIaI(v%?DoW($d6iD`moSAH0U0v0?C0;-%H}3Dz-p zRIRnj42IlG|nGWiS(ZzW%p9FOSWc$RloiLtL{43$8Aybxuvl}aaPU@$PK-)VfOJi p7%%s1Wlf((0(_+QF*Ra|PPT!RBr+(G%eH<-b$=13Dzm+h)V~JTyR-lR diff --git a/GlitchyEditor/content/Textures/EditorIcons.psd b/GlitchyEditor/content/Textures/EditorIcons.psd index 7544cded986eeb1fbf98b5cbba0c1aababd9f27f..af27432a056c3925d549bcff765cdefe4608d3f4 100644 GIT binary patch literal 16300 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 gS3xP^epMP-g!?rqAl7id20U#3%MW { + _fileSystemDirty = true; + _currentDirectoryDirty = true; + }); + + fsw.OnCreated.Add(new (filename) => { + _fileSystemDirty = true; + _currentDirectoryDirty = true; + }); + + fsw.OnDeleted.Add(new (filename) => { + _fileSystemDirty = true; + _currentDirectoryDirty = true; + }); + + fsw.OnRenamed.Add(new (newName, oldName) => { + _fileSystemDirty = true; + _currentDirectoryDirty = true; + }); + + fsw.StartRaisingEvents(); + + } + + protected override void InternalShow() + { + if(!ImGui.Begin("Content Browser", &_open, .None)) + { + ImGui.End(); + return; + } + + if (_fileSystemDirty) + { + BuildDirectoryTree(); + + _fileSystemDirty = false; + } + + if (_currentDirectoryDirty) + { + BuildCurrentDirectory(); + } + + ImGui.Columns(2); + + DrawDirectorySideBar(); + + ImGui.NextColumn(); + + DrawCurrentDirectory(); + + ImGui.Columns(1); + + ImGui.End(); + } + + private bool _fileSystemDirty = true; + private bool _currentDirectoryDirty = true; + + class DirectoryNode + { + public String Name ~ delete _; + public String Path ~ delete _; + } + + TreeNode directoryNames = new TreeNode() ~ DeleteTreeAndChildren!(_); + + class Entry + { + public String Name ~ delete _; + public bool IsDirectory; + } + + List _currentDirContent = new .() ~ DeleteContainerAndItems!(_); + + private void BuildDirectoryTree() + { + DeleteTreeAndChildren!(directoryNames); + directoryNames = new TreeNode(); + + String str = scope .(ContentDirectory); + + void AddDirectoryToTree(String path, TreeNode parentNode) + { + DirectoryNode node = new DirectoryNode(); + node.Path = new String(path); + node.Name = new String(); + + Path.GetFileName(node.Path, node.Name); + + var newNode = parentNode.AddChild(node); + + String filter = scope $"{path}/*"; + + for (var directory in Directory.Enumerate(filter, .Directories)) + { + directory.GetFilePath(str..Clear()); + + AddDirectoryToTree(str, newNode); + } + } + + String filter = scope $"{ContentDirectory}/*"; + + for (var directory in Directory.Enumerate(filter, .Directories)) + { + directory.GetFilePath(str..Clear()); + + AddDirectoryToTree(str, directoryNames); + } + } + + private void BuildCurrentDirectory() + { + ClearAndDeleteItems!(_currentDirContent); + + String filter = scope $"{_currentDirectory}/*"; + + String buffer = scope String(); + + for (var entry in Directory.Enumerate(filter, .Directories | .Files)) + { + entry.GetFilePath(buffer..Clear()); + + Entry e = new Entry(); + e.Name = new String(); + Path.GetFileName(buffer, e.Name); + e.IsDirectory = entry.IsDirectory; + + _currentDirContent.Add(e); + } + } + + private void DrawDirectorySideBar() + { + for(var child in directoryNames.Children) + { + ImGuiPrintEntityTree(child); + } + } + + private void ImGuiPrintEntityTree(TreeNode tree) + { + String name = tree.Value.Name; + + ImGui.TreeNodeFlags flags = .OpenOnArrow | .SpanAvailWidth; + + if(tree.Children.Count == 0) + flags |= .Leaf; + + if (tree.Value.Path == _currentDirectory) + { + flags |= .Selected; + } + + bool isOpen = ImGui.TreeNodeEx(name, flags, $"{name}"); + + if (ImGui.IsItemClicked(.Left)) + { + if (_currentDirectory != null) + delete _currentDirectory; + + _currentDirectory = new String(tree.Value.Path); + } + + if(isOpen) + { + for(var child in tree.Children) + { + ImGuiPrintEntityTree(child); + } + + ImGui.TreePop(); + } + } + + private static Vector2 DirectoryItemSize = .(100, 100); + + const Vector2 padding = .(24, 24); + + private void DrawCurrentDirectory() + { + ImGui.Style* style = ImGui.GetStyle(); + + float window_visible_x2 = ImGui.GetWindowPos().x + ImGui.GetWindowContentRegionMax().x; + for (var entry in _currentDirContent) + { + ImGui.PushID(entry.Name); + + DrawDirectoryItem(entry); + + float last_button_x2 = ImGui.GetItemRectMax().x; + float next_button_x2 = last_button_x2 + style.ItemSpacing.x + DirectoryItemSize.X; // Expected position if next button was on same line + if (entry != _currentDirContent.Back && next_button_x2 < window_visible_x2) + ImGui.SameLine(); + + ImGui.PopID(); + } + } + + private void DrawDirectoryItem(Entry entry) + { + ImGui.BeginChild("item", (.)DirectoryItemSize); + + SubTexture2D image = entry.IsDirectory ? s_FolderTexture : s_FileTexture; + + ImGui.PushStyleColor(.Button, ImGui.Vec4(0, 0, 0, 0)); + + ImGui.ImageButton(image, (.)(DirectoryItemSize - padding)); + + if (ImGui.BeginDragDropSource()) + { + String fullpath = scope $"{_currentDirectory}{Path.DirectorySeparatorChar}{entry.Name}"; + + ImGui.SetDragDropPayload("CONTENT_BROWSER_ITEM", fullpath.CStr(), (.)fullpath.Length, .Once); + + ImGui.EndDragDropSource(); + } + + if (ImGui.IsItemHovered() && ImGui.IsMouseDoubleClicked(.Left)) + { + EntryDoubleClicked(entry); + } + + ImGui.PopStyleColor(); + + ImGui.TextUnformatted(entry.Name); + + ImGui.EndChild(); + } + + private void EntryDoubleClicked(Entry entry) + { + if (entry.IsDirectory) + { + _currentDirectory.Append(Path.DirectorySeparatorChar); + _currentDirectory.Append(entry.Name); + } + } + } +} \ No newline at end of file diff --git a/GlitchyEditor/src/EditWindows/SceneViewportWindow.bf b/GlitchyEditor/src/EditWindows/SceneViewportWindow.bf index 33c2a5b..e78a082 100644 --- a/GlitchyEditor/src/EditWindows/SceneViewportWindow.bf +++ b/GlitchyEditor/src/EditWindows/SceneViewportWindow.bf @@ -35,12 +35,14 @@ namespace GlitchyEditor.EditWindows _editor = editor; } - private ImGui.Vec2 oldViewportSize; + private ImGui.Vec2 oldViewportSize = .(100, 100); private bool viewPortChanged; public uint32 SelectedEntityId; public bool SelectionChanged; + public Vector2 ViewportSize => (Vector2)oldViewportSize; + protected override void InternalShow() { ImGui.PushStyleVar(.WindowPadding, ImGui.Vec2(1, 1)); @@ -88,6 +90,21 @@ namespace GlitchyEditor.EditWindows //ImGui.Image(_editor.CurrentCamera.RenderTarget.GetViewBinding(0), viewportSize); //ImGui.Image(_editor.CurrentScene.[Friend]_compositeTarget.GetViewBinding(0), viewportSize); } + + if (ImGui.BeginDragDropTarget()) + { + ImGui.Payload* payload = ImGui.AcceptDragDropPayload("CONTENT_BROWSER_ITEM"); + + if (payload != null) + { + Log.EngineLogger.Warning(""); + + StringView path = .((char8*)payload.Data, (int)payload.DataSize); + _editor.RequestOpenScene(this, path); + } + + ImGui.EndDragDropTarget(); + } bool gizmoUsed = DrawImGuizmo(viewportSize); diff --git a/GlitchyEditor/src/Editor.bf b/GlitchyEditor/src/Editor.bf index f246b4b..fca76d2 100644 --- a/GlitchyEditor/src/Editor.bf +++ b/GlitchyEditor/src/Editor.bf @@ -15,10 +15,12 @@ namespace GlitchyEditor private EntityHierarchyWindow _entityHierarchyWindow ~ delete _; private ComponentEditWindow _componentEditWindow ~ delete _; private SceneViewportWindow _sceneViewportWindow = new .(this) ~ delete _; + private ContentBrowserWindow _contentBrowserWindow = new .() ~ delete _; public EntityHierarchyWindow EntityHierarchyWindow => _entityHierarchyWindow; public ComponentEditWindow ComponentEditWindow => _componentEditWindow; public SceneViewportWindow SceneViewportWindow => _sceneViewportWindow; + public ContentBrowserWindow ContentBrowserWindow => _contentBrowserWindow; public Scene CurrentScene { @@ -32,6 +34,8 @@ namespace GlitchyEditor public EditorCamera* CurrentCamera { get; set; } + public Event> RequestOpenScene ~ _.Dispose(); + /// Creates a new editor for the given world public this(Scene scene) { @@ -46,6 +50,7 @@ namespace GlitchyEditor _entityHierarchyWindow.Show(); _componentEditWindow.Show(); _sceneViewportWindow.Show(); + _contentBrowserWindow.Show(); } } } diff --git a/GlitchyEditor/src/EditorIcons.bf b/GlitchyEditor/src/EditorIcons.bf new file mode 100644 index 0000000..9580983 --- /dev/null +++ b/GlitchyEditor/src/EditorIcons.bf @@ -0,0 +1,52 @@ +using System; +using GlitchyEngine.Renderer; +using GlitchyEngine.Math; +using GlitchyEngine; + +namespace GlitchyEditor +{ + class EditorIcons : RefCounted + { + Texture2D _texture ~ _.ReleaseRef(); + + public SubTexture2D DirectionalLight ~ _.ReleaseRef(); + public SubTexture2D Camera ~ _.ReleaseRef(); + public SubTexture2D Folder ~ _.ReleaseRef(); + public SubTexture2D File ~ _.ReleaseRef(); + + public SamplerState SamplerState + { + get => _texture.SamplerState; + set => _texture.SamplerState = value; + } + + public this(String texturePath, Vector2 iconSize) + { + _texture = new Texture2D(texturePath); + + Vector2 pen = .(); + + DirectionalLight = GetNextGridTexture(ref pen, iconSize); + Camera = GetNextGridTexture(ref pen, iconSize); + Folder = GetNextGridTexture(ref pen, iconSize); + File = GetNextGridTexture(ref pen, iconSize); + } + + private SubTexture2D GetNextGridTexture(ref Vector2 pen, Vector2 iconSize) + { + SubTexture2D subTexture = .CreateFromGrid(_texture, pen, iconSize); + + pen.X += 1.0f; + + if (pen.X >= (_texture.Width / iconSize.X)) + { + pen.X = 0; + pen.Y += 1.0f; + } + + Log.EngineLogger.AssertDebug(pen.Y <=(_texture.Height / iconSize.Y)); + + return subTexture; + } + } +} \ No newline at end of file diff --git a/GlitchyEditor/src/EditorLayer.bf b/GlitchyEditor/src/EditorLayer.bf index e3e19b0..e7aad13 100644 --- a/GlitchyEditor/src/EditorLayer.bf +++ b/GlitchyEditor/src/EditorLayer.bf @@ -50,9 +50,11 @@ namespace GlitchyEditor EditorCamera _camera ~ _.Dispose(); - Texture2D _editorIcons ~ _.ReleaseRef(); + /*Texture2D _editorIcons ~ _.ReleaseRef(); SubTexture2D _iconDirectionalLight ~ _.ReleaseRef(); - SubTexture2D _iconCamera ~ _.ReleaseRef(); + SubTexture2D _iconCamera ~ _.ReleaseRef();*/ + + EditorIcons _editorIcons ~ _.ReleaseRef(); public this() : base("Example") { @@ -62,10 +64,10 @@ namespace GlitchyEditor _camera = EditorCamera(Vector3(3.5f, 1.25f, 2.75f), Quaternion.FromEulerAngles(MathHelper.ToRadians(40), MathHelper.ToRadians(25), 0), MathHelper.ToRadians(75), 0.1f, 1); _camera.RenderTarget = _cameraTarget; + + InitEditor(); NewScene(); - - InitEditor(); } private void InitGraphics() @@ -104,10 +106,16 @@ namespace GlitchyEditor .(.R8G8B8A8_UNorm)) }); - _editorIcons = new Texture2D("Textures/EditorIcons.dds"); + _editorIcons = new EditorIcons("Textures/EditorIcons.dds", .(64, 64)); + _editorIcons.SamplerState = SamplerStateManager.AnisotropicClamp; + + ContentBrowserWindow.s_FolderTexture = _editorIcons.Folder; + ContentBrowserWindow.s_FileTexture = _editorIcons.File; + + /*_editorIcons = new Texture2D("Textures/EditorIcons.dds"); _editorIcons.SamplerState = SamplerStateManager.AnisotropicClamp; _iconDirectionalLight = .CreateFromGrid(_editorIcons, .(0, 0), .(64, 64)); - _iconCamera = .CreateFromGrid(_editorIcons, .(1, 0), .(64, 64)); + _iconCamera = .CreateFromGrid(_editorIcons, .(1, 0), .(64, 64));*/ } private void InitEditor() @@ -115,6 +123,10 @@ namespace GlitchyEditor _editor = new Editor(_scene); _editor.SceneViewportWindow.ViewportSizeChangedEvent.Add(new (s, e) => ViewportSizeChanged(s, e)); _editor.CurrentCamera = &_camera; + + _editor.RequestOpenScene.Add(new (s, fileName) => { + LoadSceneFile(fileName); + }); } public override void Update(GameTime gameTime) @@ -178,7 +190,7 @@ namespace GlitchyEditor Matrix world = Billboard(transform.WorldTransform); float alpha = CalculateAlpha(transform.WorldTransform.Translation); - Renderer2D.DrawQuad(world, _iconCamera, ColorRGBA(alpha, alpha, alpha, alpha), .(0, 0, 1, 1), entity.Index); + Renderer2D.DrawQuad(world, _editorIcons.Camera, ColorRGBA(alpha, alpha, alpha, alpha), .(0, 0, 1, 1), entity.Index); //Renderer2D.DrawQuad(world, _iconCamera, .White, .(0, 0, 1, 1), entity.Index); } @@ -199,7 +211,7 @@ namespace GlitchyEditor Matrix world = Billboard(transform.WorldTransform); float alpha = CalculateAlpha(transform.WorldTransform.Translation); - Renderer2D.DrawQuad(world, _iconDirectionalLight, ColorRGBA(light.SceneLight.Color.R * alpha, light.SceneLight.Color.G * alpha, light.SceneLight.Color.B * alpha, alpha), .(0, 0, 1, 1), entity.Index); + Renderer2D.DrawQuad(world, _editorIcons.DirectionalLight, ColorRGBA(light.SceneLight.Color.R * alpha, light.SceneLight.Color.G * alpha, light.SceneLight.Color.B * alpha, alpha), .(0, 0, 1, 1), entity.Index); //Renderer2D.DrawQuad(world, _iconDirectionalLight, ColorRGBA(light.SceneLight.Color, alpha), .(0, 0, 1, 1), entity.Index); } } @@ -366,6 +378,12 @@ namespace GlitchyEditor private void NewScene() { SceneFilePath = null; + + delete _scene; + _scene = new Scene(); + _editor.CurrentScene = _scene; + var vpSize = _editor.SceneViewportWindow.ViewportSize; + _scene.OnViewportResize((.)vpSize.X, (.)vpSize.Y); _camera.Position = .(-1.5f, 1.5f, -2.5f); _camera.RotationEuler = .(MathHelper.ToRadians(25), MathHelper.ToRadians(35), 0); @@ -421,19 +439,26 @@ namespace GlitchyEditor { if (val == .OK) { - SceneFilePath = ofd.FileNames[0]; - - delete _scene; - _scene = new Scene(); - - SceneSerializer serializer = scope .(_scene); - serializer.Deserialize(SceneFilePath); - - _editor.CurrentScene = _scene; + LoadSceneFile(ofd.FileNames[0]); } } } + /// Loads the given scene file. + private void LoadSceneFile(StringView filename) + { + SceneFilePath = scope String(filename); + + delete _scene; + _scene = new Scene(); + _editor.CurrentScene = _scene; + var vpSize = _editor.SceneViewportWindow.ViewportSize; + _scene.OnViewportResize((.)vpSize.X, (.)vpSize.Y); + + SceneSerializer serializer = scope .(_scene); + serializer.Deserialize(SceneFilePath); + } + private void DrawMainMenuBar() { ImGui.BeginMainMenuBar(); diff --git a/GlitchyEngine/src/Collections/TreeNode.bf b/GlitchyEngine/src/Collections/TreeNode.bf index ab91281..bfc6f87 100644 --- a/GlitchyEngine/src/Collections/TreeNode.bf +++ b/GlitchyEngine/src/Collections/TreeNode.bf @@ -45,4 +45,26 @@ namespace GlitchyEngine.Collections return null; } } + + static + { + public static mixin DeleteTreeAndChildren(TreeNode tree) where T : class, delete + { + InternalDeleteTreeAndChildren(tree); + } + + private static void InternalDeleteTreeAndChildren(TreeNode tree) where T : class, delete + { + for (var child in tree.Children) + { + InternalDeleteTreeAndChildren(child); + } + + delete tree.Value; + + tree.Children.Clear(); + + delete tree; + } + } } diff --git a/GlitchyEngine/src/ImGui/ImGuiExtension.bf b/GlitchyEngine/src/ImGui/ImGuiExtension.bf index b23abbb..efd8d91 100644 --- a/GlitchyEngine/src/ImGui/ImGuiExtension.bf +++ b/GlitchyEngine/src/ImGui/ImGuiExtension.bf @@ -1,6 +1,7 @@ using GlitchyEngine.Math; using GlitchyEngine.Renderer; using System; +using GlitchyEngine; namespace ImGui { @@ -34,6 +35,16 @@ namespace ImGui Image(texture.GetViewBinding(), size, uv0, uv1, tint_col, border_col); } + public static void Image(SubTexture2D subTexture, Vec2 size, Vec2 uv0 = Vec2.Zero, Vec2 uv1 = Vec2.Ones, Vec4 tint_col = Vec4.Ones, Vec4 border_col = Vec4.Zero) + { + if (uv0 != .Zero || uv1 != .Ones) + Runtime.NotImplemented(); + + Vector2 v = (.)subTexture.TexCoords.XY + subTexture.TexCoords.ZW; + + Image(subTexture.Texture.GetViewBinding(), size, (.)subTexture.TexCoords.XY, (.)v, tint_col, border_col); + } + public static void Image(RenderTarget2D texture, Vec2 size, Vec2 uv0 = Vec2.Zero, Vec2 uv1 = Vec2.Ones, Vec4 tint_col = Vec4.Ones, Vec4 border_col = Vec4.Zero) { Image(texture.GetViewBinding(), size, uv0, uv1, tint_col, border_col); @@ -41,6 +52,18 @@ namespace ImGui public static extern void Image(TextureViewBinding textureViewBinding, Vec2 size, Vec2 uv0 = Vec2.Zero, Vec2 uv1 = Vec2.Ones, Vec4 tint_col = Vec4.Ones, Vec4 border_col = Vec4.Zero); + public static bool ImageButton(SubTexture2D subTexture, Vec2 size, Vec2 uv0 = Vec2.Zero, Vec2 uv1 = Vec2.Ones, int32 frame_padding = -1, Vec4 bg_col = Vec4.Zero, Vec4 tint_col = Vec4.Ones) + { + if (uv0 != .Zero || uv1 != .Ones) + Runtime.NotImplemented(); + + Vector2 v = (.)subTexture.TexCoords.XY + subTexture.TexCoords.ZW; + + return ImageButton(subTexture.Texture.GetViewBinding(), size, (.)subTexture.TexCoords.XY, (.)v, frame_padding, bg_col, tint_col); + } + + public static extern bool ImageButton(TextureViewBinding textureViewBinding, Vec2 size, Vec2 uv0 = Vec2.Zero, Vec2 uv1 = Vec2.Ones, int32 frame_padding = -1, Vec4 bg_col = Vec4.Zero, Vec4 tint_col = Vec4.Ones); + public static void TextUnformatted(StringView text) => TextUnformattedImpl(text.Ptr, text.Ptr + text.Length); public static void PushID(StringView id) => PushID(id.Ptr, id.Ptr + id.Length); diff --git a/GlitchyEngine/src/Math/Vector2.bf b/GlitchyEngine/src/Math/Vector2.bf index 1dd8b30..21ed285 100644 --- a/GlitchyEngine/src/Math/Vector2.bf +++ b/GlitchyEngine/src/Math/Vector2.bf @@ -4,7 +4,7 @@ using System; namespace GlitchyEngine.Math { [BonTarget] - [SwizzleVector(2, "Vector")] + [SwizzleVector(2, "GlitchyEngine.Math.Vector")] public struct Vector2 { public const Vector2 Zero = .(0f, 0f); diff --git a/GlitchyEngine/src/Math/Vector3.bf b/GlitchyEngine/src/Math/Vector3.bf index 033e8de..2aaba43 100644 --- a/GlitchyEngine/src/Math/Vector3.bf +++ b/GlitchyEngine/src/Math/Vector3.bf @@ -4,7 +4,7 @@ using System; namespace GlitchyEngine.Math { [BonTarget] - [SwizzleVector(3, "Vector")] + [SwizzleVector(3, "GlitchyEngine.Math.Vector")] public struct Vector3 { public const Vector3 Zero = .(0f, 0f, 0f); diff --git a/GlitchyEngine/src/Math/Vector4.bf b/GlitchyEngine/src/Math/Vector4.bf index 965aa39..334098d 100644 --- a/GlitchyEngine/src/Math/Vector4.bf +++ b/GlitchyEngine/src/Math/Vector4.bf @@ -4,7 +4,7 @@ using System; namespace GlitchyEngine.Math { [BonTarget] - [SwizzleVector(4, "Vector")] + [SwizzleVector(4, "GlitchyEngine.Math.Vector")] public struct Vector4 { public const Vector4 Zero = .(0f, 0f, 0f, 0f); diff --git a/GlitchyEngine/src/Platform/DX11/ImGui/ImGui.bf b/GlitchyEngine/src/Platform/DX11/ImGui/ImGui.bf index c82728e..b886d84 100644 --- a/GlitchyEngine/src/Platform/DX11/ImGui/ImGui.bf +++ b/GlitchyEngine/src/Platform/DX11/ImGui/ImGui.bf @@ -19,7 +19,19 @@ namespace ImGui ImGui.Image(view, size, uv0, uv1, tint_col, border_col); - textureViewBinding.ReleaseRef(); + textureViewBinding.Release(); + } + + public static override bool ImageButton(TextureViewBinding textureViewBinding, Vec2 size, Vec2 uv0 = Vec2.Zero, Vec2 uv1 = Vec2.Ones, int32 frame_padding = -1, Vec4 bg_col = Vec4.Zero, Vec4 tint_col = Vec4.Ones) + { + var view = textureViewBinding._nativeShaderResourceView..AddRef(); + _resourceViews.Add(view); + + bool pressed = ImGui.ImageButton(view, size, uv0, uv1, frame_padding, bg_col, tint_col); + + textureViewBinding.Release(); + + return pressed; } protected internal static override void CleanupFrame() diff --git a/GlitchyEngine/src/Platform/DX11/Renderer/Dx11Texture.bf b/GlitchyEngine/src/Platform/DX11/Renderer/Dx11Texture.bf index 5a34efa..c8d7c94 100644 --- a/GlitchyEngine/src/Platform/DX11/Renderer/Dx11Texture.bf +++ b/GlitchyEngine/src/Platform/DX11/Renderer/Dx11Texture.bf @@ -146,7 +146,7 @@ namespace GlitchyEngine.Renderer } // TODO: Update Texture Arrays! - protected override System.Result PlatformSetData(void* data, uint32 elementSize, uint32 destX, + protected override Result PlatformSetData(void* data, uint32 elementSize, uint32 destX, uint32 destY, uint32 destWidth, uint32 destHeight, uint32 arraySlice, uint32 mipLevel, GlitchyEngine.Renderer.MapType mapType) { Debug.Profiler.ProfileResourceFunction!(); @@ -259,7 +259,7 @@ namespace GlitchyEngine.Renderer protected override TextureViewBinding PlatformGetViewBinding() { - return .(_nativeResourceView, _samplerState.nativeSamplerState); + return .(_nativeResourceView, _samplerState?.nativeSamplerState); } } diff --git a/GlitchyEngine/src/Platform/DX11/Renderer/Dx11TextureViewBinding.bf b/GlitchyEngine/src/Platform/DX11/Renderer/Dx11TextureViewBinding.bf index aac1924..409783e 100644 --- a/GlitchyEngine/src/Platform/DX11/Renderer/Dx11TextureViewBinding.bf +++ b/GlitchyEngine/src/Platform/DX11/Renderer/Dx11TextureViewBinding.bf @@ -24,7 +24,7 @@ namespace GlitchyEngine.Renderer _nativeSamplerState?.AddRef(); } - public override void ReleaseRef() + public override void Release() { _nativeShaderResourceView?.Release(); _nativeSamplerState?.Release(); diff --git a/GlitchyEngine/src/Renderer/Effect.bf b/GlitchyEngine/src/Renderer/Effect.bf index 0cd17c9..c72cb9e 100644 --- a/GlitchyEngine/src/Renderer/Effect.bf +++ b/GlitchyEngine/src/Renderer/Effect.bf @@ -63,13 +63,20 @@ namespace GlitchyEngine.Renderer name = scope:: String(); Path.GetFileNameWithoutExtension(filepath, name); } - - Log.EngineLogger.AssertDebug(!Exists(name), "Can't add two effects with the same name to library."); - Effect effect = new Effect(filepath, name); - Add(effect); + if (Exists(name)) + { + return Get(name); + } + else + { + Log.EngineLogger.AssertDebug(!Exists(name), "Can't add two effects with the same name to library."); - return effect; + Effect effect = new Effect(filepath, name); + Add(effect); + + return effect; + } } /** @@ -182,7 +189,7 @@ namespace GlitchyEngine.Renderer for(let entry in _textures) { - entry.value.BoundTexture.ReleaseRef(); + entry.value.BoundTexture.Release(); } } @@ -192,7 +199,7 @@ namespace GlitchyEngine.Renderer ref TextureEntry entry = ref _textures[name]; - entry.BoundTexture.ReleaseRef(); + entry.BoundTexture.Release(); entry.BoundTexture = texture.GetViewBinding(); } @@ -205,7 +212,7 @@ namespace GlitchyEngine.Renderer ref TextureEntry entry = ref _textures[name]; - entry.BoundTexture.ReleaseRef(); + entry.BoundTexture.Release(); //entry.BoundTexture = .RenderTargetGroup(renderTargetGroup..AddRef(), firstTarget, targetCount); entry.BoundTexture = renderTargetGroup.GetViewBinding(firstTarget); } @@ -216,7 +223,7 @@ namespace GlitchyEngine.Renderer ref TextureEntry entry = ref _textures[name]; - entry.BoundTexture.ReleaseRef(); + entry.BoundTexture.Release(); entry.BoundTexture = textureViewBinding..AddRef(); } @@ -226,11 +233,11 @@ namespace GlitchyEngine.Renderer for(let (name, entry) in _textures) { - entry.VsSlot?.BoundTexture.ReleaseRef(); + entry.VsSlot?.BoundTexture.Release(); entry.VsSlot?.BoundTexture = entry.BoundTexture; entry.VsSlot?.BoundTexture.AddRef(); - entry.PsSlot?.BoundTexture.ReleaseRef(); + entry.PsSlot?.BoundTexture.Release(); entry.PsSlot?.BoundTexture = entry.BoundTexture; entry.PsSlot?.BoundTexture.AddRef(); } diff --git a/GlitchyEngine/src/Renderer/Material.bf b/GlitchyEngine/src/Renderer/Material.bf index a3ccb16..28af7bb 100644 --- a/GlitchyEngine/src/Renderer/Material.bf +++ b/GlitchyEngine/src/Renderer/Material.bf @@ -40,7 +40,7 @@ namespace GlitchyEngine.Renderer { for(let (name, texture) in _textures) { - texture.ReleaseRef(); + texture.Release(); } delete _textures; @@ -90,7 +90,7 @@ namespace GlitchyEngine.Renderer { if(_textures.TryGetValue(name, var entry)) { - entry.ReleaseRef(); + entry.Release(); _textures[name] = texture.GetViewBinding(); //texture?.AddRef(); } diff --git a/GlitchyEngine/src/Renderer/RenderCommand.bf b/GlitchyEngine/src/Renderer/RenderCommand.bf index 6525799..d17d1cc 100644 --- a/GlitchyEngine/src/Renderer/RenderCommand.bf +++ b/GlitchyEngine/src/Renderer/RenderCommand.bf @@ -34,7 +34,9 @@ namespace GlitchyEngine.Renderer _rendererAPI.Init(); } - [Inline] + // REPORT!!!!!!!!! + // Inline doesn't compile + //[Inline] public static void Clear(RenderTarget2D renderTarget, ColorRGBA color) { _rendererAPI.Clear(renderTarget, color); diff --git a/GlitchyEngine/src/Renderer/ShaderTextureCollection.bf b/GlitchyEngine/src/Renderer/ShaderTextureCollection.bf index acbc1f6..08a5ab7 100644 --- a/GlitchyEngine/src/Renderer/ShaderTextureCollection.bf +++ b/GlitchyEngine/src/Renderer/ShaderTextureCollection.bf @@ -31,7 +31,7 @@ namespace GlitchyEngine.Renderer for(let entry in entries) { delete entry.Name; - entry.BoundTexture.ReleaseRef(); + entry.BoundTexture.Release(); } delete entries; diff --git a/GlitchyEngine/src/Renderer/TextureViewBinding.bf b/GlitchyEngine/src/Renderer/TextureViewBinding.bf index 3b82f99..9aa24fc 100644 --- a/GlitchyEngine/src/Renderer/TextureViewBinding.bf +++ b/GlitchyEngine/src/Renderer/TextureViewBinding.bf @@ -9,8 +9,8 @@ namespace GlitchyEngine.Renderer public extern bool IsEmpty { get; } public extern void AddRef(); - public extern void ReleaseRef(); + public extern void Release(); - public void Dispose() => ReleaseRef(); + public void Dispose() => Release(); } } diff --git a/GlitchyEngine/src/World/Scene.bf b/GlitchyEngine/src/World/Scene.bf index bb47fa9..b9336d0 100644 --- a/GlitchyEngine/src/World/Scene.bf +++ b/GlitchyEngine/src/World/Scene.bf @@ -33,13 +33,13 @@ namespace GlitchyEngine.World public this() { - Entity entity = CreateEntity("Green Quad"); + /*Entity entity = CreateEntity("Green Quad"); entity.AddComponent(.(ColorRGBA.SRgbToLinear(.(0.2f, 0.9f, 0.15f)))); Entity entity2 = CreateEntity("Red Square"); var v = entity2.AddComponent(.(ColorRGBA.SRgbToLinear(.(0.95f, 0.1f, 0.3f)))); v.Sprite = new Texture2D("Textures/rocket.dds"); - v.Sprite.SamplerState = SamplerStateManager.PointClamp; + v.Sprite.SamplerState = SamplerStateManager.PointClamp;*/ _onComponentAddedHandlers.Add(typeof(CameraComponent), (e, t, c) => { CameraComponent* cameraComponent = (.)c;