diff --git a/GlitchyEditor/content/Shaders/ClearUInt.hlsl b/GlitchyEditor/content/Shaders/ClearUInt.hlsl new file mode 100644 index 0000000..f20eb92 --- /dev/null +++ b/GlitchyEditor/content/Shaders/ClearUInt.hlsl @@ -0,0 +1,16 @@ +cbuffer Constants : register(b0) +{ + uint ClearValue; +} + +float4 VS(float2 input : POSITION) : SV_Position +{ + return float4(input, 0.0f, 1.0f); +} + +uint PS(float4 input : SV_Position) : SV_Target0 +{ + return ClearValue; +} + +#effect[VS = VS, PS = PS] \ No newline at end of file diff --git a/GlitchyEditor/content/Shaders/myEffect.hlsl b/GlitchyEditor/content/Shaders/myEffect.hlsl index 8e8797f..11524f4 100644 --- a/GlitchyEditor/content/Shaders/myEffect.hlsl +++ b/GlitchyEditor/content/Shaders/myEffect.hlsl @@ -1,3 +1,5 @@ +#define OutputEntityId + #include "ShaderHelpers.hlsl" Texture2D AlbedoTexture : register(t0); @@ -28,6 +30,9 @@ cbuffer ObjectConstants * \remarks This matrix is used in order to correctly transform normal vectors. */ float3x3 Transform_InvT; +#ifdef OutputEntityId + uint EntityId; +#endif } cbuffer Constants @@ -60,6 +65,9 @@ struct PS_IN float3 Tangent : TANGENT; float2 TexCoord : TEXCOORD; //nointerpolation float Handedness : HANDEDNESS; +#ifdef OutputEntityId + nointerpolation uint EntityId : ENTITYID; +#endif }; PS_IN VS(VS_IN input) @@ -76,6 +84,8 @@ PS_IN VS(VS_IN input) // TODO: output.Handedness = input.Tangent.w output.TexCoord = input.TexCoord; + + output.EntityId = EntityId; return output; } @@ -90,6 +100,9 @@ struct PS_OUT float4 Position : SV_TARGET3; // R: Metallicity G: Roughness B: Ambient float4 Material : SV_TARGET4; +#ifdef OutputEntityId + uint EntityId : SV_TARGET5; +#endif }; PS_OUT PS(PS_IN input) @@ -134,6 +147,10 @@ PS_OUT PS(PS_IN input) output.Position = float4(input.WorldPosition, 1.0); output.Material = float4(finalMetallic, finalRoughness, 1.0, 0); +#ifdef OutputEntityId + output.EntityId = input.EntityId; +#endif + return output; } diff --git a/GlitchyEditor/src/EditWindows/EntityHierarchyWindow.bf b/GlitchyEditor/src/EditWindows/EntityHierarchyWindow.bf index 537b1c7..b761d19 100644 --- a/GlitchyEditor/src/EditWindows/EntityHierarchyWindow.bf +++ b/GlitchyEditor/src/EditWindows/EntityHierarchyWindow.bf @@ -33,7 +33,17 @@ namespace GlitchyEditor.EditWindows _selectedEntities.Clear(); _scene = scene; } - + + /*public bool SelectEntityWithId(uint32 id, bool addToSelection = false) + { + if (!addToSelection) + _selectedEntities.Clear(); + + _scene.[Friend]_ecsWorld.IsValid(id); + + _selectedEntities.Add(); + }*/ + protected override void InternalShow() { if(!ImGui.Begin(s_WindowTitle, &_open, .MenuBar)) diff --git a/GlitchyEditor/src/EditWindows/SceneViewportWindow.bf b/GlitchyEditor/src/EditWindows/SceneViewportWindow.bf index fd9adc0..ed29e38 100644 --- a/GlitchyEditor/src/EditWindows/SceneViewportWindow.bf +++ b/GlitchyEditor/src/EditWindows/SceneViewportWindow.bf @@ -12,11 +12,11 @@ namespace GlitchyEditor.EditWindows { public const String s_WindowTitle = "Scene"; - private RenderTarget2D _renderTarget ~ _?.ReleaseRef(); + private RenderTargetGroup _renderTarget ~ _?.ReleaseRef(); public Event> ViewportSizeChangedEvent ~ _.Dispose(); - public RenderTarget2D RenderTarget + public RenderTargetGroup RenderTarget { get => _renderTarget; set @@ -93,7 +93,34 @@ namespace GlitchyEditor.EditWindows if(_renderTarget != null) { - ImGui.Image(_renderTarget, viewportSize); + ImGui.Image(_renderTarget.GetViewBinding(0), viewportSize); + } + + Vector2 relativeMouse = (Vector2)ImGui.GetMousePos() - (Vector2)ImGui.GetItemRectMin(); + + int x = Renderer.[Friend]_gBuffer.Target.Width; + int y = Renderer.[Friend]_gBuffer.Target.Height; + + if (Input.IsMouseButtonPressing(.LeftButton) && relativeMouse.X >= 0 && relativeMouse.Y >= 0 && + relativeMouse.X < viewportSize.x && relativeMouse.Y < viewportSize.y && + relativeMouse.X < x && relativeMouse.Y < y) + { + uint32 id = 0; + + Renderer.[Friend]_gBuffer.Target.GetData(&id, 5, (.)relativeMouse.X, (.)relativeMouse.Y, 1, 1); + + id--; + + //_renderTarget.GetData(&pixel, 0, ); + + Log.EngineLogger.Info($"{relativeMouse} || ID = {id}"); + + /*if (id != uint32.MaxValue) + { + _editor.CurrentScene.[Friend]_ecsWorld.GetCurrentVersion() + }*/ + //_editor.EntityHierarchyWindow.SelectEntityWithId(id, true); + } DrawImGuizmo(viewportSize); diff --git a/GlitchyEditor/src/EditorLayer.bf b/GlitchyEditor/src/EditorLayer.bf index 173dd48..6a2a61e 100644 --- a/GlitchyEditor/src/EditorLayer.bf +++ b/GlitchyEditor/src/EditorLayer.bf @@ -44,7 +44,7 @@ namespace GlitchyEditor Editor _editor ~ delete _; RenderTarget2D _cameraTarget ~ _.ReleaseRef(); - RenderTarget2D _viewportTarget ~ _.ReleaseRef(); + RenderTargetGroup _viewportTarget ~ _.ReleaseRef(); SettingsWindow _settingsWindow = new .() ~ delete _; @@ -89,8 +89,16 @@ namespace GlitchyEditor _cameraTarget = new RenderTarget2D(RenderTarget2DDescription(.R16G16B16A16_Float, 100, 100) {DepthStencilFormat = .D32_Float}); _cameraTarget.SamplerState = SamplerStateManager.LinearClamp; - _viewportTarget = new RenderTarget2D(RenderTarget2DDescription(.R8G8B8A8_UNorm, 100, 100)); - _viewportTarget.SamplerState = SamplerStateManager.LinearClamp; + //_viewportTarget = new RenderTarget2D(RenderTarget2DDescription(.R8G8B8A8_UNorm, 100, 100)); + //_viewportTarget.SamplerState = SamplerStateManager.LinearClamp; + + _viewportTarget = new RenderTargetGroup(.() + { + Width = 100, + Height = 100, + ColorTargetDescriptions = TargetDescription[]( + .(.R8G8B8A8_UNorm)) + }); _editorIcons = new Texture2D("Textures/EditorIcons.dds"); _editorIcons.SamplerState = SamplerStateManager.AnisotropicClamp; @@ -114,7 +122,7 @@ namespace GlitchyEditor RenderCommand.Clear(_viewportTarget, .Color | .Depth, .(0.2f, 0.2f, 0.2f), 1.0f, 0); - RenderCommand.SetRenderTarget(_viewportTarget, 0, true); + RenderCommand.SetRenderTargetGroup(_viewportTarget, true); RenderCommand.BindRenderTargets(); RenderCommand.SetViewport(Viewport(0, 0, _viewportTarget.Width, _viewportTarget.Height)); diff --git a/GlitchyEngine/src/ImGui/ImGuiExtension.bf b/GlitchyEngine/src/ImGui/ImGuiExtension.bf index 7bde94d..b23abbb 100644 --- a/GlitchyEngine/src/ImGui/ImGuiExtension.bf +++ b/GlitchyEngine/src/ImGui/ImGuiExtension.bf @@ -29,9 +29,17 @@ namespace ImGui public static bool ColorPicker4(char* label, ref ColorRGBA col, ColorEditFlags flags = (ColorEditFlags) 0, float* ref_col = null) => ColorPicker4Impl(label, *(float[4]*)&col, flags, ref_col); - public static extern void Image(Texture2D texture, Vec2 size, Vec2 uv0 = Vec2.Zero, Vec2 uv1 = Vec2.Ones, Vec4 tint_col = Vec4.Ones, Vec4 border_col = Vec4.Zero); - // Wouldn't be necesseary if RenderTarget2D was Texture2D - public static extern void Image(RenderTarget2D texture, Vec2 size, Vec2 uv0 = Vec2.Zero, Vec2 uv1 = Vec2.Ones, Vec4 tint_col = Vec4.Ones, Vec4 border_col = Vec4.Zero); + public static void Image(Texture2D 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); + } + + 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); + } + + 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 void TextUnformatted(StringView text) => TextUnformattedImpl(text.Ptr, text.Ptr + text.Length); diff --git a/GlitchyEngine/src/Platform/DX11/ImGui/ImGui.bf b/GlitchyEngine/src/Platform/DX11/ImGui/ImGui.bf index 78744a8..c82728e 100644 --- a/GlitchyEngine/src/Platform/DX11/ImGui/ImGui.bf +++ b/GlitchyEngine/src/Platform/DX11/ImGui/ImGui.bf @@ -12,20 +12,14 @@ namespace ImGui { static List _resourceViews = new .() ~ delete _; - public static override void Image(Texture2D texture, Vec2 size, Vec2 uv0 = Vec2.Zero, Vec2 uv1 = Vec2.Ones, Vec4 tint_col = Vec4.Ones, Vec4 border_col = Vec4.Zero) + public static override void Image(TextureViewBinding textureViewBinding, Vec2 size, Vec2 uv0 = Vec2.Zero, Vec2 uv1 = Vec2.Ones, Vec4 tint_col = Vec4.Ones, Vec4 border_col = Vec4.Zero) { - var view = texture._nativeResourceView..AddRef(); + var view = textureViewBinding._nativeShaderResourceView..AddRef(); _resourceViews.Add(view); ImGui.Image(view, size, uv0, uv1, tint_col, border_col); - } - public static override void Image(RenderTarget2D texture, Vec2 size, Vec2 uv0 = Vec2.Zero, Vec2 uv1 = Vec2.Ones, Vec4 tint_col = Vec4.Ones, Vec4 border_col = Vec4.Zero) - { - var view = texture._nativeResourceView..AddRef(); - _resourceViews.Add(view); - - ImGui.Image(view, size, uv0, uv1, tint_col, border_col); + textureViewBinding.ReleaseRef(); } protected internal static override void CleanupFrame() diff --git a/GlitchyEngine/src/Platform/DX11/Renderer/Dx11ConstantBuffer.bf b/GlitchyEngine/src/Platform/DX11/Renderer/Dx11ConstantBuffer.bf index 9b2c17d..07b9fab 100644 --- a/GlitchyEngine/src/Platform/DX11/Renderer/Dx11ConstantBuffer.bf +++ b/GlitchyEngine/src/Platform/DX11/Renderer/Dx11ConstantBuffer.bf @@ -37,6 +37,8 @@ namespace GlitchyEngine.Renderer _type = .Float; case .Int: _type = .Int; + case .UInt: + _type = .UInt; default: Log.EngineLogger.Assert(false, scope $"Unhandled shader variable type: {shaderTypeDescription.Type}"); } diff --git a/GlitchyEngine/src/Platform/DX11/Renderer/Dx11RenderTarget.bf b/GlitchyEngine/src/Platform/DX11/Renderer/Dx11RenderTarget.bf index 02b8800..c30b294 100644 --- a/GlitchyEngine/src/Platform/DX11/Renderer/Dx11RenderTarget.bf +++ b/GlitchyEngine/src/Platform/DX11/Renderer/Dx11RenderTarget.bf @@ -4,6 +4,7 @@ using DirectX.Common; using DirectX.D3D11; using GlitchyEngine.Platform.DX11; using DirectX.DXGI.DXGI1_2; +using System; using internal GlitchyEngine.Platform.DX11; @@ -131,6 +132,11 @@ namespace GlitchyEngine.Renderer { switch(this) { + case .R8_SInt: + return .R8_SInt; + case .R32_UInt: + return .R32_UInt; + case .R8G8B8A8_UNorm: return .R8G8B8A8_UNorm; case .R8G8B8A8_SNorm: @@ -179,6 +185,7 @@ namespace GlitchyEngine.Renderer extension RenderTargetGroup { + protected uint32 _mipLevels; internal ID3D11Texture2D*[] _nativeTextures; internal ID3D11RenderTargetView*[] _renderTargetViews; internal ID3D11ShaderResourceView*[] _nativeResourceViews; @@ -218,6 +225,11 @@ namespace GlitchyEngine.Renderer var result = NativeDevice.CreateTexture2D(ref desc, null, &texture); Log.EngineLogger.Assert(result.Succeeded, "Failed to create RenderTarget2D"); + // TODO: calculate the max mip level + // Read back the description to get the actual mip level count. + texture.GetDescription(let actualDesc); + _mipLevels = actualDesc.MipLevels; + return texture; } @@ -374,6 +386,63 @@ namespace GlitchyEngine.Renderer return .(_nativeResourceViews[index], _colorSamplerStates[index].nativeSamplerState); } } + + protected override Result PlatformGetData(void* destination, uint32 elementSize, uint32 x, uint32 y, uint32 width, uint32 height, int renderTarget, uint32 arraySlice, uint32 mipLevel) // mapType? + { + Debug.Profiler.ProfileResourceFunction!(); + + ID3D11Texture2D* texture = renderTarget == -1 ? _nativeDepthTexture : _nativeTextures[renderTarget]; + + if (texture == null) + return .Err; + + // TODO: Dynamic textures with CPU read access don't need a staging texture. + + ID3D11Texture2D* stagingTexture = null; + + Texture2DDescription stagingDesc = .(); + stagingDesc.Width = width; + stagingDesc.Height = height; + stagingDesc.MipLevels = 1; + stagingDesc.ArraySize = 1; + stagingDesc.Format = _colorTargetDescriptions[renderTarget].Format.GetTextureFormat(); + stagingDesc.SampleDesc = .(_description.Samples, 0); + stagingDesc.Usage = .Staging; + stagingDesc.BindFlags = .None; + stagingDesc.CpuAccessFlags = .Read; + stagingDesc.MiscFlags = .None; + + var result = NativeDevice.CreateTexture2D(ref stagingDesc, null, &stagingTexture); + if (result != 0) + return .Err; + + defer stagingTexture.Release(); + + uint32 srcSubResource = D3D11.CalcSubresource(mipLevel, arraySlice, _mipLevels); + + Box srcBox = .(x, y, arraySlice, x + width, y + height, arraySlice + 1); + + NativeContext.CopySubresourceRegion(stagingTexture, 0, 0, 0, 0, texture, srcSubResource, &srcBox); + + MappedSubresource subresource = ?; + result = NativeContext.Map(stagingTexture, 0, .Read, .None, &subresource); + defer NativeContext.Unmap(stagingTexture, 0); + + if (result != 0) + return .Err; + + for (int i < height) + { + uint32 destRowLength = elementSize * width; + + uint32 count = Math.Min(destRowLength, subresource.RowPitch); + + Internal.MemCpy((uint8*)destination + i * destRowLength, (uint8*)subresource.Data + i * subresource.RowPitch, + count); + } + + return .Ok; + } } } diff --git a/GlitchyEngine/src/Platform/DX11/Renderer/Dx11RendererAPI.bf b/GlitchyEngine/src/Platform/DX11/Renderer/Dx11RendererAPI.bf index 03ee8f7..c1cc715 100644 --- a/GlitchyEngine/src/Platform/DX11/Renderer/Dx11RendererAPI.bf +++ b/GlitchyEngine/src/Platform/DX11/Renderer/Dx11RendererAPI.bf @@ -2,6 +2,7 @@ using GlitchyEngine.Math; using GlitchyEngine.Platform.DX11; +using System; using internal GlitchyEngine.Renderer; using internal GlitchyEngine.Platform.DX11; @@ -61,14 +62,31 @@ namespace GlitchyEngine.Renderer NativeContext.ClearDepthStencilView(target.nativeView, flags, depth, stencil); } - public override void Clear(RenderTargetGroup renderTarget, ClearOptions options, ColorRGBA? color = null, float? depth = null, uint8? stencil = null) + private void ClearRtv(DirectX.D3D11.ID3D11RenderTargetView* rtv, ClearColor clearColor) + { + switch(clearColor) + { + case .Color(let color): + NativeContext.ClearRenderTargetView(rtv, color); + case .UInt(let value): +/*#unwarn + NativeContext.OutputMerger.SetRenderTargets(1, &rtv, null); + + + + BindRenderTargets();*/ + default: + Runtime.NotImplemented(); + } + } + + public override void Clear(RenderTargetGroup renderTarget, ClearOptions options, ClearColor? color = null, float? depth = null, uint8? stencil = null) { if (options.HasFlag(.Color) && renderTarget._renderTargetViews != null) { for (int i < renderTarget._renderTargetViews.Count) { - NativeContext.ClearRenderTargetView(renderTarget._renderTargetViews[i], - color ?? renderTarget._colorTargetDescriptions[i].ClearColor); + ClearRtv(renderTarget._renderTargetViews[i], color ?? renderTarget._colorTargetDescriptions[i].ClearColor); } } @@ -88,9 +106,24 @@ namespace GlitchyEngine.Renderer if (flags != default) { - NativeContext.ClearDepthStencilView(renderTarget._nativeDepthTargetView, flags, - renderTarget._depthTargetDescription.ClearColor.R, - (uint8)renderTarget._depthTargetDescription.ClearColor.G); + float clearDepth = 0.0f; + uint8 clearStencil = 0; + + if (renderTarget._depthTargetDescription.ClearColor case .DepthStencil(let d, let s)) + { + clearDepth = d; + clearStencil = s; + } + else + { + Log.EngineLogger.Error("Clear color of depth stencil target must be of type DepthStencil."); + Log.EngineLogger.AssertDebug(false); + } + + clearDepth = depth ?? clearDepth; + clearStencil = stencil ?? clearStencil; + + NativeContext.ClearDepthStencilView(renderTarget._nativeDepthTargetView, flags, clearDepth, clearStencil); } } } diff --git a/GlitchyEngine/src/Renderer/BufferVariable.bf b/GlitchyEngine/src/Renderer/BufferVariable.bf index 2d06747..19af71b 100644 --- a/GlitchyEngine/src/Renderer/BufferVariable.bf +++ b/GlitchyEngine/src/Renderer/BufferVariable.bf @@ -96,6 +96,9 @@ namespace GlitchyEngine.Renderer case typeof(Int4): EnsureTypeMatch(1, 4, .Int); + case typeof(uint32): + EnsureTypeMatch(1, 1, .UInt); + case typeof(Matrix4x3): EnsureTypeMatch(4, 3, .Float); case typeof(Matrix3x3): diff --git a/GlitchyEngine/src/Renderer/ConstantBuffer.bf b/GlitchyEngine/src/Renderer/ConstantBuffer.bf index 8d6596d..0c2b995 100644 --- a/GlitchyEngine/src/Renderer/ConstantBuffer.bf +++ b/GlitchyEngine/src/Renderer/ConstantBuffer.bf @@ -102,6 +102,7 @@ namespace GlitchyEngine.Renderer Bool, Float, Int, + UInt // todo } } diff --git a/GlitchyEngine/src/Renderer/FullscreenQuad.bf b/GlitchyEngine/src/Renderer/FullscreenQuad.bf new file mode 100644 index 0000000..42a6352 --- /dev/null +++ b/GlitchyEngine/src/Renderer/FullscreenQuad.bf @@ -0,0 +1,52 @@ +namespace GlitchyEngine.Renderer +{ + static class FullscreenQuad + { + //static GeometryBinding s_fullscreenQuadGeometry; + + public static void Init() + { + /*s_fullscreenQuadGeometry = new GeometryBinding(); + s_fullscreenQuadGeometry.SetPrimitiveTopology(.TriangleList); + + using(var quadVertices = new VertexBuffer(typeof(Vector4), 4, .Immutable)) + { + Vector4[4] vertices = .( + .(-1,-1, 0, 1), + .(-1, 1, 0, 0), + .( 1, 1, 1, 0), + .( 1,-1, 1, 1) + ); + + quadVertices.SetData(vertices); + s_fullscreenQuadGeometry.SetVertexBufferSlot(quadVertices, 0); + } + + using(var quadIndices = new IndexBuffer(6, .Immutable)) + { + uint16[6] indices = .( + 0, 1, 2, + 2, 3, 0 + ); + + quadIndices.SetData(indices); + s_fullscreenQuadGeometry.SetIndexBuffer(quadIndices); + } + + VertexElement[] vertexElements = new .( + VertexElement(.R32G32_Float, "POSITION"), + VertexElement(.R32G32_Float, "TEXCOORD") + ); + + using (var quadBatchLayout = new VertexLayout(vertexElements, true, TestFullscreenEffect.VertexShader)) + { + s_fullscreenQuadGeometry.SetVertexLayout(quadBatchLayout); + }*/ + } + + public static void Deinit() + { + //s_fullscreenQuadGeometry.ReleaseRef(); + } + } +} \ No newline at end of file diff --git a/GlitchyEngine/src/Renderer/Material.bf b/GlitchyEngine/src/Renderer/Material.bf index ff8a17f..86cd5f2 100644 --- a/GlitchyEngine/src/Renderer/Material.bf +++ b/GlitchyEngine/src/Renderer/Material.bf @@ -132,6 +132,8 @@ namespace GlitchyEngine.Renderer public void SetVariable(String name, Int3 value) => SetVariable(name, value); public void SetVariable(String name, Int4 value) => SetVariable(name, value); + public void SetVariable(String name, uint32 value) => SetVariable(name, value); + public void SetVariable(String name, Color value) => SetVariable(name, value); public void SetVariable(String name, ColorRGB value) => SetVariable(name, value); public void SetVariable(String name, ColorRGBA value) => SetVariable(name, value); diff --git a/GlitchyEngine/src/Renderer/RenderTarget.bf b/GlitchyEngine/src/Renderer/RenderTarget.bf index 243bd55..3bc470d 100644 --- a/GlitchyEngine/src/Renderer/RenderTarget.bf +++ b/GlitchyEngine/src/Renderer/RenderTarget.bf @@ -88,6 +88,9 @@ namespace GlitchyEngine.Renderer case None = 0; + case R8_SInt; + case R32_UInt; + case R8G8B8A8_UNorm; case R8G8B8A8_SNorm; @@ -104,6 +107,18 @@ namespace GlitchyEngine.Renderer public bool IsDepth => HasFlag(DepthMarker); } + public enum ClearColor + { + case Color(ColorRGBA ClearColor); + case UInt(uint32 ClearValue); + case DepthStencil(float Depth, uint8 Stencil); + + public static implicit operator ClearColor(ColorRGBA color) + { + return .Color(color); + } + } + public struct TargetDescription { public RenderTargetFormat Format = .None; @@ -113,13 +128,13 @@ namespace GlitchyEngine.Renderer public bool IsShaderReadable = true; /// Clear color. For DepthStencilBuffers: R is Depth, G is Stencil - public ColorRGBA ClearColor = .Black; + public ClearColor ClearColor = .Color(.Black); public SamplerStateDescription SamplerDescription = .(); public this() { } - public this(RenderTargetFormat format, bool isSwapchainTarget = false, bool isShaderReadable = true, ColorRGBA clearColor = .Black, SamplerStateDescription samplerDescription = .()) + public this(RenderTargetFormat format, bool isSwapchainTarget = false, bool isShaderReadable = true, ClearColor clearColor = .Color(.(0, 0, 0, 1)), SamplerStateDescription samplerDescription = .()) { Format = format; IsSwapchainTarget = isSwapchainTarget; @@ -179,6 +194,9 @@ namespace GlitchyEngine.Renderer { _description = description; + Log.EngineLogger.AssertDebug(_description.Width != 0); + Log.EngineLogger.AssertDebug(_description.Height != 0); + var colorTargets = description.ColorTargetDescriptions; if (!colorTargets.IsNull && !colorTargets.IsEmpty) @@ -206,10 +224,12 @@ namespace GlitchyEngine.Renderer } _depthTargetDescription = description.DepthTargetDescription; - Log.EngineLogger.AssertDebug(_depthTargetDescription.Format.IsDepth, "Depth target must have depth format."); if (_depthTargetDescription.Format != .None) { + Log.EngineLogger.AssertDebug(_depthTargetDescription.Format.IsDepth, "Depth target must have depth format."); + Log.EngineLogger.AssertDebug(_depthTargetDescription.ClearColor case .DepthStencil, "Clear color for depth stencil target must be of type DepthStencil."); + _depthSamplerState = SamplerStateManager.GetSampler(_depthTargetDescription.SamplerDescription); } @@ -227,5 +247,16 @@ namespace GlitchyEngine.Renderer } protected extern TextureViewBinding PlatformGetViewBinding(int index); + + protected extern Result PlatformGetData(void* destination, uint32 elementSize, + uint32 x, uint32 y, uint32 width, uint32 height, int renderTarget, uint32 arraySlice, uint32 mipLevel); // mapType? + + public Result GetData(T* data, int renderTarget, uint32 left, uint32 top, uint32 width, uint32 height, uint32 arraySlice = 0, uint32 mipSlice = 0) + { + Log.EngineLogger.AssertDebug(left + width < Width); + Log.EngineLogger.AssertDebug(top + height < Height); + + return PlatformGetData(data, (.)sizeof(T), left, top, width, height, renderTarget, arraySlice, mipSlice); + } } } diff --git a/GlitchyEngine/src/Renderer/Renderer.bf b/GlitchyEngine/src/Renderer/Renderer.bf index d2ef627..716aa36 100644 --- a/GlitchyEngine/src/Renderer/Renderer.bf +++ b/GlitchyEngine/src/Renderer/Renderer.bf @@ -12,7 +12,7 @@ namespace GlitchyEngine.Renderer public Matrix ViewProjection; public Vector3 CameraPosition; public RenderTarget2D CameraTarget; - public RenderTarget2D CompositionTarget; + public RenderTargetGroup CompositionTarget; } struct ObjectConstants @@ -78,11 +78,12 @@ namespace GlitchyEngine.Renderer .(RenderTargetFormat.R16G16B16A16_SNorm){SamplerDescription = desc}, .(RenderTargetFormat.R16G16B16A16_SNorm){SamplerDescription = desc}, .(RenderTargetFormat.R32G32B32A32_Float){SamplerDescription = desc}, - .(RenderTargetFormat.R8G8B8A8_UNorm){SamplerDescription = desc} + .(RenderTargetFormat.R8G8B8A8_UNorm){SamplerDescription = desc}, + .(RenderTargetFormat.R32_UInt){SamplerDescription = desc, ClearColor = ColorRGBA(0, 0, 0, 0)}, ), TargetDescription(.D24_UNorm_S8_UInt){ SamplerDescription = desc, - ClearColor = .(1.0f, 0, 0) + ClearColor = .DepthStencil(1.0f, 0) }); Target = new RenderTargetGroup(targetDesc); } @@ -167,6 +168,7 @@ namespace GlitchyEngine.Renderer RenderCommand.Init(); Renderer2D.Init(); + FullscreenQuad.Init(); InitLineRenderer(effectLibrary); InitDeferredRenderer(effectLibrary); @@ -179,7 +181,8 @@ namespace GlitchyEngine.Renderer DeinitDeferredRenderer(); DeinitLineRenderer(); - + + FullscreenQuad.Deinit(); Renderer2D.Deinit(); _context.ReleaseRef(); @@ -303,7 +306,7 @@ namespace GlitchyEngine.Renderer //_sceneConstants.Update(); } - public static void BeginScene(Camera camera, Matrix transform, RenderTarget2D renderTarget, RenderTarget2D finalTarget) + public static void BeginScene(Camera camera, Matrix transform, RenderTarget2D renderTarget, RenderTargetGroup finalTarget) { Debug.Profiler.ProfileRendererFunction!(); @@ -314,7 +317,7 @@ namespace GlitchyEngine.Renderer _sceneConstants.CompositionTarget = finalTarget; } - public static void BeginScene(EditorCamera camera, RenderTarget2D finalTarget) + public static void BeginScene(EditorCamera camera, RenderTargetGroup finalTarget) { Debug.Profiler.ProfileRendererFunction!(); @@ -390,6 +393,8 @@ namespace GlitchyEngine.Renderer entry.Material.SetVariable("Transform", entry.Transform); + entry.Material.SetVariable("EntityId", entry.EntityId); + Matrix3x3 mat = (Matrix3x3)(entry.Transform).Invert().Transpose(); entry.Material.SetVariable("Transform_InvT", mat); } @@ -446,7 +451,7 @@ namespace GlitchyEngine.Renderer RenderCommand.SetBlendState(_gBufferBlend); - RenderCommand.SetRenderTarget(_sceneConstants.CompositionTarget, 0, false); + RenderCommand.SetRenderTargetGroup(_sceneConstants.CompositionTarget, true); RenderCommand.BindRenderTargets(); // TODO: Postprocessing effects @@ -491,12 +496,14 @@ namespace GlitchyEngine.Renderer public GeometryBinding Mesh; public Material Material; public Matrix Transform; + public uint32 EntityId; - public this(GeometryBinding mesh, Material material, Matrix transform) + public this(GeometryBinding mesh, Material material, Matrix transform, uint32 id) { Mesh = mesh..AddRef(); Material = material..AddRef(); Transform = transform; + EntityId = id; } public void Dispose() @@ -525,7 +532,14 @@ namespace GlitchyEngine.Renderer { Debug.Profiler.ProfileRendererFunction!(); - _queue.Add(SubmittedMesh(geometry, material, transform)); + _queue.Add(SubmittedMesh(geometry, material, transform, 0)); + } + + public static void Submit(GeometryBinding geometry, Material material, EcsEntity entity, Matrix transform = .Identity) + { + Debug.Profiler.ProfileRendererFunction!(); + + _queue.Add(SubmittedMesh(geometry, material, transform, entity.[Friend]Index)); } public static void Submit(SceneLight light, Matrix transform = .Identity) diff --git a/GlitchyEngine/src/Renderer/RendererAPI.bf b/GlitchyEngine/src/Renderer/RendererAPI.bf index c584d9e..bd7b244 100644 --- a/GlitchyEngine/src/Renderer/RendererAPI.bf +++ b/GlitchyEngine/src/Renderer/RendererAPI.bf @@ -21,7 +21,8 @@ namespace GlitchyEngine.Renderer public extern void Clear(DepthStencilTarget target, ClearOptions options, float depth, uint8 stencil); - public extern void Clear(RenderTargetGroup renderTarget, ClearOptions options, ColorRGBA? color = null, float? depth = null, uint8? stencil = null); + //public extern void Clear(RenderTargetGroup renderTarget, ClearOptions options, ColorRGBA? color = null, float? depth = null, uint8? stencil = null); + public extern void Clear(RenderTargetGroup renderTarget, ClearOptions options, ClearColor? color = null, float? depth = null, uint8? stencil = null); public void Clear(RenderTarget2D renderTarget, ClearOptions options, ColorRGBA color, float depth, uint8 stencil) { diff --git a/GlitchyEngine/src/World/EcsWorld.bf b/GlitchyEngine/src/World/EcsWorld.bf index e17a685..619e135 100644 --- a/GlitchyEngine/src/World/EcsWorld.bf +++ b/GlitchyEngine/src/World/EcsWorld.bf @@ -8,7 +8,7 @@ namespace GlitchyEngine.World { public class EcsWorld { - const int MaxEntities = 1024; + const int MaxEntities = 16348; internal typealias BitmaskEntry = (EcsEntity ID, BitArray ComponentMask); internal List _entities = new .(); @@ -149,6 +149,28 @@ namespace GlitchyEngine.World } } + /// Returns whether the given entity is valid or not. + public bool IsValid(EcsEntity entity) + { + if(entity.Index > _entities.Count) + return false; + + var listEntity = ref _entities[entity.Index]; + + return entity == listEntity.ID; + } + + /// Returns the entity with the same ID and the current version. Or null, if no such entity exists. + public EcsEntity? GetCurrentVersion(EcsEntity entity) + { + if(entity.Index > _entities.Count) + return null; + + var listEntity = ref _entities[entity.Index]; + + return listEntity.ID; + } + /** * Assigns a component of type T to the specified entity and returns it. */ @@ -208,7 +230,7 @@ namespace GlitchyEngine.World listEntity.ComponentMask[entry.Id] = false; } - + public void RemoveComponent(EcsEntity entity) where T : struct, new, IDisposableComponent { if(entity.Index > _entities.Count) diff --git a/GlitchyEngine/src/World/Scene.bf b/GlitchyEngine/src/World/Scene.bf index f0136fd..8737e61 100644 --- a/GlitchyEngine/src/World/Scene.bf +++ b/GlitchyEngine/src/World/Scene.bf @@ -48,7 +48,7 @@ namespace GlitchyEngine.World { } - public void UpdateRuntime(GameTime gameTime, RenderTarget2D finalTarget) + public void UpdateRuntime(GameTime gameTime, RenderTargetGroup finalTarget) { Debug.Profiler.ProfileRendererFunction!(); @@ -111,7 +111,7 @@ namespace GlitchyEngine.World } } - public void UpdateEditor(GameTime gameTime, EditorCamera camera, RenderTarget2D viewportTarget, delegate void() DebugDraw3D, delegate void() DrawDebug2D) + public void UpdateEditor(GameTime gameTime, EditorCamera camera, RenderTargetGroup viewportTarget, delegate void() DebugDraw3D, delegate void() DrawDebug2D) { Debug.Profiler.ProfileRendererFunction!(); @@ -124,7 +124,7 @@ namespace GlitchyEngine.World for (var (entity, transform, mesh, meshRenderer) in _ecsWorld.Enumerate()) { - Renderer.Submit(mesh.Mesh, meshRenderer.Material, transform.WorldTransform); + Renderer.Submit(mesh.Mesh, meshRenderer.Material, entity, transform.WorldTransform); } for (var (entity, transform, light) in _ecsWorld.Enumerate())