Circular progress bars with shaders?

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!)
User avatar
PandaDoomer
Posts: 104
Joined: Sun Apr 12, 2015 9:05 pm
Discord: PedroThePanda64#1661
Operating System: Windows 10/8.1/8/201x 64-bit
Location: USA

Circular progress bars with shaders?

Post by PandaDoomer »

Is it possible to have a circular progress bar in a zscript hud using shaders? If so, how would I go about doing it? My attempts using horizontal and vertical bars just isn't working, and I'd like to have a proper clockwise bar that actually looks right if possible anyways.
You do not have the required permissions to view the files attached to this post.
User avatar
MFG38
Posts: 392
Joined: Sun Apr 14, 2019 8:26 am
Operating System: Windows 10/8.1/8/201x 64-bit
OS Test Version: No (Using Stable Public Version)
Graphics Processor: nVidia (Modern GZDoom)
Location: Finland

Re: Circular progress bars with shaders?

Post by MFG38 »

Not doable to the best of my knowledge.
phantombeta
Posts: 1971
Joined: Thu May 02, 2013 1:27 am
Operating System: Windows 10/8.1/8/201x 64-bit
OS Test Version: No (Using Stable Public Version)
Graphics Processor: nVidia with Vulkan support

Re: Circular progress bars with shaders?

Post by phantombeta »

Not really doable with a shader (there's no way to pass inputs to material shaders without gross hacks), but it's certainly doable with the Shape2D API, though that does require using the Screen.* API instead of just ZScript HUD stuff.
User avatar
PandaDoomer
Posts: 104
Joined: Sun Apr 12, 2015 9:05 pm
Discord: PedroThePanda64#1661
Operating System: Windows 10/8.1/8/201x 64-bit
Location: USA

Re: Circular progress bars with shaders?

Post by PandaDoomer »

phantombeta wrote:Not really doable with a shader (there's no way to pass inputs to material shaders without gross hacks), but it's certainly doable with the Shape2D API, though that does require using the Screen.* API instead of just ZScript HUD stuff.


I've only used Shape2D once, and it was a real pain in the ass. Know of any good resources I can use, or tutorials? Thanks.
User avatar
Cherno
Posts: 1278
Joined: Tue Dec 06, 2016 11:25 am

Re: Circular progress bars with shaders?

Post by Cherno »

Possible with a post-processing shader, where you could pass the completion % and hud-related things like hudscale and position. The rest is math.
User avatar
AFADoomer
Posts: 1237
Joined: Tue Jul 15, 2003 4:18 pm

Re: Circular progress bars with shaders?

Post by AFADoomer »

Here's a sample ZScript function that will do what I think you want. The DTA_Rotate texture drawing tag makes this much easier than in the past.

Code: Select all

   void DrawStatusIndicator(int x, int y, int amount, int min = 0, int max = 100, color clr = 0x0, String tex = "STATFILL")
   {
      // Calculate angle of indicator
      int angle = 90 - amount * 360 / (max - min); // Scales value to 360 degree range, subtracts from 90 to start movement clockwise from top

      // Graphic used by indicator; graphic will rotate around the centerpoint
      TextureID fill = TexMan.CheckForTexture(tex); // Fill image (half circle arc)
      if (!fill.IsValid()) { return; }

      // Draw the fill at the correct angle, with a second fill drawn for the second half of the circle
      // This uses the DTA_Clip* tags to allow clipping the part of the graphic that should
      // remain unseen while smoothly drawing the progress indicator as it moves.

      // First half - clipped on the left side
      // If a tint color is defined, tint the image, otherwise draw it normally
      if (clr) { screen.DrawTexture (fill, true, x, y, DTA_AlphaChannel, true, DTA_FillColor, clr & 0xFFFFFF, DTA_CenterOffset, true, DTA_Rotate, clamp(angle, -90, 90), DTA_ClipLeft, x); }
      else { screen.DrawTexture (fill, true, x, y, DTA_CenterOffset, true, DTA_Rotate, clamp(angle, -90, 90), DTA_ClipLeft, x); }

      // Second half - clipped on the right side
      if (angle > 90 || angle < -90)
      {
         // If a tint color is defined, tint the image, otherwise draw it normally
         if (clr) { screen.DrawTexture (fill, true, x, y, DTA_AlphaChannel, true, DTA_FillColor, clr & 0xFFFFFF, DTA_CenterOffset, true, DTA_Rotate, angle, DTA_ClipRight, x); }
         else {  screen.DrawTexture (fill, true, x, y, DTA_CenterOffset, true, DTA_Rotate, angle, DTA_ClipRight, x); }
      }
   }


Called like this (for example). Assumes 'status' is an integer representing the current completion value with a range from 0 to 65536 and colors the status in green:

Code: Select all

DrawStatusIndicator(screen.GetWidth() / 2, screen.GetHeight() / 2, status, 0, 65536, 0x00FF00);


Parameters are:
x, y Screen coordinates of where to place center of indicator
amount Current value of the indicator
min Minimum range value of indicator (default 0)
max Maximum range value of indicator (default 100)
clr Color to tint the image (default 0: no tint, draw with the original graphic's colors)
tex Graphic to use as the indicator. Must be a half circle and be designed to rotate around the center of the image. Defaults to a graphic named 'STATFILL' (see attached sample).
You do not have the required permissions to view the files attached to this post.

Return to “Scripting”