我在哪里可以找到GluCylinder的源代码及其调用的函数

时间:2012-10-31 18:00:12

标签: opengl glut

我需要gluCylinder的源代码及其调用的函数,以便我可以更改它们。我做了一些谷歌搜索,但我没有找到任何东西。

有人能指出我正确的方向吗?

1 个答案:

答案 0 :(得分:6)

它就在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;
    }
}