Hi, I think I should address my question through C++ and BP, and the result. It will be helpful to understand the issue.
I am using LYRA template and UE5.3.2
Thanks for your patience to read.
Following is my code to create my texture.
- I log Width, Height, PlatformData, GetSizeX().
init_dynamic_texture(int _w, int _h, int _c, EPixelFormat pixel_format) : w(_w), h(_h), pixel_stride(_c)
{
pixel_size = w * h * pixel_stride;
// Initialize Texture Data Array.
texture_data.Init(0, pixel_size);
// Create Texture Object.
UE_LOG(LogTemp, Error, TEXT("wh = (%d, %d)."), w, h);// ---Log to debug.---
texture = UTexture2D::CreateTransient(w, h, EPixelFormat::PF_R8G8B8A8);
texture->CompressionSettings = TextureCompressionSettings::TC_VectorDisplacementmap;
texture->NeverStream = true;
texture->SRGB = 0;
texture->MipGenSettings = TextureMipGenSettings::TMGS_NoMipmaps;
texture->Filter = TextureFilter::TF_Nearest;
UE_LOG(LogTemp, Error, TEXT("addr1 = %d"), texture->GetPlatformData());//---Log address of PlatformData.---
UE_LOG(LogTemp, Error, TEXT("W = %d"), texture->GetSizeX());//---Log width.---
FTexture2DMipMap &mip_0 = texture->GetPlatformData()->Mips[0];
void *byte_bulk_data = mip_0.BulkData.Lock(LOCK_READ_WRITE);
FMemory::Memcpy(byte_bulk_data, texture_data.GetData(), pixel_size);
mip_0.BulkData.Unlock();
texture->UpdateResource();
}
In my debug function. I try to access the PlatformData, which will be used to do Memcpy.
However, I got UE crash.
- So I Log PlatformData’s address again.
- And log GetSizeX().
void update_dynamic_texture(){
UE_LOG(LogTemp, Error, TEXT("addr2 = %d"), texture->GetPlatformData());
UE_LOG(LogTemp, Error, TEXT("W = %d"), texture->GetSizeX());
FTexturePlatformData *platform_data = texture->GetPlatformData();
if (platform_data == nullptr) {
UE_LOG(LogTemp, Error, TEXT("platform_data is nullptr."));
}
// FTexture2DMipMap &mip_0 = platform_data->Mips[0];
// void *byte_bulk_data = mip_0.BulkData.Lock(LOCK_READ_WRITE);
// FMemory::Memcpy(byte_bulk_data, color.GetData(), pixel_size);
// mip_0.BulkData.Unlock();
// texture->UpdateResource();
}
My test BP.
- I have a Delay. Set it 0 second.
- I init texture.
- I set a bool Ready=true.
- Pring “nor Ready” if it’s false.
- Update texture (code is commented out, only LOG left).
- Tick every 1 second.
Now the interesting result from OutputLog.
- LogWorld: Bringing World /A_UE53/Maps/UEDPIE_0_L_Basic_Level.L_Basic_Level up for play (max tick rate 0) at 2024.07.18-08.04.14
- LogWorld: Bringing up level for play took: 0.001103
- LogCommonGame: [B_LyraUIPolicy_C_0] is adding player [LyraLocalPlayer_1]'s root layout [W_OverallUILayout_C_0] to the viewport
- PIE: Server logged in
- PIE: Play in editor total start time 0.149 seconds.
- LogBackChannel: Listening on FBackChannelConnection Client Socket (localport: 2049)
- LogRemoteSession: Started listening on port 2049
- LogSlate: InvalidateAllWidgets triggered. All widgets were invalidated
- LogBlueprintUserMessages: [t3_C_1] not Ready
- LogBlueprintUserMessages: [t3_C_1] =====================Init
- LogTemp: Error: wh = (256, 256).
- LogTemp: Error: addr1 = 1053805184
- LogTemp: Error: W = 256
- LogLyraExperience: Identified experience LyraExperienceDefinition:BP_ExpDef (Source: WorldSettings)
- LogLyraExperience: EXPERIENCE: StartExperienceLoad(CurrentExperience = LyraExperienceDefinition:BP_ExpDef, Server)
- LogLoadingScreen: Showing loading screen when ‘IsShowingInitialLoadingScreen()’ is false.
- LogLoadingScreen: Experience still loading
- LogLoadingScreen: Loading screen showing: 1. Reason: Experience still loading
- LogLyraExperience: EXPERIENCE: OnExperienceLoadComplete(CurrentExperience = LyraExperienceDefinition:BP_ExpDef, Server)
- LogUIActionRouter: Display: Applying input config for leaf-most node [W_AI_HUDLayout_C_0]
- LogUIActionRouter: Display: UIInputConfig being changed. bForceRefresh: 1
- LogUIActionRouter: Display: InputMode: Previous (None), New (ECommonInputMode::All)
- LogViewport: Display: Viewport MouseCaptureMode Changed, CapturePermanently_IncludingInitialMouseDown → CapturePermanently
- LogViewport: Display: Viewport HideCursorDuringCapture Changed, False → True
- LogUIActionRouter: Display: [User 0] No focus target for leaf-most node [W_AI_HUDLayout_C_0], and the widget isn’t focusable - focusing the game viewport.
- LogLoadingScreen: Hiding loading screen when ‘IsShowingInitialLoadingScreen()’ is false.
- LogLoadingScreen: (nothing wants to show it anymore)
- LogLoadingScreen: Garbage Collecting before dropping load screen
- LogLoadingScreen: LoadingScreen was visible for 0.05s
- LogUObjectHash: Compacting FUObjectHashTables data took 1.07ms
- LogUIActionRouter: Cleaned out [1] inactive UI action bindings
- LogTemp: Error: addr2 = 0
- LogTemp: Error: W = 0
- LogTemp: Error: platform_data is nullptr.
- LogTemp: Error: addr2 = 0
- LogTemp: Error: W = 0
- LogTemp: Error: platform_data is nullptr.
- LogTemp: Error: addr2 = 0
- LogTemp: Error: W = 0
- LogTemp: Error: platform_data is nullptr.
- LogTemp: Error: addr2 = 0
- LogTemp: Error: W = 0
- LogTemp: Error: platform_data is nullptr.
- LogTemp: Error: addr2 = 0
- LogTemp: Error: W = 0
- LogTemp: Error: platform_data is nullptr.
- LogTemp: Error: addr2 = 0
- LogTemp: Error: W = 0
- LogTemp: Error: platform_data is nullptr.
- LogTemp: Error: addr2 = 0
- LogTemp: Error: W = 0
- LogTemp: Error: platform_data is nullptr.
- Cmd: quit
Problem:
- So we got width, height = 256, 256
- addr1 is the address of PlatformData retrieved from Init func. And I got no err when Memcpy after init.
- W is also good when retrieve in Init func.
- but when tick, we are accessing memory with nullptr.
Solve it but why this happened?
- Sleep a while.
Now the result from OutputLog.
- LogViewport: Display: Viewport HideCursorDuringCapture Changed, False → True
- LogUIActionRouter: Display: [User 0] No focus target for leaf-most node [W_AI_HUDLayout_C_0], and the widget isn’t focusable - focusing the game viewport.
- LogLoadingScreen: Hiding loading screen when ‘IsShowingInitialLoadingScreen()’ is false.
- LogLoadingScreen: (nothing wants to show it anymore)
- LogLoadingScreen: Garbage Collecting before dropping load screen
- LogLoadingScreen: LoadingScreen was visible for 0.05s
- LogUObjectHash: Compacting FUObjectHashTables data took 0.91ms
- LogUIActionRouter: Cleaned out [1] inactive UI action bindings
- LogBlueprintUserMessages: [t3_C_1] =====================Init
- LogTemp: Error: wh = (256, 256).
- LogTemp: Error: addr1 = 836481728
- LogTemp: Error: W = 256
- LogTemp: Error: addr2 = 836481728
- LogTemp: Error: W = 256
- LogTemp: Error: addr2 = 836481728
- LogTemp: Error: W = 256
- LogTemp: Error: addr2 = 836481728
- Now we can access PlatformData and Width.
- Why this happened?
Can someone help me and explain what’s going on behind UE?
- It seems that if I don’t delay, the system will clean the information (but I checked the addr of *UTexture2D texture is always valid).
- Or the data after Memcpy is put in another thread?
- The 1st UE OUTPUT LOG prints some system LOG between my custom LOG. Is it a clue?