feat: ImGui debug overlay — FPS, camera position, entity count

- ImGui.NET 1.91.6.1 integrated into Engine.Graphics.Vulkan
- VulkanImGui.cs: font atlas upload (staging → VkImage), sampler,
  descriptor set (COMBINED_IMAGE_SAMPLER), separate pipeline with
  alpha blending, no depth write, dynamic scissor
- ImGui shaders: imgui.vert (ortho MVP push constant) + imgui.frag
  (font texture sampler)
- Dynamic vertex/index buffers (HOST_VISIBLE, grow on demand)
- IRenderer interface: BeginImGuiFrame/EndImGuiFrame default methods
- Program.cs: debug window with FPS, camera pos/target, entity count
- 0 critical validation errors, ~750 FPS with physics + ImGui
This commit is contained in:
emil28092005
2026-06-18 17:34:42 +03:00
parent e67e312d28
commit bfde04b381
14 changed files with 906 additions and 2 deletions
@@ -13,6 +13,7 @@ internal sealed unsafe class VulkanRenderer : IRenderer, Engine.Graphics.IScreen
private readonly VulkanSwapchain _swapchain;
private readonly VulkanPipeline _pipeline;
private readonly VulkanFrameResources _frameResources;
internal readonly VulkanImGui? _imGui;
private readonly Dictionary<ulong, (VulkanVertexBuffer vb, VulkanIndexBuffer ib, uint indexCount)> _meshCache = new();
@@ -37,6 +38,21 @@ internal sealed unsafe class VulkanRenderer : IRenderer, Engine.Graphics.IScreen
_frameResources = new VulkanFrameResources(ctx.Device, ctx.GraphicsQueueFamilyIndex,
swapchain.ImageCount, ctx, _pipeline.DescriptorSetLayout);
_imGui = new VulkanImGui(ctx, _frameResources.CommandPool, swapchain.Format, swapchain.DepthFormat);
}
internal VulkanImGui? ImGuiLayer => _imGui;
public void BeginImGuiFrame()
{
_imGui?.NewFrame();
}
public void EndImGuiFrame()
{
if (_imGui == null) return;
ImGuiNET.ImGui.Render();
}
public void RenderWorld(World world)
@@ -205,6 +221,8 @@ internal sealed unsafe class VulkanRenderer : IRenderer, Engine.Graphics.IScreen
Vk.vkCmdDrawIndexed(cmd, dc.indexCount, 1, 0, 0, 0);
}
_imGui?.Render(cmd, _swapchain.Extent.Width, _swapchain.Extent.Height);
Vk.vkCmdEndRendering(cmd);
TransitionImageLayout(cmd, _swapchain.Images[imageIndex],
@@ -389,6 +407,7 @@ internal sealed unsafe class VulkanRenderer : IRenderer, Engine.Graphics.IScreen
}
_meshCache.Clear();
_imGui?.Dispose();
_frameResources?.Dispose();
_pipeline?.Dispose();
}