[Question] UTextureRenderTarget2D and Canvas

Hi! I’m trying to figure out how to use a UTextureRenderTarget2D with canvas rendering (not a camera render target.) I’ve almost got it working, but the editor crashes (with absolutely no useful info in the Log or the crash reporter - I’ve even got the editor crashing without the error reporter coming up at all, just silently closing.)

Here’s what I’ve got so far… I have no idea if this is correct or not:

Class:

protected:

	UPROPERTY()
	UTextureRenderTarget2D* tRenderTarget;

	FCanvas* oCanvas;

	UPROPERTY()
	UCanvas* uoCanvas;

Method that creates texture:

	FVector2D v2Size = GetSize();
	
	if ( v2Size.X <= 0.f || v2Size.Y <= 0.f )
		return;

	tRenderTarget = NewObject<UTextureRenderTarget2D>( this );
	tRenderTarget->InitAutoFormat( FMath::Floor( v2Size.X ), FMath::Floor( v2Size.Y ) );
	tRenderTarget->ClearColor = FLinearColor( 0.f, 0.f, 0.f, 0.f );

	// Create canvas to draw on the render target.

	// FCanvas, not a UObject
	oCanvas = new FCanvas( tRenderTarget->GameThread_GetRenderTargetResource(), NULL, GetWorld() );

	// UCanvas UObject.
	uoCanvas = NewObject<UCanvas>( this );
	uoCanvas->Canvas = oCanvas;
	uoCanvas->Init( FMath::Floor( v2Size.X ), FMath::Floor( v2Size.Y ), NULL );

I use the uoCanvas->DrawItem to draw stuff to the render target (causes crash.)

I then use the tRenderTarget object as a texture in an FCanvasTileItem, which I draw to the hud within the DrawHUD() call (causes crash after I press Stop from doing a PIE (where a big green square is drawn on the screen.))

Does anyone have any experience with rendering to render targets with canvas? Would appreciate some tips!

Instead of creating UCanvas in my code I just use the FCanvas to make my draw calls.

_outline_canvas->DrawTile(_renderTarget_res_x*u - (STAMP_SIZE - (STAMP_SIZE/4.0)) ,
		_renderTarget_res_y*v - (STAMP_SIZE - (STAMP_SIZE/4.0)), 
		STAMP_SIZE, STAMP_SIZE, 
		0,0,1,1,
		FLinearColor::White, 
		_grassOutlineMaskSplotch->Resource,
		true);

Where the grassOutlineMaskSplotch is the texture I want to draw at the specified location on the rendertarget.

I believe a render target texture is green as default. It seems like nothing is being drawn to the render target.

Can you try to do this during construction

tRenderTarget ->ClearColor = FLinearColor::Black;

and see if its black then just to make sure you have the right handle and its just a draw issue ?

Where are you calling your draw BTW ?

Good.

Then how about setting the following during construction and trying the draw again ?

tRenderTarget ->bNeedsTwoCopies = false;

I tried something similar:

Constructor:

	static ConstructorHelpers::FObjectFinder<UTexture2D> tTextureFinder( TEXT( "Texture2D'/Game/Textures/Particles/comb.comb'" ) );
	this->tTexture2 = tTextureFinder.Object;

	UTextureRenderTarget2D* tRenderTarget = NewObject<UTextureRenderTarget2D>( this );
	tRenderTarget->InitAutoFormat( FMath::Floor( 512 ), FMath::Floor( 512 ) );

	FCanvas canvas = FCanvas( tRenderTarget->GameThread_GetRenderTargetResource(), NULL, GetWorld() );
	canvas.DrawTile( 0, 0, 512, 512, 0, 0, 1, 1, FLinearColor::White, this->tTexture2->Resource, true );

	this->tTexture = tRenderTarget;

DrawHUD:

	oCanvas->Canvas->DrawTile( 100, 100, 512, 512, 0, 0, 1, 1, FLinearColor::White, tTexture->Resource, false );
	oCanvas->Canvas->DrawTile( 620, 100, 512, 512, 0, 0, 1, 1, FLinearColor::White, tTexture2->Resource, false );

I end up with (see attached.)

I tried using a render target taken from the editor, but I got the same result. A big green square. Using an editor resource is not doable for this particular bit of code anyway because they need to be dynamically generated at runtime.

I also tried putting the render target draw calls into the DrawHUD call. Same result.

I tried using (FTextureRenderTarget2DResource*) tRenderTarget->Resource instead of the GameThread_… call, too. No luck.

It’s not crashing with this majorly simplified version, so I guess I’ve got something in my code causing that. However, I still don’t get why it’s green.

tRenderTarget->ClearColor = FLinearColor::Black;

causes the texture to become black.

It’s a custom class that derives from HUD. The initial set up of the textures is in the constructor (with PCIP etc), the second set of calls are in DrawHUD().

Still black. I’ll try moving the render target rendering back into drawhud for a try.

No luck :frowning:

Just as a test. Let’s say you create the render target through the editor and there you set the need two copies parameter to false. Does this still happen ? Because this works for me.

Np. Good luck !

Sadly, it doesn’t work :frowning:

UTextureRenderTarget2D* tRenderTarget = NewObject( this );

replaced with:

static ConstructorHelpers::FObjectFinder<UTextureRenderTarget2D> tRenderTargetFinder( TEXT( "TextureRenderTarget2D'/Game/Developers/RenderTargetTest2.RenderTargetTest2'" ) );
UTextureRenderTarget2D* tRenderTarget = tRenderTargetFinder.Object;

Same result. Black square :frowning:

Talking with James Tan in IRC, though, and he says he has some insight. If I find a fix, I’ll post!

Thanks for trying to help, though, darkZ.

This is a ScriptedTexture class that James wrote yesterday, for dynamically created render targets:

https://github.com/EpicGames/UnrealEngine/pull/24/files

Thanks, James!

https://github.com/EpicGames/UnrealEngine/pull/24/files

James Tan went to town on it. Everything you should need is here.