如何在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
属性,并且对于inputTextureCoordinate
属性,需要提供范围为0.0至1.0的X和Y坐标,但这样做将绘制一个尖锐度取决于视口分辨率的圆,并且速度非常快。
vec4
)。如果您有一个3D场景,您也不必担心您的正方形面向相机。 - kroneml一种方法是使用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();
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