x

Search in
Sort by:

Question Status:

Search help

  • Simple searches use one or more words. Separate the words with spaces (cat dog) to search cat,dog or both. Separate the words with plus signs (cat +dog) to search for items that may contain cat but must contain dog.
  • You can further refine your search on the search results page, where you can search by keywords, author, topic. These can be combined with each other. Examples
    • cat dog --matches anything with cat,dog or both
    • cat +dog --searches for cat +dog where dog is a mandatory term
    • cat -dog -- searches for cat excluding any result containing dog
    • [cats] —will restrict your search to results with topic named "cats"
    • [cats] [dogs] —will restrict your search to results with both topics, "cats", and "dogs"

How to save a procedurally generated texture?

Hello, I want to generate procedurally within the editor a UTexture2D and store it in permanentely in the assets. I use the following code for this:

     FString PackageName = TEXT("/Game/");
     PackageName += TextureName;
     UPackage* Package = CreatePackage(NULL, *PackageName);
     Package->FullyLoad();
 
     UTexture2D* NewTexture = NewObject<UTexture2D>(Package, *TextureName, EObjectFlags::RF_Public | EObjectFlags::RF_Standalone);
     NewTexture->PlatformData = new FTexturePlatformData();
     NewTexture->PlatformData->SizeX = TextureWidth;
     NewTexture->PlatformData->SizeY = TextureHeight;
     NewTexture->PlatformData->PixelFormat = EPixelFormat::PF_B8G8R8A8;
 
     if (NewTexture != NULL)
     {
         //Initializing texture
         GWarn->StatusUpdate(1, 3, LOCTEXT("Generating texture", "Generating texture"));
 
         TArray<float> FloatMap = Module->GetPlaneNoiseMap(TextureWidth, TextureHeight, 0, 1, 0, 1, bTileable);
 
         GWarn->StatusUpdate(2, 3, LOCTEXT("Generating texture", "Generating texture"));
         NewTexture->Filter = TextureFilter::TF_Default;
         // Allocate first mipmap.
         int32 NumBlocksX = TextureWidth / GPixelFormats[EPixelFormat::PF_B8G8R8A8].BlockSizeX;
         int32 NumBlocksY = TextureHeight / GPixelFormats[EPixelFormat::PF_B8G8R8A8].BlockSizeY;
         FTexture2DMipMap* Mip = new(NewTexture->PlatformData->Mips) FTexture2DMipMap();
         Mip->SizeX = TextureWidth;
         Mip->SizeY = TextureHeight;
 
         // Lock the texture so it can be modified
         Mip->BulkData.Lock(LOCK_READ_WRITE);
         Mip->BulkData.Realloc(NumBlocksX * NumBlocksY * GPixelFormats[EPixelFormat::PF_B8G8R8A8].BlockBytes);
         Mip->BulkData.Unlock();
         // Relock to write data
         uint8* MipData = static_cast<uint8*>(Mip->BulkData.Lock(LOCK_READ_WRITE));
 
         // Create base mip from the pixel color array
         for (int32 y = 0; y < NewTexture->PlatformData->Mips[0].SizeY; y++)
         {
             for (int32 x = 0; x < NewTexture->PlatformData->Mips[0].SizeX; x++)
             {
                 int32 curPixelIndex = ((y * NewTexture->PlatformData->Mips[0].SizeX) + x);
                 FColor Color = ColorGradient->GetColor(FloatMap[curPixelIndex]);
                 MipData[4 * curPixelIndex] = Color.B;
                 MipData[4 * curPixelIndex + 1] = Color.G;
                 MipData[4 * curPixelIndex + 2] = Color.R;
                 MipData[4 * curPixelIndex + 3] = Color.A;
             }
         }
 
         // Unlock the texture
         Mip->BulkData.Unlock();
 
         // Save Asset;
         NewTexture->AddToRoot();
         NewTexture->UpdateResource();
         Package->MarkPackageDirty();
 
         FAssetRegistryModule::AssetCreated(NewTexture);
         NewTexture->MarkPackageDirty();
         NewTexture->PostEditChange();
         Package->SetDirtyFlag(true);
         
 
         FString PackageFileName = FPackageName::LongPackageNameToFilename(PackageName, FPackageName::GetAssetPackageExtension());
         bool bSaved = UPackage::SavePackage(Package, NewTexture, EObjectFlags::RF_Public | EObjectFlags::RF_Standalone, *PackageFileName, GError, nullptr, true, true, SAVE_NoError);
 }

When running it, I see the texture in the assets in the editor, I can open it and it seems to work well (no error message in the log output).

However, when I restart the editor, the texture is totally black and I have the following message in the output log:

 LogTexture: Error: Texture2D /Game/T_Texture_D.T_Texture_D is unknown which is not supported.

How can I solve this?

Product Version: UE 4.18
Tags:
more ▼

asked Nov 13 '17 at 10:02 PM in C++ Programming

avatar image

isaratech
6 3 4

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

1 answer: sort voted first

I've solved my problem. Indeed PlatformData is not saved by SavePackage, so it disappears when reloading the editor. To overcome this I have added the following line before the call to UpdateResource():

 NewTexture->Source.Init(TextureWidth, TextureHeight, 1, 1, ETextureSourceFormat::TSF_BGRA8, Pixels);

This way, as the Source can be persisted, my texture is still here when I'm reloading the editor.

more ▼

answered Nov 14 '17 at 04:30 PM

avatar image

isaratech
6 3 4

(comments are locked)
10|2000 characters needed characters left
Viewable by all users
Your answer
toggle preview:

Up to 5 attachments (including images) can be used with a maximum of 5.2 MB each and 5.2 MB total.

Follow this question

Once you sign in you will be able to subscribe for any updates here

Answers to this question