如何在 iPhone 上用 openGl 画一个实心圆圈?
我找到了很多解决方案,但没有一个有效。可能是因为有很多方法可以做到这一点。但是最短代码的方法是什么?
对于一个真正平滑的圆圈,您将需要一个自定义片段着色器。例如,以下顶点着色器:
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 中为inputTextureCoordinate
属性提供范围从 0.0 到 1.0 的坐标,但这将绘制一个与视口分辨率允许的一样锐利的圆,并且执行速度非常快。
一种方法是使用 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();
要获得圆的verces:
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
这是使用着色器的超快速方法...只需使用顶点缓冲区制作一个四边形,并为四边形的每个角设置 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