How to Creat Dynamic Textures in Unreal Engine 4

What is RHI Render core

Sometimes it's necessary to create a texture at runtime and update its contents. Depending on your particular needs there are a couple different methods:

  • If you need to create a dynamic UTexture2D at runtime and update it efficiently every frame, use UTexture2D::CreateTransient() and copy/paste the following function:

NOTE: Currently UE4 doesn't support updating subregions of a texture so you have to update the entire thing every frame or you will end up with garbage in places. In the DX11 runtime the texture creation is done with D3D11_USAGE_DEFAULT not D3D11_USAGE_DYNAMIC.

NOTE: You must add "RHI" and "Render Core" to PublicDependencyModuleNames in your project's .Build.cs file to build the following function.

DynamicTexture = UTexture2D::CreateTransient(SizeX, SizeY);
 
// Allocate the texture HRI
DynamicTexture->UpdateResource();
 
// Use this function to update the texture rects you want to change:
// NOTE: There is a method called UpdateTextureRegions in UTexture2D but it is compiled WITH_EDITOR and is not marked as ENGINE_API so it cannot be linked
// from plugins.
 
void 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;
		});
	}
}

  • If you need to create a dynamic texture and update it a single time you can use this method. Note: After every call to Lock/Unlock you must call UpdateResource(). This deletes the HRI texture and recreates it so it won't be fast but if done infrequently it is simpler to use.
Texture = UTexture2D::CreateTransient(SizeX, SizeY);
FTexture2DMipMap& Mip = [Texture]->PlatformData->Mips[Level];
void* Data = Mip.BulkData.Lock( LOCK_READ_WRITE );
FMemory::Memcpy( Data, NewData, DataSize );
Mip.BulkData.Unlock( );
Texture->UpdateResource();
  • If you are using Slate, or a Slate viewport to render you can use a FSlateTexture2DRHIRef which can be created from the slate function:
FSlateTexture2DRHIRef Texture = MakeShareable(new FSlateTexture2DRHIRef(Width, Height, PF_B8G8R8A8, NULL, TexCreate_Dynamic, bCreateEmptyTexture));


Texture

the RHI texture resource to update

MipIndex

mip level index to be modified

UpdateRegion

The rectangle to copy source image data from

SourcePitch

size in bytes of each row of the source image

SourceData

source image data, starting at the upper left corner of the source rectangle (in same pixel format as texture)


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值