I’ve been working on a HUD in Canvas and in the process of refactoring I ran into a bit of an issue with FCanvasTileItem. I’ve written a helper function which generates a FCanvasTileItem and then Draws it to the canvas.
USTRUCT()
struct FCGWidgetBrush
{
GENERATED_USTRUCT_BODY()
/** The actual texture for this "brush". */
UPROPERTY(EditDefaultsOnly, Category = Texture)
UTexture* Texture;
/**UV start Point.*/
UPROPERTY(EditDefaultsOnly, Category = Texture)
FVector2D UV;
/** Texture size in relation to UV coordinates */
UPROPERTY(EditDefaultsOnly, Category = Texture)
FVector2D UVSize;
/** The Scale of the icon, not normalized.*/
UPROPERTY(EditDefaultsOnly, Category = Texture)
FVector2D Scale;
/** The anchor point of the texture. */
UPROPERTY(EditDefaultsOnly, Category = Texture)
FVector2D Anchor;
/** The alignment of the texture relative to the Anchor. Normalized*/
UPROPERTY(EditDefaultsOnly, Category = Texture)
FVector2D Alignment;
/** The color of this element.*/
UPROPERTY(EditDefaultsOnly, Category = Texture)
FLinearColor DefaultColor;
FCGWidgetBrush()
{
Scale = FVector2D(1.f, 1.f);
Anchor = FVector2D(0.f, 0.f);
Alignment = FVector2D(0.f, 0.f);
DefaultColor = FLinearColor::White;
}
};
void UCGHUDWidget::DrawBrush(const FCGWidgetBrush& Brush, const FLinearColor& Color) const
{
if (Brush.Texture && Brush.Texture->Resource)
{
// Scale
FVector2D Size(UIScale.X * Brush.Scale.X * Brush.UVSize.X,
UIScale.Y * Brush.Scale.Y * Brush.UVSize.Y);
// Anchor Offset
FVector2D Position(Origin + (Brush.Anchor * UIScale));
// Alignment - Depends on anchor/origin and alignment.
Position += Size * Brush.Alignment;
FCanvasTileItem BrushItem( Position, Brush.Texture->Resource,
Brush.UV, Brush.UVSize + Brush.UV, Color);
BrushItem.BlendMode = SE_BLEND_Translucent;
OwnerCanvas->DrawItem(BrushItem);
}
}
This code executes fine, but I crash in FCanvasBatchedElementRenderItem::Render_GameThread on line 391 in the Canvas.cpp file in Debug Mode. Alternatively, in development I crash with the following crash report:
Access violation - code c0000005
(first/second chance not available)UE4Editor_D3D11RHI!GetD3D11TextureFromRHITexture()
- 21 bytes [d:\buildfarm\buildmachine_++depot+ue4-releases+4.7\engine\source\runtime\windows\d3d11rhi\public\d3d11resources.h:530]
UE4Editor_D3D11RHI!FD3D11DynamicRHI::RHISetShaderTexture()- 46 bytes [d:\buildfarm\buildmachine_++depot+ue4-releases+4.7\engine\source\runtime\windows\d3d11rhi\private\d3d11commands.cpp:351]
UE4Editor_Engine!FSimpleElementPS::SetParameters()- 127 bytes [d:\buildfarm\buildmachine_++depot+ue4-releases+4.7\engine\source\runtime\engine\private\simpleelementshaders.cpp:90]
UE4Editor_Engine!FSimpleElementGammaBasePS::SetParameters()- 32 bytes [d:\buildfarm\buildmachine_++depot+ue4-releases+4.7\engine\source\runtime\engine\private\simpleelementshaders.cpp:123]
UE4Editor_Engine!FBatchedElements::PrepareShaders()- 2365 bytes [d:\buildfarm\buildmachine_++depot+ue4-releases+4.7\engine\source\runtime\engine\private\batchedelements.cpp:618]
UE4Editor_Engine!FBatchedElements::Draw()- 35479 bytes [d:\buildfarm\buildmachine_++depot+ue4-releases+4.7\engine\source\runtime\engine\private\batchedelements.cpp:981]
UE4Editor_Engine!FCanvasBatchedElementRenderItem::Render_GameThread'::
8’::EURCMacro_BatchedDrawCommand::DoTask()- 201 bytes [d:\buildfarm\buildmachine_++depot+ue4-releases+4.7\engine\source\runtime\engine\private\userinterface\canvas.cpp:445]
UE4Editor_Engine!TGraphTask<FCanvasBatchedElementRenderItem::Render_GameThread'::
8’::EURCMacro_BatchedDrawCommand>::ExecuteTask()- 456 bytes [d:\buildfarm\buildmachine_++depot+ue4-releases+4.7\engine\source\runtime\core\public\async\taskgraphinterfaces.h:669]
UE4Editor_Core!FTaskThread::ProcessTasks()- 3125 bytes [d:\buildfarm\buildmachine_++depot+ue4-releases+4.7\engine\source\runtime\core\private\async\taskgraph.cpp:428]
UE4Editor_Core!FTaskThread::ProcessTasksUntilQuit()- 77 bytes [d:\buildfarm\buildmachine_++depot+ue4-releases+4.7\engine\source\runtime\core\private\async\taskgraph.cpp:271]
UE4Editor_RenderCore!RenderingThreadMain()- 183 bytes [d:\buildfarm\buildmachine_++depot+ue4-releases+4.7\engine\source\runtime\rendercore\private\renderingthread.cpp:282]
UE4Editor_RenderCore!FRenderingThread::Run()- 58 bytes [d:\buildfarm\buildmachine_++depot+ue4-releases+4.7\engine\source\runtime\rendercore\private\renderingthread.cpp:385]
UE4Editor_Core!FRunnableThreadWin::Run()- 102 bytes [d:\buildfarm\buildmachine_++depot+ue4-releases+4.7\engine\source\runtime\core\private\windows\windowsrunnablethread.cpp:73]
UE4Editor_Core!FRunnableThreadWin::GuardedRun() + 93 bytes [d:\buildfarm\buildmachine_++depot+ue4-releases+4.7\engine\source\runtime\core\private\windows\windowsrunnablethread.cpp:26]
kernel32 + 5074 bytes ntdll + 87108
bytes
To verify that my texture was valid I used the DrawTile function in Canvas which works, am I just neglecting to account for something in regards to FCanvasTileItem?
DrawTile code is as follows:
OwnerCanvas->SetDrawColor(Color);
OwnerCanvas->DrawTile(
Brush.Texture,
Position.X, Position.Y,
Size.X, Size.Y,
Brush.UV.X, Brush.UV.Y,
Brush.UVSize.X, Brush.UVSize.Y,
EBlendMode::BLEND_Translucent);
Edit:
This code exists in a class which is given the Canvas each DrawHUD call.