UE4 C++ 从内存数据创建动态材质

动态材质的创建

需要注意的是,本文写的是根据二进制数据流创建动态材质,而不是单纯的用C++加载一个材质并赋予模型。项目有需求需要把视频采集卡采集到的视频在UE4里显示,所以简单研究了一下。

我的目的是把用第三方硬件的SDK开发出来的程序写的数据流创建为动态材质,所以如何把采集到的视频写成数据流不再考虑范围内,我们直接用就好了。

unsigned int CaptureChannels::readChannelData(unsigned int cardId, unsigned int channelId, unsigned char *buffer, unsigned int &length)
{
    unsigned int idx = cardId * MAX_CHANNEL_NUM_PER_CARD + channelId;
    memcpy(buffer, channelData[idx].buffer, channelData[idx].buflen);
    length = channelData[idx].buflen;
    return channelData[idx].seqNo;
}

所以,我们只要把数据从buffer从还原为图片在构建贴图就好了。

在UE4中新建一个Actor类,因为要往场景中放置,材质要在模型上显示。然后新建一个材质并把它的texture节点参数化再继承它的材质实例。
在头文件中声明变量

    UPROPERTY(EditAnywhere, Category = Mesh)
    class UStaticMeshComponent* MeshScreen;
    unsigned char *buffer;
    UTexture2D *m_texture;
    UMaterialInterface *ScreenMaterial;
    UMaterialInstanceDynamic *DynamicMaterial; 

在源文件中的构造函数和BeginPlay函数中完成初始化操作

ACaptureActor::ACaptureActor()
{
    // Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
    PrimaryActorTick.bCanEverTick = true;
    MeshScreen = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Mesh1P"));
    buffer = new unsigned char[2048 * 2048 * 4];

}

// Called when the game starts or when spawned
void ACaptureActor::BeginPlay()
{
    Super::BeginPlay();
    FString path = "/Game/Mesh/phong1.phong1";
    ScreenMaterial = Cast<UMaterialInterface>(StaticLoadObject(UMaterialInterface::StaticClass(), nullptr, *path));
    DynamicMaterial = UMaterialInstanceDynamic::Create(ScreenMaterial, this);
    CaptureChannels::Instance()->readConfig();
    CaptureChannels::Instance()->initCaputre();
    m_texture = UTexture2D::CreateTransient(1024, 512);

}

CaptureChannels的相关操作不用理会。然后编写核心函数并在Tick中调用。

void ACaptureActor::setTextureFromLoadImg(bool bWasSuccessful)
{
    unsigned int  len = 0;

    CaptureChannels::Instance()->run();
    CaptureChannels::Instance()->readChannelData(0, 0, buffer, len);

    //FUpdateTextureRegion2D *Region2D = new FUpdateTextureRegion2D(0, 0, 0, 0, 1024, 512);
    //m_texture->UpdateTextureRegions(0, 1, Region2D, 1, 4, buffer, test);

    void* temp_dataPtr = m_texture->PlatformData->Mips[0].BulkData.Lock(LOCK_READ_WRITE);
    FMemory::Memcpy(temp_dataPtr, buffer, len);
    m_texture->PlatformData->Mips[0].BulkData.Unlock();

    m_texture->UpdateResource();

    DynamicMaterial->SetTextureParameterValue("TextureScreen", m_texture);
    MeshScreen->SetMaterial(0, DynamicMaterial);

}

我注释掉的两行代码是UE4的API,从4.9到现在有了很大的改变,理论上是可以直接用的,我没有找到用法,知道的朋友请不吝赐教。大体思路是,先在UE4里创建材质和材质实例,然后在C++中修改参数。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值