我需要gluCylinder
的源代码及其调用的函数,以便我可以更改它们。我做了一些谷歌搜索,但我没有找到任何东西。
有人能指出我正确的方向吗?
答案 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;
}
}