2010-11-29 67 views
11

我正在尋找一種方式來繪製類似這些「旋鈕」的東西與GLSL着色器繪製一個圓openGL的GLSL着色器:在平坦的多邊形

alt text

我只想繪製彩色圈子,我的應用程序不是一個旋鈕而是一個​​時髦的進度計。只需使用着色器就可以在平面多邊形上繪製圓(或更具體爲圓弧)?那麼如何開始這個過程呢?

回答

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

+0

並非所有的最優雅的方式,我會說)你介紹一個分支( ?:)每圈,這當然可以避免。另外,可以延長一些平滑。 (仍然,+1) – Kos 2010-12-01 16:47:01

11

是的,這是可能的。 將紋理座標設置爲多邊形,以便可以訪問着色器中的相對座標(例如,從-1,-1到1,1使多邊形的中心爲0,0)。在片段着色器中用pythagoran計算到中心的距離。如果距離小於圓的半徑,則像素在圓內。然後,可以爲兩個圓圈指定半徑,並在像素位於外部圓圈內部和內部圓圈外部時對像素着色。

如果你只想着色一個弧,用atan(y,x)得到角度並檢查它是否在給定範圍內。

如果確定點是否在圓內,也可以使用插值(步,平滑步等)代替簡單圓來平滑圓。

同樣作爲優化,當計算到中心的距離時,如果您改爲檢查半徑^ 2,則不需要計算平方根。