I have been knocking my head around at this problem for a couple days now. I have no source texture, I want to generate a new Texture2D asset (not at runtime) from generated pixel data.
The object shows up in editor and appears to get down to the Texture->Source.Init()
line without issue. For the life of me I cannot figure out how to apply the pixel data. I am sure I am missing something obvious but clearly I’ve been staring at it for too long.
// Texture Information
FString FileName = FString("MyTexture");
int width = 1024;
int height = 1024;
uint8* pixels = 1728061504; //magic number in PF_R8G8B8A8
// Create Package
FString pathPackage = FString("/Game/MyTextures/");
FString absolutePathPackage = FPaths::ProjectContentDir() + "/MyTextures/";
// Load necessary modules
FAssetToolsModule& AssetToolsModule = FModuleManager::Get().LoadModuleChecked<FAssetToolsModule>("AssetTools");
FAssetRegistryModule& AssetRegistryModule = FModuleManager::LoadModuleChecked<FAssetRegistryModule>(TEXT("AssetRegistry"));
// Generate a unique asset name
FString Name, PackageName;
AssetToolsModule.Get().CreateUniqueAssetName(TEXT("/Game/MyTextures/AssetName"), TEXT(""), PackageName, Name);
FString PackagePath = FPackageName::GetLongPackagePath(PackageName);
// Create and Cast the new object as a UTexture2D
UPackage* Package = CreatePackage(*PackageName);
UTexture2DFactoryNew* MyFactory = NewObject<UTexture2DFactoryNew>(UTexture2DFactoryNew::StaticClass());
UObject* NewObject = AssetToolsModule.Get().CreateAsset(Name, PackagePath, UTexture2D::StaticClass(), MyFactory);
UTexture2D* Texture = Cast<UTexture2D>(NewObject);
Texture->Source.Init(width, height, 1, 1, TSF_RGBA16, 0);
Texture->GetPlatformData()->PixelFormat = PF_R8G8B8A8;
//Add pixel data
FTexture2DMipMap Mip = Texture->GetPlatformMips()[0];
Mip.BulkData.Lock(LOCK_READ_WRITE);
uint8* TextureData = (uint8 *) Mip.BulkData.Realloc(height * width * sizeof(uint8)*4);
FMemory::Memcpy(TextureData, pixels, sizeof(uint8) * height * width * 4);
Mip.BulkData.Unlock();
Texture->AddToRoot();
Texture->UpdateResource();
Texture->PostEditChange();
Package->MarkPackageDirty();