Hi!
I have previously worked on a similar project.
In general, I only use the OnPaint function for basic and mostly debug related graphics and texts, it is not very optimized.
I would recommend using a UI Material along with the native “Custom” HLSL node (if needed) instead of creating a custom c++ function for this. Using a UI Material would open up many more customization options besides drawing textures or colors along the shapes and it is already optimized.
Here’s a quick overview:
1- Create a Material and make sure its Domain is set to User Interface and Blend Mode is set to Translucent (or Masked).
2- Add an Image widget to the canvas of your custom widget, make sure it covers the screen.
3- On Event Construct or Event PreConstruct, create an instance of the UI Material and save it as a variable.
4- Set the material instance reference as the brush of the Image widget using Set Brush From Material function.
5- Open the UI Material and add a “Custom” HLSL node or use existing nodes and functions depending on the complexity of the shapes you are drawing. I personally prefer using the Custom node which allows me to experiment more and allows adding custom inputs and outputs.
6- Set the parameters of the material instance dynamically, on Tick event for example.
Depending on your use case, you might need to create a material instance and an Image widget per shape, unless you have a predefined number of shapes then the Custom node would just need inputs for the positions of each shape. A better approach would be creating a widget called WB_Shape for example, which would have the Image widget and the dynamic material instance, and a function to set the parameters of the material instance including positions, colors, textures, effects and etc.
I hope this helps!