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!)
Post Reply
User avatar
PandaDoomer
Posts: 107
Joined: Sun Apr 12, 2015 9:05 pm
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.
Attachments
fuck.png
fuck.png (11.18 KiB) Viewed 569 times
User avatar
MFG38
Posts: 414
Joined: Sun Apr 14, 2019 8:26 am
Graphics Processor: nVidia (Modern GZDoom)
Location: Finland
Contact:

Re: Circular progress bars with shaders?

Post by MFG38 »

Not doable to the best of my knowledge.
User avatar
phantombeta
Posts: 2088
Joined: Thu May 02, 2013 1:27 am
Operating System Version (Optional): Windows 10
Graphics Processor: nVidia with Vulkan support
Location: Brazil

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: 107
Joined: Sun Apr 12, 2015 9:05 pm
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: 1311
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: 1324
Joined: Tue Jul 15, 2003 4:18 pm
Contact:

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).
Attachments
Graphic for status indicator
Graphic for status indicator
StatFill.png (3.55 KiB) Viewed 387 times
Post Reply

Return to “Scripting”