Best way to draw text in RenderOverlay?

Ask about ACS, DECORATE, ZScript, or any other scripting questions here!

Moderator: GZDoom Developers

Forum rules
Before asking on how to use a ZDoom feature, read the ZDoom wiki first. If you still don't understand how to use a feature, then ask here.

Please bear in mind that the people helping you do not automatically know how much you know. You may be asked to upload your project file to look at. Don't be afraid to ask questions about what things mean, but also please be patient with the people trying to help you. (And helpers, please be patient with the person you're trying to help!)
Post Reply
User avatar
krokots
Posts: 296
Joined: Tue Jan 19, 2010 5:07 pm

Best way to draw text in RenderOverlay?

Post 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.
User avatar
Player701
 
 
Posts: 1710
Joined: Wed May 13, 2009 3:15 am
Graphics Processor: nVidia with Vulkan support
Contact:

Re: Best way to draw text in RenderOverlay?

Post 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).
User avatar
m8f
 
 
Posts: 1462
Joined: Fri Dec 29, 2017 4:15 am
Preferred Pronouns: He/Him
Location: Siberia (UTC+7)
Contact:

Re: Best way to draw text in RenderOverlay?

Post 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().
User avatar
krokots
Posts: 296
Joined: Tue Jan 19, 2010 5:07 pm

Re: Best way to draw text in RenderOverlay?

Post by krokots »

Thanks, I knew I was missing something about StatusBar. I'm gonna stick to that.
Post Reply

Return to “Scripting”