UE4图片文本

制作游戏UI的时候经常会有界面上的自定义样式的文本需求,在2d引擎中我们都会以

这样的图片资源来进行动态数字文本的显示,而固定的属性名称等内容则使用指定贴图代替,现在我们就在ue4中实现这样的渲染

注意:

1.本实例只实现了横向文本渲染,没有多行文本处理,如有需要可以在uv采样上添加Y轴的起始及偏移自行扩展

2.理论上采样贴图size设置的够大能支持无限字符长度采样,但是受限于引擎或者性能影响,建议还是根据需求合理扩展使用

8-22更新:

将4个通道都用起来,兼容更多的字符节约开销

1.修改uv存储贴图的数据写入逻辑,将起始uv分别写入4个通道(如果是做多行的情况,这里就需要修改为分别写入两个通道,每个像素填入两个字符)

UFUNCTION(BlueprintCallable, Category = "AceImageText")
		static void UpdateDynImage(UTexture2DDynamic* tex, TArray<float> values) {
		if (!tex) {
			return;
		}
		FTexture2DDynamicResource* dynRes = static_cast<FTexture2DDynamicResource*>(tex->Resource);
		TArray<FColor> src;
		src.Init(FColor(0, 0, 0), tex->SizeX);	
		if (values.Num() > 0) {
			int len = values.Num() / 4;
			if (values.Num() - len * 4 > 0) {
				len = len + 1;
			}
			for (size_t i = 0; i < len; i++)
			{
				if (i >= src.Num())break;
				int index = i * 4;
				float r, g, b, a;
				r = values[index];
				if (index + 1 < values.Num()) {
					g = values[index + 1];
				}
				if (index + 2 < values.Num()) {
					b = values[index + 2];
				}
				if (index + 3 < values.Num()) {
					a = values[index + 3];
				}
				FLinearColor c(r, g, b, a);
				src[i] = (c.ToFColor(false));
			}
		}
		/*
		更新实现参照
		UTexture2D::UpdateTextureRegions();
		*/

		ENQUEUE_RENDER_COMMAND(FWriteRawDataToDyn)(
			[dynRes, src](FRHICommandListImmediate& FRHICommandList) {
				check(IsInRenderingThread());
				if (dynRes) {
					FRHITexture2D* rhi = dynRes->GetTexture2DRHI();
					uint32 d = 0;
					FColor* data = reinterpret_cast<FColor*>(RHILockTexture2D(rhi, 0, RLM_WriteOnly, d, false));

					FMemory::Memcpy(data, src.GetData(), sizeof(FColor) * src.Num());

					RHIUnlockTexture2D(rhi, 0, false);
				}
			}
		);
	}

2.修改材质采样部分,使用4个通道数据

 3.修改组件蓝图兼容的最大字符数计算

材质

 

材质中包含动态赋予属性:

fontTexSampleScale 文字贴图的每个字符所占的uv宽度 ,我们采样的时候根据这个数据来计算出采样uv插值 

NumSize 在实际渲染中每个字符在渲染网格或Image上所占用的uv宽度

uvOffsetSampleSize  每个字符的起始uv数据在动态uv偏移贴图上所对应的uv宽度

FontSampleTex 根据当前文本数据动态刷新的uv偏移贴图,采样获取每个文本单元的起始uv

NumTex  需要渲染的文本字符集贴图,因制作的时候是出于需要动态掉血数值绘制,所以取名NumTex

UV偏移贴图

创建

贴图高度永远为1,因为我们只考虑横向采样

 参数width:贴图的宽度,代表了可以采样的最大文本长度

UFUNCTION(BlueprintCallable, Category = "AceImageText")
		static UTexture2DDynamic* CreateDynImage(int width) {
		UTexture2DDynamic* tex= UTexture2DDynamic::Create(width, 1);
		tex->SRGB = false;
		tex->SamplerAddressMode = AM_Clamp;
		tex->CompressionSettings = TC_HDR;
		tex->Filter = TF_Nearest;
		tex->MipGenSettings = TMGS_NoMipmaps;
		tex->UpdateResource();
		TArray<FColor> src;
		src.Init(FColor(0, 0, 0), width);
		for (size_t i = 0; i < width; i++)
		{
			auto v = (i % 2)*255;
			FColor c(v, v, v);
			src[i] = c;
		}
		FTexture2DDynamicResource* dynRes= static_cast<FTexture2DDynamicResource*>(tex->Resource);
		ENQUEUE_RENDER_COMMAND(FWriteRawDataToDyn)(
			[dynRes, src](FRHICommandListImmediate& FRHICommandList) {
				check(IsInRenderingThread());
				FRHITexture2D* rhi= dynRes->GetTexture2DRHI();
				uint32 d = 0;
				FColor* data= reinterpret_cast<FColor*>( RHILockTexture2D(rhi, 0, RLM_WriteOnly, d,false));
				
				FMemory::Memcpy(data, src.GetData(), sizeof(FColor) * src.Num());
				
				RHIUnlockTexture2D(rhi, 0, false);
			}
		);
		return tex;
	}

更新

参数 tex:uv偏移的动态贴图对象,有上面的创建方法创建后用户进行存档,更新时传入

参数values:字符串的uv偏移值数组,长度为字符串的长度

UFUNCTION(BlueprintCallable, Category = "AceImageText")
		static void UpdateDynImage(UTexture2DDynamic* tex, TArray<float> values) {
		if (!tex) {
			return;
		}
		FTexture2DDynamicResource* dynRes = static_cast<FTexture2DDynamicResource*>(tex->Resource);
		TArray<FColor> src;
		src.Init(FColor(0, 0, 0), tex->SizeX);		
		for (size_t i = 0; i < values.Num(); i++)
		{
			if (i >= src.Num())break;
			FLinearColor c(values[i], values[i], values[i]);
			src[i]=(c.ToFColor(false));
		}
		/*
		更新实现参照
		UTexture2D::UpdateTextureRegions();
		*/

		ENQUEUE_RENDER_COMMAND(FWriteRawDataToDyn)(
			[dynRes, src](FRHICommandListImmediate& FRHICommandList) {
				check(IsInRenderingThread());
				FRHITexture2D* rhi = dynRes->GetTexture2DRHI();
				uint32 d = 0;
				FColor* data = reinterpret_cast<FColor*>(RHILockTexture2D(rhi, 0, RLM_WriteOnly, d, false));

				FMemory::Memcpy(data, src.GetData(), sizeof(FColor) * src.Num());

				RHIUnlockTexture2D(rhi, 0, false);
			}
		);
	}

对齐方式枚举

        

组件蓝图

变量

 dynFontMat 动态渲染材质

 uvmap 字符集的起始uv偏移映射表

 fontSize 渲染的字符大小,起始就是image对象的单元大小,每个字符这里实现都是正方形

 text 当前渲染的文本

 dynFontUVTex 动态uv偏移贴图的缓存

 maxLength 最大字符长度,超出长度的字符不会做渲染

 align 横向对齐方式,参照对齐方式枚举,纵向始终居中

 fontImage UMG组件,用于最终文本的渲染

构造

初始化布局

初始化渲染

 

 

 

设置文本渲染

 

 

 最终效果

1.

 2.

3.

猜你喜欢

转载自blog.csdn.net/qq769919187/article/details/126423009
UE4