// Copyright 2026 (c) Jupiter. All Rights Reserved. #pragma once #include "CoreMinimal.h" #include "RHIGPUReadback.h" #include "RHICommandList.h" #include "Engine/TextureRenderTarget2D.h" #include "Subsystems/WorldSubsystem.h" #include "Tickable.h" #include "CameraCaptureSubSystem.generated.h" struct FCameraReadbackItem { int32 CameraIndex = INDEX_NONE; int32 Width = 0; int32 Height = 0; TUniquePtr Readback; }; struct FPendingAtlasCapture { int64 FrameId = 0; int32 AtlasW = 0; int32 AtlasH = 0; TArray Items; }; class ACameraCaptureActor; UCLASS() class CAMERACAPTURE_API UCameraCaptureSubSystem : public UWorldSubsystem, public FTickableGameObject { GENERATED_BODY() public: virtual void Initialize(FSubsystemCollectionBase& Collection) override; virtual void Deinitialize() override; virtual void OnWorldBeginPlay(UWorld& InWorld) override; virtual void Tick(float DeltaTime) override; virtual TStatId GetStatId() const override; virtual bool IsTickable() const override { return true; } private: void CaptureViewToImageTick(); // :发起 Capture + Enqueue GPU Readback void BeginCaptureViewToAtlas(); // 轮询并取回 GPU 数据,再拼图 void TryResolveCaptureViewAtlas(); void AsyncWriteImageToDisk(TArray AtlasPixels, const int32 AtlasW, const int32 AtlasH); TArray> AllCaptureCameras; // 输出的目录 UPROPERTY() FString OutPutDirectoryPath; TUniquePtr PendingAtlasCapture; bool bReadbackInFlight = false; };