void RenderSphere(float cx, float cy, float cz, float r, int p)
{
GL.PushAttrib(AttribMask.AllAttribBits);
GL.Disable(EnableCap.Fog);
GL.Disable(EnableCap.Texture2D);
GL.Disable(EnableCap.Dither);
GL.Disable(EnableCap.Lighting);
GL.Disable(EnableCap.LineStipple);
GL.Disable(EnableCap.PolygonStipple);
GL.Disable(EnableCap.CullFace);
GL.Disable(EnableCap.Blend);
GL.Disable(EnableCap.AlphaTest);
GL.Disable(EnableCap.DepthTest);
const float TWOPI = 6.28318530717958f;
const float PIDIV2 = 1.57079632679489f;
float theta1 = 0.0f;
float theta2 = 0.0f;
float theta3 = 0.0f;
float ex = 0.0f;
float ey = 0.0f;
float ez = 0.0f;
float px = 0.0f;
float py = 0.0f;
float pz = 0.0f;
// Disallow a negative number for radius.
if (r < 0)
r = -r;
// Disallow a negative number for precision.
if (p < 0)
p = -p;
// If the sphere is too small, just render a OpenGL point instead.
if (p < 4 || r <= 0)
{
GL.Begin(PrimitiveType.Points);
GL.Vertex3(cx, cy, cz);
GL.End();
return;
}
for (int i = 0; i < p / 2; ++i)
{
theta1 = i * TWOPI / p - PIDIV2;
theta2 = (i + 1) * TWOPI / p - PIDIV2;
GL.Begin(PrimitiveType.TriangleStrip);
{
for (int j = 0; j <= p; ++j)
{
theta3 = j * TWOPI / p;
ex = (float)(Math.Cos(theta2) * Math.Cos(theta3));
ey = (float)Math.Sin(theta2);
ez = (float)(Math.Cos(theta2) * Math.Sin(theta3));
px = cx + r * ex;
py = cy + r * ey;
pz = cz + r * ez;
GL.Normal3(ex, ey, ez);
GL.TexCoord2(-(j / (float)p), 2 * (i + 1) / (float)p);
GL.Vertex3(px, py, pz);
ex = (float)(Math.Cos(theta1) * Math.Cos(theta3));
ey = (float)Math.Sin(theta1);
ez = (float)(Math.Cos(theta1) * Math.Sin(theta3));
px = cx + r * ex;
py = cy + r * ey;
pz = cz + r * ez;
GL.Normal3(ex, ey, ez);
GL.TexCoord2(-(j / (float)p), 2 * i / (float)p);
GL.Vertex3(px, py, pz);
}
}
GL.End();
}
GL.PopAttrib();
}