2012-07-12 41 views
4

如何在iPhone上使用openGl繪製實心圓?如何在iPhone上用OpenGL ES繪製實心圓?

我發現了很多解決方案,但都沒有工作。可能是因爲有很多方法可以做到這一點。但是最短代碼的方法是什麼?

+0

「它們都不起作用」哦?怎麼會這樣? – genpfault 2012-07-12 13:36:51

+0

聽說您找到的解決方案以及迄今爲止嘗試過的解決方案將是非常有趣的。如果它們都不起作用,我懷疑你的實現中有一些錯誤! – kroneml 2012-07-13 08:12:57

回答

16

對於一個真正的流暢型圈,你會希望有一個自定義的片段着色器。例如,下面的頂點着色器:

attribute vec4 position; 
attribute vec4 inputTextureCoordinate; 

varying vec2 textureCoordinate; 

void main() 
{ 
    gl_Position = position; 
    textureCoordinate = inputTextureCoordinate.xy; 
} 

和片段着色器:

varying highp vec2 textureCoordinate; 

const highp vec2 center = vec2(0.5, 0.5); 
const highp float radius = 0.5; 

void main() 
{ 
    highp float distanceFromCenter = distance(center, textureCoordinate); 
    lowp float checkForPresenceWithinCircle = step(distanceFromCenter, radius); 

    gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0) * checkForPresenceWithinCircle;  
} 

將吸引你畫到屏幕上一個正方形內的光滑紅色圓圈。您需要爲您的方塊提供頂點,並將position屬性的座標和X和Y範圍從0.0到1.0的座標提供給inputTextureCoordinate屬性,但這會繪製一個與您的視口分辨率允許的速度一樣銳利的圓,並且可以非常快地完成。

+0

我非常喜歡這個解決方案。 – 2012-07-12 18:38:05

+0

我也認爲這是最好的解決方案。請注意,您可以使用(三角形)廣告牌繪製正方形,也可以只繪製正確點大小的點。第二種解決方案的優點是隻需傳輸點位置和半徑(即一個「vec4」)。如果您有3D場景,您也不必擔心您的方形面向相機。 – kroneml 2012-07-13 08:10:27

+0

但是如何避免正方形的黑色部分被繪製? E.g,如果你想在屏幕上畫出幾個這樣的球體,並且它們重疊,那麼正方形的「黑色」部分將覆蓋其他球體,如下圖所示:http://imgur.com/e7Z4ugb – OMH 2014-03-13 20:50:16

2

一種方法是使用GL_POINTS:

glPointSize(radius); 
glBegin(GL_POINTS); 
glVertex2f(x,y); 
glEnd(); 

另一種方法是使用GL_TRIANGLE_FAN:

radius = 1.0; 
glBegin(GL_TRIANGLE_FAN); 
glVertex2f(x, y); 
for(int angle = 1; angle <= 360; angle = angle + 1) 
glVertex2f(x + sind(angle) * radius, y + cosd(angle) * radius); 
glEnd(); 
+0

謝謝,我得到了「隱式聲明函數glBegin在c99中無效」警告。這是什麼意思 ? – aneuryzm 2012-07-14 09:17:13

+0

我們真的需要看你的代碼,看看你錯在哪裏。 – StuGrey 2012-07-14 14:59:39

+0

Ios似乎不支持glBegin調用。記住這是ES2,他們已經消除了一些功能。似乎也沒有glEnd功能。 – 2012-12-03 20:45:12

1

爲了得到一個圓的verices:

 float[] verts=MakeCircle2d(1,100,0,0) 

    public static float[] MakeCircle2d(float rad,int points,float x,float y)//x,y ofsets 
    { 
      float[] verts=new float[points*2+2]; 
      boolean first=true; 
      float fx=0; 
      float fy=0; 
      int c=0; 
      for (int i = 0; i < points; i++) 
      { 
        float fi = 2*Trig.PI*i/points; 
        float xa = rad*Trig.sin(fi + Trig.PI)+x ; 
        float ya = rad*Trig.cos(fi + Trig.PI)+y ; 
        if(first) 
        { 
         first=false; 
         fx=xa; 
         fy=ya; 
        } 
        verts[c]=xa; 
        verts[c+1]=ya; 
        c+=2; 
      } 
      verts[c]=fx; 
      verts[c+1]=fy; 
      return verts; 
     } 

它畫成GL10.GL_LINES如果你想有一個空的圓形

gl.glDrawArrays(GL10.GL_LINES, 0, verts.length/2); 

或者,如果你想有一個填充繪製成GL10.GL_TRIANGLE_FAN一個

gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 0, verts.length/2); 

它的Java,但它是很容易轉換爲C++/objc

0

這是一個使用着色器的超快速方法...只需使用頂點緩衝區製作四邊形,並將四邊形的每個角的UV從-1設置爲1即可。

浮點數中的頂點緩衝區應如下所示: 注意:這也需要一個索引緩衝區。

var verts = new float[20] 
{ 
    -1, -1, 0, -1, -1, 
    -1, 1, 0, -1, 1, 
    1, 1, 0, 1, 1, 
    1, -1, 0, 1, -1, 
}; 


#VS 
attribute vec3 Position0; 
attribute vec2 Texcoord0; 

varying vec4 Position_VSPS; 
varying vec2 Texcoord_VSPS; 

uniform vec2 Location; 

void main() 
{ 
    vec3 loc = vec3(Position0.xy + Location, Position0.z); 
    gl_Position = Position_VSPS = vec4(loc, 1); 
    Texcoord_VSPS = loc.xy; 
} 
#END 

#PS 
varying vec4 Position_VSPS; 
varying vec2 Texcoord_VSPS; 

uniform vec2 Location; 

void main() 
{ 
    float dis = distance(Location, Texcoord_VSPS); 
    if (.1 - dis < 0.0) discard; 

    gl_FragData[0] = vec4(0, 0, 1, 1); 
} 
#END