From 2603d123940e422f1905c5ba5a806d23c73b678f Mon Sep 17 00:00:00 2001 From: Alexandre Date: Thu, 13 Aug 2026 19:51:57 +0200 Subject: [PATCH] Added Viewport, now adding logs --- CMakeLists.txt | 1 + src/Engine/engine/engine.h | 186 ++++++++++++++++++++++++++++++++++--- 2 files changed, 173 insertions(+), 14 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a03d62d..7a9955a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -128,6 +128,7 @@ function ( addBinary BINARY_NAME ) ${CMAKE_SOURCE_DIR}/src/imgui/imgui_tables.cpp ${CMAKE_SOURCE_DIR}/src/imgui/imgui_widgets.cpp ${CMAKE_SOURCE_DIR}/src/imgui/imgui_demo.cpp + ${CMAKE_SOURCE_DIR}/src/imgui/imgui_memory_editor.h ${CMAKE_SOURCE_DIR}/src/imgui/backends/imgui_impl_glfw.cpp ${CMAKE_SOURCE_DIR}/src/imgui/backends/imgui_impl_vulkan.cpp diff --git a/src/Engine/engine/engine.h b/src/Engine/engine/engine.h index 97ab0c4..3946759 100644 --- a/src/Engine/engine/engine.h +++ b/src/Engine/engine/engine.h @@ -12,7 +12,8 @@ #include #include #include - +#include "imgui.h" // For types +#include "imgui_memory_editor.h" // For mem edit struct FrameData { VkCommandPool _commandPool; @@ -107,6 +108,13 @@ class Engine { VkPipelineLayout _trianglePipelineLayout; VkPipeline _trianglePipeline; + // ImGUI texture sampler + VkSampler _viewportSampler; + VkDescriptorSet _viewportTextureID; + + // ImGUI memory editor + MemoryEditor _memEdit; + void init(); @@ -151,6 +159,10 @@ class Engine { VkImageView targetImageView ); void resizeSwapchain(); + void resizeRenderImage( + uint32_t width, + uint32_t height + ); }; @@ -185,6 +197,8 @@ class Engine { #include "imgui.h" #include "imgui_impl_glfw.h" #include "imgui_impl_vulkan.h" +#include "imgui_memory_editor.h" // For mem edit + #include "VkBootstrap.h" #include "vk_mem_alloc.h" @@ -347,6 +361,8 @@ void Engine::draw() { drawGeometry(cmd); + /* + // Commented for Viewport // Transfer the draw image and swapchain image to the correct layouts vkutil::transitionImage( cmd, @@ -379,6 +395,22 @@ void Engine::draw() { VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL ); + */ + + vkutil::transitionImage( + cmd, + _drawImage.image, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL + ); + + vkutil::transitionImage( + cmd, + _swapchainImages[swapchainImageIndex], + VK_IMAGE_LAYOUT_UNDEFINED, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL + ); + drawImgui( cmd, _swapchainImageViews[swapchainImageIndex] @@ -580,7 +612,8 @@ void Engine::initSwapchain() { VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_STORAGE_BIT | - VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT + VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | + VK_IMAGE_USAGE_SAMPLED_BIT }; VkImageCreateInfo rImgInfo = { @@ -1153,6 +1186,27 @@ void Engine::initImgui() { ImGui_ImplVulkan_Init(&initInfo); + // Create a sampler for Viewport rendering + VkSamplerCreateInfo samplerInfo = {}; + samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; + samplerInfo.magFilter = VK_FILTER_LINEAR; + samplerInfo.minFilter = VK_FILTER_LINEAR; + samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR; + samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + samplerInfo.anisotropyEnable = VK_FALSE; + samplerInfo.maxAnisotropy = 1.0f; + + VK_CHECK(vkCreateSampler(_device, &samplerInfo, nullptr, &_viewportSampler)); + + // Register the draw image as a texture for ImGui + _viewportTextureID = ImGui_ImplVulkan_AddTexture( + _viewportSampler, + _drawImage.imageView, + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL + ); + _mainDeletionQueue.pushFunction([this, imguiPool]() { ImGui_ImplVulkan_Shutdown(); ImGui_ImplGlfw_Shutdown(); @@ -1162,6 +1216,11 @@ void Engine::initImgui() { imguiPool, nullptr ); + vkDestroySampler( + _device, + _viewportSampler, + nullptr + ); }); #ifdef DEBUG fmt::println("[Engine:Init] ImGui initialized !"); @@ -1225,6 +1284,26 @@ void Engine::buildImgui() { // Main ImGui things ImGui::ShowDemoWindow(); + // Viewport + if (ImGui::Begin( + "Viewport", + nullptr, + ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse + )) { + ImVec2 size = ImGui::GetWindowSize(); + if (size.x > 0 && size.y > 0) { + // Redimensionner l'image de rendu si la taille du dock a changé + if ((uint32_t)size.x != _drawImage.imageExtent.width || + (uint32_t)size.y != _drawImage.imageExtent.height) { + resizeRenderImage((uint32_t)size.x, (uint32_t)size.y); + } + // Afficher la texture en remplissant la zone + ImGui::Image(_viewportTextureID, size); + } + } + ImGui::End(); + + // Shader control if(ImGui::Begin("Background Shader control")) { ComputeEffect& selected = backgroundEffects[currentBackgroundEffect]; @@ -1259,18 +1338,11 @@ void Engine::buildImgui() { } ImGui::End(); - - if (ImGui::Begin("Viewport")) { - // Debug info - #ifdef DEBUG - ImVec2 avail = ImGui::GetWindowSize(); - float width = avail.x; - float height = avail.y; - //println("[Engine:Info] Available size : \nx: {}\ny: {}", width, height ); - #endif - } - ImGui::End(); - + // Memory editor + if(ImGui::Begin("Memory")) { + _memEdit.DrawContents(this, sizeof(*this), (size_t)this); + } + ImGui::End(); // Finish everything ImGui::Render(); @@ -1522,5 +1594,91 @@ void Engine::resizeSwapchain() { #endif } +void Engine::resizeRenderImage(uint32_t width, uint32_t height) { + #ifdef DEBUG + fmt::println("[Engine:Utils] Resizing render image to {}x{}", width, height); + #endif + + vkDeviceWaitIdle(_device); + + // Remove old ImGui texture + if (_viewportTextureID) { + ImGui_ImplVulkan_RemoveTexture(_viewportTextureID); + _viewportTextureID = nullptr; + } + + // Destroy old draw image and view + vmaDestroyImage(_allocator, _drawImage.image, _drawImage.allocation); + vkDestroyImageView(_device, _drawImage.imageView, nullptr); + + // Create new image with new extents + VkExtent3D newExtent = { width, height, 1 }; + _drawImage.imageExtent = newExtent; + + VkImageUsageFlags drawImageUsages { + VK_IMAGE_USAGE_TRANSFER_SRC_BIT | + VK_IMAGE_USAGE_TRANSFER_DST_BIT | + VK_IMAGE_USAGE_STORAGE_BIT | + VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | + VK_IMAGE_USAGE_SAMPLED_BIT + }; + + VkImageCreateInfo rImgInfo = vkinit::imageCreateInfo( + _drawImage.imageFormat, + drawImageUsages, + newExtent + ); + + VmaAllocationCreateInfo rImgAllocInfo = { + .usage = VMA_MEMORY_USAGE_GPU_ONLY, + .requiredFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT + }; + + vmaCreateImage( + _allocator, + &rImgInfo, + &rImgAllocInfo, + &_drawImage.image, + &_drawImage.allocation, + nullptr + ); + + VkImageViewCreateInfo rViewInfo = vkinit::imageViewCreateInfo( + _drawImage.imageFormat, + _drawImage.image, + VK_IMAGE_ASPECT_COLOR_BIT + ); + VK_CHECK(vkCreateImageView(_device, &rViewInfo, nullptr, &_drawImage.imageView)); + + // Update compute descriptor set with new image view + VkDescriptorImageInfo imgInfo { + .imageView = _drawImage.imageView, + .imageLayout = VK_IMAGE_LAYOUT_GENERAL + }; + VkWriteDescriptorSet drawImageWrite = { + .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, + .pNext = nullptr, + .dstSet = _drawImageDescriptors, + .dstBinding = 0, + .descriptorCount = 1, + .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, + .pImageInfo = &imgInfo + }; + vkUpdateDescriptorSets(_device, 1, &drawImageWrite, 0, nullptr); + + // Re-register texture for ImGui + _viewportTextureID = ImGui_ImplVulkan_AddTexture( + _viewportSampler, + _drawImage.imageView, + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL + ); + + #ifdef DEBUG + fmt::println("[Engine:Utils] Render image resized !"); + #endif +} + + + #endif #endif