Kaynağa Gözat

Examples: Using draw_data->DisplaySize, followup to c50198debe4978853f3f8ed6e84a7b2685991c06. Fix Vulkan secondary viewport rendering. SDL+Vulkan: Matched changes. Fix vcprojs. (#1542, #1042)

omar 7 yıl önce
ebeveyn
işleme
98b66a5fc9

+ 7 - 5
examples/imgui_impl_dx9.cpp

@@ -42,8 +42,7 @@ struct CUSTOMVERTEX
 void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data)
 {
     // Avoid rendering when minimized
-    ImGuiIO& io = ImGui::GetIO();
-    if (io.DisplaySize.x <= 0.0f || io.DisplaySize.y <= 0.0f)
+    if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f)
         return;
 
     // Create and grow buffers if needed
@@ -101,8 +100,8 @@ void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data)
     // Setup viewport
     D3DVIEWPORT9 vp;
     vp.X = vp.Y = 0;
-    vp.Width = (DWORD)io.DisplaySize.x;
-    vp.Height = (DWORD)io.DisplaySize.y;
+    vp.Width = (DWORD)draw_data->DisplaySize.x;
+    vp.Height = (DWORD)draw_data->DisplaySize.y;
     vp.MinZ = 0.0f;
     vp.MaxZ = 1.0f;
     g_pd3dDevice->SetViewport(&vp);
@@ -131,7 +130,10 @@ void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data)
     // Setup orthographic projection matrix
     // Being agnostic of whether <d3dx9.h> or <DirectXMath.h> can be used, we aren't relying on D3DXMatrixIdentity()/D3DXMatrixOrthoOffCenterLH() or DirectX::XMMatrixIdentity()/DirectX::XMMatrixOrthographicOffCenterLH()
     {
-        const float L = 0.5f, R = io.DisplaySize.x+0.5f, T = 0.5f, B = io.DisplaySize.y+0.5f;
+        float L = draw_data->DisplayPos.x + 0.5f;
+        float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x + 0.5f;
+        float T = draw_data->DisplayPos.y + 0.5f;
+        float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y + 0.5f;
         D3DMATRIX mat_identity = { { 1.0f, 0.0f, 0.0f, 0.0f,  0.0f, 1.0f, 0.0f, 0.0f,  0.0f, 0.0f, 1.0f, 0.0f,  0.0f, 0.0f, 0.0f, 1.0f } };
         D3DMATRIX mat_projection =
         {

+ 2 - 2
examples/imgui_impl_opengl2.cpp

@@ -60,8 +60,8 @@ void ImGui_ImplOpenGL2_RenderDrawData(ImDrawData* draw_data)
 {
     // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
     ImGuiIO& io = ImGui::GetIO();
-    int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x);
-    int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y);
+    int fb_width = (int)(draw_data->DisplaySize.x * io.DisplayFramebufferScale.x);
+    int fb_height = (int)(draw_data->DisplaySize.y * io.DisplayFramebufferScale.y);
     if (fb_width == 0 || fb_height == 0)
         return;
     draw_data->ScaleClipRects(io.DisplayFramebufferScale);

+ 2 - 2
examples/imgui_impl_vulkan.cpp

@@ -263,8 +263,8 @@ void ImGui_ImplVulkan_RenderDrawData(VkCommandBuffer command_buffer, ImDrawData*
         VkViewport viewport;
         viewport.x = 0;
         viewport.y = 0;
-        viewport.width = io.DisplaySize.x;
-        viewport.height = io.DisplaySize.y;
+        viewport.width = draw_data->DisplaySize.x;
+        viewport.height = draw_data->DisplaySize.y;
         viewport.minDepth = 0.0f;
         viewport.maxDepth = 1.0f;
         vkCmdSetViewport(command_buffer, 0, 1, &viewport);

+ 1 - 1
examples/sdl_opengl2_example/main.cpp

@@ -121,7 +121,7 @@ int main(int, char**)
         }
 
         // Rendering
-        glViewport(0, 0, (int)ImGui::GetIO().DisplaySize.x, (int)ImGui::GetIO().DisplaySize.y);
+        glViewport(0, 0, (int)io.DisplaySize.x, (int)io.DisplaySize.y);
         glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w);
         glClear(GL_COLOR_BUFFER_BIT);
         //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context where shaders may be bound

+ 25 - 49
examples/sdl_vulkan_example/main.cpp

@@ -9,7 +9,6 @@
 #include <SDL_vulkan.h>
 #include <vulkan/vulkan.h>
 
-// FIXME-VULKAN: Resizing with IMGUI_UNLIMITED_FRAME_RATE triggers errors from the validation layer.
 #define IMGUI_UNLIMITED_FRAME_RATE
 #ifdef _DEBUG
 #define IMGUI_VULKAN_DEBUG_REPORT
@@ -220,19 +219,20 @@ static void CleanupVulkan()
     vkDestroyInstance(g_Instance, g_Allocator);
 }
 
-static void FrameBegin(ImGui_ImplVulkan_WindowData* wd)
+static void FrameRender(ImGui_ImplVulkan_WindowData* wd)
 {
+	VkResult err;
+
+	VkSemaphore& image_acquired_semaphore  = wd->Frames[wd->FrameIndex].ImageAcquiredSemaphore;
+	err = vkAcquireNextImageKHR(g_Device, wd->Swapchain, UINT64_MAX, image_acquired_semaphore, VK_NULL_HANDLE, &wd->FrameIndex);
+	check_vk_result(err);
+
     ImGui_ImplVulkan_FrameData* fd = &wd->Frames[wd->FrameIndex];
-    VkResult err;
-    for (;;)
     {
-        err = vkWaitForFences(g_Device, 1, &fd->Fence, VK_TRUE, 100);
-        if (err == VK_SUCCESS) break;
-        if (err == VK_TIMEOUT) continue;
+		err = vkWaitForFences(g_Device, 1, &fd->Fence, VK_TRUE, UINT64_MAX);	// wait indefinitely instead of periodically checking
         check_vk_result(err);
-    }
-    {
-        err = vkAcquireNextImageKHR(g_Device, wd->Swapchain, UINT64_MAX, fd->PresentCompleteSemaphore, VK_NULL_HANDLE, &fd->BackbufferIndex);
+
+		err = vkResetFences(g_Device, 1, &fd->Fence);
         check_vk_result(err);
     }
     {
@@ -248,26 +248,25 @@ static void FrameBegin(ImGui_ImplVulkan_WindowData* wd)
         VkRenderPassBeginInfo info = {};
         info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
         info.renderPass = wd->RenderPass;
-        info.framebuffer = wd->Framebuffer[fd->BackbufferIndex];
+		info.framebuffer = wd->Framebuffer[wd->FrameIndex];
         info.renderArea.extent.width = wd->Width;
         info.renderArea.extent.height = wd->Height;
         info.clearValueCount = 1;
         info.pClearValues = &wd->ClearValue;
         vkCmdBeginRenderPass(fd->CommandBuffer, &info, VK_SUBPASS_CONTENTS_INLINE);
     }
-}
 
-static void FrameEnd(ImGui_ImplVulkan_WindowData* wd)
-{
-    ImGui_ImplVulkan_FrameData* fd = &wd->Frames[wd->FrameIndex];
-    VkResult err;
+	// Record Imgui Draw Data and draw funcs into command buffer
+	ImGui_ImplVulkan_RenderDrawData(fd->CommandBuffer, ImGui::GetDrawData());
+
+	// Submit command buffer
     vkCmdEndRenderPass(fd->CommandBuffer);
     {
         VkPipelineStageFlags wait_stage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
         VkSubmitInfo info = {};
         info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
         info.waitSemaphoreCount = 1;
-        info.pWaitSemaphores = &fd->PresentCompleteSemaphore;
+		info.pWaitSemaphores = &image_acquired_semaphore;
         info.pWaitDstStageMask = &wait_stage;
         info.commandBufferCount = 1;
         info.pCommandBuffers = &fd->CommandBuffer;
@@ -276,8 +275,6 @@ static void FrameEnd(ImGui_ImplVulkan_WindowData* wd)
 
         err = vkEndCommandBuffer(fd->CommandBuffer);
         check_vk_result(err);
-        err = vkResetFences(g_Device, 1, &fd->Fence);
-        check_vk_result(err);
         err = vkQueueSubmit(g_Queue, 1, &info, fd->Fence);
         check_vk_result(err);
     }
@@ -285,23 +282,15 @@ static void FrameEnd(ImGui_ImplVulkan_WindowData* wd)
 
 static void FramePresent(ImGui_ImplVulkan_WindowData* wd)
 {
-    VkResult err;
-    // If IMGUI_UNLIMITED_FRAME_RATE is defined we present the latest but one frame. Otherwise we present the latest rendered frame
-#ifdef IMGUI_UNLIMITED_FRAME_RATE
-    uint32_t PresentIndex = (wd->FrameIndex + IMGUI_VK_QUEUED_FRAMES - 1) % IMGUI_VK_QUEUED_FRAMES;
-#else
-    uint32_t PresentIndex = wd->FrameIndex;
-#endif // IMGUI_UNLIMITED_FRAME_RATE
-
-    ImGui_ImplVulkan_FrameData* fd = &wd->Frames[PresentIndex];
+    ImGui_ImplVulkan_FrameData* fd = &wd->Frames[wd->FrameIndex];
     VkPresentInfoKHR info = {};
     info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
     info.waitSemaphoreCount = 1;
     info.pWaitSemaphores = &fd->RenderCompleteSemaphore;
     info.swapchainCount = 1;
     info.pSwapchains = &wd->Swapchain;
-    info.pImageIndices = &fd->BackbufferIndex;
-    err = vkQueuePresentKHR(g_Queue, &info);
+	info.pImageIndices = &wd->FrameIndex;
+	VkResult err = vkQueuePresentKHR(g_Queue, &info);
     check_vk_result(err);
 }
 
@@ -329,6 +318,7 @@ int main(int, char**)
 
     // Create Window Surface
     VkSurfaceKHR surface;
+    VkResult err;
     if (SDL_Vulkan_CreateSurface(window, g_Instance, &surface) == 0)
     {
         printf("Failed to create Vulkan surface.\n");
@@ -348,6 +338,9 @@ int main(int, char**)
     io.ConfigFlags |= ImGuiConfigFlags_PlatformNoTaskBar;
     //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;  // Enable Keyboard Controls
 
+    // Setup SDL binding
+    ImGui_ImplSDL2_Init(window, NULL);
+
     // Setup Vulkan binding
     ImGui_ImplVulkan_InitInfo init_info = {};
     init_info.Instance = g_Instance;
@@ -359,7 +352,6 @@ int main(int, char**)
     init_info.DescriptorPool = g_DescriptorPool;
     init_info.Allocator = g_Allocator;
     init_info.CheckVkResultFn = check_vk_result;
-    ImGui_ImplSDL2_Init(window, NULL);
     ImGui_ImplVulkan_Init(&init_info, wd->RenderPass);
 
     // Setup style
@@ -387,7 +379,6 @@ int main(int, char**)
         VkCommandPool command_pool = wd->Frames[wd->FrameIndex].CommandPool;
         VkCommandBuffer command_buffer = wd->Frames[wd->FrameIndex].CommandBuffer;
 
-        VkResult err;
         err = vkResetCommandPool(g_Device, command_pool, 0);
         check_vk_result(err);
         VkCommandBufferBeginInfo begin_info = {};
@@ -416,8 +407,6 @@ int main(int, char**)
     bool show_another_window = false;
     ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
 
-    bool swap_chain_has_at_least_one_image = false;
-
     // Main loop
     bool done = false;
     while (!done)
@@ -478,26 +467,13 @@ int main(int, char**)
         // Rendering
         ImGui::Render();
         memcpy(&wd->ClearValue.color.float32[0], &clear_color, 4 * sizeof(float));
-        FrameBegin(wd);
-        ImGui_ImplVulkan_RenderDrawData(wd->Frames[wd->FrameIndex].CommandBuffer, ImGui::GetDrawData());
-        FrameEnd(wd);
-
+		FrameRender(wd);
 		ImGui::RenderAdditionalViewports();
-
-#ifdef IMGUI_UNLIMITED_FRAME_RATE
-        // When IMGUI_UNLIMITED_FRAME_RATE is defined we render into latest image acquired from the swapchain but we display the image which was rendered before.
-        // Hence we must render once and increase the FrameIndex without presenting.
-        if (swap_chain_has_at_least_one_image)
-            FramePresent(wd);
-#else
         FramePresent(wd);
-#endif
-        swap_chain_has_at_least_one_image = true;
-        wd->FrameIndex = (wd->FrameIndex + 1) % IMGUI_VK_QUEUED_FRAMES;
     }
 
     // Cleanup
-    VkResult err = vkDeviceWaitIdle(g_Device);
+    err = vkDeviceWaitIdle(g_Device);
     check_vk_result(err);
     ImGui_ImplVulkan_Shutdown();
     ImGui_ImplSDL2_Shutdown();

+ 1 - 1
examples/sdl_vulkan_example/sdl_vulkan_example.vcxproj

@@ -20,7 +20,7 @@
   </ItemGroup>
   <PropertyGroup Label="Globals">
     <ProjectGuid>{BAE3D0B5-9695-4EB1-AD0F-75890EB4A3B3}</ProjectGuid>
-    <RootNamespace>opengl3_example</RootNamespace>
+    <RootNamespace>sdl_vulkan_example</RootNamespace>
   </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">

+ 1 - 1
examples/vulkan_example/vulkan_example.vcxproj

@@ -20,7 +20,7 @@
   </ItemGroup>
   <PropertyGroup Label="Globals">
     <ProjectGuid>{57E2DF5A-6FC8-45BB-99DD-91A18C646E80}</ProjectGuid>
-    <RootNamespace>opengl3_example</RootNamespace>
+    <RootNamespace>vulkan_example</RootNamespace>
   </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">