Skip to content

Instantly share code, notes, and snippets.

@gerard-geer
Created March 17, 2017 22:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gerard-geer/09a212cce5ec56a0134a9e1452100024 to your computer and use it in GitHub Desktop.
Save gerard-geer/09a212cce5ec56a0134a9e1452100024 to your computer and use it in GitHub Desktop.
Need some help on texture loading
void AFreshMeshActor::UpdateTextureRegions(UTexture2D* Texture, int32 MipIndex,
uint32 NumRegions, FUpdateTextureRegion2D* Regions,
uint32 SrcPitch, uint32 SrcBpp,
uint8* SrcData, bool bFreeData)
{
if (Texture && Texture->Resource)
{
struct FUpdateTextureRegionsData
{
FTexture2DResource* Texture2DResource;
int32 MipIndex;
uint32 NumRegions;
FUpdateTextureRegion2D* Regions;
uint32 SrcPitch;
uint32 SrcBpp;
uint8* SrcData;
};
FUpdateTextureRegionsData* RegionData = new FUpdateTextureRegionsData;
RegionData->Texture2DResource = (FTexture2DResource*)Texture->Resource;
RegionData->MipIndex = MipIndex;
RegionData->NumRegions = NumRegions;
RegionData->Regions = Regions;
RegionData->SrcPitch = SrcPitch;
RegionData->SrcBpp = SrcBpp;
RegionData->SrcData = SrcData;
ENQUEUE_UNIQUE_RENDER_COMMAND_TWOPARAMETER(
UpdateTextureRegionsData,
FUpdateTextureRegionsData*, RegionData, RegionData,
bool, bFreeData, bFreeData,
{
for (uint32 RegionIndex = 0; RegionIndex < RegionData->NumRegions; ++RegionIndex)
{
int32 CurrentFirstMip = RegionData->Texture2DResource->GetCurrentFirstMip();
if (RegionData->MipIndex >= CurrentFirstMip)
{
RHIUpdateTexture2D(
RegionData->Texture2DResource->GetTexture2DRHI(),
RegionData->MipIndex - CurrentFirstMip,
RegionData->Regions[RegionIndex],
RegionData->SrcPitch,
RegionData->SrcData
+ RegionData->Regions[RegionIndex].SrcY * RegionData->SrcPitch
+ RegionData->Regions[RegionIndex].SrcX * RegionData->SrcBpp
);
}
}
if (bFreeData)
{
FMemory::Free(RegionData->Regions);
FMemory::Free(RegionData->SrcData);
}
delete RegionData;
});
}
}
UTexture2D * AFreshMeshActor::loadTexture(const TCHAR * filepath, TCHAR *filename)
{
// Represents the entire file in memory.
//TArray<uint8> RawFileData;
// Preemptively declare a pointer for our new texture.
UTexture2D * mytex = NULL;
// Append the filename to the path for correct access.
FString path;
path.Append(filepath);
if (path[path.Len() - 1] != '/') path.Append(TEXT("/"));
path.Append(filename);
// Get the file extension from the filename so we can use the correct loader.
FString ext = FPaths::GetExtension(filename, false);
UE_LOG(OBJParserLog, Log, TEXT("Loading texture \"%s\""), filename);
IImageWrapperModule& ImageWrapperModule = FModuleManager::LoadModuleChecked<IImageWrapperModule>(FName("ImageWrapper"));
IImageWrapperPtr ImageWrapper;
if (ext.Equals("png", ESearchCase::IgnoreCase))
{
UE_LOG(OBJParserLog, Log, TEXT("Image format: PNG (%s)"), *ext);
ImageWrapper = ImageWrapperModule.CreateImageWrapper(EImageFormat::PNG);
}
else if (ext.Equals("jpg", ESearchCase::IgnoreCase) || ext.Equals("jpeg", ESearchCase::IgnoreCase))
{
UE_LOG(OBJParserLog, Log, TEXT("Image format: JPEG (%s)"), *ext);
ImageWrapper = ImageWrapperModule.CreateImageWrapper(EImageFormat::JPEG);
}
else if (ext.Equals("bmp", ESearchCase::IgnoreCase))
{
UE_LOG(OBJParserLog, Log, TEXT("Image format: BMP (%s)"), *ext);
ImageWrapper = ImageWrapperModule.CreateImageWrapper(EImageFormat::BMP);
}
else
{
UE_LOG(OBJParserLog, Error, TEXT("Unrecognized texture format: \"%s\". Going with PNG"), *ext);
ImageWrapper = ImageWrapperModule.CreateImageWrapper(EImageFormat::PNG);
}
//Load From File
TArray<uint8> RawFileData;
if (!FFileHelper::LoadFileToArray(RawFileData, *path))
{
UE_LOG(OBJParserLog, Error, TEXT("Could not open texture image."), *ext);
return NULL;
}
//Create T2D!
if (ImageWrapper.IsValid() && ImageWrapper->SetCompressed(RawFileData.GetData(), RawFileData.Num()))
{
const TArray<uint8>* UncompressedBGRA = NULL;
if (ImageWrapper->GetRaw(ERGBFormat::RGBA, 8, UncompressedBGRA))
{
UE_LOG(OBJParserLog, Error, TEXT("Fourth pixel: %d,%d,%d,%d"),
(*UncompressedBGRA)[12],
(*UncompressedBGRA)[13],
(*UncompressedBGRA)[14],
(*UncompressedBGRA)[15]);
mytex = UTexture2D::CreateTransient(ImageWrapper->GetWidth(), ImageWrapper->GetHeight(), PF_B8G8R8A8);
mytex->UpdateResource();
//Valid?
if (!mytex)
{
UE_LOG(OBJParserLog, Error, TEXT("Could not create transient texture."), *ext);
return NULL;
}
else
{
UE_LOG(OBJParserLog, Log, TEXT("Texture dimensions: %d %d"), ImageWrapper->GetWidth(), ImageWrapper->GetHeight());
}
//Copy!
FUpdateTextureRegion2D * region = new FUpdateTextureRegion2D(0, 0, 0, 0, ImageWrapper->GetWidth(), ImageWrapper->GetHeight());
uint8 *data = (uint8*)malloc(sizeof(uint8)*UncompressedBGRA->Num());
for (int i = 0; i < UncompressedBGRA->Num(); ++i)
{
data[i] = (*UncompressedBGRA)[i];
}
//UpdateTextureRegions(mytex, 0, 1, region, ImageWrapper->GetWidth()*4, 4, data, false);
FTexture2DMipMap& Mip = mytex->PlatformData->Mips[0];
void* Data = Mip.BulkData.Lock(LOCK_READ_WRITE);
FMemory::Memcpy(Data, data, UncompressedBGRA->Num());
Mip.BulkData.Unlock();
//Update!
mytex->UpdateResource();
}
}
// Success!
return mytex;
}
// This is what my function call to loadTexture and setTextureParameterValue look like:
UTexture2D *tex = loadTexture(*path, diffFilename);
m->SetTextureParameterValue(TEXT("map_diff"), tex);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment