This is achieved through clever use of a texture where the alpha channel fades from 0-1 in a ring.
Using a shader we can fill the meter based on a value that goes from 0.0f-1.0f when comparing against this texture and just render our actual visible image in place.
Question is... let's say this was an old system without fancy shaders available to us. What would be an efficient way to achieve a similar result without using either a shader or far too many draw calls than is healthy?
Winner will receive a cosplayer to keep for a week
Pretty sure you would fake the effect with multiple images, I would just make the frames in something like Flash and possibly put them in a flipbook texture.
For example Chaos Field's entire HUD comes from a single texture.
you can use the stencil buffer in opengl, not easy though...
cagars solution is the best for a older system, you never have more than 3 draw calls...
Hellsinker does a pretty neat thing with this concept, kagura xanthel type has swords that circle around leaving an after shadow (that does damage). its essentially, a slice of a pie, rendered at different angles, all made to line up. looks really cool.
edit: thought this thread was about creating new and awesomely mindblowing hud designs.
This was not "how do we do it on old arcade systems" - it was how do we reproduce this (as in this exact thing - or as close to as possible) on an older system that lacks shaders? using the example of the ultra meter at the very top of the thread. Segmented sprites are not exactly taxing on the brain.
For a HUD, you could do the following:
3 sprites, a draw order setting, one sprite drawn completely black, a toggle of the second segment and rotation. Stare at the image - it'll come to you.
Cagar: You'll note that I actually have a meter like that in my game (both in fact) surrounding the players ship during hyper to serve as a timer, so this clearly is not the answer to the problem given I already have a working implementation and could if desired - use the extremely fast shader technique described above. No cosplayers for you!
Not that there's any right/wrong way here - all are valid. Just what you've suggested isn't really an accurate meter due to its somewhat blocky nature.
That's the only way really. The reason it's done like that on older systems (includes 3D stuff too, by the way!) is because it's the only way to do it really. If you don't care about transparency, I imagine you could use another trick, but why bother. Even CAVE does it like Cagar said, except for non-full segments they alpha blend it based on the percentage through that segment.
My game, Lunacy Star, heavily abuses radial bars, and it's achieved by calculating the individual vertices of the bar and drawing primitive shapes to fit.
Basically it breaks a circle into 64 fragments and will draw triangles to fit those 64 fragments such that when stitched together they look.. well, just like what you've got right there.
Do you find this to be accurate enough though? I mean here's what I'm getting at:-
A circle is 360 degrees - minus say the... 30 degree arc for the completely black part of the Ultra Meter in SSF4 you're talking about 330 degrees here.
Now, if you were dealing with say a rect - you could easily fill your meter up with say:-
// Assuming width of rect is 400
fPct = currentUltra / maxUltra;
width = 400*fPct;
So that's gonna be pretty damned accurate. With the segmented approach I sort of feel like you might lose out on some of this - which is really what I'm getting at.
Now with the shader method of just drawing pixels that are over a certain alpha threshold - you get in to the territory where the part of your bar furthest 'Right' - talking about the alpha mask graphic here - is of color (r,g,b,1.0) and the furthest left is (r,g,b,0.0)
So this gives you a huge range of values you can actually go through.
I know this is really being anal - but the way I've described above is to basically have 3 sprites. Lower circular section (below the divider) upper circular section and a black mask the same size as a single one of the circular segments.
When meter < 50% - you're drawing on top of the bottom one and not rendering the top one.
Draworder: lowerfill, blackout, null
When meter >= 50% - you're drawing on top of the top one and the draw order dictates that the black mask is now below the lower fill
Draworder: lowerfill, upperfill, blackout
Using the orange circle in the center as your pivot point (imagine this is a square graphic) you can then rotate the sprite based on a percentile value.
3 sprites, same job - more accurate presentation. Caveat here is that it looks shit if it's not embedded in an opaque meter somewhere because black backgrounds tend to clutter the playing area and you want as much negative space as possible (hence the shader approach)
Do you find this to be accurate enough though? I mean here's what I'm getting at:-
A circle is 360 degrees - minus say the... 30 degree arc for the completely black part of the Ultra Meter in SSF4 you're talking about 330 degrees here.
Now, if you were dealing with say a rect - you could easily fill your meter up with say:-
// Assuming width of rect is 400
fPct = currentUltra / maxUltra;
width = 400*fPct;
So that's gonna be pretty damned accurate. With the segmented approach I sort of feel like you might lose out on some of this - which is really what I'm getting at.
It works well for what I use it for. The hiccups in the segments truly are only noticeable whenever the bars are large,
or you've whittled a boss character down to next-to-no health and its "total" healthbar is decrementing in notable notches.
(The "current" healthbar is the inner HP circle and the "total" healthbar is the outer, grayer, HP circle.)
n0rtygames wrote:With the segmented approach I sort of feel like you might lose out on some of this - which is really what I'm getting at.
You really don't. If you make the segments small enough, then you can get nearly perfect precision anyways. The granularity goes down to however small you want and how many splits/images your graphical output can handle.
Something that I *can* do to mitigate the jumpiness, is render the last polygon not at the standard pi/32 size, but to a size that is representative of how much OUT of pi/32 that piece is to represent.
So if my circle is meant to be 54.38 out of 64 pieces, instead of the 54 pieces it would ordinarily draw, I may have the game draw one more polygon that is of the size 0.38 * (pi/32).
By nearly perfect, I mean at least as close as you would with that alpha shader method. With all them fancy subpixel shenanigans, you might even be able to make it more precise