Files
UnrealEngine/Engine/Source/Runtime/UMG/Public/Slate/SMeshWidget.h
2025-05-18 13:04:45 +08:00

129 lines
4.5 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "UObject/GCObject.h"
#include "Textures/SlateShaderResource.h"
#include "Rendering/RenderingCommon.h"
#include "Widgets/DeclarativeSyntaxSupport.h"
#include "Widgets/SLeafWidget.h"
class FPaintArgs;
class FSlateWindowElementList;
class UMaterialInstanceDynamic;
class USlateVectorArtData;
struct FSlateBrush;
/**
* A widget that draws vertexes provided by a 2.5D StaticMesh.
* The Mesh's material is used.
* Hardware instancing is supported.
*/
class SMeshWidget : public SLeafWidget, public FGCObject
{
public:
SLATE_BEGIN_ARGS(SMeshWidget)
: _MeshData(nullptr)
{}
/** The StaticMesh asset that should be drawn. */
SLATE_ARGUMENT(USlateVectorArtData*, MeshData)
SLATE_END_ARGS()
UMG_API void Construct(const FArguments& Args);
/**
* Draw the InStaticMesh when this widget paints.
*
* @return the Index of the mesh data that was added; cache this value for use with @see FRenderRun.
*/
UMG_API uint32 AddMesh(USlateVectorArtData& InMeshData);
/** Much like AddMesh, but also enables instancing support for this MeshId. */
UMG_API uint32 AddMeshWithInstancing(USlateVectorArtData& InMeshData, int32 InitialBufferSize = 1);
/**
* Switch from static material to material instance dynamic.
*
* @param MeshId The index of the mesh; returned from AddMesh.
*
* @return The MID for this Asset on which parameters can be set.
*/
UMG_API UMaterialInstanceDynamic* ConvertToMID( uint32 MeshId );
/** Discard any previous runs and reserve space for new render runs if needed. */
UMG_API void ClearRuns(int32 NumRuns);
/**
* Tell the widget to draw instances of a mesh a given number of times starting at
* a given offset.
*
* @param InMeshIndex Which mesh to draw; returned by @see AddMesh
* @param InInstanceOffset Start drawing with this instance
* @param InNumInstances Draw this many instances
*/
FORCEINLINE void AddRenderRun(uint32 InMeshIndex, uint32 InInstanceOffset, uint32 InNumInstances)
{
RenderRuns.Add(FRenderRun(InMeshIndex, InInstanceOffset, InNumInstances));
}
/** Enable hardware instancing */
UMG_API void EnableInstancing(uint32 MeshId, int32 InitialSize);
/** Updates the per instance buffer. Automatically enables hardware instancing. */
UMG_API void UpdatePerInstanceBuffer(uint32 MeshId, FSlateInstanceBufferData& Data);
protected:
// BEGIN SLeafWidget interface
UMG_API virtual int32 OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyCullingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled) const override;
UMG_API virtual FVector2D ComputeDesiredSize(float) const override;
// END SLeafWidget interface
// ~ FGCObject
UMG_API virtual void AddReferencedObjects(FReferenceCollector& Collector) override;
UMG_API virtual FString GetReferencerName() const override;
// ~ FGCObject
protected:
static UMG_API void PushUpdate(uint32 VectorArtId, SMeshWidget& Widget, const FVector2D& Position, float Scale, uint32 BaseAddress);
static UMG_API void PushUpdate(uint32 VectorArtId, SMeshWidget& Widget, const FVector2D& Position, float Scale, float OptionalFloat = 0);
struct FRenderData
{
/** Holds a copy of the Static Mesh's data converted to a format that Slate understands. */
TArray<FSlateVertex> VertexData;
/** Connectivity data: Order in which the vertexes occur to make up a series of triangles. */
TArray<SlateIndex> IndexData;
/** Holds on to the material that is found on the StaticMesh. */
TSharedPtr<FSlateBrush> Brush;
/** A rendering handle used to quickly access the rendering data for the slate element*/
FSlateResourceHandle RenderingResourceHandle;
/** Per instance data that can be passed to */
TSharedPtr<ISlateUpdatableInstanceBuffer> PerInstanceBuffer;
};
TArray<FRenderData, TInlineAllocator<3>> RenderData;
private:
/** Which mesh to draw, starting with which instance offset and how many instances to draw in this run/batch. */
class FRenderRun
{
public:
FRenderRun(uint32 InMeshIndex, uint32 InInstanceOffset, uint32 InNumInstances)
: MeshIndex(InMeshIndex)
, InstanceOffset(InInstanceOffset)
, NumInstances(InNumInstances)
{
}
uint32 GetMeshIndex() const { return MeshIndex; }
uint32 GetInstanceOffset() const { return InstanceOffset; }
uint32 GetNumInstances() const { return NumInstances; }
private:
uint32 MeshIndex;
uint32 InstanceOffset;
uint32 NumInstances;
};
TArray<FRenderRun> RenderRuns;
};