Rendering only to slate viewport

I’m working on an application in as much C++ as possible which will serve as the front end for controlling some external equipment. It will have a number of controls and then a 3d interactive viewport similar in idea to the unreal editor (but much simpler). I have most of the Slate details figured out and am able to make a decently functional UI. The hangup I’m having is the 3d viewport and I feel like I may be approaching it wrong because I come from a more low level 3d programming background.

What I really want is to disable the main window’s 3d rendering and then create some kind of slate panel/widget and direct a camera of some sort to render right to that panel/widget. I have been able to render to texture using SceneCapture2D and display that as a UMG widget or show on a 3D object, but I would much rather it be to a slate widget from C++. I haven’t been able to figure out how to get a reference to the material from C++ and set the Image when on an SImage when I call something like:


**SNew(SImage).Image(new FSlateImageBrush(FName(*FString(FString(FPaths::GameContentDir() / "M_Testmat"))), FVector2D(256, 256)));**

The SImage is created but, but it is all white so my guess is I’m not specifying the content properly even though there is a “M_Testmat.uasset” in my content folder. What am I missing with this?

It seems like my options are only:

  • Render to image then *somehow *display the image in a control.

  • I don’t like this because you wind up with all of these textures to resize if the window/panel is resized or moved.

  • How can I disable the main window rendering?

  • Render to a separate window

  • This isn’t completely out of the question, but it is not my favorite option because it is on the user to manage their window position

  • Pray that there is a way to render directly to a panel

Does anyone have an idea what they’d do for this type of application?

UPDATE:
I have found that this seems to work.
The setup is: SceneCapture2D capturing to a Render Target material, which is then linked to a Material



// Grab the material using LoadObject, put it into a FSlateImageBrush, put that into an SImage
auto slateMaterial = LoadObject<UMaterial>(NULL, *FString("/Game/M_Testmat.M_Testmat"), NULL, LOAD_None, NULL);
auto slateImage = new FSlateImageBrush((UObject*)slateMaterial, FVector2D(1024, 1024));
auto renderImage = SNew(SImage).Image(slateImage);

// also, if you need to change the image dynamically
slateImage->SetResourceObject(slateMaterial);


I also wrap the SImage in an SScaleBox to keep the aspect ratio



ChildSlot
 ...
  SNew(SBox)

  [INDENT=2]SNew(SScaleBox)[/INDENT]
  [INDENT=2].Stretch(EStretch::ScaleToFill)
[/INDENT]
  [INDENT=3]renderImage[/INDENT]
  [INDENT=2]][/INDENT]
  ]
...
  ]
 

I would like the render target and FSlateImageBrush to resize to be the same size as the parent widget as the window resizes. I’m assuming I will have to somehow hook into widget resizing events to change those.