Next code causes unknown unhandled exception:
void UNoxMagicFunctions::RawDataFromTexture(UTexture2D* texture, FTextureRaw& rawData)
{
rawData.width = texture->Resource->GetSizeX();
rawData.height = texture->Resource->GetSizeY();
rawData.pixels.Init(FColor(255, 255, 255, 255), rawData.width * rawData.height);
FTexture2DMipMap& mip = texture->PlatformData->Mips[0];
void* data = mip.BulkData.Lock(LOCK_READ_WRITE);
UE_LOG(LogTemp, Warning, TEXT("%d"), ((FColor*)data)[0].R); // error here
//FMemory::Memcpy(rawData.pixels.GetData(), data, rawData.width * rawData.height * 4); // and here
mip.BulkData.Unlock();
texture->UpdateResource();
}
I tried many checks and everything leads to reading any data from data
. It happens even with try-catch block. When I comment error lines, everything works fine. Why?
It was happening because mip.BulkData.Lock(LOCK_READ_WRITE)
was returned nullptr
. To avoid this, according to this guide, before accessing bulkdata your texture must have next parameters:
-
CompressionSettings set to VectorDisplacementmap
-
MipGenSettings to NoMipmaps
-
SRGB to false
i.e. in my case it looks like:
void UNoxMagicFunctions::RawDataFromTexture(UTexture2D* texture, FTextureRaw& rawData)
{
// setup required parameters
TextureCompressionSettings OldCompressionSettings = texture->CompressionSettings;
TextureMipGenSettings OldMipGenSettings = texture->MipGenSettings;
bool OldSRGB = texture->SRGB;
texture->CompressionSettings = TextureCompressionSettings::TC_VectorDisplacementmap;
texture->MipGenSettings = TextureMipGenSettings::TMGS_NoMipmaps;
texture->SRGB = false;
texture->UpdateResource();
// read data
rawData.width = texture->Resource->GetSizeX();
rawData.height = texture->Resource->GetSizeY();
rawData.pixels.Init(FColor::White, rawData.width * rawData.height);
FColor* data = (FColor*)texture->PlatformData->Mips[0].BulkData.LockReadOnly();
FMemory::Memcpy(rawData.pixels.GetData(), data, sizeof(FColor) * rawData.width * rawData.height);
texture->PlatformData->Mips[0].BulkData.Unlock();
// return old parameters
texture->CompressionSettings = OldCompressionSettings;
texture->MipGenSettings = OldMipGenSettings;
texture->SRGB = OldSRGB;
texture->UpdateResource();
}
Note that any operations with MipGenSettings
should be wrapped with #if WITH_EDITOR
if you packaging build.
1 Like