void FTileSetEditorViewportClient::Draw(FViewport* InViewport, FCanvas* Canvas)
{
	// Clear the viewport
	Canvas->Clear(GetBackgroundColor());

	// Can only proceed if we have a valid tile set
	UPaperTileSet* TileSet = TileSetBeingEdited.Get();
	if (TileSet == nullptr)
	{
		return;
	}

	if (UTexture2D* Texture = TileSet->GetTileSheetTexture())
	{
		const bool bUseTranslucentBlend = Texture->HasAlphaChannel();

		// Fully stream in the texture before drawing it.
		Texture->SetForceMipLevelsToBeResident(30.0f);
		Texture->WaitForStreaming();

		FLinearColor TextureDrawColor = FLinearColor::White;

		{
			// Draw the tile sheet texture 
			const float XPos = -ZoomPos.X * ZoomAmount;
			const float YPos = -ZoomPos.Y * ZoomAmount;
			const float Width = Texture->GetSurfaceWidth() * ZoomAmount;
			const float Height = Texture->GetSurfaceHeight() * ZoomAmount;

			Canvas->DrawTile(XPos, YPos, Width, Height, 0.0f, 0.0f, 1.0f, 1.0f, TextureDrawColor, Texture->Resource, bUseTranslucentBlend);
		}


		const FLinearColor BorderRectangleColor(0.3f, 0.3f, 0.3f, 1.0f);
		{
			const FIntPoint TextureSize = Texture->GetImportedSize();
			const FIntMargin BorderSize = TileSet->GetMargin();
			const FIntRect TileSetRegion(BorderSize.Left, BorderSize.Top, TextureSize.X - BorderSize.Right, TextureSize.Y - BorderSize.Bottom);

			const float X = (TileSetRegion.Min.X - ZoomPos.X) * ZoomAmount;
			const float Y = (TileSetRegion.Min.Y - ZoomPos.Y) * ZoomAmount;
			const float W = TileSetRegion.Width() * ZoomAmount;
			const float H = TileSetRegion.Height() * ZoomAmount;

			FCanvasBoxItem BoxItem(FVector2D(X, Y), FVector2D(W, H));
			BoxItem.SetColor(BorderRectangleColor);
			Canvas->DrawItem(BoxItem);
		}

		if (bShowTilesWithCollision || bShowTilesWithMetaData)
		{
			// Draw an overlay rectangle on top of any tiles that have collision or metadata geometry
			const int32 NumTiles = TileSet->GetTileCount();

			const FLinearColor CollisionOverlayColor(0.0f, 0.7f, 1.0f, 0.5f);
			const FLinearColor MetaDataOverlayColor(1.0f, 0.2f, 0.0f, 0.5f);
			const FLinearColor InfoOverlayColor = bShowTilesWithCollision ? CollisionOverlayColor : MetaDataOverlayColor;

			const FIntPoint TileSetTileSize(TileSet->GetTileSize());
			const float Width = (TileSetTileSize.X - 2) * ZoomAmount;
			const float Height = (TileSetTileSize.Y - 2) * ZoomAmount;

			for (int32 TileIndex = 0; TileIndex < NumTiles; ++TileIndex)
			{
				if (const FPaperTileMetadata* TileMetadata = TileSet->GetTileMetadata(TileIndex))
				{
					const bool bShowDueToCollision = TileMetadata->HasCollision() && bShowTilesWithCollision;
					const bool bShowDueToMetaData = TileMetadata->HasMetaData() && bShowTilesWithMetaData;

					if (bShowDueToCollision || bShowDueToMetaData)
					{
						FVector2D TileUV;
						TileSet->GetTileUV(TileIndex, /*out*/ TileUV);

						const float XPos = (TileUV.X + 1 - ZoomPos.X) * ZoomAmount;
						const float YPos = (TileUV.Y + 1 - ZoomPos.Y) * ZoomAmount;

						Canvas->DrawTile(XPos, YPos, Width, Height, 0.0f, 0.0f, 1.0f, 1.0f, InfoOverlayColor, GWhiteTexture, /*bUseTranslucentBlend=*/ true);
					}
				}
			}
		}
	}

	// Overlay the selection rectangles
	DrawSelectionRectangles(InViewport, Canvas);

	if (bHasValidPaintRectangle)
	{
		const FViewportSelectionRectangle& Rect = ValidPaintRectangle;

		const float X = (Rect.TopLeft.X - ZoomPos.X) * ZoomAmount;
		const float Y = (Rect.TopLeft.Y - ZoomPos.Y) * ZoomAmount;
		const float W = Rect.Dimensions.X * ZoomAmount;
		const float H = Rect.Dimensions.Y * ZoomAmount;

		FCanvasBoxItem BoxItem(FVector2D(X, Y), FVector2D(W, H));
		BoxItem.SetColor(Rect.Color);
		Canvas->DrawItem(BoxItem);
	}

	if (CurrentSelectedTileIndex != INDEX_NONE)
	{
		const FString TileIndexString = FString::Printf(TEXT("Tile# %d"), CurrentSelectedTileIndex);

		int32 XL;
		int32 YL;
		StringSize(GEngine->GetLargeFont(), XL, YL, *TileIndexString);
		const float DrawX = 4.0f;
		const float DrawY = FMath::FloorToFloat(InViewport->GetSizeXY().Y - YL - 4.0f);
		Canvas->DrawShadowedString(DrawX, DrawY, *TileIndexString, GEngine->GetLargeFont(), FLinearColor::White);
	}
}
void FTextureEditorViewportClient::Draw(FViewport* Viewport, FCanvas* Canvas)
{
	if (!TextureEditorPtr.IsValid())
	{
		return;
	}
	
	UTexture* Texture = TextureEditorPtr.Pin()->GetTexture();
	FVector2D Ratio = FVector2D(GetViewportHorizontalScrollBarRatio(), GetViewportVerticalScrollBarRatio());
	FVector2D ViewportSize = FVector2D(TextureEditorViewportPtr.Pin()->GetViewport()->GetSizeXY().X, TextureEditorViewportPtr.Pin()->GetViewport()->GetSizeXY().Y);
	FVector2D ScrollBarPos = GetViewportScrollBarPositions();
	int32 YOffset = (Ratio.Y > 1.0f)? ((ViewportSize.Y - (ViewportSize.Y / Ratio.Y)) * 0.5f): 0;
	int32 YPos = YOffset - ScrollBarPos.Y;
	int32 XOffset = (Ratio.X > 1.0f)? ((ViewportSize.X - (ViewportSize.X / Ratio.X)) * 0.5f): 0;
	int32 XPos = XOffset - ScrollBarPos.X;
	
	UpdateScrollBars();

	const UTextureEditorSettings& Settings = *GetDefault<UTextureEditorSettings>();

	Canvas->Clear( Settings.BackgroundColor );

	TextureEditorPtr.Pin()->PopulateQuickInfo();
	
	// Get the rendering info for this object
	FThumbnailRenderingInfo* RenderInfo = GUnrealEd->GetThumbnailManager()->GetRenderingInfo(Texture);

	// If there is an object configured to handle it, draw the thumbnail
	if (RenderInfo != NULL && RenderInfo->Renderer != NULL)
	{
		UTexture2D* Texture2D = Cast<UTexture2D>(Texture);
		UTextureCube* TextureCube = Cast<UTextureCube>(Texture);
		UTextureRenderTarget2D* TextureRT2D = Cast<UTextureRenderTarget2D>(Texture);
		UTextureRenderTargetCube* RTTextureCube = Cast<UTextureRenderTargetCube>(Texture);

		// Fully stream in the texture before drawing it.
		if (Texture2D)
		{
			Texture2D->SetForceMipLevelsToBeResident(30.0f);
			Texture2D->WaitForStreaming();
		}

		// Figure out the size we need
		uint32 Width, Height;
		TextureEditorPtr.Pin()->CalculateTextureDimensions(Width, Height);

		TRefCountPtr<FBatchedElementParameters> BatchedElementParameters;

		if (GMaxRHIFeatureLevel >= ERHIFeatureLevel::SM4)
		{
			if (TextureCube || RTTextureCube)
			{
				BatchedElementParameters = new FMipLevelBatchedElementParameters((float)TextureEditorPtr.Pin()->GetMipLevel(), false);
			}
			else if (Texture2D)
			{
				float MipLevel = (float)TextureEditorPtr.Pin()->GetMipLevel();
				bool bIsNormalMap = Texture2D->IsNormalMap();
				bool bIsSingleChannel = Texture2D->CompressionSettings == TC_Grayscale || Texture2D->CompressionSettings == TC_Alpha;
				BatchedElementParameters = new FBatchedElementTexture2DPreviewParameters(MipLevel, bIsNormalMap, bIsSingleChannel);
			}
			else if (TextureRT2D)
			{
				float MipLevel = (float)TextureEditorPtr.Pin()->GetMipLevel();
				BatchedElementParameters = new FBatchedElementTexture2DPreviewParameters(MipLevel, false, false);
			}
			else
			{
				// Default to treating any UTexture derivative as a 2D texture resource
				float MipLevel = (float)TextureEditorPtr.Pin()->GetMipLevel();
				BatchedElementParameters = new FBatchedElementTexture2DPreviewParameters(MipLevel, false, false);
			}
		}

		// Draw the background checkerboard pattern in the same size/position as the render texture so it will show up anywhere
		// the texture has transparency
		if (Settings.Background == TextureEditorBackground_CheckeredFill)
		{
			Canvas->DrawTile( 0.0f, 0.0f, Viewport->GetSizeXY().X, Viewport->GetSizeXY().Y, 0.0f, 0.0f, (Viewport->GetSizeXY().X / CheckerboardTexture->GetSizeX()), (Viewport->GetSizeXY().Y / CheckerboardTexture->GetSizeY()), FLinearColor::White, CheckerboardTexture->Resource);
		}
		else if (Settings.Background == TextureEditorBackground_Checkered)
		{
			Canvas->DrawTile( XPos, YPos, Width, Height, 0.0f, 0.0f, (Width / CheckerboardTexture->GetSizeX()), (Height / CheckerboardTexture->GetSizeY()), FLinearColor::White, CheckerboardTexture->Resource);
		}

		float Exposure = FMath::Pow(2.0f, (float)TextureEditorViewportPtr.Pin()->GetExposureBias());

		FCanvasTileItem TileItem( FVector2D( XPos, YPos ), Texture->Resource, FVector2D( Width, Height ), FLinearColor(Exposure, Exposure, Exposure) );
		TileItem.BlendMode = TextureEditorPtr.Pin()->GetColourChannelBlendMode();
		TileItem.BatchedElementParameters = BatchedElementParameters;
		Canvas->DrawItem( TileItem );

		// Draw a white border around the texture to show its extents
		if (Settings.TextureBorderEnabled)
		{
			FCanvasBoxItem BoxItem( FVector2D(XPos, YPos), FVector2D(Width , Height ) );
			BoxItem.SetColor( Settings.TextureBorderColor );
			Canvas->DrawItem( BoxItem );
		}
	}
}
Example #3
0
/**
 *
 * @param Item the stat to render
 * @param Canvas the render interface to draw with
 * @param X the X location to start drawing at
 * @param Y the Y location to start drawing at
 * @param Indent Indentation of this cycles, used when rendering hierarchy
 * @param bStackStat If false, this is a non-stack cycle counter, don't render the call count column
 */
static int32 RenderCycle( const FComplexStatMessage& Item, class FCanvas* Canvas, int32 X, int32 Y, const int32 Indent, const bool bStackStat )
{
	FColor Color = GetStatRenderGlobals().StatColor;	

	check(Item.NameAndInfo.GetFlag(EStatMetaFlags::IsCycle));

	const bool bIsInitialized = Item.NameAndInfo.GetField<EStatDataType>() == EStatDataType::ST_int64;

	const int32 IndentWidth = Indent*8;

	if( bIsInitialized )
	{
		const float InMs = FPlatformTime::ToMilliseconds(Item.GetValue_Duration(EComplexStatField::IncAve));
		// Color will be determined by the average value of history
		// If show inclusive and and show exclusive is on, then it will choose color based on inclusive average
		// @TODO yrx 2014-08-21 This is slow, fix this.
		FString CounterName = Item.GetShortName().ToString();
		CounterName.RemoveFromStart(TEXT("STAT_"));
		GEngine->GetStatValueColoration(CounterName, InMs, Color);

		const float MaxMeter = 33.3f; // the time of a "full bar" in ms
		const int32 MeterWidth = GetStatRenderGlobals().AfterNameColumnOffset;

		int32 BarWidth = int32((InMs / MaxMeter) * MeterWidth);
		if (BarWidth > 2)
		{
			if (BarWidth > MeterWidth ) 
			{
				BarWidth = MeterWidth;
			}

			FCanvasBoxItem BoxItem( FVector2D(X + MeterWidth - BarWidth, Y + .4f * GetStatRenderGlobals().GetFontHeight()), FVector2D(BarWidth, 0.2f * GetStatRenderGlobals().GetFontHeight()) );
			BoxItem.SetColor( FLinearColor::Red );
			BoxItem.Draw( Canvas );		
		}
	}

	Canvas->DrawShadowedString(X + IndentWidth, Y, *ShortenName(*Item.GetDescription()), GetStatRenderGlobals().StatFont, Color);

	int32 CurrX = X + GetStatRenderGlobals().AfterNameColumnOffset;
	// Now append the call count
	if( bStackStat )
	{
		if (Item.NameAndInfo.GetFlag(EStatMetaFlags::IsPackedCCAndDuration) && bIsInitialized)
		{
			RightJustify(Canvas,CurrX,Y,*FString::Printf(TEXT("%u"), Item.GetValue_CallCount(EComplexStatField::IncAve)),Color);
		}
		CurrX += GetStatRenderGlobals().InterColumnOffset;
	}

	// Add the two inclusive columns if asked
	if( bIsInitialized )
	{
		RightJustify(Canvas,CurrX,Y,*FString::Printf(TEXT("%1.2f ms"),FPlatformTime::ToMilliseconds(Item.GetValue_Duration(EComplexStatField::IncAve))),Color); 
	}
	CurrX += GetStatRenderGlobals().InterColumnOffset;

	if( bIsInitialized )
	{
		RightJustify(Canvas,CurrX,Y,*FString::Printf(TEXT("%1.2f ms"),FPlatformTime::ToMilliseconds(Item.GetValue_Duration(EComplexStatField::IncMax))),Color);
		
	}
	CurrX += GetStatRenderGlobals().InterColumnOffset;

	if( bStackStat )
	{
		// And the exclusive if asked
		if( bIsInitialized )
		{
			RightJustify(Canvas,CurrX,Y,*FString::Printf(TEXT("%1.2f ms"),FPlatformTime::ToMilliseconds(Item.GetValue_Duration(EComplexStatField::ExcAve))),Color);
		}
		CurrX += GetStatRenderGlobals().InterColumnOffset;

		if( bIsInitialized )
		{
			RightJustify(Canvas,CurrX,Y,*FString::Printf(TEXT("%1.2f ms"),FPlatformTime::ToMilliseconds(Item.GetValue_Duration(EComplexStatField::ExcMax))),Color);
		}
		CurrX += GetStatRenderGlobals().InterColumnOffset;
	}
	return GetStatRenderGlobals().GetFontHeight();
}
Example #4
0
void FCanvasItemTestbed::Draw( class FViewport* Viewport, class FCanvas* Canvas )
{
	bTestState = !bTestState;

	if( !bShowTestbed )
	{
		return;
	}

	
	// A little ott for a testbed - but I wanted to draw several lines to ensure it worked :)
	if( TestLine.bTestSet == false )
	{
		TestLine.bTestSet = true;
		TestLine.LineStart.X = FMath::FRandRange( 0.0f, Viewport->GetSizeXY().X );
		TestLine.LineStart.Y = FMath::FRandRange( 0.0f, Viewport->GetSizeXY().Y );
		TestLine.LineEnd.X = FMath::FRandRange( 0.0f, Viewport->GetSizeXY().X );
		TestLine.LineEnd.Y  = FMath::FRandRange( 0.0f, Viewport->GetSizeXY().Y );
		TestLine.LineMove.X = FMath::FRandRange( 0.0f, 32.0f );
		TestLine.LineMove.Y = FMath::FRandRange( 0.0f, 32.0f );
		TestLine.LineMove2.X = FMath::FRandRange( 0.0f, 32.0f );
		TestLine.LineMove2.Y = FMath::FRandRange( 0.0f, 32.0f );
	}
	else
	{
		TestLine.LineStart += TestLine.LineMove;
		TestLine.LineEnd += TestLine.LineMove2;
		if( TestLine.LineStart.X < 0 )
		{
			TestLine.LineMove.X = -TestLine.LineMove.X;
		}
		if( TestLine.LineStart.Y < 0 )
		{
			TestLine.LineMove.Y = -TestLine.LineMove.Y;
		}
		if( TestLine.LineEnd.X < 0 )
		{
			TestLine.LineMove2.X = -TestLine.LineMove2.X;
		}
		if( TestLine.LineEnd.Y < 0 )
		{
			TestLine.LineMove2.Y = -TestLine.LineMove2.Y;
		}
		if( TestLine.LineStart.X > Viewport->GetSizeXY().X )
		{
			TestLine.LineMove.X = -TestLine.LineMove.X;
		}
		if( TestLine.LineStart.Y > Viewport->GetSizeXY().Y )
		{
			TestLine.LineMove.Y = -TestLine.LineMove.Y;
		}
		if( TestLine.LineEnd.X > Viewport->GetSizeXY().X )
		{
			TestLine.LineMove2.X = -TestLine.LineMove2.X;
		}
		if( TestLine.LineEnd.Y > Viewport->GetSizeXY().Y )
		{
			TestLine.LineMove2.Y = -TestLine.LineMove2.Y;
		}
	}
	
	// Text
	float CenterX = 0.0f;
	float YTest = 16.0f;
	FCanvasTextItem TextItem( FVector2D( CenterX, YTest ), LOCTEXT( "stringhere", "String Here" ), GEngine->GetSmallFont(), FLinearColor::Red );	
	TextItem.Draw( Canvas );
	
	// Shadowed text
	TextItem.Position.Y += TextItem.DrawnSize.Y;
	TextItem.Scale.X = 2.0f;
	TextItem.EnableShadow( FLinearColor::Green, FVector2D( 2.0f, 2.0f ) );
	TextItem.Text = LOCTEXT( "Scaled String here", "Scaled String here" );
	TextItem.Draw( Canvas );
	TextItem.DisableShadow();

	TextItem.Position.Y += TextItem.DrawnSize.Y;;
	TextItem.Text = LOCTEXT( "CenterdStringhere", "CenterdStringhere" );
	TextItem.Scale.X = 1.0f;
	TextItem.bCentreX = true;
	TextItem.Draw( Canvas );

	// Outlined text
	TextItem.Position.Y += TextItem.DrawnSize.Y;
	TextItem.Text = LOCTEXT( "ScaledCentredStringhere", "Scaled Centred String here" );	
	TextItem.OutlineColor = FLinearColor::Black;
	TextItem.bOutlined = true;
	TextItem.Scale = FVector2D( 2.0f, 2.0f );
	TextItem.SetColor( FLinearColor::Green );
	TextItem.Text = LOCTEXT( "ScaledCentredOutlinedStringhere", "Scaled Centred Outlined String here" );	
	TextItem.Draw( Canvas );
	
	// a line
	FCanvasLineItem LineItem( TestLine.LineStart, TestLine.LineEnd );
	LineItem.Draw( Canvas );

	// some boxes
	FCanvasBoxItem BoxItem( FVector2D( 88.0f, 88.0f ), FVector2D( 188.0f, 188.0f ) );
	BoxItem.SetColor( FLinearColor::Yellow );
	BoxItem.Draw( Canvas );

	BoxItem.SetColor( FLinearColor::Red );
	BoxItem.Position = FVector2D( 256.0f, 256.0f );
	BoxItem.Draw( Canvas );

	BoxItem.SetColor( FLinearColor::Blue );
	BoxItem.Position = FVector2D( 6.0f, 6.0f );
	BoxItem.Size = FVector2D( 48.0f, 96.0f );
	BoxItem.Draw( Canvas );
	
	// Triangle
	FCanvasTriangleItem TriItem(  FVector2D( 48.0f, 48.0f ), FVector2D( 148.0f, 48.0f ), FVector2D( 48.0f, 148.0f ), GWhiteTexture );
	TriItem.Draw( Canvas );

	// Triangle list
	TArray< FCanvasUVTri >	TriangleList;
	FCanvasUVTri SingleTri;
	SingleTri.V0_Pos = FVector2D( 128.0f, 128.0f );
	SingleTri.V1_Pos = FVector2D( 248.0f, 108.0f );
	SingleTri.V2_Pos = FVector2D( 100.0f, 348.0f );
	SingleTri.V0_UV = FVector2D::ZeroVector;
	SingleTri.V1_UV = FVector2D::ZeroVector;
	SingleTri.V2_UV = FVector2D::ZeroVector;
	TriangleList.Add( SingleTri );
	SingleTri.V0_Pos = FVector2D( 348.0f, 128.0f );
	SingleTri.V1_Pos = FVector2D( 448.0f, 148.0f );
	SingleTri.V2_Pos = FVector2D( 438.0f, 308.0f );
	TriangleList.Add( SingleTri );

	FCanvasTriangleItem TriItemList( TriangleList, GWhiteTexture );
	TriItemList.SetColor( FLinearColor::Red );
	TriItemList.Draw( Canvas );
	
// 	FCanvasNGonItem NGon( FVector2D( 256.0f, 256.0f ), FVector2D( 256.0f, 256.0f ), 6, GWhiteTexture, FLinearColor::White );
// 	NGon.Draw( Canvas );
// 
// 	FCanvasNGonItem NGon2( FVector2D( 488, 666.0f ), FVector2D( 256.0f, 256.0f ), 16, GWhiteTexture, FLinearColor::Green );
// 	NGon2.Draw( Canvas );

	// Texture
	UTexture* SelectedTexture = GEditor->GetSelectedObjects()->GetTop<UTexture>();	
	if( SelectedTexture )
	{
		// Plain tex
		FCanvasTileItem TileItem( FVector2D( 128.0f,128.0f ), SelectedTexture->Resource, FLinearColor::White );
		TileItem.Draw( Canvas );
		TileItem.Size = FVector2D( 32.0f,32.0f );
		TileItem.Position = FVector2D( 16.0f,16.0f );
		TileItem.Draw( Canvas );

		// UV 
		TileItem.Size = FVector2D( 64.0f,64.0f );
		TileItem.UV0 = FVector2D( 0.0f, 0.0f );
		TileItem.UV1 = FVector2D( 1.0f, 1.0f );
		TileItem.Position = FVector2D( 256.0f,16.0f );
		TileItem.Draw( Canvas );

		// UV 
		TileItem.Size = FVector2D( 64.0f,64.0f );
		TileItem.UV0 = FVector2D( 0.0f, 0.0f );
		TileItem.UV1 = FVector2D( 1.0f, -1.0f );
		TileItem.Position = FVector2D( 356.0f,16.0f );
		TileItem.Draw( Canvas );

		// UV 
		TileItem.Size = FVector2D( 64.0f,64.0f );
		TileItem.UV0 = FVector2D( 0.0f, 0.0f );
		TileItem.UV1 = FVector2D( -1.0f, 1.0f );
		TileItem.Position = FVector2D( 456.0f,16.0f );
		TileItem.Draw( Canvas );

		// UV 
		TileItem.Size = FVector2D( 64.0f,64.0f );
		TileItem.UV0 = FVector2D( 0.0f, 0.0f );
		TileItem.UV1 = FVector2D( -1.0f, -1.0f );
		TileItem.Position = FVector2D( 556.0f,16.0f );
		TileItem.Draw( Canvas );

		// Rotate top/left pivot
		TileItem.Size = FVector2D( 96.0f,96.0f );
		TileItem.UV0 = FVector2D( 0.0f, 0.0f );
		TileItem.UV1 = FVector2D( 1.0f, 1.0f );
		TileItem.Position = FVector2D( 400.0f,264.0f );
		TileItem.Rotation.Yaw = TestLine.Testangle;
		TileItem.Draw( Canvas );

		// Rotate center pivot
		TileItem.Size = FVector2D( 128.0f, 128.0f );
		TileItem.UV0 = FVector2D( 0.0f, 0.0f );
		TileItem.UV1 = FVector2D( 1.0f, 1.0f );
		TileItem.Position = FVector2D( 600.0f,264.0f );
		TileItem.Rotation.Yaw = 360.0f - TestLine.Testangle;
		TileItem.PivotPoint = FVector2D( 0.5f, 0.5f );
		TileItem.Draw( Canvas );

		TestLine.Testangle = FMath::Fmod( TestLine.Testangle + 2.0f, 360.0f );

		// textured tri
		FCanvasTriangleItem TriItemTex(  FVector2D( 48.0f, 48.0f ), FVector2D( 148.0f, 48.0f ), FVector2D( 48.0f, 148.0f ), FVector2D( 0.0f, 0.0f ), FVector2D( 1.0f, 0.0f ), FVector2D( 0.0f, 1.0f ), SelectedTexture->Resource  );
		TriItem.Texture = GWhiteTexture;
		TriItemTex.Draw( Canvas );

		// moving tri (only 1 point moves !)
		TriItemTex.Position = TestLine.LineStart;
		TriItemTex.Draw( Canvas );
	}
}