Projekt for SPIE - Avatar for safety briefing / managment event
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

109 lines
4.1 KiB

// Fill out your copyright notice in the Description page of Project Settings.
#undef UpdateResource
#include "CineCameraRenderActor.h"
#include "CineCameraComponent.h"
#include "Components/SceneCaptureComponent2D.h"
#include "Engine/TextureRenderTarget2D.h"
#include "Engine/Texture2D.h"
#include "Engine/World.h"
#include "RenderUtils.h"
// Sets default values
ACineCameraRenderActor::ACineCameraRenderActor()
{
PrimaryActorTick.bCanEverTick = true;
// Create a default scene root
RootComponent = CreateDefaultSubobject<USceneComponent>(TEXT("RootComponent"));
// Create the Cine Camera Component and attach it to the root
CineCameraComponent = CreateDefaultSubobject<UCineCameraComponent>(TEXT("CineCameraComponent"));
CineCameraComponent->SetupAttachment(RootComponent);
// Create the Scene Capture Component 2D and attach it to the Cine Camera
SceneCaptureComponent = CreateDefaultSubobject<USceneCaptureComponent2D>(TEXT("SceneCaptureComponent"));
SceneCaptureComponent->SetupAttachment(CineCameraComponent);
SceneCaptureComponent->bCaptureEveryFrame = true;
SceneCaptureComponent->bCaptureOnMovement = true;
SceneCaptureComponent->CaptureSource = ESceneCaptureSource::SCS_FinalColorLDR;
// Synchronize Field of View
SceneCaptureComponent->FOVAngle = CineCameraComponent->FieldOfView;
// Copy over post-process settings and blend weight
SceneCaptureComponent->PostProcessSettings = CineCameraComponent->PostProcessSettings;
SceneCaptureComponent->PostProcessBlendWeight = CineCameraComponent->PostProcessBlendWeight;
// If you have additional settings (e.g., aspect ratio, custom projection parameters),
// copy them here as needed.
// Do not create RenderTarget here—create it in BeginPlay
RenderTarget = nullptr;
DisplayTexture = nullptr;
}
// Called when the game starts or when spawned
void ACineCameraRenderActor::BeginPlay()
{
Super::BeginPlay();
// Create the RenderTarget at runtime
if (!RenderTarget)
{
RenderTarget = NewObject<UTextureRenderTarget2D>(this, TEXT("RenderTarget"));
RenderTarget->InitAutoFormat(RenderTargetWidth, RenderTargetHeight);
RenderTarget->ClearColor = FLinearColor::Black;
RenderTarget->UpdateResourceImmediate(true);
// Assign RenderTarget to the SceneCaptureComponent
if (SceneCaptureComponent)
{
SceneCaptureComponent->TextureTarget = RenderTarget;
}
}
// Create the transient DisplayTexture at runtime from the RenderTarget
if (!DisplayTexture)
{
DisplayTexture = UTexture2D::CreateTransient(RenderTargetWidth, RenderTargetHeight, PF_B8G8R8A8);
if (DisplayTexture && DisplayTexture->GetPlatformData())
{
DisplayTexture->GetPlatformData()->SizeX = RenderTargetWidth;
DisplayTexture->GetPlatformData()->SizeY = RenderTargetHeight;
DisplayTexture->UTexture::UpdateResource();
}
}
}
// Called every frame
void ACineCameraRenderActor::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
// Update the DisplayTexture from the RenderTarget
if (RenderTarget && DisplayTexture)
{
FTextureRenderTargetResource* RTResource = RenderTarget->GameThread_GetRenderTargetResource();
if (RTResource)
{
TArray<FColor> OutBMP;
// Read the pixels from the render target
if (RTResource->ReadPixels(OutBMP))
{
// Ensure we have the correct number of pixels
if (OutBMP.Num() == RenderTargetWidth * RenderTargetHeight)
{
// Lock the texture's mip data to write to it
FTexture2DMipMap& Mip = DisplayTexture->GetPlatformData()->Mips[0];
void* Data = Mip.BulkData.Lock(LOCK_READ_WRITE);
FMemory::Memcpy(Data, OutBMP.GetData(), OutBMP.Num() * sizeof(FColor));
Mip.BulkData.Unlock();
// Update the texture resource so the new data is used
DisplayTexture->UTexture::UpdateResource();
}
}
}
}
}