Search code examples
graphicsglut

GLUT GL 3/4 sphere something wrong


I have task to do for my graphics lessons. I have to build 3/4 of using only GL_TRIANGLE_STRIP. I have already finished it, but there is one major bug that I cannot accept.

GLfloat radius = 3, alpha, beta, PI = 3.14314159;


//lHorizontal and lVertical im changing using keyboard it says how many 
 sphere divisions are 

for (alpha = 0.0; alpha < PI; alpha += PI / lVertical)
{

    glBegin(GL_TRIANGLE_STRIP);


    for (beta = 0.0; beta < 1.5075*PI; beta += PI / lHorizontal)
    {

        glColor3f(1, 1, 0);
        x = radius * cos(beta)*sin(alpha);
        y = radius * sin(beta)*sin(alpha);
        z = radius * cos(alpha);

        glNormal3f(x, y, z);
        glVertex3f(x, y, z);

        glColor3f(0, 1, 1);
        x = radius * cos(beta)*sin(alpha + PI / lVertical);
        y = radius * sin(beta)*sin(alpha + PI / lVertical);
        z = radius * cos(alpha + PI / lVertical);

        glNormal3f(x, y, z);
        glVertex3f(x, y, z);



    }
    glEnd();
}


glColor3f(1, 1, 0);
glBegin(GL_TRIANGLE_STRIP);

for (alpha = PI; alpha < 2.01*PI; alpha += PI / lVertical) {
    x = -radius * sin(alpha);
    y = 0;
    z = radius * cos(alpha);
    glNormal3f(x, y, z);
    glVertex3f(x, y, z);
    glNormal3f(0, 0, 0);
    glVertex3f(0, 0, 0);
}
glEnd();


glBegin(GL_TRIANGLE_STRIP);

for (alpha = PI; alpha < 2.01*PI; alpha += PI / lVertical) {
    x = 0;
    y = radius * sin(alpha);
    z = -radius * cos(alpha);
    glNormal3f(x, y, z);
    glVertex3f(x, y, z);
    glNormal3f(0, 0, 0);
    glVertex3f(0, 0, 0);
}
glEnd();

The result of this code is:

Correct one (pic)

As Im changing lHorizontal appear piece that shouldnt be there (look at pic). What can i change in code to avoid this problem?

Bugged one (pic)


Solution

  • The value of PI is wrong:

    ..., PI = 3.14314159; // 3.14159... ?
    

    After correcting this, let's test the values of alpha in the outer loop, for lVertical = 8:

    int lVertical = 8;
    GLfloat radius = 3, alpha, beta, PI = 3.141592654;
    
    for (alpha = 0.0; alpha < PI; alpha += PI / lVertical)
    {
        printf("%f, %f\n", alpha, alpha + PI / lVertical);
    }
    

    Output:

    0.000000, 0.392699
    0.392699, 0.785398
    0.785398, 1.178097
    1.178097, 1.570796
    1.570796, 1.963495
    1.963495, 2.356194
    2.356194, 2.748893
    2.748893, 3.141593
    3.141593, 3.534292 <<
    

    3.534292 is greater than PI, which means that it is an invalid value for alpha. The effect is that the last polygon ring "folds" around, producing the part that shouldn't be there.

    It is better to directly calculate the angles from an integer index:

    for (int i = 0; int i < lVertical; i++)
    {
        GLfloat alpha1 = (PI / lVertical) * i;
        GLfloat alpha2 = (PI / lVertical) * (i + 1);
    
        glBegin(GL_TRIANGLE_STRIP);
    
        for (int j = 0; j < lHorizontal; j++)
        {
            GLfloat beta1 = (PI / lHorizontal) * j;
            GLfloat beta2 = (PI / lHorizontal) * (j + 1);
    
            glColor3f(1, 1, 0);
            x = radius * cos(beta1)*sin(alpha1);
            y = radius * sin(beta1)*sin(alpha1);
            z = radius * cos(alpha1);
    
            glNormal3f(x, y, z);
            glVertex3f(x, y, z);
    
            glColor3f(0, 1, 1);
            x = radius * cos(beta2)*sin(alpha2);
            y = radius * sin(beta2)*sin(alpha2);
            z = radius * cos(alpha2);
    
            glNormal3f(x, y, z);
            glVertex3f(x, y, z);
        }
    
        glEnd();
    }