Copying UTexture2D over another - Close, but not close enough

I have transparent textures and would like to display them with a custom background.

Step 1: Create the new texture



UTexture2D* UClass1::CreateTexture(const FIntPoint& size, EPixelFormat pixelFormat)
{
auto newTexture = UTexture2D::CreateTransient(size.X, size.Y, pixelFormat);
newTexture->MipGenSettings = TextureMipGenSettings::TMGS_NoMipmaps;
newTexture->CompressionSettings = TextureCompressionSettings::TC_VectorDisplacementmap;
newTexture->SRGB = 0;
newTexture->AddToRoot();
newTexture->UpdateResource();

return newTexture;
}


Step 2: Blank this texture with a custom color



void UClass1::BlankTexture(UTexture2D* texture, const FColor& pixelColor)
{
const auto DestWidth = texture->GetSizeX();
const auto DestHeight = texture->GetSizeY();
const auto BytesPerPixel = 4;

const auto BufferSize = DestWidth * DestHeight * BytesPerPixel;
auto newTextureBuffer = new uint8[BufferSize];

int destPixelIndex = 0;
for (int y = 0; y < DestHeight; y++)
{
for (int x = 0; x < DestWidth; x++)
{
newTextureBuffer[destPixelIndex++] = pixelColor.B;
newTextureBuffer[destPixelIndex++] = pixelColor.G;
newTextureBuffer[destPixelIndex++] = pixelColor.R;
newTextureBuffer[destPixelIndex++] = pixelColor.A;
}
}
texture->UpdateResource();

auto updateTextureRegion = new FUpdateTextureRegion2D(0, 0, 0, 0, DestWidth, DestHeight);
const auto BufferPitch = DestWidth * BytesPerPixel;
texture->UpdateTextureRegions(0, 1, updateTextureRegion, BufferPitch, BytesPerPixel, newTextureBuffer, &CleanMemory);
}


Step 3: Test



auto sourceTexture = LoadObject<UTexture2D>(nullptr, TEXT("/Game/Materials/Textures/T_Whatever.T_Whatever"));
auto newTexture = CreateTexture(FIntPoint(sourceTexture->GetSizeX(), sourceTexture->GetSizeY()), sourceTexture->PlatformData->PixelFormat);
BlankTexture(newTexture, FColor::FromHex("#00CC00FF"));
imageWidget->SetBrushFromTexture(newTexture);


At this point, it works. It shows an image filled with my color (green in this case)

Now, to copy the sourceTexture, I lock its PlatformData->Mips[0]->BulkData which gives me a pointer to its FColor structures. Fine.
For pixels that are transparent, I want to use the pixels of the background (the texture I created) so I also lock its BulkData.



auto sourceMipMap = &sourceTexture->PlatformData->Mips[0];
auto sourceRawImageData = &sourceMipMap->BulkData;
auto sourceFormatedImageData = static_cast<FColor*>(sourceRawImageData->Lock(LOCK_READ_ONLY));

auto backgroundMipMap = &backgroundTexture->PlatformData->Mips[0];
auto backgroundRawImageData = &backgroundMipMap->BulkData;
auto backgroundFormatedImageData = static_cast<FColor*>(backgroundRawImageData->Lock(LOCK_READ_ONLY));


I expected the data of backgroundFormatedImageData to also be FColor structures but when I look at the memory that points to it, the bytes represent another memory address which leads to another, and another… So it seems the BulkData of the texture I created is invalid but when I called UImage::SetBrushFromTexture() with it, UE knew what to do with it and worked fine. Me, on the other hand, have no idea how to fetch the pixel colors of it.

Another thing I find odd is that the Mip[0].SizeZ = 1 in my source texture compared to my own/new texture which has 0. Is something missing?