diff --git a/Source/ImGui/Private/ImGuiDrawData.cpp b/Source/ImGui/Private/ImGuiDrawData.cpp index 479e30a..4126bfe 100644 --- a/Source/ImGui/Private/ImGuiDrawData.cpp +++ b/Source/ImGui/Private/ImGuiDrawData.cpp @@ -5,12 +5,16 @@ #include "ImGuiDrawData.h" +#if WITH_OBSOLETE_CLIPPING_API void FImGuiDrawList::CopyVertexData(TArray& OutVertexBuffer, const FVector2D VertexPositionOffset, const FSlateRotatedRect& VertexClippingRect) const +#else +void FImGuiDrawList::CopyVertexData(TArray& OutVertexBuffer, const FVector2D VertexPositionOffset) const +#endif // WITH_OBSOLETE_CLIPPING_API { // Reset and reserve space in destination buffer. OutVertexBuffer.SetNumUninitialized(ImGuiVertexBuffer.Size, false); - // Transform and copy vertex data. + // Transform and copy vertex data. for (int Idx = 0; Idx < ImGuiVertexBuffer.Size; Idx++) { const ImDrawVert& ImGuiVertex = ImGuiVertexBuffer[Idx]; @@ -25,8 +29,10 @@ void FImGuiDrawList::CopyVertexData(TArray& OutVertexBuffer, const SlateVertex.Position[0] = ImGuiVertex.pos.x + VertexPositionOffset.X; SlateVertex.Position[1] = ImGuiVertex.pos.y + VertexPositionOffset.Y; +#if WITH_OBSOLETE_CLIPPING_API // Set clipping rectangle. SlateVertex.ClipRect = VertexClippingRect; +#endif // WITH_OBSOLETE_CLIPPING_API // Unpack ImU32 color. SlateVertex.Color = ImGuiInterops::UnpackImU32Color(ImGuiVertex.col); diff --git a/Source/ImGui/Private/ImGuiDrawData.h b/Source/ImGui/Private/ImGuiDrawData.h index 9293cc8..a2083d0 100644 --- a/Source/ImGui/Private/ImGuiDrawData.h +++ b/Source/ImGui/Private/ImGuiDrawData.h @@ -4,11 +4,16 @@ #include "ImGuiInteroperability.h" +#include #include #include +// Starting from version 4.17 Slate doesn't have per-vertex clipping rectangle and GSlateScissorRect. Use this to +// support older engine versions. +#define WITH_OBSOLETE_CLIPPING_API (ENGINE_MAJOR_VERSION < 4 || (ENGINE_MAJOR_VERSION == 4 && ENGINE_MINOR_VERSION < 17)) + // ImGui draw command data transformed for Slate. struct FImGuiDrawCommand { @@ -34,16 +39,23 @@ public: return{ ImGuiCommand.ElemCount, ImGuiInterops::ToSlateRect(ImGuiCommand.ClipRect), ImGuiInterops::ToTextureIndex(ImGuiCommand.TextureId) }; } +#if WITH_OBSOLETE_CLIPPING_API // Transform and copy vertex data to target buffer (old data in the target buffer are replaced). // @param OutVertexBuffer - Destination buffer // @param VertexPositionOffset - Position offset added to every vertex to transform it to different space // @param VertexClippingRect - Clipping rectangle for Slate vertices void CopyVertexData(TArray& OutVertexBuffer, const FVector2D VertexPositionOffset, const FSlateRotatedRect& VertexClippingRect) const; +#else + // Transform and copy vertex data to target buffer (old data in the target buffer are replaced). + // @param OutVertexBuffer - Destination buffer + // @param VertexPositionOffset - Position offset added to every vertex to transform it to different space + void CopyVertexData(TArray& OutVertexBuffer, const FVector2D VertexPositionOffset) const; +#endif // WITH_OBSOLETE_CLIPPING_API // Transform and copy index data to target buffer (old data in the target buffer are replaced). // Internal index buffer contains enough data to match the sum of NumElements from all draw commands. // @param OutIndexBuffer - Destination buffer - // @param StartIndex - Start copying source data starting from this index + // @param StartIndex - Start copying source data starting from this index // @param NumElements - How many elements we want to copy void CopyIndexData(TArray& OutIndexBuffer, const int32 StartIndex, const int32 NumElements) const; diff --git a/Source/ImGui/Private/SImGuiWidget.cpp b/Source/ImGui/Private/SImGuiWidget.cpp index 3307fa7..2b839b4 100644 --- a/Source/ImGui/Private/SImGuiWidget.cpp +++ b/Source/ImGui/Private/SImGuiWidget.cpp @@ -403,12 +403,15 @@ int32 SImGuiWidget::OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGeo for (const auto& DrawList : ContextProxy->GetDrawData()) { +#if WITH_OBSOLETE_CLIPPING_API DrawList.CopyVertexData(VertexBuffer, VertexPositionOffset, VertexClippingRect); // Get access to the Slate scissor rectangle defined in Slate Core API, so we can customize elements drawing. extern SLATECORE_API TOptional GSlateScissorRect; - auto GSlateScissorRectSaver = ScopeGuards::MakeStateSaver(GSlateScissorRect); +#else + DrawList.CopyVertexData(VertexBuffer, VertexPositionOffset); +#endif // WITH_OBSOLETE_CLIPPING_API int IndexBufferOffset = 0; for (int CommandNb = 0; CommandNb < DrawList.NumCommands(); CommandNb++) @@ -423,11 +426,21 @@ int32 SImGuiWidget::OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGeo // Get texture resource handle for this draw command (null index will be also mapped to a valid texture). const FSlateResourceHandle& Handle = ModuleManager->GetTextureManager().GetTextureHandle(DrawCommand.TextureId); - // Transform clipping rectangle to screen space and set in Slate, to apply it to elements that we draw. - GSlateScissorRect = FShortRect{ DrawCommand.ClippingRect.OffsetBy(MyClippingRect.GetTopLeft()).IntersectionWith(MyClippingRect) }; + // Transform clipping rectangle to screen space and apply to elements that we draw. + const FSlateRect ClippingRect = DrawCommand.ClippingRect.OffsetBy(MyClippingRect.GetTopLeft()).IntersectionWith(MyClippingRect); + +#if WITH_OBSOLETE_CLIPPING_API + GSlateScissorRect = FShortRect{ ClippingRect }; +#else + OutDrawElements.PushClip(FSlateClippingZone{ ClippingRect }); +#endif // WITH_OBSOLETE_CLIPPING_API // Add elements to the list. FSlateDrawElement::MakeCustomVerts(OutDrawElements, LayerId, Handle, VertexBuffer, IndexBuffer, nullptr, 0, 0); + +#if !WITH_OBSOLETE_CLIPPING_API + OutDrawElements.PopClip(); +#endif // WITH_OBSOLETE_CLIPPING_API } } }