Page 1 of 1

Best way to draw text in RenderOverlay?

Posted: Tue Jul 05, 2022 9:45 am
by krokots
I want to make a simple UI addon that displays current powerups and their time in seconds. It seems to me that the best option for that is to use RenderOverlay to draw things, so it would always work, without interfering with other mods. So I tried to draw some texts, and I have problems controlling their position. First I tried Screen.DrawText at 0, 0.

The text position is always top left which is good, but it does not scale with UI, which is bad. I think I could use DTA_VirtualWidth / Height to match the HUD "resolution" ? Not sure how to do that right now.
I also tried StatusBar.DrawString at 0, 0

It is scaling now, cool but the position is wrong, it looks like there is a 320x200 rectangle in the mid-bottom and the 0, 0 is top-left of that rectangle. I also don't know how to do anything with that. Right now I just added some values based on scale (StatusBar.GetHUDScale()) but that's really crappy solution.

Re: Best way to draw text in RenderOverlay?

Posted: Wed Jul 06, 2022 1:24 am
by Player701
If you want to use Screen.DrawText, you have to get the HUD scale first and divide the screen width and height by the X and Y scale factors respectively:

Code: Select all

class OverlayHandler : EventHandler
{
    override void RenderOverlay(RenderEvent e)
    {
        let scale = StatusBar.GetHUDScale();
        int w = int(Screen.GetWidth() / scale.X);
        int h = int(Screen.GetHeight() / scale.Y);
        Screen.DrawText(SmallFont, Font.CR_RED, 0, 0, "Screen.DrawText", DTA_KeepRatio, true, DTA_VirtualWidth, w, DTA_VirtualHeight, h);
    }
}
If you want to use StatusBar.DrawString, you have to call StatusBar.BeginHUD() first, and also create a HUDFont instance, which you'll need to do in RenderOverlay as well:

Code: Select all

class OverlayHandler : EventHandler
{
    private ui HUDFont _smallFont;

    override void RenderOverlay(RenderEvent e)
    {
        if (_smallFont == null) _smallFont = HUDFont.Create(SmallFont);
        StatusBar.BeginHUD();
        StatusBar.DrawString(_smallFont, "StatusBar.DrawString", (0, 0), translation: Font.CR_RED);
    }
}
As for which of the two methods to use, I'd probably use StatusBar.DrawString if I wanted my text to scale along with the HUD automatically, and Screen.DrawText otherwise. Note that it is generally not a good idea to ignore the user's scaling options except in some special cases (e.g. you want your text to occupy a part of the screen proportional to its total size).

Re: Best way to draw text in RenderOverlay?

Posted: Wed Jul 06, 2022 2:44 am
by m8f
Alternatively, you can use DTA_ScaleX and DTA_ScaleY in Screen.DrawText (like this) and calculate the scale depending on Screen.getWidth() or Screen.getHeight().

Re: Best way to draw text in RenderOverlay?

Posted: Wed Jul 06, 2022 5:21 am
by krokots
Thanks, I knew I was missing something about StatusBar. I'm gonna stick to that.