Circular Loading Bar


#1

Hi, I want to create a 2d circular loading bar. I’ve tried with a LineSegs that draw lines in a circular way, and it do the job, but not perfectly if I have to say it.

I use this function like argument of a LerpFunc (step 0 to self._BAR_STEPS)

def _update_loading_bar(self, step):
    
        a = angleRadians * step / self._BAR_STEPS
        
        y = math.sin(a)
        x = math.cos(a)
        pos = (x, 0, y)
        self._line_seg.drawTo(pos)
        
        node = self._line_seg.create()   
#         if self._bar_node_path != None:
#             self._bar_node_path.removeNode()
        self._bar_node_path = render2d.attachNewNode(node)
        self._bar_node_path.reparent_to(self._time_label)
        self._bar_node_path.setScale(0.4)

The result have jagged edges even with self._BAR_STEPS very high. Is there a better way to achieve something like this? Thanks in advance.


#2

One problem that jumps out is that if you don’t call _update_loading_bar for every step, a line segment may jump a few steps forward. So, you’d have to create a line segment for every intermediate step since the last one.

One other idea that comes to mind:
You could create an image of a circle, and then cut out a few degrees of it. Then, you can replicate that image except rotate it 5 degrees around the centre every step.


#3

How about using shaders? That will be a lot faster then creating a lot of images :stuck_out_tongue:

You can also do stuff like this with this:

Code:


from panda3d.core import *

import direct.directbase.DirectStart


cm = CardMaker("c")
cm.setFrame(-100, 100, -100, 100)
cn = pixel2d.attachNewNode(cm.generate())
cn.setPos(500, 0, -400)

vertex = """
#version 150
uniform mat4 p3d_ModelViewProjectionMatrix;
uniform mat4 trans_model_to_world;
in vec4 p3d_Vertex;
in vec2 p3d_MultiTexCoord0;
out vec2 texcoord;
void main() {
    gl_Position = p3d_ModelViewProjectionMatrix * p3d_Vertex;
    texcoord = (p3d_Vertex).xz;
}
"""

fragment = """
#version 150
out vec4 color;
in vec2 texcoord;
uniform float radiusStart;
uniform float radiusEnd;
uniform vec3 circleColor;
uniform float progress;

const float PI = 3.14159265359;
void main() {
    float radius = distance(texcoord, vec2(0));
    color = vec4(0);
    if (radius > radiusStart && radius < radiusEnd) {
        float angle = atan(texcoord.x, texcoord.y) / (2.0*PI);
        if (angle < 0.0) angle = 1.0 + angle;
        if (angle < progress) {
            // Uncomment this to get a gradient
            //color = vec4(angle*circleColor, 1);    
            color = vec4(circleColor, 1);    
        }
    }
}
"""

cn.setShader(Shader.make(Shader.SLGLSL, vertex, fragment))
cn.setShaderInput("radiusStart", 50.0)
cn.setShaderInput("radiusEnd", 70.0)
cn.setShaderInput("circleColor", Vec3(0.2, 0.6, 1.0))
cn.setShaderInput("progress", 0.7)
cn.setTransparency(True)

base.run()

#4

This seems a pretty good idea! I’m not familiar with shaders in Panda3d so I don’t know all the achievable things with it.
I’ve tried the code you share and I’m wondering: what if I have to change the “progress” parameter of the shader with a LerpFunc?

[EDIT] It works with a LerpFunc. Thanks a lot for the help!


#5

Hi again! I have some trouble running this shader on a ubuntu 14.04. In the first place it gave this error:

:display:gsg:glgsg(error): An error occurred while compiling shader created-shader
0:4(19): error: `in' qualifier in declaration of `p3d_Vertex' only valid for function parameters in GLSL 1.10
0:5(27): error: `in' qualifier in declaration of `p3d_MultiTexCoord0' only valid for function parameters in GLSL 1.10
0:6(18): error: `out' qualifier in declaration of `texcoord' only valid for function parameters in GLSL 1.10

:display:gsg:glgsg(error): An error occurred while compiling shader created-shader
0:2(15): error: `out' qualifier in declaration of `color' only valid for function parameters in GLSL 1.10
0:3(17): error: `in' qualifier in declaration of `texcoord' only valid for function parameters in GLSL 1.10

After installing 3.0 Mesa 9.0.3 on the system it gave:

:display:gsg:glgsg(error): An error occurred while compiling shader created-shader
0:4(19): error: `in' qualifier in declaration of `p3d_Vertex' only valid for function parameters in (null).
0:5(27): error: `in' qualifier in declaration of `p3d_MultiTexCoord0' only valid for function parameters in (null).
0:6(18): error: `out' qualifier in declaration of `texcoord' only valid for function parameters in (null).

It looks like there are some thing deprecated or not compatible with GLSL current version…any ideas?


#6

For some reason it’s compiling it as GLSL 1.10. Are you sure you have at least #version 130 on top, maybe more? Perhaps you have outdated drivers?