How to make a circular / radial progress bar

I’m pretty sure I’m not the first thinking of doing a circular progress bar:

I can think on a few ways:

  • Have a square geometry and repaint a texture on run-time pixel per pixel
  • Create a circular geometry (just like a torus un 2D) and give it a color
  • Do some kind of trick with the blending modes
  • Have a square geometry and paint it in the shader

And… I think there were a few more things I though but the point is, which is really feasible and has an acceptable performance to use in multiple places in an android game? (obviously, talking about implementing it on JME3).

  1. idea: How to create a Radial Lifebar in Construct 2 - YouTube

Hint: use something like that

Result:

I did it on shaders. The most simple solution is to pass a value and check if it is greater or less than a color value on one map, and depending on that draw a pixel from main texture. A little more playing with formulas would give you nice smooth edge.

That idea already went out in the brainstorming session xD, but it has too much limitations. Thanks anyway :wink:

-O- I almost had it (or that I think) with Midpoint circle algorithm - Wikipedia and pixel painting. Your way, though, seems cleaner and simpler (the worst thing is that some time ago I already saw that solution and I forgot about it :sweat_smile:).

The thing now is… it is better (efficiency talking now) the shader alternative or the texture painting one?

It is waaaay much better to do it on shaders and just pass a value than paint a new texture (or repaint an existing one) every time you need to update the progress.

100% sure?. Anyway, I think I’m going with the shader one (the other is time loosing I think xD)

Yes, I’m sure. The main task of your GPU is to paint pixels while your CPU must do many other things.

I second that, painting a texture on the cpu is slow period, however the GPU is literally done for that.

DONE!!! . As easy as 4 shader line codes xD.

Thanks for your help :wink:

1 Like

Hi @NemesisMate,
Do you care to share this solution?

Of course not. You only need an image with a degraded color (ie: a grayscale alphamap) to use as threshold for showing the portion of another image or just a color. The threshold/progress is passed then every time it changes. In other words:

He gave some example images. An example shader would be:

varying vec2 texCoord;


uniform sampler2D m_ThresholdMap;
uniform float m_FallColor;

#ifdef COLORMAP
    uniform sampler2D m_ColorMap;
#else
    uniform vec4 m_Color;
#endif


void main() {
    if(m_FallColor < texture2D(m_ThresholdMap, texCoord).r) {
        #ifdef COLORMAP
            gl_FragColor = texture2D(m_ColorMap, texCoord);
        #else
            gl_FragColor = m_Color;
        #endif
    } else {
        gl_FragColor = vec4(.0, .0, .0, .0);
    }
}
3 Likes

Thanks, I will try this.