From f8e689561fc9644c03c5532fe794f509e3697408 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Tue, 17 Apr 2018 20:28:29 +0100 Subject: [PATCH] Switched to FTransform2D when processing ImGui output before rendering it in Slate. This allows for more flexibility when transforming that data. Changed interface of FImGuiDrawList to enforce consistent transformation of vertices and clipping rectangle. --- Source/ImGui/Private/ImGuiDrawData.cpp | 14 +++++++------- Source/ImGui/Private/ImGuiDrawData.h | 16 +++++++++------- Source/ImGui/Private/ImGuiInteroperability.h | 6 ++++++ Source/ImGui/Private/SImGuiWidget.cpp | 13 ++++++++----- 4 files changed, 30 insertions(+), 19 deletions(-) diff --git a/Source/ImGui/Private/ImGuiDrawData.cpp b/Source/ImGui/Private/ImGuiDrawData.cpp index 4126bfe..c2ed960 100644 --- a/Source/ImGui/Private/ImGuiDrawData.cpp +++ b/Source/ImGui/Private/ImGuiDrawData.cpp @@ -6,9 +6,9 @@ #if WITH_OBSOLETE_CLIPPING_API -void FImGuiDrawList::CopyVertexData(TArray& OutVertexBuffer, const FVector2D VertexPositionOffset, const FSlateRotatedRect& VertexClippingRect) const +void FImGuiDrawList::CopyVertexData(TArray& OutVertexBuffer, const FTransform2D& Transform, const FSlateRotatedRect& VertexClippingRect) const #else -void FImGuiDrawList::CopyVertexData(TArray& OutVertexBuffer, const FVector2D VertexPositionOffset) const +void FImGuiDrawList::CopyVertexData(TArray& OutVertexBuffer, const FTransform2D& Transform) const #endif // WITH_OBSOLETE_CLIPPING_API { // Reset and reserve space in destination buffer. @@ -25,13 +25,13 @@ void FImGuiDrawList::CopyVertexData(TArray& OutVertexBuffer, const SlateVertex.TexCoords[1] = ImGuiVertex.uv.y; SlateVertex.TexCoords[2] = SlateVertex.TexCoords[3] = 1.f; - // Copy ImGui position and add offset. - SlateVertex.Position[0] = ImGuiVertex.pos.x + VertexPositionOffset.X; - SlateVertex.Position[1] = ImGuiVertex.pos.y + VertexPositionOffset.Y; - #if WITH_OBSOLETE_CLIPPING_API - // Set clipping rectangle. + const FVector2D VertexPosition = Transform.TransformPoint(ImGuiInterops::ToVector2D(ImGuiVertex.pos)); + SlateVertex.Position[0] = VertexPosition.X; + SlateVertex.Position[1] = VertexPosition.Y; SlateVertex.ClipRect = VertexClippingRect; +#else + SlateVertex.Position = Transform.TransformPoint(ImGuiInterops::ToVector2D(ImGuiVertex.pos)); #endif // WITH_OBSOLETE_CLIPPING_API // Unpack ImU32 color. diff --git a/Source/ImGui/Private/ImGuiDrawData.h b/Source/ImGui/Private/ImGuiDrawData.h index a2083d0..c179e95 100644 --- a/Source/ImGui/Private/ImGuiDrawData.h +++ b/Source/ImGui/Private/ImGuiDrawData.h @@ -32,24 +32,26 @@ public: // Get the draw command by number. // @param CommandNb - Number of draw command + // @param Transform - Transform to apply to clipping rectangle // @returns Draw command data - FORCEINLINE FImGuiDrawCommand GetCommand(int CommandNb) const + FImGuiDrawCommand GetCommand(int CommandNb, const FTransform2D& Transform) const { const ImDrawCmd& ImGuiCommand = ImGuiCommandBuffer[CommandNb]; - return{ ImGuiCommand.ElemCount, ImGuiInterops::ToSlateRect(ImGuiCommand.ClipRect), ImGuiInterops::ToTextureIndex(ImGuiCommand.TextureId) }; + return { ImGuiCommand.ElemCount, TransformRect(Transform, 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; + // @param Transform - Transform to apply to all vertices + // @param VertexClippingRect - Clipping rectangle for transformed Slate vertices + void CopyVertexData(TArray& OutVertexBuffer, const FTransform2D& Transform, 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; + // @param Transform - Transform to apply to all vertices + void CopyVertexData(TArray& OutVertexBuffer, const FTransform2D& Transform) const; #endif // WITH_OBSOLETE_CLIPPING_API // Transform and copy index data to target buffer (old data in the target buffer are replaced). diff --git a/Source/ImGui/Private/ImGuiInteroperability.h b/Source/ImGui/Private/ImGuiInteroperability.h index 86e311b..12d845f 100644 --- a/Source/ImGui/Private/ImGuiInteroperability.h +++ b/Source/ImGui/Private/ImGuiInteroperability.h @@ -85,6 +85,12 @@ namespace ImGuiInterops return FSlateRect{ ImGuiRect.x, ImGuiRect.y, ImGuiRect.z, ImGuiRect.w }; } + // Convert from ImVec2 rectangle to FVector2D. + FORCEINLINE FVector2D ToVector2D(const ImVec2& ImGuiVector) + { + return FVector2D{ ImGuiVector.x, ImGuiVector.y }; + } + // Convert from ImGui Texture Id to Texture Index that we use for texture resources. FORCEINLINE TextureIndex ToTextureIndex(ImTextureID Index) { diff --git a/Source/ImGui/Private/SImGuiWidget.cpp b/Source/ImGui/Private/SImGuiWidget.cpp index 8148b11..5979d34 100644 --- a/Source/ImGui/Private/SImGuiWidget.cpp +++ b/Source/ImGui/Private/SImGuiWidget.cpp @@ -443,22 +443,25 @@ int32 SImGuiWidget::OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGeo // Convert clipping rectangle to format required by Slate vertex. const FSlateRotatedRect VertexClippingRect{ MyClippingRect }; + // Scale -> CanvasOffset in Screen Space + const FTransform2D Transform{ VertexPositionOffset }; + for (const auto& DrawList : ContextProxy->GetDrawData()) { #if WITH_OBSOLETE_CLIPPING_API - DrawList.CopyVertexData(VertexBuffer, VertexPositionOffset, VertexClippingRect); + DrawList.CopyVertexData(VertexBuffer, Transform, 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); + DrawList.CopyVertexData(VertexBuffer, Transform); #endif // WITH_OBSOLETE_CLIPPING_API int IndexBufferOffset = 0; for (int CommandNb = 0; CommandNb < DrawList.NumCommands(); CommandNb++) { - const auto& DrawCommand = DrawList.GetCommand(CommandNb); + const auto& DrawCommand = DrawList.GetCommand(CommandNb, Transform); DrawList.CopyIndexData(IndexBuffer, IndexBufferOffset, DrawCommand.NumElements); @@ -469,7 +472,7 @@ int32 SImGuiWidget::OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGeo const FSlateResourceHandle& Handle = ModuleManager->GetTextureManager().GetTextureHandle(DrawCommand.TextureId); // Transform clipping rectangle to screen space and apply to elements that we draw. - const FSlateRect ClippingRect = DrawCommand.ClippingRect.OffsetBy(MyClippingRect.GetTopLeft()).IntersectionWith(MyClippingRect); + const FSlateRect ClippingRect = DrawCommand.ClippingRect.IntersectionWith(MyClippingRect); #if WITH_OBSOLETE_CLIPPING_API GSlateScissorRect = FShortRect{ ClippingRect }; @@ -534,7 +537,7 @@ static TArray GetImGuiMappedKeys() return Keys; } -// Column layout unitlities. +// Column layout utilities. namespace Columns { template