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
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();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|