Search code examples
c++openglshapesnormals

Algorithm to draw a sphere using quadrilaterals


I am attempting to draw a sphere from scratch using OpenGL. The function must be defined as void drawSphere(float radius, int nSegments, int nSlices), must be centred at the (0, 0, 0) origin and must be created using GL_QUADS.

Firstly, are the "slices" the sort of tapered cylinder shapes that are stacked on top of each other to create the sphere, and the "segments" are the quads that are generated in a circle to generate the wall/side of each of these tapered cylinder slices?

Secondly, I cannot seem to find any algorithms or examples of how to make the calculations to generate this sphere using quadrilaterals - most example seem to be generated from triangles instead.

EDIT

Here is what I have just tried, which is definitely in the right direction, but my coordinate calculations are off somewhere:

void drawSphere(float radius, int nSegments, int nSlices) {
  /*
   * TODO
   * Draw sphere centered at the origin using GL_QUADS
   * Compute and set normal vectors for each vertex to ensure proper shading
   * Set texture coordinates
   */

  for (float slice = 0.0; slice < nSlices; slice += 1.0) {
        float lat0 = M_PI * (((slice - 1) / nSlices) - 0.5);
        float z0 = sin(lat0);
        float zr0 = cos(lat0);

        float lat1 = M_PI * ((slice / nSlices) - 0.5);
        float z1 = sin(lat1);
        float zr1 = cos(lat1);

        glBegin(GL_QUADS);

        for (float segment = 0.0; segment < nSegments; segment += 1.0) {
            float long0 = 2 * M_PI * ((segment -1 ) / nSegments);
            float x0 = cos(long0);
            float y0 = sin(long0);

            float long1 = 2 * M_PI * (segment / nSegments);
            float x1 = cos(long1);
            float y1 = sin(long1);

            glVertex3f(x0 * zr0, y0 * zr0, z0);
            glVertex3f(x1 * zr1, y1 * zr1, z0);
            glVertex3f(x0 * zr0, y0 * zr0, z1);
            glVertex3f(x1 * zr1, y1 * zr1, z1);
        }

        glEnd();
    }
}

Solution

  • I'm not seeing radius being used. Probably a simple omission. Let's assume that for the rest of your computation the radius is 1. You should generate your 4 values by using 0-1 on both (x, y), and (z, zr), but not mix within those tuples.

    So x1 * zr1, y1 * zr1, z0 is not right because you're mixing zr1 and z0. You can see that the norm of this vector is not 1 anymore. Your 4 values should be

    x0 * zr0, y0 * zr0, z0
    x1 * zr0, y1 * zr0, z0
    x0 * zr1, y0 * zr1, z1
    x1 * zr1, y1 * zr1, z1
    

    I'm not too sure about the order since I don't use Quads but triangles.