The right way to dynamically update a texture.

Ok, I want to be able to get the raw bits from a texture, and evey tick, change them. So I asume I make an Actor class.

Now here is where I get confused. I have been looking at the code that runs MoviePlayer.h and the various Apple/Microsoft interface and figured out how to access the raw data. The idea is to make an
actor component that outputs a texture (in this case a UTexture2DDynamic) that you can slap onto a mesh. I would use a view-port, but that’s way deeper than I have gotten in the past few days.

This is the pseudo code I have so far.



UTexture2DDynamic* Texture = UTexture2DDynamic::Create(VideoDimensions.X, VideoDimensions.Y, PF_B8G8R8A8);
FTexture2DDynamicResource*	Res = (FTexture2DDynamicResource*)Texture->CreateResource();

// in tick and after some error checking
uint32 Stride;
uint8* DestTextureData = (uint8*)RHILockTexture2D(Res->GetTexture2DRHI(), 0, RLM_WriteOnly, Stride, false);
FMemory::Memcpy(DestTextureData, TextureData.GetData(), TextureData.Num());
RHIUnlockTexture2D(Res->GetTexture2DRHI(), 0, false);


Before I start heading down this route, is there a better way to do this? How does the rendering engine tell if a texture, dynamic or otherwse, must be updated and is there a way I can flag that?

Eventually I want to make a blueprint compatible component that you can give it input, and just tell it to output a texture.

In a related question, is there a way to use FCanvas against a texture? As the UI interfaces worked like in Doom 3? That’s my real goal at the end of the day.

Yes & yes.

The Coherent UI plugin I’ve been working use FCanvas to render the texture and add the mouse cursor.

And your psuedo code is similar to what I did to get the texture updated:



    uint32* Dest = (uint32*)ViewTexture->PlatformData->Mips[0].BulkData.Lock(LOCK_READ_WRITE);

    FMemory::Memcpy(Dest, Src, Size);
    
    ViewTexture->PlatformData->Mips[0].BulkData.Unlock();
    ViewTexture->UpdateResource();


ViewTexture is a standard UTexture2D creating using UTexture2D::CreateTransient().
You can see the results here.

Haven’t ported it over to the public build yet.

As for FCanvas, this came up in the beta, to wit:



    // Create a Render Texture and initialise it.
    RenderTexture = CastChecked<UTextureRenderTarget2D>(StaticConstructObject(UTextureRenderTarget2D::StaticClass()));
    RenderTexture->AddToRoot();
    RenderTexture->ClearColor = FLinearColor::Black;
    RenderTexture->bNeedsTwoCopies = false;
    RenderTexture->bHDR = false;
    RenderTexture->InitAutoFormat(Width, Height);
    RenderTexture->UpdateResourceImmediate();

    // Create a Canvas and assign the render texture resource to it.
    FTextureRenderTarget2DResource* RenderTextureResource = (FTextureRenderTarget2DResource*)RenderTexture->Resource;
    Canvas = new FCanvas(RenderTextureResource, NULL, 0, 0, 0);
    Canvas->Clear(RenderTexture->ClearColor);

    // Draw stuff on canvas.
    Canvas->DrawItem(bla bla bla);

    Canvas->Flush();


Should really put this on the wiki as a code snippet :slight_smile:

Oh so do that! Thats it right there FTextureRenderTarget2DResource was what I was looking for. The UpdateResource() shows exactly what it does in the back end… as long as the video card supports write-to-texture atleast. My biggest problem was finding the right object that did what I wanted and I was afraid I was going to have to make it myself:P

Love that video of that plug in btw, really awesome. Its kind of making me want to get the VNC client protocol and make a virtual data-center. How did you handle the threading for it? That is did you have to do anything special to make sure the web browser/FCanvas wouldn’t choke the engine if webkit crashed? I really need to look into how threading works in here. Again, only spent like a few days on this vs the 50+ hours on the Doom 3 source when it came out.

Sigh. If anything this is giving me a reason to shell out the grand form visual studio 2013.

One quick question, is there a way you can take control of the keyboard easily? Right now when I “aim” at a box, I save the old key map and change them all out in this very long copy and paste function since I was lazy. I ask because I bet your doing the same thing on your plugin. Thanks alot:)

All I did was learn how to take the image data Coherent UI provides and get it to render.
Coherent UI handles everything else in the background.

For input, I send a dummy-Slate widget to hijack and redirect input to what ever view is currently in-focus.

Well, I did in the beta.

Coherent Labs apparently has their own plugin in the works too, which wil undoubtably be better then mine.
I’m still moving mine over to the public build though, as it allows me to get aquainted with the updated plugin system and will be useful to others.
ie. Nothing stopping someone taking my code and making it work with libRocket, CEF3 etc.

Hi. I just found this old topic. I’ve got a very specific question and if there’s a place I can get an answer for it, it’s probably here :confused:

I procedurally modified the bulkdata of a texture’s only mip. The changes are visible in the editor, but only until the editor got closed and restarted. How do I save the modified bulkdata to the asset file? I tried simply saving the texture asset, but that isn’t enough.

edit: actually, nevermind. I found the “persistent” data under UTexture2D::Source.