I want to accomplish something that should be quite simple. However I explored the engine’s source code, the documentation, and the forum, and I was not able to find anything about it (though it’s possible that I didn’t use the right search keywords, so any hint would be helpful).
I started from one of the templates and added an ACameraActor in the corner of the map. I would like to access what the camera sees as a frame buffer in C++. I am able to access the main viewport as a TArray<FColor> using FSlateApplication::Get().TakeScreenshot. How can I do the same for other cameras or viewports? I feel like I probably missed something obvious. Thank you for any help!
I ended up finding a solution after some time. For anyone who also has this problem, the key is to use a RenderTarget. Here are the relevant parts of my code:
#include <Kismet/KismetRenderingLibrary.h>
#include <ImageUtils.h>
#include "Camera/CameraComponent.h"
#include "Kismet/KismetSystemLibrary.h"
USceneCaptureComponent2D *CaptureComp = CreateDefaultSubobject<USceneCaptureComponent2D>(TEXT("SceneCapture"));
CaptureComp->CaptureSource = SCS_FinalColorLDR;
CaptureComp->SetupAttachment(RootComponent);
TArray<FColor> PixelBuf;
// Set up
UTextureRenderTarget2D *TextureRender = NewObject<UTextureRenderTarget2D>(this);
if (IsValid(TextureRender))
{
TextureRender->RenderTargetFormat = RTF_RGBA16f;
TextureRender->InitAutoFormat(FRAME_WIDTH, FRAME_HEIGHT);
TextureRender->UpdateResourceImmediate(true);
CaptureComp->TextureTarget = TextureRender;
}
// Take a screenshot
if (IsValid(CaptureComp) && IsValid(TextureRender))
{
TextureRender->UpdateResourceImmediate(false);
FTextureRenderTargetResource *RenderTargetResource = TextureRender->GameThread_GetRenderTargetResource();
RenderTargetResource->ReadPixels(PixelBuf);
}
// Access the pixels
(uint8*) PixelBuf.GetData(); // Four bytes per pixel
PixelBuf.Num() * PixelBuf.GetTypeSize() // Number of bytes