Lets say im trying to add it like this:
void ATextureReader::AddTextureToTextureArray(UTexture2D* Texture, UTexture2DArray* TextureArray) {
TextureArray.Add(Texture);
}
Though this doesnt work clearly… Is there a work around?
From my searches it seems this is very out of reach…
Id be fine to create a new UTexture2DArray at runtime, with textures, if it is not possible to dynamically change an existing UTexture2DArray.
Btw, UTexture2DArray refers to this class:
Edit:
So this function i made creates a Texture2DArray at runtime. Though its empty… How do i make it so that it is created with a texture inside, in this case SourceTexture ?
UTexture2DArray* ATextureReader::CreateAndSaveTextureArray(int32 Width, int32 Height, int32 ArraySize, UTexture2D* SourceTexture)
{
if (!SourceTexture)
{
UE_LOG(LogTemp, Warning, TEXT("Source texture is null."));
return nullptr; // Early exit if the source texture is null
}
FString PackageName = TEXT("/Game/ProceduralTextures/");
FString TextureArrayName = TEXT("NewTextureArray");
PackageName += TextureArrayName;
UPackage* Package = CreatePackage(nullptr, *PackageName);
Package->FullyLoad();
// Create a new UTexture2DArray
UTexture2DArray* NewTextureArray = NewObject<UTexture2DArray>(Package, *TextureArrayName, RF_Public | RF_Standalone | RF_MarkAsRootSet);
NewTextureArray->AddToRoot(); // Prevent garbage collection
NewTextureArray->PlatformData = new FTexturePlatformData(); // Initialize the PlatformData
NewTextureArray->PlatformData->SizeX = Width; // Set the width
NewTextureArray->PlatformData->SizeY = Height; // Set the height
NewTextureArray->PlatformData->SetNumSlices(ArraySize); // Set the number of slices (depth)
NewTextureArray->PlatformData->PixelFormat = EPixelFormat::PF_B8G8R8A8; // Set the pixel format
// Create empty mip maps for the array
for (int32 SliceIndex = 0; SliceIndex < ArraySize; ++SliceIndex)
{
FTexture2DMipMap& Mip = *(new(NewTextureArray->PlatformData->Mips) FTexture2DMipMap());
Mip.SizeX = Width;
Mip.SizeY = Height;
Mip.BulkData.Lock(LOCK_READ_WRITE);
Mip.BulkData.Realloc(Width * Height * 4); // Allocate space for the texture data
Mip.BulkData.Unlock();
}
// Copy the source texture data into the first slice of the texture array
if (ArraySize > 0)
{
FTexture2DMipMap& SourceMip = SourceTexture->PlatformData->Mips[0];
void* SourceData = SourceMip.BulkData.Lock(LOCK_READ_ONLY);
FTexture2DMipMap& DestMip = NewTextureArray->PlatformData->Mips[0];
DestMip.BulkData.Lock(LOCK_READ_WRITE);
void* DestData = DestMip.BulkData.Realloc(Width * Height * 4);
FMemory::Memcpy(DestData, SourceData, Width * Height * 4); // Copy pixel data
DestMip.BulkData.Unlock();
SourceMip.BulkData.Unlock(); // Unlock the source mip
}
NewTextureArray->UpdateResource(); // Update the resource to reflect the changes
Package->MarkPackageDirty(); // Mark the package as dirty
FAssetRegistryModule::AssetCreated(NewTextureArray); // Inform the asset registry
// Save the package
FString PackageFileName = FPackageName::LongPackageNameToFilename(PackageName, FPackageName::GetAssetPackageExtension());
bool bSaved = UPackage::SavePackage(Package, NewTextureArray, EObjectFlags::RF_Public | EObjectFlags::RF_Standalone, *PackageFileName, GError, nullptr, true, true, SAVE_NoError);
return NewTextureArray; // Return the newly created texture array
}
Video: