ostenlund's picture

How to draw a sphere?

Hi,

I'd like to know if it's possible to draw a sphere with OpenTK.

Olli


Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
the Fiddler's picture

It is.

Check this and the comments below.

ostenlund's picture

I'd like to know also how it can be done? I didn't find any sphere class or function.

ostenlund's picture

Oh, there was a link. I'll check that.

TheNerd's picture

Hey Ostenlund,

I have the following code from Fiddler himself to create a sphere. The first two methods will grant you an index array and a vertex array, respectively.

 public static Vertex[] CalculateVertices2(float radius, float height, byte segments, byte rings)
        {
            var data = new Vertex[segments * rings];
 
            int i = 0;
 
            for (double y = 0; y < rings; y++)
            {
                double phi = (y / (rings - 1)) * Math.PI; //was /2 
                for (double x = 0; x < segments; x++)
                {
                    double theta = (x / (segments - 1)) * 2 * Math.PI;
 
                    Vector3 v = new Vector3()
                    {
                        X = (float)(radius * Math.Sin(phi) * Math.Cos(theta)),
                        Y = (float)(height * Math.Cos(phi)),
                        Z = (float)(radius * Math.Sin(phi) * Math.Sin(theta)),
                    };
                    Vector3 n = Vector3.Normalize(v);
                    Vector2 uv = new Vector2()
                    {
                        X = (float)(x / (segments - 1)),
                        Y = (float)(y / (rings - 1))
                    };
                    // Using data[i++] causes i to be incremented multiple times in Mono 2.2 (bug #479506).
                    data[i] = new Vertex() { Position = v, Normal = n, TexCoord = uv };
                    i++;
                }
 
            }
 
            return data;
        }
 
        public static ushort[] CalculateElements(float radius, float height, byte segments, byte rings)
        {
            var num_vertices = segments * rings;
            var data = new ushort[num_vertices * 6];
 
            ushort i = 0;
 
            for (byte y = 0; y < rings - 1; y++)
            {
                for (byte x = 0; x < segments - 1; x++)
                {
                    data[i++] = (ushort)((y + 0) * segments + x);
                    data[i++] = (ushort)((y + 1) * segments + x);
                    data[i++] = (ushort)((y + 1) * segments + x + 1);
 
                    data[i++] = (ushort)((y + 1) * segments + x + 1);
                    data[i++] = (ushort)((y + 0) * segments + x + 1);
                    data[i++] = (ushort)((y + 0) * segments + x);
                }
            }
 
            // Verify that we don't access any vertices out of bounds:
            foreach (int index in data)
                if (index >= segments * rings)
                    throw new IndexOutOfRangeException();
 
            return data;
        }
 
 
  public struct Vertex
    { // mimic InterleavedArrayFormat.T2fN3fV3f
        public Vector2 TexCoord;
        public Vector3 Normal;
        public Vector3 Position;
    }
 
 
protected override void OnRenderFrame(OpenTK.FrameEventArgs e)
        {
            base.OnRenderFrame(e);
 
            Vertex[] SphereVertices = Shape.CalculateVertices2(0.5f, 0.5f, 100, 100);
           ushort[] SphereElements = Shape.CalculateElements(0.5f, 0.5f, 100, 100);
 
            GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
 
 
            GL.MatrixMode(MatrixMode.Modelview);
 
            GL.LoadMatrix(ref modelview);
 
           GL.Begin(BeginMode.Triangles);
            foreach (var element in SphereElements)
            {
                GL.Color4(1.5f, 0.0f, 1.0f, 0.50f);
                var vertex = SphereVertices[element];
                GL.TexCoord2(vertex.TexCoord);
                GL.Normal3(vertex.Normal);
                GL.Vertex3(vertex.Position);
            }
 
            GL.End();
 
              SwapBuffers();
}

Hope this helps!

-TheNerd

ostenlund's picture

Thx, it works.

Does anyone know how to draw a cylinder?

Olli

ostenlund's picture

I found the answer how to draw a cylinder!

Change your phi to this:

double phi = (y / (rings - 1));

And X, Y and Z to this:

X = (float)(radius * Math.Cos(theta)),
Y = (float)(height * phi)
Z = (float)(radius * Math.Sin(theta)),

Olli

migueltk's picture

Hi, ...

This you'll like ... GLShadingSubdivideSphere
I added the source code. This works on CsGL, just port it to OpenTK.

Regards, ...

AttachmentSize
GL_shading_subdivide.7z99.9 KB
knji's picture

Guys, I tried above code and get a blank window. What is the line of code to create modelView in OnRenderFrame?

Matrix4 modelview = Matrix4.LookAt(Vector3.Zero, Vector3.UnitZ, Vector3.UnitY);

Does not work for me.

Thanks.

VASUDEVAN's picture

When i ran the above code
it gives

system.windows.shapes.shape does not contain a definition for calculate vertices 2
Anyone help me?