openGL GLSL着色器:在平面多边形上绘制一个圆

时间:2010-11-29 04:54:22

标签: opengl glsl shader

我正在寻找一种方法,用GLSL着色器绘制类似于这些“旋钮”的东西

alt text

我只想绘制彩色圆圈,我的应用程序不是用于旋钮而是一个​​时髦的进度表。是否可以通过使用着色器在平面多边形上绘制圆(或更具体的弧)?一个人如何开始这个过程?

2 个答案:

答案 0 :(得分:11)

是的,有可能。 将纹理坐标设置为多边形,以便可以访问着色器中的相对坐标(例如,从-1,-1到1,1使多边形的中心为0,0)。在片段着色器中使用毕达哥拉计算到中心的距离。如果距离小于圆的半径,则像素在圆内。然后,您可以指定两个圆的半径,如果像素位于外圆内,则位于内圆外。

如果您想仅为圆弧着色,请使用atan(y,x)获取角度,并检查它是否在给定范围内。

如果确定点是否在圆圈内,您还可以使用插值(步,平滑步等)而不是简单来平滑圆。

同样作为优化,如果您反对检查半径^ 2,则在计算到中心的距离时不需要计算平方根。

答案 1 :(得分:8)

是的,这是可能的!检查这个绘制几个不同弧的GLSL脚本:


#define between(v,x1,x2) (v>= x1 && v<=x2)
#define pi 3.141592653589793238462643383279

uniform sampler2D tex;

void main()
{
    vec2  pnt = vec2(0.5,0.5);
    float dr = 0.005;
    float fr = 0.15;
    float r1 = fr;
    float r2 = 1.5*fr;
    float r3 = 2.0*fr;
    float r4 = 2.5*fr;
    float r5 = 3.0*fr;
    float rp = distance(pnt,gl_TexCoord[0].xy);
    vec4 col1 = vec4(0.4,0.1,0.,1.);
    vec4 col2 = vec4(1.,1.,1.,1.);
    float angle = atan(gl_TexCoord[0].y,gl_TexCoord[0].x);
    vec4 rezcol;
    rezcol = (between(rp,r1-dr,r1+dr) && between(angle,-pi,pi))? col1:col2;
    rezcol = (between(rp,r2-dr,r2+dr) && between(angle,-pi,pi/3.1) && rezcol==col2)? col1:rezcol;
    rezcol = (between(rp,r3-dr,r3+dr) && between(angle,-pi,pi/4.6) && rezcol==col2)? col1:rezcol;
    rezcol = (between(rp,r4-dr,r4+dr) && between(angle,-pi,pi/8.8) && rezcol==col2)? col1:rezcol;
    rezcol = (between(rp,r5-dr,r5+dr) && between(angle,-pi,pi/22.8) && rezcol==col2)? col1:rezcol;
    gl_FragColor = rezcol;
}

导致这样的图像:

alt text