mirror of
https://github.com/Drezil/imgui.git
synced 2024-11-15 01:17:00 +00:00
Backends: Metal: Fixed a crash when clipping rect larger than framebuffer is submitted. (#4464)
Backends: Normalize clipping rect handling across backends. + Squashed amends.
This commit is contained in:
parent
f8bad7e1e3
commit
2b0bd40b99
@ -171,9 +171,15 @@ void ImGui_ImplAllegro5_RenderDrawData(ImDrawData* draw_data)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Draw
|
// Project scissor/clipping rectangles into framebuffer space
|
||||||
|
ImVec2 clip_min(pcmd->ClipRect.x - clip_off.x, pcmd->ClipRect.y - clip_off.y);
|
||||||
|
ImVec2 clip_max(pcmd->ClipRect.z - clip_off.x, pcmd->ClipRect.w - clip_off.y);
|
||||||
|
if (clip_max.x < clip_min.x || clip_max.y < clip_min.y)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Apply scissor/clipping rectangle, Draw
|
||||||
ALLEGRO_BITMAP* texture = (ALLEGRO_BITMAP*)pcmd->GetTexID();
|
ALLEGRO_BITMAP* texture = (ALLEGRO_BITMAP*)pcmd->GetTexID();
|
||||||
al_set_clipping_rectangle(pcmd->ClipRect.x - clip_off.x, pcmd->ClipRect.y - clip_off.y, pcmd->ClipRect.z - pcmd->ClipRect.x, pcmd->ClipRect.w - pcmd->ClipRect.y);
|
al_set_clipping_rectangle(clip_min.x, clip_min.y, clip_max.x, clip_max.y);
|
||||||
al_draw_prim(&vertices[0], bd->VertexDecl, texture, idx_offset, idx_offset + pcmd->ElemCount, ALLEGRO_PRIM_TRIANGLE_LIST);
|
al_draw_prim(&vertices[0], bd->VertexDecl, texture, idx_offset, idx_offset + pcmd->ElemCount, ALLEGRO_PRIM_TRIANGLE_LIST);
|
||||||
}
|
}
|
||||||
idx_offset += pcmd->ElemCount;
|
idx_offset += pcmd->ElemCount;
|
||||||
|
@ -253,8 +253,14 @@ void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// Project scissor/clipping rectangles into framebuffer space
|
||||||
|
ImVec2 clip_min(pcmd->ClipRect.x - clip_off.x, pcmd->ClipRect.y - clip_off.y);
|
||||||
|
ImVec2 clip_max(pcmd->ClipRect.z - clip_off.x, pcmd->ClipRect.w - clip_off.y);
|
||||||
|
if (clip_max.x < clip_min.x || clip_max.y < clip_min.y)
|
||||||
|
continue;
|
||||||
|
|
||||||
// Apply scissor/clipping rectangle
|
// Apply scissor/clipping rectangle
|
||||||
const D3D10_RECT r = { (LONG)(pcmd->ClipRect.x - clip_off.x), (LONG)(pcmd->ClipRect.y - clip_off.y), (LONG)(pcmd->ClipRect.z - clip_off.x), (LONG)(pcmd->ClipRect.w - clip_off.y)};
|
const D3D10_RECT r = { (LONG)clip_min.x, (LONG)clip_min.y, (LONG)clip_max.x, (LONG)clip_max.y };
|
||||||
ctx->RSSetScissorRects(1, &r);
|
ctx->RSSetScissorRects(1, &r);
|
||||||
|
|
||||||
// Bind texture, Draw
|
// Bind texture, Draw
|
||||||
|
@ -263,8 +263,14 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// Project scissor/clipping rectangles into framebuffer space
|
||||||
|
ImVec2 clip_min(pcmd->ClipRect.x - clip_off.x, pcmd->ClipRect.y - clip_off.y);
|
||||||
|
ImVec2 clip_max(pcmd->ClipRect.z - clip_off.x, pcmd->ClipRect.w - clip_off.y);
|
||||||
|
if (clip_max.x < clip_min.x || clip_max.y < clip_min.y)
|
||||||
|
continue;
|
||||||
|
|
||||||
// Apply scissor/clipping rectangle
|
// Apply scissor/clipping rectangle
|
||||||
const D3D11_RECT r = { (LONG)(pcmd->ClipRect.x - clip_off.x), (LONG)(pcmd->ClipRect.y - clip_off.y), (LONG)(pcmd->ClipRect.z - clip_off.x), (LONG)(pcmd->ClipRect.w - clip_off.y) };
|
const D3D11_RECT r = { (LONG)clip_min.x, (LONG)clip_min.y, (LONG)clip_max.x, (LONG)clip_max.y };
|
||||||
ctx->RSSetScissorRects(1, &r);
|
ctx->RSSetScissorRects(1, &r);
|
||||||
|
|
||||||
// Bind texture, Draw
|
// Bind texture, Draw
|
||||||
|
@ -259,16 +259,19 @@ void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandL
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Apply Scissor, Bind texture, Draw
|
// Project scissor/clipping rectangles into framebuffer space
|
||||||
const D3D12_RECT r = { (LONG)(pcmd->ClipRect.x - clip_off.x), (LONG)(pcmd->ClipRect.y - clip_off.y), (LONG)(pcmd->ClipRect.z - clip_off.x), (LONG)(pcmd->ClipRect.w - clip_off.y) };
|
ImVec2 clip_min(pcmd->ClipRect.x - clip_off.x, pcmd->ClipRect.y - clip_off.y);
|
||||||
if (r.right > r.left && r.bottom > r.top)
|
ImVec2 clip_max(pcmd->ClipRect.z - clip_off.x, pcmd->ClipRect.w - clip_off.y);
|
||||||
{
|
if (clip_max.x < clip_min.x || clip_max.y < clip_min.y)
|
||||||
D3D12_GPU_DESCRIPTOR_HANDLE texture_handle = {};
|
continue;
|
||||||
texture_handle.ptr = (UINT64)pcmd->GetTexID();
|
|
||||||
ctx->SetGraphicsRootDescriptorTable(1, texture_handle);
|
// Apply Scissor/clipping rectangle, Bind texture, Draw
|
||||||
ctx->RSSetScissorRects(1, &r);
|
const D3D12_RECT r = { (LONG)clip_min.x, (LONG)clip_min.y, (LONG)clip_max.x, (LONG)clip_max.y };
|
||||||
ctx->DrawIndexedInstanced(pcmd->ElemCount, 1, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset, 0);
|
D3D12_GPU_DESCRIPTOR_HANDLE texture_handle = {};
|
||||||
}
|
texture_handle.ptr = (UINT64)pcmd->GetTexID();
|
||||||
|
ctx->SetGraphicsRootDescriptorTable(1, texture_handle);
|
||||||
|
ctx->RSSetScissorRects(1, &r);
|
||||||
|
ctx->DrawIndexedInstanced(pcmd->ElemCount, 1, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
global_idx_offset += cmd_list->IdxBuffer.Size;
|
global_idx_offset += cmd_list->IdxBuffer.Size;
|
||||||
|
@ -248,7 +248,14 @@ void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const RECT r = { (LONG)(pcmd->ClipRect.x - clip_off.x), (LONG)(pcmd->ClipRect.y - clip_off.y), (LONG)(pcmd->ClipRect.z - clip_off.x), (LONG)(pcmd->ClipRect.w - clip_off.y) };
|
// Project scissor/clipping rectangles into framebuffer space
|
||||||
|
ImVec2 clip_min(pcmd->ClipRect.x - clip_off.x, pcmd->ClipRect.y - clip_off.y);
|
||||||
|
ImVec2 clip_max(pcmd->ClipRect.z - clip_off.x, pcmd->ClipRect.w - clip_off.y);
|
||||||
|
if (clip_max.x < clip_min.x || clip_max.y < clip_min.y)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Apply Scissor/clipping rectangle, Bind texture, Draw
|
||||||
|
const RECT r = { (LONG)clip_min.x, (LONG)clip_min.y, (LONG)clip_max.x, (LONG)clip_max.y };
|
||||||
const LPDIRECT3DTEXTURE9 texture = (LPDIRECT3DTEXTURE9)pcmd->GetTexID();
|
const LPDIRECT3DTEXTURE9 texture = (LPDIRECT3DTEXTURE9)pcmd->GetTexID();
|
||||||
bd->pd3dDevice->SetTexture(0, texture);
|
bd->pd3dDevice->SetTexture(0, texture);
|
||||||
bd->pd3dDevice->SetScissorRect(&r);
|
bd->pd3dDevice->SetScissorRect(&r);
|
||||||
|
@ -5,13 +5,14 @@
|
|||||||
// [X] Renderer: User texture binding. Use 'MTLTexture' as ImTextureID. Read the FAQ about ImTextureID!
|
// [X] Renderer: User texture binding. Use 'MTLTexture' as ImTextureID. Read the FAQ about ImTextureID!
|
||||||
// [X] Renderer: Support for large meshes (64k+ vertices) with 16-bit indices.
|
// [X] Renderer: Support for large meshes (64k+ vertices) with 16-bit indices.
|
||||||
|
|
||||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||||
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
|
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
|
||||||
// Read online: https://github.com/ocornut/imgui/tree/master/docs
|
// Read online: https://github.com/ocornut/imgui/tree/master/docs
|
||||||
|
|
||||||
// CHANGELOG
|
// CHANGELOG
|
||||||
// (minor and older changes stripped away, please see git history for details)
|
// (minor and older changes stripped away, please see git history for details)
|
||||||
|
// 2021-08-24: Metal: Fixed a crash when clipping rect larger than framebuffer is submitted. (#4464)
|
||||||
// 2021-05-19: Metal: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
|
// 2021-05-19: Metal: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
|
||||||
// 2021-02-18: Metal: Change blending equation to preserve alpha in output buffer.
|
// 2021-02-18: Metal: Change blending equation to preserve alpha in output buffer.
|
||||||
// 2021-01-25: Metal: Fixed texture storage mode when building on Mac Catalyst.
|
// 2021-01-25: Metal: Fixed texture storage mode when building on Mac Catalyst.
|
||||||
@ -504,36 +505,37 @@ void ImGui_ImplMetal_DestroyDeviceObjects()
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Project scissor/clipping rectangles into framebuffer space
|
// Project scissor/clipping rectangles into framebuffer space
|
||||||
ImVec4 clip_rect;
|
ImVec2 clip_min((pcmd->ClipRect.x - clip_off.x) * clip_scale.x, (pcmd->ClipRect.y - clip_off.y) * clip_scale.y);
|
||||||
clip_rect.x = (pcmd->ClipRect.x - clip_off.x) * clip_scale.x;
|
ImVec2 clip_max((pcmd->ClipRect.z - clip_off.x) * clip_scale.x, (pcmd->ClipRect.w - clip_off.y) * clip_scale.y);
|
||||||
clip_rect.y = (pcmd->ClipRect.y - clip_off.y) * clip_scale.y;
|
|
||||||
clip_rect.z = (pcmd->ClipRect.z - clip_off.x) * clip_scale.x;
|
|
||||||
clip_rect.w = (pcmd->ClipRect.w - clip_off.y) * clip_scale.y;
|
|
||||||
|
|
||||||
if (clip_rect.x < fb_width && clip_rect.y < fb_height && clip_rect.z >= 0.0f && clip_rect.w >= 0.0f)
|
// Clamp to viewport as setScissorRect() 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)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Apply scissor/clipping rectangle
|
||||||
|
MTLScissorRect scissorRect =
|
||||||
{
|
{
|
||||||
// Apply scissor/clipping rectangle
|
.x = NSUInteger(clip_min.x),
|
||||||
MTLScissorRect scissorRect =
|
.y = NSUInteger(clip_min.y),
|
||||||
{
|
.width = NSUInteger(clip_max.x - clip_min.x),
|
||||||
.x = NSUInteger(clip_rect.x),
|
.height = NSUInteger(clip_max.y - clip_min.y)
|
||||||
.y = NSUInteger(clip_rect.y),
|
};
|
||||||
.width = NSUInteger(clip_rect.z - clip_rect.x),
|
[commandEncoder setScissorRect:scissorRect];
|
||||||
.height = NSUInteger(clip_rect.w - clip_rect.y)
|
|
||||||
};
|
|
||||||
[commandEncoder setScissorRect:scissorRect];
|
|
||||||
|
|
||||||
|
// Bind texture, Draw
|
||||||
|
if (ImTextureID tex_id = pcmd->GetTexID())
|
||||||
|
[commandEncoder setFragmentTexture:(__bridge id<MTLTexture>)(tex_id) atIndex:0];
|
||||||
|
|
||||||
// Bind texture, Draw
|
[commandEncoder setVertexBufferOffset:(vertexBufferOffset + pcmd->VtxOffset * sizeof(ImDrawVert)) atIndex:0];
|
||||||
if (ImTextureID tex_id = pcmd->GetTexID())
|
[commandEncoder drawIndexedPrimitives:MTLPrimitiveTypeTriangle
|
||||||
[commandEncoder setFragmentTexture:(__bridge id<MTLTexture>)(tex_id) atIndex:0];
|
indexCount:pcmd->ElemCount
|
||||||
|
indexType:sizeof(ImDrawIdx) == 2 ? MTLIndexTypeUInt16 : MTLIndexTypeUInt32
|
||||||
[commandEncoder setVertexBufferOffset:(vertexBufferOffset + pcmd->VtxOffset * sizeof(ImDrawVert)) atIndex:0];
|
indexBuffer:indexBuffer.buffer
|
||||||
[commandEncoder drawIndexedPrimitives:MTLPrimitiveTypeTriangle
|
indexBufferOffset:indexBufferOffset + pcmd->IdxOffset * sizeof(ImDrawIdx)];
|
||||||
indexCount:pcmd->ElemCount
|
|
||||||
indexType:sizeof(ImDrawIdx) == 2 ? MTLIndexTypeUInt16 : MTLIndexTypeUInt32
|
|
||||||
indexBuffer:indexBuffer.buffer
|
|
||||||
indexBufferOffset:indexBufferOffset + pcmd->IdxOffset * sizeof(ImDrawIdx)];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,21 +200,17 @@ void ImGui_ImplOpenGL2_RenderDrawData(ImDrawData* draw_data)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Project scissor/clipping rectangles into framebuffer space
|
// Project scissor/clipping rectangles into framebuffer space
|
||||||
ImVec4 clip_rect;
|
ImVec2 clip_min((pcmd->ClipRect.x - clip_off.x) * clip_scale.x, (pcmd->ClipRect.y - clip_off.y) * clip_scale.y);
|
||||||
clip_rect.x = (pcmd->ClipRect.x - clip_off.x) * clip_scale.x;
|
ImVec2 clip_max((pcmd->ClipRect.z - clip_off.x) * clip_scale.x, (pcmd->ClipRect.w - clip_off.y) * clip_scale.y);
|
||||||
clip_rect.y = (pcmd->ClipRect.y - clip_off.y) * clip_scale.y;
|
if (clip_max.x < clip_min.x || clip_max.y < clip_min.y)
|
||||||
clip_rect.z = (pcmd->ClipRect.z - clip_off.x) * clip_scale.x;
|
continue;
|
||||||
clip_rect.w = (pcmd->ClipRect.w - clip_off.y) * clip_scale.y;
|
|
||||||
|
|
||||||
if (clip_rect.x < fb_width && clip_rect.y < fb_height && clip_rect.z >= 0.0f && clip_rect.w >= 0.0f)
|
// Apply scissor/clipping rectangle (Y is inverted in OpenGL)
|
||||||
{
|
glScissor((int)clip_min.x, (int)(fb_height - clip_max.y), (int)(clip_max.x - clip_min.x), (int)(clip_max.y - clip_min.y));
|
||||||
// Apply scissor/clipping rectangle
|
|
||||||
glScissor((int)clip_rect.x, (int)(fb_height - clip_rect.w), (int)(clip_rect.z - clip_rect.x), (int)(clip_rect.w - clip_rect.y));
|
|
||||||
|
|
||||||
// Bind texture, Draw
|
// Bind texture, Draw
|
||||||
glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->GetTexID());
|
glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->GetTexID());
|
||||||
glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer);
|
glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
idx_buffer += pcmd->ElemCount;
|
idx_buffer += pcmd->ElemCount;
|
||||||
}
|
}
|
||||||
|
@ -442,26 +442,22 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Project scissor/clipping rectangles into framebuffer space
|
// Project scissor/clipping rectangles into framebuffer space
|
||||||
ImVec4 clip_rect;
|
ImVec2 clip_min((pcmd->ClipRect.x - clip_off.x) * clip_scale.x, (pcmd->ClipRect.y - clip_off.y) * clip_scale.y);
|
||||||
clip_rect.x = (pcmd->ClipRect.x - clip_off.x) * clip_scale.x;
|
ImVec2 clip_max((pcmd->ClipRect.z - clip_off.x) * clip_scale.x, (pcmd->ClipRect.w - clip_off.y) * clip_scale.y);
|
||||||
clip_rect.y = (pcmd->ClipRect.y - clip_off.y) * clip_scale.y;
|
if (clip_max.x < clip_min.x || clip_max.y < clip_min.y)
|
||||||
clip_rect.z = (pcmd->ClipRect.z - clip_off.x) * clip_scale.x;
|
continue;
|
||||||
clip_rect.w = (pcmd->ClipRect.w - clip_off.y) * clip_scale.y;
|
|
||||||
|
|
||||||
if (clip_rect.x < fb_width && clip_rect.y < fb_height && clip_rect.z >= 0.0f && clip_rect.w >= 0.0f)
|
// Apply scissor/clipping rectangle (Y is inverted in OpenGL)
|
||||||
{
|
glScissor((int)clip_min.x, (int)(fb_height - clip_max.y), (int)(clip_max.x - clip_min.x), (int)(clip_max.y - clip_min.y));
|
||||||
// Apply scissor/clipping rectangle
|
|
||||||
glScissor((int)clip_rect.x, (int)(fb_height - clip_rect.w), (int)(clip_rect.z - clip_rect.x), (int)(clip_rect.w - clip_rect.y));
|
|
||||||
|
|
||||||
// Bind texture, Draw
|
// Bind texture, Draw
|
||||||
glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->GetTexID());
|
glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->GetTexID());
|
||||||
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_VTX_OFFSET
|
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_VTX_OFFSET
|
||||||
if (bd->GlVersion >= 320)
|
if (bd->GlVersion >= 320)
|
||||||
glDrawElementsBaseVertex(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, (void*)(intptr_t)(pcmd->IdxOffset * sizeof(ImDrawIdx)), (GLint)pcmd->VtxOffset);
|
glDrawElementsBaseVertex(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, (void*)(intptr_t)(pcmd->IdxOffset * sizeof(ImDrawIdx)), (GLint)pcmd->VtxOffset);
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, (void*)(intptr_t)(pcmd->IdxOffset * sizeof(ImDrawIdx)));
|
glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, (void*)(intptr_t)(pcmd->IdxOffset * sizeof(ImDrawIdx)));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -511,31 +511,27 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Project scissor/clipping rectangles into framebuffer space
|
// Project scissor/clipping rectangles into framebuffer space
|
||||||
ImVec4 clip_rect;
|
ImVec2 clip_min((pcmd->ClipRect.x - clip_off.x) * clip_scale.x, (pcmd->ClipRect.y - clip_off.y) * clip_scale.y);
|
||||||
clip_rect.x = (pcmd->ClipRect.x - clip_off.x) * clip_scale.x;
|
ImVec2 clip_max((pcmd->ClipRect.z - clip_off.x) * clip_scale.x, (pcmd->ClipRect.w - clip_off.y) * clip_scale.y);
|
||||||
clip_rect.y = (pcmd->ClipRect.y - clip_off.y) * clip_scale.y;
|
|
||||||
clip_rect.z = (pcmd->ClipRect.z - clip_off.x) * clip_scale.x;
|
|
||||||
clip_rect.w = (pcmd->ClipRect.w - clip_off.y) * clip_scale.y;
|
|
||||||
|
|
||||||
if (clip_rect.x < fb_width && clip_rect.y < fb_height && clip_rect.z >= 0.0f && clip_rect.w >= 0.0f)
|
// Clamp to viewport as vkCmdSetScissor() won't accept values that are off bounds
|
||||||
{
|
if (clip_min.x < 0.0f) { clip_min.x = 0.0f; }
|
||||||
// Negative offsets are illegal for vkCmdSetScissor
|
if (clip_min.y < 0.0f) { clip_min.y = 0.0f; }
|
||||||
if (clip_rect.x < 0.0f)
|
if (clip_max.x > fb_width) { clip_max.x = (float)fb_width; }
|
||||||
clip_rect.x = 0.0f;
|
if (clip_max.y > fb_height) { clip_max.y = (float)fb_height; }
|
||||||
if (clip_rect.y < 0.0f)
|
if (clip_max.x < clip_min.x || clip_max.y < clip_min.y)
|
||||||
clip_rect.y = 0.0f;
|
continue;
|
||||||
|
|
||||||
// Apply scissor/clipping rectangle
|
// Apply scissor/clipping rectangle
|
||||||
VkRect2D scissor;
|
VkRect2D scissor;
|
||||||
scissor.offset.x = (int32_t)(clip_rect.x);
|
scissor.offset.x = (int32_t)(clip_min.x);
|
||||||
scissor.offset.y = (int32_t)(clip_rect.y);
|
scissor.offset.y = (int32_t)(clip_min.y);
|
||||||
scissor.extent.width = (uint32_t)(clip_rect.z - clip_rect.x);
|
scissor.extent.width = (uint32_t)(clip_max.x - clip_min.x);
|
||||||
scissor.extent.height = (uint32_t)(clip_rect.w - clip_rect.y);
|
scissor.extent.height = (uint32_t)(clip_max.y - clip_min.y);
|
||||||
vkCmdSetScissor(command_buffer, 0, 1, &scissor);
|
vkCmdSetScissor(command_buffer, 0, 1, &scissor);
|
||||||
|
|
||||||
// Draw
|
// Draw
|
||||||
vkCmdDrawIndexed(command_buffer, pcmd->ElemCount, 1, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset, 0);
|
vkCmdDrawIndexed(command_buffer, pcmd->ElemCount, 1, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset, 0);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
global_idx_offset += cmd_list->IdxBuffer.Size;
|
global_idx_offset += cmd_list->IdxBuffer.Size;
|
||||||
|
@ -443,13 +443,14 @@ void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder
|
|||||||
wgpuRenderPassEncoderSetBindGroup(pass_encoder, 1, image_bind_group, 0, NULL);
|
wgpuRenderPassEncoderSetBindGroup(pass_encoder, 1, image_bind_group, 0, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply Scissor, Bind texture, Draw
|
// Project scissor/clipping rectangles into framebuffer space
|
||||||
uint32_t clip_rect[4];
|
ImVec2 clip_min((pcmd->ClipRect.x - clip_off.x) * clip_scale.x, (pcmd->ClipRect.y - clip_off.y) * clip_scale.y);
|
||||||
clip_rect[0] = (uint32_t)(clip_scale.x * (pcmd->ClipRect.x - clip_off.x));
|
ImVec2 clip_max((pcmd->ClipRect.z - clip_off.x) * clip_scale.x, (pcmd->ClipRect.w - clip_off.y) * clip_scale.y);
|
||||||
clip_rect[1] = (uint32_t)(clip_scale.y * (pcmd->ClipRect.y - clip_off.y));
|
if (clip_max.x < clip_min.x || clip_max.y < clip_min.y)
|
||||||
clip_rect[2] = (uint32_t)(clip_scale.x * (pcmd->ClipRect.z - clip_off.x));
|
continue;
|
||||||
clip_rect[3] = (uint32_t)(clip_scale.y * (pcmd->ClipRect.w - clip_off.y));
|
|
||||||
wgpuRenderPassEncoderSetScissorRect(pass_encoder, clip_rect[0], clip_rect[1], clip_rect[2] - clip_rect[0], clip_rect[3] - clip_rect[1]);
|
// Apply scissor/clipping rectangle, Draw
|
||||||
|
wgpuRenderPassEncoderSetScissorRect(pass_encoder, (uint32_t)clip_min.x, (uint32_t)clip_min.y, (uint32_t)(clip_max.x - clip_min.x), (uint32_t)(clip_max.y - clip_min.y));
|
||||||
wgpuRenderPassEncoderDrawIndexed(pass_encoder, pcmd->ElemCount, 1, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset, 0);
|
wgpuRenderPassEncoderDrawIndexed(pass_encoder, pcmd->ElemCount, 1, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,6 +49,9 @@ Other Changes:
|
|||||||
- Fonts: Fixed ImFontAtlas::ClearInputData() marking atlas as not built. (#4455, #3487)
|
- Fonts: Fixed ImFontAtlas::ClearInputData() marking atlas as not built. (#4455, #3487)
|
||||||
- Backends: OpenGL3: Fixed our new GL loader conflicting with user using GL3W. (#4445)
|
- Backends: OpenGL3: Fixed our new GL loader conflicting with user using GL3W. (#4445)
|
||||||
- Backends: WebGPU: Fixed for latest specs. (#4472) [@Kangz]
|
- Backends: WebGPU: Fixed for latest specs. (#4472) [@Kangz]
|
||||||
|
- Backends: Metal: Fixed a crash when clipping rect larger than framebuffer is submitted via
|
||||||
|
a direct unclipped PushClipRect() call. (#4464)
|
||||||
|
- Backends: All renderers: Normalize clipping rect handling across backends. (#4464)
|
||||||
|
|
||||||
|
|
||||||
-----------------------------------------------------------------------
|
-----------------------------------------------------------------------
|
||||||
|
Loading…
Reference in New Issue
Block a user