How do I draw a filled circle with OpenGL ES on iPhone?

后端 未结 4 1822
春和景丽
春和景丽 2020-12-14 13:49

How do I draw a filled circle with openGl on iPhone ?

I\'ve found many solutions but none of them work. Probably because there are many ways to do it. But what\'s th

相关标签:
4条回答
  • 2020-12-14 13:53

    For a truly smooth circle, you're going to want a custom fragment shader. For example, the following vertex shader:

     attribute vec4 position;
     attribute vec4 inputTextureCoordinate;
    
     varying vec2 textureCoordinate;
    
     void main()
     {
        gl_Position = position;
        textureCoordinate = inputTextureCoordinate.xy;
     }
    

    and fragment shader:

     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;     
     }
    

    will draw a smooth red circle within a square that you draw to the screen. You'll need to supply vertices for your square to the position attribute and coordinates that range from 0.0 to 1.0 in X and Y to the inputTextureCoordinate attribute, but this will draw a circle that's as sharp as your viewport's resolution allows and do so very quickly.

    0 讨论(0)
  • 2020-12-14 13:54

    To get the verices of a circle:

         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;
          }
    

    Draw it as GL10.GL_LINES if you want a empty circle

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

    Or draw it as GL10.GL_TRIANGLE_FAN if you want a filled one

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

    Its java but it is really easy to convert to c++/objc

    0 讨论(0)
  • 2020-12-14 14:04

    One way would be to use GL_POINTS:

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

    Another alternative would be to use 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 讨论(0)
  • 2020-12-14 14:15

    Here is a super fast way using shaders... Just make a Quad with a vertex buffer and set the UV's from -1 to 1 for each corner of the quad.

    The vertex buffer in floats should look like: NOTE: this needs a index buffer too.

    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
    
    0 讨论(0)
提交回复
热议问题