From a78a18a99a25ac3b9a244ed7f9a7d90c32cdd200 Mon Sep 17 00:00:00 2001 From: redstrate Date: Wed, 13 Oct 2021 07:25:18 -0400 Subject: [PATCH] Set scissor for imgui commands --- engine/gfx/vulkan/src/gfx_vulkan.cpp | 11 +++++++++++ engine/renderer/src/imguipass.cpp | 27 ++++++++++++++++++++------- 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/engine/gfx/vulkan/src/gfx_vulkan.cpp b/engine/gfx/vulkan/src/gfx_vulkan.cpp index f7b9be7..8f71a9c 100755 --- a/engine/gfx/vulkan/src/gfx_vulkan.cpp +++ b/engine/gfx/vulkan/src/gfx_vulkan.cpp @@ -1485,6 +1485,17 @@ void GFXVulkan::submit(GFXCommandBuffer* command_buffer, const platform::window_ scissor.extent.width = command.data.set_viewport.viewport.width; scissor.extent.height = command.data.set_viewport.viewport.height; + vkCmdSetScissor(cmd, 0, 1, &scissor); + } + break; + case GFXCommandType::SetScissor: + { + VkRect2D scissor = {}; + scissor.offset.x = command.data.set_scissor.rect.offset.x; + scissor.offset.y = command.data.set_scissor.rect.offset.y; + scissor.extent.width = command.data.set_scissor.rect.extent.width; + scissor.extent.height = command.data.set_scissor.rect.extent.height; + vkCmdSetScissor(cmd, 0, 1, &scissor); } break; diff --git a/engine/renderer/src/imguipass.cpp b/engine/renderer/src/imguipass.cpp index f7e28d6..3de9a50 100755 --- a/engine/renderer/src/imguipass.cpp +++ b/engine/renderer/src/imguipass.cpp @@ -123,17 +123,30 @@ void ImGuiPass::render_post(GFXCommandBuffer* command_buffer, RenderTarget& targ if(pcmd->UserCallback != nullptr) { pcmd->UserCallback(cmd_list, pcmd); } else { - ImVec4 clip_rect = {}; - clip_rect.x = (pcmd->ClipRect.x - clip_offset.x) * clip_scale.x; - clip_rect.y = (pcmd->ClipRect.y - clip_offset.y) * clip_scale.y; - clip_rect.z = (pcmd->ClipRect.z - clip_offset.x) * clip_scale.x; - clip_rect.w = (pcmd->ClipRect.w - clip_offset.y) * clip_scale.y; + ImVec2 clip_min((pcmd->ClipRect.x - clip_offset.x) * clip_scale.x, (pcmd->ClipRect.y - clip_offset.y) * clip_scale.y); + ImVec2 clip_max((pcmd->ClipRect.z - clip_offset.x) * clip_scale.x, (pcmd->ClipRect.w - clip_offset.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 > framebuffer_width) { clip_max.x = (float)framebuffer_width; } + if (clip_max.y > framebuffer_height) { clip_max.y = (float)framebuffer_height; } + if (clip_max.x < clip_min.x || clip_max.y < clip_min.y) + continue; + + // Apply scissor/clipping rectangle + prism::Rectangle 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); + + command_buffer->set_scissor(scissor); - if(clip_rect.x < framebuffer_width && clip_rect.y < framebuffer_height && clip_rect.z >= 0.0f && clip_rect.w >= 0.0f) { command_buffer->draw_indexed(pcmd->ElemCount, (index_offset + pcmd->IdxOffset), (vertex_offset + pcmd->VtxOffset), 0); - } + } }