Updated to Unreal Engine 4.17 (backward compatible):

- Removed usage of per-vertex ClipRect.
- Replaced usage of GSlateScissorRect with new FSlateWindowElementList::PushClip/PopClip functions.
- Defined WITH_OBSOLETE_CLIPPING_API to switch to old implementation for older engine versions.
This commit is contained in:
Sebastian 2017-11-05 19:41:34 +00:00
parent 865ade48c0
commit 9db4abcb0a
3 changed files with 36 additions and 5 deletions

View File

@ -5,12 +5,16 @@
#include "ImGuiDrawData.h"
#if WITH_OBSOLETE_CLIPPING_API
void FImGuiDrawList::CopyVertexData(TArray<FSlateVertex>& OutVertexBuffer, const FVector2D VertexPositionOffset, const FSlateRotatedRect& VertexClippingRect) const
#else
void FImGuiDrawList::CopyVertexData(TArray<FSlateVertex>& 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<FSlateVertex>& 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);

View File

@ -4,11 +4,16 @@
#include "ImGuiInteroperability.h"
#include <Runtime/Launch/Resources/Version.h>
#include <SlateCore.h>
#include <imgui.h>
// 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<FSlateVertex>& 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<FSlateVertex>& 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<SlateIndex>& OutIndexBuffer, const int32 StartIndex, const int32 NumElements) const;

View File

@ -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<FShortRect> 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
}
}
}