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);