Hi all, I’ve seen a few posts about this, but none of the code snippets I found seemed to resolve my issue.
I create a camera/Scene Capture 2D responsible for capturing its view to a render target.
From this render target, I aim to create a Texture2D and read the pixel data within C++ for additional processing.
It appears the Texture2D is created and that its platform Data exists, however, when I print out the elements, I’m unable to get anything other than 0s.
Any assistance would be appreciated! (Windows, Unreal 5.2.3)
// Fill out your copyright notice in the Description page of Project Settings.
#include "MyCameraActor.h"
#include "Runtime/Engine/Classes/Engine/TextureRenderTarget2D.h"
#include "Components/SceneCaptureComponent2D.h"
#include "Components/SphereComponent.h"
// Sets default values
AMyCameraActor::AMyCameraActor()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
RootComponent = CreateDefaultSubobject<USphereComponent>(TEXT("Root"));
SetRootComponent(RootComponent);
Camera = CreateDefaultSubobject<USceneCaptureComponent2D>(TEXT("Camera"));
Camera -> SetupAttachment(RootComponent);
if (Camera)
{
UE_LOG(LogTemp, Warning, TEXT("Camera component created successfully"));
}
else
{
UE_LOG(LogTemp, Error, TEXT("Failed to create camera component"));
}
ConstructorHelpers::FObjectFinder<UTextureRenderTarget2D> RenderTargetAsset(TEXT("/Game/Game/MyLittleRenderTarget"));
if (RenderTargetAsset.Succeeded())
{
// Assign the found texture render target to the RenderTarget member variable
UE_LOG(LogTemp, Error, TEXT("FOUND the target asset: /MyLittleRenderTarget"));
RenderTarget = RenderTargetAsset.Object;
RenderTarget->InitAutoFormat(1024, 1024);
Camera->TextureTarget = RenderTarget;
}
else
{
// Log an error if the texture render target asset is not found
UE_LOG(LogTemp, Error, TEXT("Failed to find texture render target asset: /Game/MyLittleRenderTarget"));
}
}
// Called when the game starts or when spawned
void AMyCameraActor::BeginPlay()
{
Super::BeginPlay();
Camera->TextureTarget = RenderTarget;
int X = RenderTarget->GetSurfaceHeight();
int Y = RenderTarget->GetSurfaceWidth();
GLog->Logf(TEXT("Size: %d %d"), X, Y);
//Texture2D = RenderTarget->ConstructTexture2D(this, FString("Tex2D"), EObjectFlags::RF_NoFlags);
Texture2D = UTexture2D::CreateTransient(X, Y, PF_B8G8R8A8);
Texture2D->MipGenSettings = TMGS_NoMipmaps;
Texture2D->SRGB = false;
Texture2D->UpdateResource();
if (Texture2D)
{
UE_LOG(LogTemp, Warning, TEXT("TEX2D component created successfully"));
int xx = Texture2D->GetSizeX();
int yy = Texture2D->GetSizeY();
GLog->Logf(TEXT("Texture size: %d %d"), xx, yy);
FTexturePlatformData* Data = Texture2D->PlatformData;
if (Data)
{
UE_LOG(LogTemp, Warning, TEXT("Data component created successfully"));
EPixelFormat Format = Data->PixelFormat; //crashing here
GLog->Logf(TEXT("Pixel format: %d"), (uint8)(Format));
//format of pixel is PFloatRGBA
int size = Data->Mips[0].BulkData.GetElementSize();
int N = Data->Mips[0].BulkData.GetElementCount();
GLog->Logf(TEXT("Number of elements: %d, size of one element: %d"), N, size);
const void* Table = Data->Mips[0].BulkData.LockReadOnly();
Data->Mips[0].BulkData.Unlock();
const uint16* Tab2 = StaticCast<const uint16*>(Table);
// Test print. Array containing RGBA values. Correct size for Texture dimensions, but Prints 0 for every element.
for (int i = 0; i < 100; ++i) {
UE_LOG(LogTemp, Warning, TEXT("Tab2[%d]: %d"), i, Tab2[i]);
}
}
else
{
UE_LOG(LogTemp, Error, TEXT("Failed to create Data component"));
}
}
else
{
UE_LOG(LogTemp, Error, TEXT("Failed to create TEX2D component"));
}
}
// Called every frame
void AMyCameraActor::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}