UE4 Gif图插件

因为项目中用到了Gif格式的图片作为loading界面的资源,但UE本身不支持该格式,所以只能找找看是否有大佬写过相应的插件,果然被我找到了,是一个叫AnimatedTexture的插件。

虚幻4动画贴图插件 | 游戏程序员的自我修养

不过原插件Gift图的tick是在游戏线程中进行的。因为我们项目里面的loading是阻塞游戏线程加载,所以想要在加载界面中使用这个插件,就需要对原插件进行一部分修改,让Gif图资源在游戏线程阻塞时,也能够更新texture。

这里将原有的AnimatedTexture2D继承FTickableGameObject,修改为FAnimatedTextureResource继承FTickableObjectRenderThread,这样就可以在渲染线程中进行tick。我为了减小资源文件大小,把原有的导入时解析,改为了资源加载后解析。

同时对资源tick进行了一定优化,仅在纹理可见时才进行tick,不可见一段时间后不在进行纹理更新。

这里给出修改后的插件地址:

https://github.com/sorkNasrk/AnimatedTexture

多线程上可能没有做过多的保护,后期需要再优化一些

删除了原有的AnimatedGIFDecoder, UAnimatedTextureSource:

其中主要修改代码如下:

AnimatedTexture2D.h

/**
 * Copyright 2019 Neil Fang. All Rights Reserved.
 *
 * Animated Texture from GIF file
 *
 * Created by Neil Fang
 * GitHub Repo: https://github.com/neil3d/UnrealAnimatedTexturePlugin
 * GitHub Page: http://neil3d.github.io
 *
*/

#pragma once

#include "CoreMinimal.h"
#include "Tickable.h"	// Engine
#include "Engine/Texture.h"	// Engine

#include "AnimatedTexture2D.generated.h"

class FAnimatedTextureResource;
ANIMATEDTEXTURE_API bool isGifData(const void* data);

USTRUCT()
struct FGIFFrame
{
	GENERATED_BODY()
public:
	UPROPERTY()
		float Time;	// next frame delay in sec
	UPROPERTY()
		uint32 Index;	// 0-based index of the current frame
	UPROPERTY()
		uint32 Width;	// current frame width
	UPROPERTY()
		uint32 Height;	// current frame height
	UPROPERTY()
		uint32 OffsetX;	// current frame horizontal offset
	UPROPERTY()
		uint32 OffsetY;	// current frame vertical offset
	UPROPERTY()
		bool Interlacing;	// see: https://en.wikipedia.org/wiki/GIF#Interlacing
	UPROPERTY()
		uint8 Mode;	// next frame (sic next, not current) blending mode
	UPROPERTY()
		int16 TransparentIndex;	// 0-based transparent color index (or −1 when transparency is disabled)
	UPROPERTY()
		TArray<uint8> PixelIndices;	// pixel indices for the current frame
	UPROPERTY()
		TArray<FColor> Palette;	// the current palette

	FGIFFrame() :Time(0), Index(0), Width(0), Height(0), OffsetX(0), OffsetY(0),
		Interlacing(false), Mode(0), TransparentIndex(-1)
	{}
};


/**
 *
 */
UCLASS(BlueprintType, Category = AnimatedTexture, hideCategories = (Adjustments, Compression, LevelOfDetail))
class ANIMATEDTEXTURE_API UAnimatedTexture2D : public UTexture
{
	GENERATED_BODY()

public:
	friend FAnimatedTextureResource;

	UAnimatedTexture2D(const FObjectInitializer& ObjectInitializer = FObjectInitializer::Get());

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = AnimatedTexture, meta = (DisplayName = "X-axis Tiling Method"), AssetRegistrySearchable, AdvancedDisplay)
		TEnumAsByte<enum TextureAddress> AddressX;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = AnimatedTexture, meta = (DisplayName = "Y-axis Tiling Method"), AssetRegistrySearchable, AdvancedDisplay)
		TEnumAsByte<enum TextureAddress> AddressY;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = AnimatedTexture)
		bool SupportsTransparency = true;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = AnimatedTexture)
		float DefaultFrameDelay = 1.0f / 10;	// used while Frame.Delay==0

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = AnimatedTexture)
		float PlayRate = 1.0f;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = AnimatedTexture)
		bool bLooping = true;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = AnimatedTexture)
		bool bAlwaysTickEvenNoSee = false;

	UPROPERTY(VisibleAnywhere, Transient,Category = AnimatedTexture)
		int FrameNum;


	virtual void PostLoad() override;


	virtual void BeginDestroy() override;


	bool ImportGIF(const uint8* Buffer, uint32 BufferSize);

	void ResetToInVaildGif()
	{
		GlobalWidth = 0;
		GlobalHeight = 0;
		Background = 0;
		Duration = 0.0f;
		Frames.Empty();
		FrameNum = 0;
	}

	void Import_Init(uint32 InGlobalWidth, uint32 InGlobalHeight, uint8 InBackground, uint32 InFrameCount);

	int GetFrameCount() const
	{ 
		return Frames.Num(); 
	}
	
	FGIFFrame& GetFrame(int32 Index) {
		return Frames[Index];
	}

	float GetFrameDelay(int FrameIndex) const
	{
		const FGIFFrame& Frame = Frames[FrameIndex];
		return Frame.Time;
	}

	float GetTotalDuration() const { return Duration; }


	void Import_Finished();

	void PostInitProperti
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值