Using SImage with ScreenCapture

Hello I have some code where I am trying to dynamically capture a texture from a scene, construct a 2D Texture object, and then attach it to a Slate SImage. I first spawn AScenceCapture2D camera in my world and then access it’s TextureTarget to create a 2DTexture to feed into my SlateImageBrush for use in my SImage. Unfortunately when I run, I get nothing in the SImage. I think I’m doing something wrong with the SlateBrush. I would love some guidance. I’ve done some My code setup is as follows:

// Fill out your copyright notice in the Description page of Project Settings.
#include "GlobePanelHUD.h"
#include "CoreMinimal.h"
#include "CookbookStyle.h"
#include "Kismet/GameplayStatics.h"
#include "GlobeGameModeBase.h"
#include "Engine.h"
#include "SlateBasics.h"
#include "Slate/SceneViewport.h"
#include "Widgets/SOverlay.h"
#include "Slate/SGameLayerManager.h"
#include "GlobePlayerController.h"
#include "Components/Image.h"
AGlobePanelHUD::AGlobePanelHUD() :Super()
{
	PrimaryActorTick.bCanEverTick = true;
	PrimaryActorTick.bStartWithTickEnabled = true;


}

void AGlobePanelHUD::DrawHUD()
{
	//updateCall();


}

void AGlobePanelHUD::updateCall()
{


}

void AGlobePanelHUD::BeginPlay()
{
	//PrimaryActorTick.bCanEverTick = true;
	Super::BeginPlay();

	FVector location = FVector(0.0, 1.0, 0.0);
	FRotator rotation;
	actorCap = GetWorld()->SpawnActor<ASceneCapture2D>(ASceneCapture2D::StaticClass());

	actorCap->Rename(*(FString("SceneCapCamera")));


	
	//Create a new scene capture component and set view

	renderTarget = NewObject<UTextureRenderTarget2D>();
	renderTarget->SizeX = 256;
	renderTarget->SizeY = 256;
	renderTarget->InitCustomFormat(256, 256, EPixelFormat::PF_B8G8R8A8, true);
	renderTarget->UpdateResourceImmediate();
	capturedTexture2D = NewObject<UTexture2D>();
	snap = true;


	sCapture = NewObject<USceneCaptureComponent2D>();
	s_Image = SNew(SImage);

	//Reassign the sCapture to the SceneComponent's capture component
	sCapture = actorCap->GetCaptureComponent2D();
	sCapture->bCaptureEveryFrame = true;
	sCapture->TextureTarget = renderTarget;



	AActor* firstActor = GetGameInstance()->GetFirstLocalPlayerController()->GetViewTarget();


	FMinimalViewInfo vInfo;

	vInfo.Location = FVector(0, 0, 0);
	vInfo.Rotation = FRotator(FQuat(FVector(0, 1, 0), 0));



	sCapture->SetCameraView(vInfo);

	sCapture->CaptureScene();
	sCapture->UpdateContent();
	capturedTexture2D = sCapture->TextureTarget->ConstructTexture2D(this, "Capture1", RF_NoFlags, CTF_Default | CTF_AllowMips, NULL);


	dImgBrush = TSharedPtr<FSlateDynamicImageBrush>(new FSlateDynamicImageBrush(capturedTexture2D, FVector2D(sCapture->TextureTarget->SizeX, sCapture->TextureTarget->SizeY), ""));




	s_Image->SetImage(dImgBrush.Get());



	anOverlay = SNew(SOverlay)
		+ SOverlay::Slot()
		.HAlign(HAlign_Center)
		.VAlign(VAlign_Center)
		[
			SNew(SBox)
			.WidthOverride(FOptionalSize(256))
		.HeightOverride(FOptionalSize(256))
		[


			s_Image.ToSharedRef()


		]
		];


	GEngine->GameViewport->AddViewportWidgetContent(anOverlay.ToSharedRef());
	
}



void AGlobePanelHUD::Tick(float seconds)
{
	Super::Tick(seconds);

	if (renderTarget == nullptr)
	{
		renderTarget = NewObject<UTextureRenderTarget2D>();
		renderTarget->InitAutoFormat(256, 256);
		renderTarget->UpdateResourceImmediate();
	}
	

	sCapture->TextureTarget = renderTarget;
	sCapture->CaptureScene();
	sCapture->UpdateContent();


	capturedTexture2D = UTexture2D::CreateTransient(256, 256);
	s_Image->SetImage(dImgBrush.Get());



}

Thanks

I just figured out this problem and want to share with others. It turns out that you have to set the Capture Source of the CaptureComponent2D of your SceneCapture Actor to SCS_FinalColorLDR to see the full color image. There are other modes, but SCS_FinalColorLDR let me see the correct rendered image in the SImage widget.

1 Like