copenglglutglu

Where can I find source code of gluCylinder() and the functions it calls?


I need the source code of gluCylinder() and the function it calls so I can alter them.

Can anyone point me to the right direction?


Solution

  • It's right there in the mesa git tree:

    void GLAPIENTRY
    gluCylinder(GLUquadric *qobj, GLdouble baseRadius, GLdouble topRadius,
            GLdouble height, GLint slices, GLint stacks)
    {
        GLint i,j;
        GLfloat sinCache[CACHE_SIZE];
        GLfloat cosCache[CACHE_SIZE];
        GLfloat sinCache2[CACHE_SIZE];
        GLfloat cosCache2[CACHE_SIZE];
        GLfloat sinCache3[CACHE_SIZE];
        GLfloat cosCache3[CACHE_SIZE];
        GLfloat angle;
        GLfloat zLow, zHigh;
        GLfloat sintemp, costemp;
        GLfloat length;
        GLfloat deltaRadius;
        GLfloat zNormal;
        GLfloat xyNormalRatio;
        GLfloat radiusLow, radiusHigh;
        int needCache2, needCache3;
    
        if (slices >= CACHE_SIZE) slices = CACHE_SIZE-1;
    
        if (slices < 2 || stacks < 1 || baseRadius < 0.0 || topRadius < 0.0 ||
            height < 0.0) {
        gluQuadricError(qobj, GLU_INVALID_VALUE);
        return;
        }
    
        /* Compute length (needed for normal calculations) */
        deltaRadius = baseRadius - topRadius;
        length = SQRT(deltaRadius*deltaRadius + height*height);
        if (length == 0.0) {
        gluQuadricError(qobj, GLU_INVALID_VALUE);
        return;
        }
    
        /* Cache is the vertex locations cache */
        /* Cache2 is the various normals at the vertices themselves */
        /* Cache3 is the various normals for the faces */
        needCache2 = needCache3 = 0;
        if (qobj->normals == GLU_SMOOTH) {
        needCache2 = 1;
        }
    
        if (qobj->normals == GLU_FLAT) {
        if (qobj->drawStyle != GLU_POINT) {
            needCache3 = 1;
        }
        if (qobj->drawStyle == GLU_LINE) {
            needCache2 = 1;
        }
        }
    
        zNormal = deltaRadius / length;
        xyNormalRatio = height / length;
    
        for (i = 0; i < slices; i++) {
        angle = 2 * PI * i / slices;
        if (needCache2) {
            if (qobj->orientation == GLU_OUTSIDE) {
            sinCache2[i] = xyNormalRatio * SIN(angle);
            cosCache2[i] = xyNormalRatio * COS(angle);
            } else {
            sinCache2[i] = -xyNormalRatio * SIN(angle);
            cosCache2[i] = -xyNormalRatio * COS(angle);
            }
        }
        sinCache[i] = SIN(angle);
        cosCache[i] = COS(angle);
        }
    
        if (needCache3) {
        for (i = 0; i < slices; i++) {
            angle = 2 * PI * (i-0.5) / slices;
            if (qobj->orientation == GLU_OUTSIDE) {
            sinCache3[i] = xyNormalRatio * SIN(angle);
            cosCache3[i] = xyNormalRatio * COS(angle);
            } else {
            sinCache3[i] = -xyNormalRatio * SIN(angle);
            cosCache3[i] = -xyNormalRatio * COS(angle);
            }
        }
        }
    
        sinCache[slices] = sinCache[0];
        cosCache[slices] = cosCache[0];
        if (needCache2) {
        sinCache2[slices] = sinCache2[0];
        cosCache2[slices] = cosCache2[0];
        }
        if (needCache3) {
        sinCache3[slices] = sinCache3[0];
        cosCache3[slices] = cosCache3[0];
        }
    
        switch (qobj->drawStyle) {
          case GLU_FILL:
        /* Note:
        ** An argument could be made for using a TRIANGLE_FAN for the end
        ** of the cylinder of either radii is 0.0 (a cone).  However, a
        ** TRIANGLE_FAN would not work in smooth shading mode (the common
        ** case) because the normal for the apex is different for every
        ** triangle (and TRIANGLE_FAN doesn't let me respecify that normal).
        ** Now, my choice is GL_TRIANGLES, or leave the GL_QUAD_STRIP and
        ** just let the GL trivially reject one of the two triangles of the
        ** QUAD.  GL_QUAD_STRIP is probably faster, so I will leave this code
        ** alone.
        */
        for (j = 0; j < stacks; j++) {
            zLow = j * height / stacks;
            zHigh = (j + 1) * height / stacks;
            radiusLow = baseRadius - deltaRadius * ((float) j / stacks);
            radiusHigh = baseRadius - deltaRadius * ((float) (j + 1) / stacks);
    
            glBegin(GL_QUAD_STRIP);
            for (i = 0; i <= slices; i++) {
            switch(qobj->normals) {
              case GLU_FLAT:
                glNormal3f(sinCache3[i], cosCache3[i], zNormal);
                break;
              case GLU_SMOOTH:
                glNormal3f(sinCache2[i], cosCache2[i], zNormal);
                break;
              case GLU_NONE:
              default:
                break;
            }
            if (qobj->orientation == GLU_OUTSIDE) {
                if (qobj->textureCoords) {
                glTexCoord2f(1 - (float) i / slices,
                    (float) j / stacks);
                }
                glVertex3f(radiusLow * sinCache[i],
                    radiusLow * cosCache[i], zLow);
                if (qobj->textureCoords) {
                glTexCoord2f(1 - (float) i / slices,
                    (float) (j+1) / stacks);
                }
                glVertex3f(radiusHigh * sinCache[i],
                    radiusHigh * cosCache[i], zHigh);
            } else {
                if (qobj->textureCoords) {
                glTexCoord2f(1 - (float) i / slices,
                    (float) (j+1) / stacks);
                }
                glVertex3f(radiusHigh * sinCache[i],
                    radiusHigh * cosCache[i], zHigh);
                if (qobj->textureCoords) {
                glTexCoord2f(1 - (float) i / slices,
                    (float) j / stacks);
                }
                glVertex3f(radiusLow * sinCache[i],
                    radiusLow * cosCache[i], zLow);
            }
            }
            glEnd();
        }
        break;
          case GLU_POINT:
        glBegin(GL_POINTS);
        for (i = 0; i < slices; i++) {
            switch(qobj->normals) {
              case GLU_FLAT:
              case GLU_SMOOTH:
            glNormal3f(sinCache2[i], cosCache2[i], zNormal);
            break;
              case GLU_NONE:
              default:
            break;
            }
            sintemp = sinCache[i];
            costemp = cosCache[i];
            for (j = 0; j <= stacks; j++) {
            zLow = j * height / stacks;
            radiusLow = baseRadius - deltaRadius * ((float) j / stacks);
    
            if (qobj->textureCoords) {
                glTexCoord2f(1 - (float) i / slices,
                    (float) j / stacks);
            }
            glVertex3f(radiusLow * sintemp,
                radiusLow * costemp, zLow);
            }
        }
        glEnd();
        break;
          case GLU_LINE:
        for (j = 1; j < stacks; j++) {
            zLow = j * height / stacks;
            radiusLow = baseRadius - deltaRadius * ((float) j / stacks);
    
            glBegin(GL_LINE_STRIP);
            for (i = 0; i <= slices; i++) {
            switch(qobj->normals) {
              case GLU_FLAT:
                glNormal3f(sinCache3[i], cosCache3[i], zNormal);
                break;
              case GLU_SMOOTH:
                glNormal3f(sinCache2[i], cosCache2[i], zNormal);
                break;
              case GLU_NONE:
              default:
                break;
            }
            if (qobj->textureCoords) {
                glTexCoord2f(1 - (float) i / slices,
                    (float) j / stacks);
            }
            glVertex3f(radiusLow * sinCache[i],
                radiusLow * cosCache[i], zLow);
            }
            glEnd();
        }
        /* Intentionally fall through here... */
          case GLU_SILHOUETTE:
        for (j = 0; j <= stacks; j += stacks) {
            zLow = j * height / stacks;
            radiusLow = baseRadius - deltaRadius * ((float) j / stacks);
    
            glBegin(GL_LINE_STRIP);
            for (i = 0; i <= slices; i++) {
            switch(qobj->normals) {
              case GLU_FLAT:
                glNormal3f(sinCache3[i], cosCache3[i], zNormal);
                break;
              case GLU_SMOOTH:
                glNormal3f(sinCache2[i], cosCache2[i], zNormal);
                break;
              case GLU_NONE:
              default:
                break;
            }
            if (qobj->textureCoords) {
                glTexCoord2f(1 - (float) i / slices,
                    (float) j / stacks);
            }
            glVertex3f(radiusLow * sinCache[i], radiusLow * cosCache[i],
                zLow);
            }
            glEnd();
        }
        for (i = 0; i < slices; i++) {
            switch(qobj->normals) {
              case GLU_FLAT:
              case GLU_SMOOTH:
            glNormal3f(sinCache2[i], cosCache2[i], 0.0);
            break;
              case GLU_NONE:
              default:
            break;
            }
            sintemp = sinCache[i];
            costemp = cosCache[i];
            glBegin(GL_LINE_STRIP);
            for (j = 0; j <= stacks; j++) {
            zLow = j * height / stacks;
            radiusLow = baseRadius - deltaRadius * ((float) j / stacks);
    
            if (qobj->textureCoords) {
                glTexCoord2f(1 - (float) i / slices,
                    (float) j / stacks);
            }
            glVertex3f(radiusLow * sintemp,
                radiusLow * costemp, zLow);
            }
            glEnd();
        }
        break;
          default:
        break;
        }
    }