diff --git a/backends/imgui_impl_vulkan.cpp b/backends/imgui_impl_vulkan.cpp index 1b4e81c2f030..bcaf21729538 100644 --- a/backends/imgui_impl_vulkan.cpp +++ b/backends/imgui_impl_vulkan.cpp @@ -495,28 +495,28 @@ static void ImGui_ImplVulkan_SetupRenderState(ImDrawData* draw_data, VkPipeline } // Setup viewport: - { - VkViewport viewport; - viewport.x = 0; - viewport.y = 0; - viewport.width = (float)fb_width; - viewport.height = (float)fb_height; - viewport.minDepth = 0.0f; - viewport.maxDepth = 1.0f; - vkCmdSetViewport(command_buffer, 0, 1, &viewport); - } + + VkViewport viewport; + viewport.x = draw_data->OwnerViewport->Pos.x; + viewport.y = draw_data->OwnerViewport->Pos.y; + viewport.width = (float)fb_width; + viewport.height = (float)fb_height; + viewport.minDepth = 0.0f; + viewport.maxDepth = 1.0f; + vkCmdSetViewport(command_buffer, 0, 1, &viewport); + // Setup scale and translation: // Our visible imgui space lies from draw_data->DisplayPps (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps. { - float scale[2]; - scale[0] = 2.0f / draw_data->DisplaySize.x; - scale[1] = 2.0f / draw_data->DisplaySize.y; - float translate[2]; - translate[0] = -1.0f - draw_data->DisplayPos.x * scale[0]; - translate[1] = -1.0f - draw_data->DisplayPos.y * scale[1]; - vkCmdPushConstants(command_buffer, bd->PipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, sizeof(float) * 0, sizeof(float) * 2, scale); - vkCmdPushConstants(command_buffer, bd->PipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, sizeof(float) * 2, sizeof(float) * 2, translate); + float scale_translate[4]; + //first two are scale + scale_translate[0] = 2.0f / draw_data->DisplaySize.x; + scale_translate[1] = 2.0f / draw_data->DisplaySize.y; + //second two are translate + scale_translate[2] = -1.0f - draw_data->DisplayPos.x * scale_translate[0]; + scale_translate[3] = -1.0f - draw_data->DisplayPos.y * scale_translate[1]; + vkCmdPushConstants(command_buffer, bd->PipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(float) * 4, scale_translate); } } @@ -629,23 +629,35 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm else { // Project scissor/clipping rectangles into framebuffer space - ImVec2 clip_min((pcmd->ClipRect.x - clip_off.x) * clip_scale.x, (pcmd->ClipRect.y - clip_off.y) * clip_scale.y); - ImVec2 clip_max((pcmd->ClipRect.z - clip_off.x) * clip_scale.x, (pcmd->ClipRect.w - clip_off.y) * clip_scale.y); + ImVec2 scissor_offset{ + pcmd->ClipRect.x * clip_scale.x, + pcmd->ClipRect.y * clip_scale.y + }; + ImVec2 scissor_extent{ + (pcmd->ClipRect.z - clip_off.x) * clip_scale.x, + (pcmd->ClipRect.w - clip_off.y) * clip_scale.y + }; // Clamp to viewport as vkCmdSetScissor() won't accept values that are off bounds - if (clip_min.x < 0.0f) { clip_min.x = 0.0f; } - if (clip_min.y < 0.0f) { clip_min.y = 0.0f; } - if (clip_max.x > fb_width) { clip_max.x = (float)fb_width; } - if (clip_max.y > fb_height) { clip_max.y = (float)fb_height; } - if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y) + if (scissor_offset.x < 0.0f) { scissor_offset.x = 0.0f; } + if (scissor_offset.y < 0.0f) { scissor_offset.y = 0.0f; } + const float scissor_rect_right = scissor_offset.x + scissor_extent.x; + const float scissor_rect_bottom = scissor_offset.y + scissor_offset.y; + if (scissor_rect_right > fb_width) { scissor_extent.x = (float)fb_width - scissor_offset.x; } + if (scissor_rect_bottom > fb_height) { scissor_extent.y = (float)fb_height - scissor_offset.y; } + if(scissor_extent.x <= 0.f || scissor_extent.y <= 0.f){ + continue; + } + if(scissor_offset.x >= fb_width || scissor_offset.y >= fb_height){ continue; + } // Apply scissor/clipping rectangle VkRect2D scissor; - scissor.offset.x = (int32_t)(clip_min.x); - scissor.offset.y = (int32_t)(clip_min.y); - scissor.extent.width = (uint32_t)(clip_max.x - clip_min.x); - scissor.extent.height = (uint32_t)(clip_max.y - clip_min.y); + scissor.offset.x = (int32_t)(scissor_offset.x); + scissor.offset.y = (int32_t)(scissor_offset.y); + scissor.extent.width = uint32_t(scissor_extent.x); + scissor.extent.height = uint32_t(scissor_extent.y); vkCmdSetScissor(command_buffer, 0, 1, &scissor); // Bind DescriptorSet with font or user texture diff --git a/imgui.cpp b/imgui.cpp index 353eda54b255..feafb9ef99f8 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -15816,7 +15816,6 @@ static void ImGui::UpdateViewportsNewFrame() // FIXME-VIEWPORT: Size is driven by backend/user code for backward-compatibility but we should aim to make this more consistent. ImGuiViewportP* main_viewport = g.Viewports[0]; main_viewport->Flags = ImGuiViewportFlags_IsPlatformWindow | ImGuiViewportFlags_OwnedByApp; - main_viewport->Pos = ImVec2(0.0f, 0.0f); main_viewport->Size = g.IO.DisplaySize; main_viewport->FramebufferScale = g.IO.DisplayFramebufferScale; IM_ASSERT(main_viewport->FramebufferScale.x > 0.0f && main_viewport->FramebufferScale.y > 0.0f);