28 const UTextureRenderTarget2D &RenderTarget,
30 FRHICommandListImmediate &RHICmdList,
33 TRACE_CPUPROFILER_EVENT_SCOPE_STR(
"WritePixelsToBuffer");
34 check(IsInRenderingThread());
38 static_cast<const FTextureRenderTarget2DResource *
>(RenderTarget.Resource);
39 FTexture2DRHIRef Texture = RenderResource->GetRenderTargetTexture();
46 auto BackBufferReadback = std::make_unique<FRHIGPUTextureReadback>(TEXT(
"CameraBufferReadback"));
47 FIntPoint BackBufferSize = Texture->GetSizeXY();
48 EPixelFormat BackBufferPixelFormat = Texture->GetFormat();
52 TRACE_CPUPROFILER_EVENT_SCOPE_STR(
"EnqueueCopy");
53 BackBufferReadback->EnqueueCopy(RHICmdList,
55 FResolveRect(0, 0, BackBufferSize.X, BackBufferSize.Y));
60 FRenderQueryRHIRef Query = RHICreateRenderQuery(RQT_AbsoluteTime);
61 TRACE_CPUPROFILER_EVENT_SCOPE_STR(
"create query");
62 RHICmdList.EndRenderQuery(Query);
63 TRACE_CPUPROFILER_EVENT_SCOPE_STR(
"Flush");
64 RHICmdList.ImmediateFlush(EImmediateFlushType::FlushRHIThread);
65 TRACE_CPUPROFILER_EVENT_SCOPE_STR(
"query result");
66 uint64 OldAbsTime = 0;
67 RHICmdList.GetRenderQueryResult(Query, OldAbsTime,
true);
71 AsyncTask(ENamedThreads::HighTaskPriority, [=, Readback=std::move(BackBufferReadback)]()
mutable {
73 TRACE_CPUPROFILER_EVENT_SCOPE_STR(
"Wait GPU transfer");
74 while (!Readback->IsReady())
76 std::this_thread::yield();
81 TRACE_CPUPROFILER_EVENT_SCOPE_STR(
"Readback data");
82 FPixelFormatInfo PixelFormat = GPixelFormats[BackBufferPixelFormat];
83 uint32 ExpectedRowBytes = BackBufferSize.X * PixelFormat.BlockBytes;
84 int32 Size = (BackBufferSize.Y * (PixelFormat.BlockBytes * BackBufferSize.X));
85 void* LockedData = Readback->Lock(Size);
89 FuncForSending(LockedData, Size, Offset, ExpectedRowBytes);
105 UTextureRenderTarget2D &RenderTarget,
106 TArray<FColor> &BitMap)
108 check(IsInGameThread());
109 FTextureRenderTargetResource *RTResource =
110 RenderTarget.GameThread_GetRenderTargetResource();
111 if (RTResource ==
nullptr)
113 UE_LOG(LogCarla, Error, TEXT(
"FPixelReader: UTextureRenderTarget2D missing render target"));
116 FReadSurfaceDataFlags ReadPixelFlags(RCM_UNorm);
117 ReadPixelFlags.SetLinearToGamma(
true);
118 return RTResource->ReadPixels(BitMap, ReadPixelFlags);
128 UTextureRenderTarget2D &RenderTarget)
130 const FIntPoint DestSize(RenderTarget.GetSurfaceWidth(), RenderTarget.GetSurfaceHeight());
131 TUniquePtr<TImagePixelData<FColor>> PixelData = MakeUnique<TImagePixelData<FColor>>(DestSize);
132 TArray<FColor> Pixels(PixelData->Pixels.GetData(), PixelData->Pixels.Num());
137 PixelData->Pixels = Pixels;
163 TUniquePtr<TImagePixelData<FColor>> PixelData,
164 const FString &FilePath)
166 TUniquePtr<FImageWriteTask> ImageTask = MakeUnique<FImageWriteTask>();
167 ImageTask->PixelData = MoveTemp(PixelData);
168 ImageTask->Filename = FilePath;
169 ImageTask->Format = EImageFormat::PNG;
170 ImageTask->CompressionQuality = (int32) EImageCompressionQuality::Default;
171 ImageTask->bOverwriteFile =
true;
172 ImageTask->PixelPreProcessors.Add(TAsyncAlphaWrite<FColor>(255));
174 FHighResScreenshotConfig &HighResScreenshotConfig = GetHighResScreenshotConfig();
175 return HighResScreenshotConfig.ImageWriteQueue->Enqueue(MoveTemp(ImageTask));
UE_LOG(LogCarla, Log, TEXT("UActorDispatcher::Destroying actor: '%s' %x"), *Id, Actor)
static void WritePixelsToBuffer(const UTextureRenderTarget2D &RenderTarget, uint32 Offset, FRHICommandListImmediate &InRHICmdList, FPixelReader::Payload FuncForSending)
将 RenderTarget 中的像素复制到 Buffer。