Download

How to apply a UTexture2D to a UStaticMeshComponent?

So in my header I have:



UPROPERTY(EditAnywhere)
UStaticMeshComponent* SampleMesh;


And set the mesh with the dragged in instance:

The in my cpp implementation I load a PNG into a UTexture2D successfully.



TSharedPtr<IImageWrapper> PNGImageWrapper = ImageWrapperModule.CreateImageWrapper(EImageFormat::PNG);
/*
File load code skipped for this post
*/
if(PNGImageWrapper->GetRaw(ERGBFormat::BGRA, 8, RawData))
{
UE_LOG(LogTemp, Log, TEXT("GetRaw success keep going"));


UTexture2D* myTexture = UTexture2D::CreateTransient(500, 500, PF_B8G8R8A8);
FTexture2DMipMap& Mip = myTexture->PlatformData->Mips[0];
void* Data = Mip.BulkData.Lock(LOCK_READ_WRITE);
FMemory::Memcpy(Data, RawData.GetData(), (500 * 500 * 4));
Mip.BulkData.Unlock();
myTexture->UpdateResource();

//SampleMesh
}


Now I’m not quite sure how to take that and apply it to this plane.

I figure there’s a few lines of setting up this UTexture2D with a material?

Any pointers would be greatly appreciated.

Ok, so first off, which are you trying to do: Are you trying to apply your texture to a StaticMeshComponent that has been placed on an actor in your world? Or do you want to apply your texture to the static mesh actor that you’ve dragged into your world (StaticMeshComponent still applies, but it would be good to know what your end goal is). I ask because you said you have that StaticMeshComponent property in your header – header of what?

Actually, nevermind. I think I see what you’re doing now. So, here’s what I would do – it may not be the best, and someone may have better ideas, but this should get you started. Make a new material. In your Content folder, right-click and choose Material & Textures > Material. Name your material (I’ll call it Foo to keep it simple). Then open up your material, right-click in the material graph and search for TextureSampleParameter2D – give the parameter a name, like TextureInput. And connect the RGB pin to the Base Color pin of Foo. You can keep the TextureOverride value to whatever the default is – we’ll be changing it to your Texture2D in code:

Now, back in your code, give your class another property – UMaterialInstanceDynamic* MyMaterial – this will be the material you’ll be applying to your mesh. After you’re done creating your Texture2D, you’ll want to load the material you saved in your Content folder, and then change the texture its using to your texture. Something like this:


UMaterialInterface* LoadedMaterial = LoadObject<UMaterialInterface>(nullptr, TEXT("/Game/Foo.Foo"), nullptr, LOAD_None, nullptr);
if (LoadedMaterial)
{
   MyMaterial = UMaterialInstanceDynamic::Create(LoadedMaterial, NULL);

  if (MyMaterial)
  {
      //Here we're applying your texture to the material
      MyMaterial->SetTextureParameterValue(TEXT("TextureInput"), myTexture);

      //Finally, apply the material to your mesh component
      SampleMesh->SetMaterial(0, MyMaterial);
  }
}

See if that works. Again, there may be better ways, but this is how I’d try to go about it.

Thanks for the tips!! I got it to compile and update the texture but it just shows up as white. It is indeed updating the material/texture though! Another step closer… Maybe I’ll try another png and see if I at least see a color difference…

BOOM! I at least got it to show up! Now I can fiddle with the alignment! You also pointed out a lot of subjects I can now study about how/why this works so thank you much!

Not a problem. Glad I could help.

Only thing now is I tried packaging it to run as a delivered app, it doesn’t grab the cat image. just displays as a white texutre… I saw a window pop up saying allow my program to have access type message, so I accepted that, close/reopen, still a white texture… Hmmm

Actually tried again . Originally built as development package which gave me white square. Deleted that and packaged a shipping output and it worked! BUT for some reason the cat in shipping outout it perfectly aligned with plane while in the testing environment it had an image offset… i don’t love that it looks different on final export… maybe I have to do some extra lines of code to specify the texture alignment with that plane…