Sacro's picture

Using IsoSphere

Hi, i'm using an isosphere VBO in my project but I can't seen to get it to render correctly, I've tried GL_TRIANGLES, GL_QUADS, GL_POLYGONS, all of those and none seem to be quite right, GL_POLYGONS does it best but it's still looking like a series of rings around a central point when you zoom in.

Anyone have any ideas?


Comments

Comment viewing options

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

Screenshots and some source code please. My guess is that you are not connecting the vertices correctly to form triangles or quads.

Sacro's picture

I'm using the Isosphere code from Source\Examples\Shapes\IsoSphere.cs

Currently rendering using GL_POLYGONS, it provides the best distance view but up close you can see it's not quite right, GL_TRIANGLES makes the sphere patchy as does GL_QUADS.

I'm using the VBO sample code too if that helps.

AttachmentSize
brokensphere.PNG10.5 KB
the Fiddler's picture

The IsoSphere class is unmaintained. I don't think it ever worked, actually.

I'm using the following code to generate skydomes. Modifying that to generate spheres is trivial:

        static VertexP3N3T2[] CalculateVertices(float radius, float height, byte segments, byte rings)
        {
            var data = new VertexP3N3T2[segments * rings];
 
            int i = 0;
 
            for (double y = 0; y < rings; y++)
            {
                double phi = (y / (rings - 1)) * Math.PI / 2;  // Remove the / 2 to generate spheres.
                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 VertexP3N3T2() { Position = v, Normal = n, TexCoord = uv };
                    i++;
                }
 
            }  
 
            return data;
        }
 
        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;
        }
Sacro's picture

Right, that's working beautifully and googling VertexP3N3T2 brought up your other post in which you provide texcoords, now to attempt to try and bind a texture to it!

Any sample code would be most helpful :)