From 1cc37ee1685cb1bee99264cc12ec0004af85f266 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20L=C3=BCbe=C3=9F?= Date: Thu, 30 Dec 2021 16:18:22 +0100 Subject: [PATCH 1/5] Run default constructor when assigning component --- GlitchyEngine/src/World/EcsWorld.bf | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/GlitchyEngine/src/World/EcsWorld.bf b/GlitchyEngine/src/World/EcsWorld.bf index e2b42bb..2d73c56 100644 --- a/GlitchyEngine/src/World/EcsWorld.bf +++ b/GlitchyEngine/src/World/EcsWorld.bf @@ -145,7 +145,7 @@ namespace GlitchyEngine.World /** * Assigns a component of type T to the specified entity and returns it. */ - public T* AssignComponent(Entity entity) where T : struct + public T* AssignComponent(Entity entity) where T : struct, new { if(entity.Index > _entities.Count) return null; @@ -167,8 +167,12 @@ namespace GlitchyEngine.World // return null; listEntity.ComponentMask[entry.Id] = true; - - return (.)entry.Pool.Get(entity.Index); + + T* component = (T*)entry.Pool.Get(entity.Index); + + *component = T(); + + return component; } /** From b3ab30e72af83ef52cf7a8444d4cf262487093d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20L=C3=BCbe=C3=9F?= Date: Thu, 30 Dec 2021 16:18:43 +0100 Subject: [PATCH 2/5] DrawQuad with transform matrix --- GlitchyEngine/src/Renderer/Renderer2D.bf | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/GlitchyEngine/src/Renderer/Renderer2D.bf b/GlitchyEngine/src/Renderer/Renderer2D.bf index bccb4d4..c2e72eb 100644 --- a/GlitchyEngine/src/Renderer/Renderer2D.bf +++ b/GlitchyEngine/src/Renderer/Renderer2D.bf @@ -587,6 +587,18 @@ namespace GlitchyEngine.Renderer } } + public static void DrawQuad(Matrix transform, Texture2D texture, ColorRGBA color = .White, Vector4 uvTransform = .(0, 0, 1, 1)) + { + Log.EngineLogger.AssertDebug(s_sceneRunning, "Missing call of BeginScene."); + + QueueQuadInstance(transform, color, texture, transform.Translation.Z, uvTransform); + + if(s_drawOrder == .Immediate) + { + DrawDeferred(); + } + } + public static void DrawQuadPivotCorner(Vector3 position, Vector2 size, float rotation, Texture2D texture, ColorRGBA color = .White, Vector4 uvTransform = .(0, 0, 1, 1)) { DrawQuad(position + Vector3(size.X / 2, size.Y / -2, 0), size, rotation, texture, color, uvTransform); From b555cc37d12e0beabf5b94af8cb09cc2742cb30a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20L=C3=BCbe=C3=9F?= Date: Thu, 30 Dec 2021 16:52:13 +0100 Subject: [PATCH 3/5] Simplified dispose function of DisposableComponents --- GlitchyEngine/src/Renderer/MeshComponent.bf | 6 ++---- GlitchyEngine/src/World/AnimationComponent.bf | 8 +++----- GlitchyEngine/src/World/DebugNameComponent.bf | 6 ++---- GlitchyEngine/src/World/EcsWorld.bf | 20 ++++++++++++------- .../src/World/IDisposableComponent.bf | 2 +- .../src/World/MeshRendererComponent.bf | 5 ++--- .../src/World/SkinnedMeshRendererComponent.bf | 8 +++----- 7 files changed, 26 insertions(+), 29 deletions(-) diff --git a/GlitchyEngine/src/Renderer/MeshComponent.bf b/GlitchyEngine/src/Renderer/MeshComponent.bf index 3a1daf0..9a33453 100644 --- a/GlitchyEngine/src/Renderer/MeshComponent.bf +++ b/GlitchyEngine/src/Renderer/MeshComponent.bf @@ -19,11 +19,9 @@ namespace GlitchyEngine.Renderer } } - public static void DisposeComponent(void* component) + public void Dispose() mut { - Self* self = (Self*)component; - - ReleaseRefAndNullify!(self._mesh); + ReleaseRefAndNullify!(_mesh); } } } diff --git a/GlitchyEngine/src/World/AnimationComponent.bf b/GlitchyEngine/src/World/AnimationComponent.bf index 51ab285..d997ed8 100644 --- a/GlitchyEngine/src/World/AnimationComponent.bf +++ b/GlitchyEngine/src/World/AnimationComponent.bf @@ -28,12 +28,10 @@ namespace GlitchyEngine.World public SkeletonPose Pose => _pose; - public static void DisposeComponent(void* component) + public void Dispose() { - Self* animationComponent = (Self*)component; - - animationComponent._animationClip?.ReleaseRef(); - delete animationComponent._pose; + _animationClip?.ReleaseRef(); + delete _pose; } } } diff --git a/GlitchyEngine/src/World/DebugNameComponent.bf b/GlitchyEngine/src/World/DebugNameComponent.bf index 3559100..f2c86bf 100644 --- a/GlitchyEngine/src/World/DebugNameComponent.bf +++ b/GlitchyEngine/src/World/DebugNameComponent.bf @@ -18,11 +18,9 @@ namespace GlitchyEngine.World _debugName = new String(name); } - public static void DisposeComponent(void* component) + public void Dispose() mut { - Self* self = (Self*)component; - - DeleteAndNullify!(self._debugName); + DeleteAndNullify!(_debugName); } } } diff --git a/GlitchyEngine/src/World/EcsWorld.bf b/GlitchyEngine/src/World/EcsWorld.bf index 2d73c56..262f630 100644 --- a/GlitchyEngine/src/World/EcsWorld.bf +++ b/GlitchyEngine/src/World/EcsWorld.bf @@ -17,7 +17,7 @@ namespace GlitchyEngine.World typealias DisposeFunction = function void(void* component); - internal typealias ComponentPoolEntry = (uint32 Id, IComponentPool Pool, DisposeFunction DisposeFunction); + internal typealias ComponentPoolEntry = (uint32 Id, IComponentPool Pool, DisposeFunction DisposeComponent); internal Dictionary _componentPools = new .(); /// A list containing all pools whose components need to be disposed before removal. @@ -60,7 +60,7 @@ namespace GlitchyEngine.World uint32 id = (uint32)_componentPools.Count; ComponentPool componentPool = new ComponentPool(MaxEntities); - DisposeFunction disposeFunction = => T.DisposeComponent; + DisposeFunction disposeFunction = => DisposeComponent; _componentPools.Add(typeof(T), (id, componentPool, disposeFunction)); @@ -68,6 +68,13 @@ namespace GlitchyEngine.World _disposingPools.Add(typeof(T)); } + /// Enables us to bind a function pointer to the components dispose function + private static void DisposeComponent(void* component) where T : IDisposableComponent + { + T* myComponent = (T*)component; + (*myComponent).Dispose(); + } + /** @brief Returns the component pool for the given component type. * @param TComponent The type of the component whose component pool will be returned. * @returns A reference to the component pool. @@ -137,7 +144,7 @@ namespace GlitchyEngine.World // Get pointer to component void* component = pool.Pool.Get(listEntity.ID.Index); // Dispose component - pool.DisposeFunction(component); + pool.DisposeComponent(component); } } } @@ -218,7 +225,7 @@ namespace GlitchyEngine.World listEntity.ComponentMask[entry.Id] = false; // Get component and call dispose - T.DisposeComponent(entry.Pool.Get(entity.Index)); + DisposeComponent(entry.Pool.Get(entity.Index)); } public T* GetComponent(Entity entity) where T : struct @@ -307,10 +314,9 @@ namespace GlitchyEngine.World { public bool IsDisposed; - public static void DisposeComponent(void* component) + public void Dispose() mut { - Self* testComponent = (Self*)component; - testComponent.IsDisposed = true; + IsDisposed = true; } } diff --git a/GlitchyEngine/src/World/IDisposableComponent.bf b/GlitchyEngine/src/World/IDisposableComponent.bf index 4340615..c9ce271 100644 --- a/GlitchyEngine/src/World/IDisposableComponent.bf +++ b/GlitchyEngine/src/World/IDisposableComponent.bf @@ -7,6 +7,6 @@ namespace GlitchyEngine.World * @Note This function will be called when the given component was removed from the entity * or when the entity itself was removed. */ - static void DisposeComponent(void* component); + void Dispose() mut; } } diff --git a/GlitchyEngine/src/World/MeshRendererComponent.bf b/GlitchyEngine/src/World/MeshRendererComponent.bf index 5510666..303eb8c 100644 --- a/GlitchyEngine/src/World/MeshRendererComponent.bf +++ b/GlitchyEngine/src/World/MeshRendererComponent.bf @@ -23,10 +23,9 @@ namespace GlitchyEngine.World } } - public static void DisposeComponent(void* component) + public void Dispose() mut { - Self* meshRenderComponent = (Self*)component; - meshRenderComponent._material?.ReleaseRef(); + _material?.ReleaseRef(); } } } diff --git a/GlitchyEngine/src/World/SkinnedMeshRendererComponent.bf b/GlitchyEngine/src/World/SkinnedMeshRendererComponent.bf index 7b45f96..e3047b3 100644 --- a/GlitchyEngine/src/World/SkinnedMeshRendererComponent.bf +++ b/GlitchyEngine/src/World/SkinnedMeshRendererComponent.bf @@ -40,12 +40,10 @@ namespace GlitchyEngine.World } } - public static void DisposeComponent(void* component) + public void Dispose() { - Self* meshRenderComponent = (Self*)component; - - meshRenderComponent._material?.ReleaseRef(); - meshRenderComponent._skeleton?.ReleaseRef(); + _material?.ReleaseRef(); + _skeleton?.ReleaseRef(); } } } From 664ba552ea9c0a4ed819f6203d90d93f84b46c5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20L=C3=BCbe=C3=9F?= Date: Thu, 30 Dec 2021 16:52:32 +0100 Subject: [PATCH 4/5] Added struct and disposable component Generators --- .../NewDisposableComponentGenerator.bf | 40 +++++++++++++++++++ .../src/Generators/NewStructGenerator.bf | 32 +++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 GlitchyEngine/src/Generators/NewDisposableComponentGenerator.bf create mode 100644 GlitchyEngine/src/Generators/NewStructGenerator.bf diff --git a/GlitchyEngine/src/Generators/NewDisposableComponentGenerator.bf b/GlitchyEngine/src/Generators/NewDisposableComponentGenerator.bf new file mode 100644 index 0000000..c512318 --- /dev/null +++ b/GlitchyEngine/src/Generators/NewDisposableComponentGenerator.bf @@ -0,0 +1,40 @@ +using System; +using System.Text; +using static System.Compiler; + +namespace GlitchyEngine.Generators +{ + public class NewDisposableComponentGenerator : Generator + { + public override String Name => "New Disposable Component"; + + public override void InitUI() + { + AddEdit("name", "Component Name", ""); + } + + public override void Generate(String outFileName, String outText, ref Flags generateFlags) + { + var name = mParams["name"]; + if (name.EndsWith(".bf", .OrdinalIgnoreCase)) + name.RemoveFromEnd(3); + outFileName.Append(name); + + outText.AppendF( + $""" + using GlitchyEngine.World; + + namespace {Namespace} + {{ + struct {name} : IDisposableComponent + {{ + public void Dispose() mut + {{ + // TODO: Dispose of the content + }} + }} + }} + """); + } + } +} \ No newline at end of file diff --git a/GlitchyEngine/src/Generators/NewStructGenerator.bf b/GlitchyEngine/src/Generators/NewStructGenerator.bf new file mode 100644 index 0000000..d7fc1bd --- /dev/null +++ b/GlitchyEngine/src/Generators/NewStructGenerator.bf @@ -0,0 +1,32 @@ +using System; +using static System.Compiler; + +namespace GlitchyEngine.Generators +{ + public class NewStructGenerator : Generator + { + public override String Name => "New Struct"; + + public override void InitUI() + { + AddEdit("name", "Struct Name", ""); + } + + public override void Generate(String outFileName, String outText, ref Flags generateFlags) + { + var name = mParams["name"]; + if (name.EndsWith(".bf", .OrdinalIgnoreCase)) + name.RemoveFromEnd(3); + outFileName.Append(name); + outText.AppendF( + $""" + namespace {Namespace} + {{ + struct {name} + {{ + }} + }} + """); + } + } +} \ No newline at end of file From b2ce560bfc3952d3e9fabb8a3b88f105a794871d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20L=C3=BCbe=C3=9F?= Date: Sat, 1 Jan 2022 19:34:59 +0100 Subject: [PATCH 5/5] Added DepthStencilState --- .../DX11/Renderer/Dx11DepthStencilState.bf | 62 +++++++++++++ .../Platform/DX11/Renderer/Dx11RendererAPI.bf | 8 ++ .../src/Renderer/DepthStencilState.bf | 93 +++++++++++++++++++ GlitchyEngine/src/Renderer/RenderCommand.bf | 5 + GlitchyEngine/src/Renderer/RendererAPI.bf | 2 + 5 files changed, 170 insertions(+) create mode 100644 GlitchyEngine/src/Platform/DX11/Renderer/Dx11DepthStencilState.bf create mode 100644 GlitchyEngine/src/Renderer/DepthStencilState.bf diff --git a/GlitchyEngine/src/Platform/DX11/Renderer/Dx11DepthStencilState.bf b/GlitchyEngine/src/Platform/DX11/Renderer/Dx11DepthStencilState.bf new file mode 100644 index 0000000..4e32b13 --- /dev/null +++ b/GlitchyEngine/src/Platform/DX11/Renderer/Dx11DepthStencilState.bf @@ -0,0 +1,62 @@ +#if GE_GRAPHICS_DX11 + +using DirectX.D3D11; +using GlitchyEngine.Platform.DX11; + +using internal GlitchyEngine.Renderer; +using internal GlitchyEngine.Platform.DX11; + +namespace GlitchyEngine.Renderer +{ + internal typealias D3DDepthStencilStateDesc = DirectX.D3D11.DepthStencilStateDescription; + internal typealias DxDSSDesc = DirectX.D3D11.DepthStencilStateDescription; + internal typealias GEDSSDesc = GlitchyEngine.Renderer.DepthStencilStateDescription; + + internal typealias DxDepthStencilOpDesc = DirectX.D3D11.DepthStencilOperationDescription; + + extension StencilOperation + { + public static explicit operator DirectX.D3D11.StencilOperation(Self self) + { + return (.)self.Underlying; + } + } + + extension DepthStencilOperationDescription + { + public static explicit operator DxDepthStencilOpDesc(Self desc) + { + return DxDepthStencilOpDesc((.)desc.StencilFailOperation, (.)desc.StencilDepthFailOperation, + (.)desc.StencilPassOperation, (.)desc.StencilFunction); + } + } + + extension DepthStencilStateDescription + { + public static explicit operator DxDSSDesc(Self desc) + { + return DxDSSDesc(desc.DepthEnabled, desc.WriteDepth ? .All : .Zero, (.)desc.DepthFunction, desc.StencilEnabled, + desc.StencilReadMask, desc.StencilWriteMask, (.)desc.FrontFace, (.)desc.BackFace); + } + } + + extension DepthStencilState + { + internal DxDSSDesc nativeDescription; + internal ID3D11DepthStencilState* nativeDepthStencilState ~ _?.Release(); + + public this(GEDSSDesc description) + { + _description = description; + nativeDescription = (.)description; + + var result = NativeDevice.CreateDepthStencilState(ref nativeDescription, &nativeDepthStencilState); + if (result.Failed) + { + Log.EngineLogger.Error($"Failed to create depth stencil state. Message({(int)result}): {result}"); + } + } + } +} + +#endif diff --git a/GlitchyEngine/src/Platform/DX11/Renderer/Dx11RendererAPI.bf b/GlitchyEngine/src/Platform/DX11/Renderer/Dx11RendererAPI.bf index 3c4bfae..a1f9261 100644 --- a/GlitchyEngine/src/Platform/DX11/Renderer/Dx11RendererAPI.bf +++ b/GlitchyEngine/src/Platform/DX11/Renderer/Dx11RendererAPI.bf @@ -87,6 +87,14 @@ namespace GlitchyEngine.Renderer SetReference!(_currentBlendState, blendState); NativeContext.OutputMerger.SetBlendState(_currentBlendState.nativeBlendState, blendFactor); } + + private DepthStencilState _currentDepthStencilState ~ _?.ReleaseRef(); + + public override void SetDepthStencilState(DepthStencilState depthStencilState, uint8 stencilReference) + { + SetReference!(_currentDepthStencilState, depthStencilState); + NativeContext.OutputMerger.SetDepthStencilState(_currentDepthStencilState.nativeDepthStencilState, stencilReference); + } public override void DrawIndexed(GeometryBinding geometry) { diff --git a/GlitchyEngine/src/Renderer/DepthStencilState.bf b/GlitchyEngine/src/Renderer/DepthStencilState.bf new file mode 100644 index 0000000..cdde756 --- /dev/null +++ b/GlitchyEngine/src/Renderer/DepthStencilState.bf @@ -0,0 +1,93 @@ +using GlitchyEngine.Core; + +namespace GlitchyEngine.Renderer +{ + /// The stencil operations that can be performed during depth-stencil testing. + public enum StencilOperation : uint32 + { + /// Keep the existing stencil data. + Keep = 1, + /// Set the stencil data to 0. + Zero= 2, + /// Set the stencil data to the reference value set by calling ID3D11DeviceContext::OMSetDepthStencilState. + Replace = 3, + /// Increment the stencil value by 1, and clamp the result. + IncrementAndClamp = 4, + /// Decrement the stencil value by 1, and clamp the result. + DecrementAndClamp = 5, + /// Invert the stencil data. + Invert = 6, + /// Increment the stencil value by 1, and wrap the result if necessary. + Increment = 7, + /// Decrement the stencil value by 1, and wrap the result if necessary. + Decrement = 8 + } + + public struct DepthStencilOperationDescription + { + /// The stencil operation to perform when stencil testing fails. + public StencilOperation StencilFailOperation = .Keep; + + /// The stencil operation to perform when stencil testing passes and depth testing fails. + public StencilOperation StencilDepthFailOperation = .Keep; + + /// The stencil operation to perform when stencil testing and depth testing both pass. + public StencilOperation StencilPassOperation = .Keep; + + /// A function that compares stencil data against existing stencil data. + public ComparisonFunction StencilFunction = .Always; + + public this(StencilOperation stencilFailOperation = .Keep, StencilOperation stencilDepthFailOperation = .Keep, + StencilOperation stencilPassOperation = .Keep, ComparisonFunction stencilFunction = .Always) + { + StencilFunction = stencilFunction; + } + + public const Self Default = Self(); + } + + public struct DepthStencilStateDescription + { + /// True if depth testing is enabled. + public bool DepthEnabled = true; + + /// If true writing to the depth-stencil buffer is enabled. + public bool WriteDepth = true; + + /// The function that is used to compare depth data against the existing depth data. + public ComparisonFunction DepthFunction = .Less; + + /// True if stencil testing is enabled. + public bool StencilEnabled = false; + + public uint8 StencilReadMask = 255; + public uint8 StencilWriteMask = 255; + + public DepthStencilOperationDescription FrontFace = .(); + public DepthStencilOperationDescription BackFace = .(); + + public this(bool depthEnabled = true, bool writeDepth = true, ComparisonFunction depthFunction = .Less, + bool stencilEnabled = false, uint8 stencilReadMask = 255, uint8 stencilWriteMask = 255, + DepthStencilOperationDescription frontFace = .(), + DepthStencilOperationDescription backFace = .()) + { + DepthEnabled = depthEnabled; + WriteDepth = writeDepth; + DepthFunction = depthFunction; + StencilEnabled = stencilEnabled; + StencilReadMask = stencilReadMask; + StencilWriteMask = stencilWriteMask; + FrontFace = frontFace; + BackFace = backFace; + } + + public const DepthStencilStateDescription Default = Self(); + } + + class DepthStencilState : RefCounter + { + public DepthStencilStateDescription _description; + + public extern this(DepthStencilStateDescription description); + } +} \ No newline at end of file diff --git a/GlitchyEngine/src/Renderer/RenderCommand.bf b/GlitchyEngine/src/Renderer/RenderCommand.bf index 40c9f0f..14690b5 100644 --- a/GlitchyEngine/src/Renderer/RenderCommand.bf +++ b/GlitchyEngine/src/Renderer/RenderCommand.bf @@ -75,6 +75,11 @@ namespace GlitchyEngine.Renderer { _rendererAPI.SetBlendState(blendState, blendFactor); } + + public static void SetDepthStencilState(DepthStencilState depthStencilState, uint8 stencilReference = 0) + { + _rendererAPI.SetDepthStencilState(depthStencilState, stencilReference); + } [Inline] public static void DrawIndexed(GeometryBinding geometry) diff --git a/GlitchyEngine/src/Renderer/RendererAPI.bf b/GlitchyEngine/src/Renderer/RendererAPI.bf index 322bdba..4e2cf7b 100644 --- a/GlitchyEngine/src/Renderer/RendererAPI.bf +++ b/GlitchyEngine/src/Renderer/RendererAPI.bf @@ -42,6 +42,8 @@ namespace GlitchyEngine.Renderer public extern void SetBlendState(BlendState blendState, ColorRGBA blendFactor); + public extern void SetDepthStencilState(DepthStencilState depthStencilState, uint8 stencilReference); + public extern void DrawIndexed(GeometryBinding geometry); public extern void DrawInstanced(GeometryBinding geometry);