Sign in to follow this  

How to draw round bars

This topic is 4779 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I want to have an indicator in my game's GUI with a round shape. Let's say it's a circle that shows a power charging over time. When time passes, the circle should get completed little by little until it's full. It starts as a triangular slice and grows clockwise. How should I do this without having a bitmap for every possible state of the indicator?

Share this post


Link to post
Share on other sites
Well, I'm not sure if this would be the best design, but the first solution that came to mind would be to do this by rotating two different semi-circles over the top of another circle.

For example, if you want to have an all yellow circle when the guage is empty and all red when it's full, with zero starting at the top and proceeding clockwise, you can do this:

First draw a circle as the background with the left half yellow and the right have red. Then to indicate 0%, you'd have to cover the right half of the circle with a yellow semi-circle. As you increase from 0 to 50%, you rotate that yellow semi-circle clockwise around the center of the guage. This will gradually reveal the right side of the background circle. At 50% the yellow semi-circle is no longer needed as it lies on the left half (which is already yellow). Now to go above 50%, you need a red semi-circle which would start by covering the right half again. As you increase from 50% to 100%, you rotate that red semi-circle clockwise around the center of the guage. This will gradually cover the left side of the background circle. Then on top of all that you'd draw any tick marks on the guage. An arrow or needle could be part of the semi-circle on the edge that is revealing or covering or just a separate image.

It should work, just not sure if it's the best way.

Share this post


Link to post
Share on other sites
@Alpha_ProgDes:

That wouldn't be exactly what I want as I would like the circle to be textured, not a plain color...

@reana1:

I like your solution. Provided that the texture of the circle is symmetrical with respect to the circle center, it should work OK... as long as the semicircles are opaque. I would like to be able to usa alpha-blended graphics, and in that case what you propose doesn't look right. :(

Any other suggestions?

Share this post


Link to post
Share on other sites
If you are using a pixel shader:
You should be able to set up your texcoords on a strip of triangles arranged in a circle so that by passing a control variable to the shader and comparing it to the texcoord you could determine the alpha value. This is one way you could control how much of the circle to draw.

Share this post


Link to post
Share on other sites
Decide how many "levels" you need and make a triangle fan with that many subsections. This is one of the few times when a fan would work well.

To make it more circular you can fade out the circle texture at the edges so the pointy bits will be invisible.

Then just draw as many sections as you need for your GUI state.

Share this post


Link to post
Share on other sites
Quote:
Original post by DrunkenHyena
Decide how many "levels" you need and make a triangle fan with that many subsections. This is one of the few times when a fan would work well.

To make it more circular you can fade out the circle texture at the edges so the pointy bits will be invisible.

Then just draw as many sections as you need for your GUI state.


Triangle Fans really are the best way to do this. You can create a triangle fan dynamically, so that your final sliver changes as a percentage of the total amount. I wrote a system like this for our clock in game, and it worked great. I had a texture that was a full circle, centered a 64 x 64 texture, then I had a second texture, with alpha, that was the 'bezel' around the circle, framing it. I would draw the first texture with a triangle fan, with enough triangles to make it look right, calculating each of them by hand. Then I would draw the bezel texture overtop, to frame the slivers. It worked well.

Share this post


Link to post
Share on other sites
Creating it dynamically seems a waste of effort. If you want increments of 10% (as an example) have 10 pie slices. Then when you call DrawPrim on it you pass the percent complete/10 and it draws that many pieces of the pie.

I do like the bezel texture idea. Beautifully simple solution to handling the "pointy artifacts" that a fan can give.

Share this post


Link to post
Share on other sites
If you used triangle lists instead of a triangle fan (you'd really have to want this effect!), then you could adjust the vertex alpha values for the parts that aren't visible, setting them to 0. You could then adjust the vertex alpha values for the parts that are the interior edge of the slice to 75%, and the interior edge of the slice would fade out (picture a Radar working in reverse). This wouldn't work on a triangle fan though, because your center vertex is shared and changing its alpha value would affect the rest of the fan.

Chris

Share this post


Link to post
Share on other sites
Quote:
Original post by DrunkenHyena
Creating it dynamically seems a waste of effort. If you want increments of 10% (as an example) have 10 pie slices. Then when you call DrawPrim on it you pass the percent complete/10 and it draws that many pieces of the pie.

I do like the bezel texture idea. Beautifully simple solution to handling the "pointy artifacts" that a fan can give.


In the case that I needed the round bar, I couldn't establish a number of pie slices needed since the clock, which I was making, needed infinite resolution. The clock's duration could be 10 seconds long, one minute long, or ten minutes long. Using only 10 pie slices would make the clock pop dramatically when playing a 10 minute game. I found dynamically creating the clock was the best. Instead of doing all the cos/sin calculations every frame, I cached the data. I had 10 slices, it's true, but the last 'visible' slice was always calculated programatically so that it would start out ata full 1/10 of the unit circle, and decrease with time. Once the slice was invisible then I would remove it and only draw nine slices, shrinking the ninth slice as time went by. I continued to do this until all the slices were gone. Dynamically drawing a tri-fan with ten slices every frame is, realistically, a very cheap thing to do. Almost everything else in the game was static. I should add, perhaps, that this was for a console game, where unified memory and the like make this kind of thing, perhaps, easier to swallow, but I maintain that it's not too expensive and it avoids the 'popping' you get with a fixed set of slice sizes. Ten slices gives you 36 degrees per slice. The bigger your clock, the more obvious the slice-pop. Aesthetically, building the whole thing, or at least the last slice, dynamically just looked better.

Share this post


Link to post
Share on other sites
What I *meant* to say was "In the general case, Creating it dynamically seems a waste of effort". Sorry if it came across as a criticism of what you did.

In most applications the required resolution would be known ahead of time, and in that case having the "pie" predefined makes setting up and drawing it dead easy as well as very efficient. And in most cases 10 slices would not be sufficient, that was just a number I pulled out of the air.

This of course doesn't hold true if your requirements are different.

Share this post


Link to post
Share on other sites

This topic is 4779 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this