【问题标题】:How do you update a UTextureRenderTarget2D dynamically in C++?如何在 C++ 中动态更新 UTextureRenderTarget2D?
【发布时间】:2020-04-25 13:06:12
【问题描述】:

我一直在尝试,但无法使用此代码进行操作

UTextureRenderTarget2D *renderTarget; // In header

void UMyActorComponent::BeginPlay()
{
    Super::BeginPlay();
    texture = UTexture2D::CreateTransient(1, 1);
    FTexture2DMipMap& Mip = texture->PlatformData->Mips[0];
    void* Data = Mip.BulkData.Lock(LOCK_READ_WRITE);
    uint8 red[4] = { 255, 255, 255, 255 };
    FMemory::Memcpy(Data, &red, sizeof(red));
    Mip.BulkData.Unlock();
    texture->UpdateResource();

    renderTarget->UpdateTexture2D(texture, TSF_BGRA8);
}

我至少知道我有正确的 renderTarget 句柄,因为我已经能够清除渲染目标。我可能会遗漏一些简单的东西,感谢您的帮助。

【问题讨论】:

  • 如果你在renderTarget->UpdateTexture2D(texture, TSF_BGRA8);之后调用renderTarget->UpdateResourceImmediate(false);会发生什么吗?
  • @Ruzihm 在挖掘源代码后,我发现 UpdateTexture2D 完全包裹在我读过的 #if WITH_EDITOR 块中,这意味着它在您的游戏中没有任何作用。虽然我注意到资源在函数结束时没有更新,但你非常接近,但我想这并不重要。当我弄清楚时,我会发布我的解决方案。

标签: c++ unreal-engine4


【解决方案1】:

我找到了一个解决方案,它似乎是正确的方法。

免责声明

使用纹理渲染目标可能不是最好的方法,因为通常渲染目标会将您从 gpu 渲染到 gpu。在这种情况下,我将数据从 cpu 写入 gpu。因此,如果您采用这种方法,您可能会遇到一些无法预料的问题。可能创建一个瞬态纹理是正确的方法。

解决方案

动态初始化渲染目标的资源

所以首先你需要使用这个函数将你的 UTextureRenderTarget2D 初始化为你想要的分辨率。把它放在有意义的地方。

RenderTarget->InitCustomFormat(2, 2, PF_B8G8R8A8, true);

在本示例中,我使用的是具有 BGRA8 像素格式和线性色彩空间的 2x2 图像

更新渲染目标的功能

然后您需要将此函数放在代码中可访问的位置

void UpdateTextureRegion(FTexture2DRHIRef TextureRHI, int32 MipIndex, uint32 NumRegions, FUpdateTextureRegion2D Region, uint32 SrcPitch, uint32 SrcBpp, uint8* SrcData, TFunction<void(uint8* SrcData)> DataCleanupFunc = [](uint8*) {})
 {
     ENQUEUE_RENDER_COMMAND(UpdateTextureRegionsData)(
         [=](FRHICommandListImmediate& RHICmdList)
         {
             check(TextureRHI.IsValid());
             RHIUpdateTexture2D(
                 TextureRHI,
                 MipIndex,
                 Region,
                 SrcPitch,
                 SrcData
                 + Region.SrcY * SrcPitch
                 + Region.SrcX * SrcBpp
             );
             
             DataCleanupFunc(SrcData);
         });
 }

更新渲染目标

这段代码会写一个红绿蓝白

static uint8 rgbw[4 * 4] = {
                       0,   0,   255, 255,
                       0,   255,   0, 255,
                       255,   0,   0, 255,
                       255, 255, 255, 255

    };
auto region = FUpdateTextureRegion2D(0, 0, 0, 0, 2, 2);
UpdateTextureRegion(RenderTarget, 0, 1, region, 2*4, 4, rgbw);

在编辑器中将渲染目标附加到一个平面,当一切都说完后,它应该看起来像这样

你应该有一些功能代码可以玩。

【讨论】:

  • 对不起一个简单的问题,SrcPitch 是什么?它是如何在 RHIUpdateTexture2D 函数中使用的?
  • @MassimoIsonni 是 SrcData 行之间的距离,以字节为单位。因此,如果 SrcData 紧密排列,行和 BGRA8 数据之间没有间隙,则它等于 SrcData 中行长度的 4 倍
猜你喜欢
  • 1970-01-01
  • 2023-03-28
  • 2014-12-04
  • 2017-07-08
  • 2018-06-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-02
相关资源
最近更新 更多