diff --git a/Videos/cortex_20260619_091023.mp4 b/Videos/cortex_20260619_091023.mp4 new file mode 100644 index 0000000..49ce3d0 Binary files /dev/null and b/Videos/cortex_20260619_091023.mp4 differ diff --git a/src/Engine.Graphics.Vulkan/VulkanContext.cs b/src/Engine.Graphics.Vulkan/VulkanContext.cs index 4cc2bf6..bf65fcb 100644 --- a/src/Engine.Graphics.Vulkan/VulkanContext.cs +++ b/src/Engine.Graphics.Vulkan/VulkanContext.cs @@ -361,12 +361,12 @@ internal sealed unsafe class VulkanContext : IDisposable var formats = stackalloc VkSurfaceFormatKHR[(int)formatCount]; Vk.vkGetPhysicalDeviceSurfaceFormatsKHR(PhysicalDevice, Surface, &formatCount, formats); - SurfaceFormat = VkFormat.B8G8R8A8Srgb; + SurfaceFormat = VkFormat.B8G8R8A8Unorm; SurfaceColorSpace = VkColorSpaceKHR.SrgbNonlinearKHR; for (uint i = 0; i < formatCount; i++) { - if (formats[(int)i].format == VkFormat.B8G8R8A8Srgb && + if (formats[(int)i].format == VkFormat.B8G8R8A8Unorm && formats[(int)i].colorSpace == VkColorSpaceKHR.SrgbNonlinearKHR) { SurfaceFormat = formats[(int)i].format; @@ -375,7 +375,7 @@ internal sealed unsafe class VulkanContext : IDisposable } } - if (SurfaceFormat == VkFormat.B8G8R8A8Srgb) + if (SurfaceFormat == VkFormat.B8G8R8A8Unorm) { SurfaceFormat = formats[0].format; SurfaceColorSpace = formats[0].colorSpace; diff --git a/src/Engine.Graphics.Vulkan/VulkanRenderer.cs b/src/Engine.Graphics.Vulkan/VulkanRenderer.cs index 1e59a5c..62b5681 100644 --- a/src/Engine.Graphics.Vulkan/VulkanRenderer.cs +++ b/src/Engine.Graphics.Vulkan/VulkanRenderer.cs @@ -521,17 +521,41 @@ public sealed unsafe class VulkanRenderer : IRenderer, Engine.Graphics.IScreensh Vk.vkCmdDrawIndexed(cmd, dc.indexCount, 1, 0, 0, 0); } + // Capture BEFORE ImGui — video without UI + if (IsRecording) + { + // End rendering temporarily to do copy outside render pass + Vk.vkCmdEndRendering(cmd); + CaptureFrame(cmd, imageIndex); + + // Start new render pass for ImGui + var imgClearValue = new VkClearValue + { + Color = new VkClearColorValue { Float0 = 0, Float1 = 0, Float2 = 0, Float3 = 0 }, + }; + var imgLoadAttachment = new VkRenderingAttachmentInfo + { + sType = VkStructureType.RenderingAttachmentInfo, + imageView = _swapchain.ImageViews[imageIndex], + imageLayout = VkImageLayout.ColorAttachmentOptimal, + loadOp = VkAttachmentLoadOp.Load, // Keep existing content + storeOp = VkAttachmentStoreOp.Store, + }; + var imgRenderingInfo = new VkRenderingInfo + { + sType = VkStructureType.RenderingInfo, + renderArea = new VkRect2D { Offset = new VkOffset2D { X = 0, Y = 0 }, Extent = _swapchain.Extent }, + layerCount = 1, + colorAttachmentCount = 1, + pColorAttachments = &imgLoadAttachment, + }; + Vk.vkCmdBeginRendering(cmd, &imgRenderingInfo); + } + _imGui?.Render(cmd, _swapchain.Extent.Width, _swapchain.Extent.Height); Vk.vkCmdEndRendering(cmd); - // Capture frame for video recording — AFTER render pass, BEFORE present - // This captures scene + ImGui. To capture without UI, we'd need separate render pass. - if (IsRecording) - { - CaptureFrame(cmd, imageIndex); - } - TransitionImageLayout(cmd, _swapchain.Images[imageIndex], VkImageLayout.ColorAttachmentOptimal, VkImageLayout.PresentSrcKHR, 0x400, 0x100,