I found this example code for a dynamic texture here: , and I’ve been trying to set up a simple class derived from Actor that fills a 2D texture with data that I can create in C++. I’ve got it compiling and running, but my texture always comes out white (I have it hard-coded where it should all be blue). I’m not sure what I’m missing.
Header:
#pragma once
#include "GameFramework/Actor.h"
#include "EchoManager.generated.h"
#define ECHO_TEXTURE_SIZEX 1024
#define ECHO_TEXTURE_SIZEY 1024
#define ECHO_TEXTURE_DATA_LENGTH ECHO_TEXTURE_SIZEX * ECHO_TEXTURE_SIZEY * 4
UCLASS()
class ECHOES_API AEchoManager : public AActor
{
GENERATED_UCLASS_BODY()
protected:
/** Dynamically created texture */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Echo)
UTexture2D* EchoTexture;
/** Update texture region from */
void UpdateTextureRegions(UTexture2D* Texture, int32 MipIndex, uint32 NumRegions, FUpdateTextureRegion2D* Regions, uint32 SrcPitch, uint32 SrcBpp, uint8* SrcData, bool bFreeData);
UFUNCTION(BlueprintCallable, Category = Echo)
void CreateEchoTexture();
UFUNCTION(BlueprintCallable, Category = Echo)
void UpdateEcho();
private:
UPROPERTY()
TArray<FColor> data;
FUpdateTextureRegion2D *echoUpdateTextureRegion;
};
Body:
#include "Echoes.h"
#include "EchoManager.h"
AEchoManager::AEchoManager(const class FPostConstructInitializeProperties& PCIP)
: Super(PCIP)
{
PrimaryActorTick.bCanEverTick = true;
echoUpdateTextureRegion = new FUpdateTextureRegion2D(0, 0, 0, 0, ECHO_TEXTURE_SIZEX, ECHO_TEXTURE_SIZEY);
}
//////////////////////////////////////////////////////////////////////////
// Texture
void AEchoManager::UpdateTextureRegions(UTexture2D* Texture, int32 MipIndex, uint32 NumRegions, FUpdateTextureRegion2D* Regions, uint32 SrcPitch, uint32 SrcBpp, uint8* SrcData, bool bFreeData)
{
if (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;
});
}
}
void AEchoManager::CreateEchoTexture()
{
// Create echo texture
EchoTexture = UTexture2D::CreateTransient(1024, 1024);
for (int i = 0; i < ECHO_TEXTURE_DATA_LENGTH; ++i)
{
data.Add(FColor(0,0,255,255));
}
UpdateTextureRegions(EchoTexture, (int32)0, (uint32)1, echoUpdateTextureRegion, (uint32)(4 * ECHO_TEXTURE_SIZEX), (uint32)4, (uint8*)data.GetTypedData(), false);
EchoTexture->UpdateResource();
UE_LOG(LogTemp, Warning, TEXT("Create Echo Texture."));
}
void AEchoManager::UpdateEcho()
{
//UpdateTextureRegions(EchoTexture, (int32)0, (uint32)1, &echoUpdateTextureRegion, (uint32)(4 * ECHO_TEXTURE_SIZEX), (uint32)4, data, false);
//EchoTexture->UpdateResource();
//UE_LOG(LogTemp, Warning, TEXT("Update Echo Texture."));
}
And a simple blueprint set up simply to call the Create and Update functions. Right now the Update function is empty, but I eventually want to add some code to change the texture data and update it dynamically every frame.
I’m not an expert in C++ or the inner workings of UE4 so there may be something obvious I’ve overlooked. A working example of a dynamic texture or any suggestions on how to do it better would be greatly appreciated. Thanks.