~ubuntu-branches/ubuntu/quantal/mesa-glw/quantal

« back to all changes in this revision

Viewing changes to src/glu/sgi/libutil/quad.c

  • Committer: Bazaar Package Importer
  • Author(s): Morten Kjeldgaard
  • Date: 2008-05-06 16:19:15 UTC
  • Revision ID: james.westby@ubuntu.com-20080506161915-uynz7nftmfixu6bq
Tags: upstream-7.0.3
ImportĀ upstreamĀ versionĀ 7.0.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
** License Applicability. Except to the extent portions of this file are
 
3
** made subject to an alternative license as permitted in the SGI Free
 
4
** Software License B, Version 1.1 (the "License"), the contents of this
 
5
** file are subject only to the provisions of the License. You may not use
 
6
** this file except in compliance with the License. You may obtain a copy
 
7
** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
 
8
** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
 
9
**
 
10
** http://oss.sgi.com/projects/FreeB
 
11
**
 
12
** Note that, as provided in the License, the Software is distributed on an
 
13
** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
 
14
** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
 
15
** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
 
16
** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
 
17
**
 
18
** Original Code. The Original Code is: OpenGL Sample Implementation,
 
19
** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
 
20
** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
 
21
** Copyright in any portions created by third parties is as indicated
 
22
** elsewhere herein. All Rights Reserved.
 
23
**
 
24
** Additional Notice Provisions: The application programming interfaces
 
25
** established by SGI in conjunction with the Original Code are The
 
26
** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
 
27
** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
 
28
** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
 
29
** Window System(R) (Version 1.3), released October 19, 1998. This software
 
30
** was created using the OpenGL(R) version 1.2.1 Sample Implementation
 
31
** published by SGI, but has not been independently verified as being
 
32
** compliant with the OpenGL(R) version 1.2.1 Specification.
 
33
**
 
34
*/
 
35
 
 
36
#include "gluos.h"
 
37
#include "gluint.h"
 
38
#include <stdio.h>
 
39
#include <stdlib.h>
 
40
#include <math.h>
 
41
#include <GL/gl.h>
 
42
#include <GL/glu.h>
 
43
 
 
44
/* Make it not a power of two to avoid cache thrashing on the chip */
 
45
#define CACHE_SIZE      240
 
46
 
 
47
#undef  PI
 
48
#define PI            3.14159265358979323846
 
49
 
 
50
struct GLUquadric {
 
51
    GLint       normals;
 
52
    GLboolean   textureCoords;
 
53
    GLint       orientation;
 
54
    GLint       drawStyle;
 
55
    void        (GLAPIENTRY *errorCallback)( GLint );
 
56
};
 
57
 
 
58
GLUquadric * GLAPIENTRY
 
59
gluNewQuadric(void)
 
60
{
 
61
    GLUquadric *newstate;
 
62
 
 
63
    newstate = (GLUquadric *) malloc(sizeof(GLUquadric));
 
64
    if (newstate == NULL) {
 
65
        /* Can't report an error at this point... */
 
66
        return NULL;
 
67
    }
 
68
    newstate->normals = GLU_SMOOTH;
 
69
    newstate->textureCoords = GL_FALSE;
 
70
    newstate->orientation = GLU_OUTSIDE;
 
71
    newstate->drawStyle = GLU_FILL;
 
72
    newstate->errorCallback = NULL;
 
73
    return newstate;
 
74
}
 
75
 
 
76
 
 
77
void GLAPIENTRY
 
78
gluDeleteQuadric(GLUquadric *state)
 
79
{
 
80
    free(state);
 
81
}
 
82
 
 
83
static void gluQuadricError(GLUquadric *qobj, GLenum which)
 
84
{
 
85
    if (qobj->errorCallback) {
 
86
        qobj->errorCallback(which);
 
87
    }
 
88
}
 
89
 
 
90
void GLAPIENTRY
 
91
gluQuadricCallback(GLUquadric *qobj, GLenum which, _GLUfuncptr fn)
 
92
{
 
93
    switch (which) {
 
94
      case GLU_ERROR:
 
95
        qobj->errorCallback = (void (GLAPIENTRY *)(GLint)) fn;
 
96
        break;
 
97
      default:
 
98
        gluQuadricError(qobj, GLU_INVALID_ENUM);
 
99
        return;
 
100
    }
 
101
}
 
102
 
 
103
void GLAPIENTRY
 
104
gluQuadricNormals(GLUquadric *qobj, GLenum normals)
 
105
{
 
106
    switch (normals) {
 
107
      case GLU_SMOOTH:
 
108
      case GLU_FLAT:
 
109
      case GLU_NONE:
 
110
        break;
 
111
      default:
 
112
        gluQuadricError(qobj, GLU_INVALID_ENUM);
 
113
        return;
 
114
    }
 
115
    qobj->normals = normals;
 
116
}
 
117
 
 
118
void GLAPIENTRY
 
119
gluQuadricTexture(GLUquadric *qobj, GLboolean textureCoords)
 
120
{
 
121
    qobj->textureCoords = textureCoords;
 
122
}
 
123
 
 
124
void GLAPIENTRY
 
125
gluQuadricOrientation(GLUquadric *qobj, GLenum orientation)
 
126
{
 
127
    switch(orientation) {
 
128
      case GLU_OUTSIDE:
 
129
      case GLU_INSIDE:
 
130
        break;
 
131
      default:
 
132
        gluQuadricError(qobj, GLU_INVALID_ENUM);
 
133
        return;
 
134
    }
 
135
    qobj->orientation = orientation;
 
136
}
 
137
 
 
138
void GLAPIENTRY
 
139
gluQuadricDrawStyle(GLUquadric *qobj, GLenum drawStyle)
 
140
{
 
141
    switch(drawStyle) {
 
142
      case GLU_POINT:
 
143
      case GLU_LINE:
 
144
      case GLU_FILL:
 
145
      case GLU_SILHOUETTE:
 
146
        break;
 
147
      default:
 
148
        gluQuadricError(qobj, GLU_INVALID_ENUM);
 
149
        return;
 
150
    }
 
151
    qobj->drawStyle = drawStyle;
 
152
}
 
153
 
 
154
void GLAPIENTRY
 
155
gluCylinder(GLUquadric *qobj, GLdouble baseRadius, GLdouble topRadius,
 
156
                GLdouble height, GLint slices, GLint stacks)
 
157
{
 
158
    GLint i,j;
 
159
    GLfloat sinCache[CACHE_SIZE];
 
160
    GLfloat cosCache[CACHE_SIZE];
 
161
    GLfloat sinCache2[CACHE_SIZE];
 
162
    GLfloat cosCache2[CACHE_SIZE];
 
163
    GLfloat sinCache3[CACHE_SIZE];
 
164
    GLfloat cosCache3[CACHE_SIZE];
 
165
    GLfloat angle;
 
166
    GLfloat zLow, zHigh;
 
167
    GLfloat sintemp, costemp;
 
168
    GLfloat length;
 
169
    GLfloat deltaRadius;
 
170
    GLfloat zNormal;
 
171
    GLfloat xyNormalRatio;
 
172
    GLfloat radiusLow, radiusHigh;
 
173
    int needCache2, needCache3;
 
174
 
 
175
    if (slices >= CACHE_SIZE) slices = CACHE_SIZE-1;
 
176
 
 
177
    if (slices < 2 || stacks < 1 || baseRadius < 0.0 || topRadius < 0.0 ||
 
178
            height < 0.0) {
 
179
        gluQuadricError(qobj, GLU_INVALID_VALUE);
 
180
        return;
 
181
    }
 
182
 
 
183
    /* Compute length (needed for normal calculations) */
 
184
    deltaRadius = baseRadius - topRadius;
 
185
    length = SQRT(deltaRadius*deltaRadius + height*height);
 
186
    if (length == 0.0) {
 
187
        gluQuadricError(qobj, GLU_INVALID_VALUE);
 
188
        return;
 
189
    }
 
190
 
 
191
    /* Cache is the vertex locations cache */
 
192
    /* Cache2 is the various normals at the vertices themselves */
 
193
    /* Cache3 is the various normals for the faces */
 
194
    needCache2 = needCache3 = 0;
 
195
    if (qobj->normals == GLU_SMOOTH) {
 
196
        needCache2 = 1;
 
197
    }
 
198
 
 
199
    if (qobj->normals == GLU_FLAT) {
 
200
        if (qobj->drawStyle != GLU_POINT) {
 
201
            needCache3 = 1;
 
202
        }
 
203
        if (qobj->drawStyle == GLU_LINE) {
 
204
            needCache2 = 1;
 
205
        }
 
206
    }
 
207
 
 
208
    zNormal = deltaRadius / length;
 
209
    xyNormalRatio = height / length;
 
210
 
 
211
    for (i = 0; i < slices; i++) {
 
212
        angle = 2 * PI * i / slices;
 
213
        if (needCache2) {
 
214
            if (qobj->orientation == GLU_OUTSIDE) {
 
215
                sinCache2[i] = xyNormalRatio * SIN(angle);
 
216
                cosCache2[i] = xyNormalRatio * COS(angle);
 
217
            } else {
 
218
                sinCache2[i] = -xyNormalRatio * SIN(angle);
 
219
                cosCache2[i] = -xyNormalRatio * COS(angle);
 
220
            }
 
221
        }
 
222
        sinCache[i] = SIN(angle);
 
223
        cosCache[i] = COS(angle);
 
224
    }
 
225
 
 
226
    if (needCache3) {
 
227
        for (i = 0; i < slices; i++) {
 
228
            angle = 2 * PI * (i-0.5) / slices;
 
229
            if (qobj->orientation == GLU_OUTSIDE) {
 
230
                sinCache3[i] = xyNormalRatio * SIN(angle);
 
231
                cosCache3[i] = xyNormalRatio * COS(angle);
 
232
            } else {
 
233
                sinCache3[i] = -xyNormalRatio * SIN(angle);
 
234
                cosCache3[i] = -xyNormalRatio * COS(angle);
 
235
            }
 
236
        }
 
237
    }
 
238
 
 
239
    sinCache[slices] = sinCache[0];
 
240
    cosCache[slices] = cosCache[0];
 
241
    if (needCache2) {
 
242
        sinCache2[slices] = sinCache2[0];
 
243
        cosCache2[slices] = cosCache2[0];
 
244
    }
 
245
    if (needCache3) {
 
246
        sinCache3[slices] = sinCache3[0];
 
247
        cosCache3[slices] = cosCache3[0];
 
248
    }
 
249
 
 
250
    switch (qobj->drawStyle) {
 
251
      case GLU_FILL:
 
252
        /* Note:
 
253
        ** An argument could be made for using a TRIANGLE_FAN for the end
 
254
        ** of the cylinder of either radii is 0.0 (a cone).  However, a
 
255
        ** TRIANGLE_FAN would not work in smooth shading mode (the common
 
256
        ** case) because the normal for the apex is different for every
 
257
        ** triangle (and TRIANGLE_FAN doesn't let me respecify that normal).
 
258
        ** Now, my choice is GL_TRIANGLES, or leave the GL_QUAD_STRIP and
 
259
        ** just let the GL trivially reject one of the two triangles of the
 
260
        ** QUAD.  GL_QUAD_STRIP is probably faster, so I will leave this code
 
261
        ** alone.
 
262
        */
 
263
        for (j = 0; j < stacks; j++) {
 
264
            zLow = j * height / stacks;
 
265
            zHigh = (j + 1) * height / stacks;
 
266
            radiusLow = baseRadius - deltaRadius * ((float) j / stacks);
 
267
            radiusHigh = baseRadius - deltaRadius * ((float) (j + 1) / stacks);
 
268
 
 
269
            glBegin(GL_QUAD_STRIP);
 
270
            for (i = 0; i <= slices; i++) {
 
271
                switch(qobj->normals) {
 
272
                  case GLU_FLAT:
 
273
                    glNormal3f(sinCache3[i], cosCache3[i], zNormal);
 
274
                    break;
 
275
                  case GLU_SMOOTH:
 
276
                    glNormal3f(sinCache2[i], cosCache2[i], zNormal);
 
277
                    break;
 
278
                  case GLU_NONE:
 
279
                  default:
 
280
                    break;
 
281
                }
 
282
                if (qobj->orientation == GLU_OUTSIDE) {
 
283
                    if (qobj->textureCoords) {
 
284
                        glTexCoord2f(1 - (float) i / slices,
 
285
                                (float) j / stacks);
 
286
                    }
 
287
                    glVertex3f(radiusLow * sinCache[i],
 
288
                            radiusLow * cosCache[i], zLow);
 
289
                    if (qobj->textureCoords) {
 
290
                        glTexCoord2f(1 - (float) i / slices,
 
291
                                (float) (j+1) / stacks);
 
292
                    }
 
293
                    glVertex3f(radiusHigh * sinCache[i],
 
294
                            radiusHigh * cosCache[i], zHigh);
 
295
                } else {
 
296
                    if (qobj->textureCoords) {
 
297
                        glTexCoord2f(1 - (float) i / slices,
 
298
                                (float) (j+1) / stacks);
 
299
                    }
 
300
                    glVertex3f(radiusHigh * sinCache[i],
 
301
                            radiusHigh * cosCache[i], zHigh);
 
302
                    if (qobj->textureCoords) {
 
303
                        glTexCoord2f(1 - (float) i / slices,
 
304
                                (float) j / stacks);
 
305
                    }
 
306
                    glVertex3f(radiusLow * sinCache[i],
 
307
                            radiusLow * cosCache[i], zLow);
 
308
                }
 
309
            }
 
310
            glEnd();
 
311
        }
 
312
        break;
 
313
      case GLU_POINT:
 
314
        glBegin(GL_POINTS);
 
315
        for (i = 0; i < slices; i++) {
 
316
            switch(qobj->normals) {
 
317
              case GLU_FLAT:
 
318
              case GLU_SMOOTH:
 
319
                glNormal3f(sinCache2[i], cosCache2[i], zNormal);
 
320
                break;
 
321
              case GLU_NONE:
 
322
              default:
 
323
                break;
 
324
            }
 
325
            sintemp = sinCache[i];
 
326
            costemp = cosCache[i];
 
327
            for (j = 0; j <= stacks; j++) {
 
328
                zLow = j * height / stacks;
 
329
                radiusLow = baseRadius - deltaRadius * ((float) j / stacks);
 
330
 
 
331
                if (qobj->textureCoords) {
 
332
                    glTexCoord2f(1 - (float) i / slices,
 
333
                            (float) j / stacks);
 
334
                }
 
335
                glVertex3f(radiusLow * sintemp,
 
336
                        radiusLow * costemp, zLow);
 
337
            }
 
338
        }
 
339
        glEnd();
 
340
        break;
 
341
      case GLU_LINE:
 
342
        for (j = 1; j < stacks; j++) {
 
343
            zLow = j * height / stacks;
 
344
            radiusLow = baseRadius - deltaRadius * ((float) j / stacks);
 
345
 
 
346
            glBegin(GL_LINE_STRIP);
 
347
            for (i = 0; i <= slices; i++) {
 
348
                switch(qobj->normals) {
 
349
                  case GLU_FLAT:
 
350
                    glNormal3f(sinCache3[i], cosCache3[i], zNormal);
 
351
                    break;
 
352
                  case GLU_SMOOTH:
 
353
                    glNormal3f(sinCache2[i], cosCache2[i], zNormal);
 
354
                    break;
 
355
                  case GLU_NONE:
 
356
                  default:
 
357
                    break;
 
358
                }
 
359
                if (qobj->textureCoords) {
 
360
                    glTexCoord2f(1 - (float) i / slices,
 
361
                            (float) j / stacks);
 
362
                }
 
363
                glVertex3f(radiusLow * sinCache[i],
 
364
                        radiusLow * cosCache[i], zLow);
 
365
            }
 
366
            glEnd();
 
367
        }
 
368
        /* Intentionally fall through here... */
 
369
      case GLU_SILHOUETTE:
 
370
        for (j = 0; j <= stacks; j += stacks) {
 
371
            zLow = j * height / stacks;
 
372
            radiusLow = baseRadius - deltaRadius * ((float) j / stacks);
 
373
 
 
374
            glBegin(GL_LINE_STRIP);
 
375
            for (i = 0; i <= slices; i++) {
 
376
                switch(qobj->normals) {
 
377
                  case GLU_FLAT:
 
378
                    glNormal3f(sinCache3[i], cosCache3[i], zNormal);
 
379
                    break;
 
380
                  case GLU_SMOOTH:
 
381
                    glNormal3f(sinCache2[i], cosCache2[i], zNormal);
 
382
                    break;
 
383
                  case GLU_NONE:
 
384
                  default:
 
385
                    break;
 
386
                }
 
387
                if (qobj->textureCoords) {
 
388
                    glTexCoord2f(1 - (float) i / slices,
 
389
                            (float) j / stacks);
 
390
                }
 
391
                glVertex3f(radiusLow * sinCache[i], radiusLow * cosCache[i],
 
392
                        zLow);
 
393
            }
 
394
            glEnd();
 
395
        }
 
396
        for (i = 0; i < slices; i++) {
 
397
            switch(qobj->normals) {
 
398
              case GLU_FLAT:
 
399
              case GLU_SMOOTH:
 
400
                glNormal3f(sinCache2[i], cosCache2[i], 0.0);
 
401
                break;
 
402
              case GLU_NONE:
 
403
              default:
 
404
                break;
 
405
            }
 
406
            sintemp = sinCache[i];
 
407
            costemp = cosCache[i];
 
408
            glBegin(GL_LINE_STRIP);
 
409
            for (j = 0; j <= stacks; j++) {
 
410
                zLow = j * height / stacks;
 
411
                radiusLow = baseRadius - deltaRadius * ((float) j / stacks);
 
412
 
 
413
                if (qobj->textureCoords) {
 
414
                    glTexCoord2f(1 - (float) i / slices,
 
415
                            (float) j / stacks);
 
416
                }
 
417
                glVertex3f(radiusLow * sintemp,
 
418
                        radiusLow * costemp, zLow);
 
419
            }
 
420
            glEnd();
 
421
        }
 
422
        break;
 
423
      default:
 
424
        break;
 
425
    }
 
426
}
 
427
 
 
428
void GLAPIENTRY
 
429
gluDisk(GLUquadric *qobj, GLdouble innerRadius, GLdouble outerRadius,
 
430
            GLint slices, GLint loops)
 
431
{
 
432
    gluPartialDisk(qobj, innerRadius, outerRadius, slices, loops, 0.0, 360.0);
 
433
}
 
434
 
 
435
void GLAPIENTRY
 
436
gluPartialDisk(GLUquadric *qobj, GLdouble innerRadius,
 
437
                   GLdouble outerRadius, GLint slices, GLint loops,
 
438
                   GLdouble startAngle, GLdouble sweepAngle)
 
439
{
 
440
    GLint i,j;
 
441
    GLfloat sinCache[CACHE_SIZE];
 
442
    GLfloat cosCache[CACHE_SIZE];
 
443
    GLfloat angle;
 
444
    GLfloat sintemp, costemp;
 
445
    GLfloat deltaRadius;
 
446
    GLfloat radiusLow, radiusHigh;
 
447
    GLfloat texLow = 0.0, texHigh = 0.0;
 
448
    GLfloat angleOffset;
 
449
    GLint slices2;
 
450
    GLint finish;
 
451
 
 
452
    if (slices >= CACHE_SIZE) slices = CACHE_SIZE-1;
 
453
    if (slices < 2 || loops < 1 || outerRadius <= 0.0 || innerRadius < 0.0 ||
 
454
            innerRadius > outerRadius) {
 
455
        gluQuadricError(qobj, GLU_INVALID_VALUE);
 
456
        return;
 
457
    }
 
458
 
 
459
    if (sweepAngle < -360.0) sweepAngle = 360.0;
 
460
    if (sweepAngle > 360.0) sweepAngle = 360.0;
 
461
    if (sweepAngle < 0) {
 
462
        startAngle += sweepAngle;
 
463
        sweepAngle = -sweepAngle;
 
464
    }
 
465
 
 
466
    if (sweepAngle == 360.0) {
 
467
        slices2 = slices;
 
468
    } else {
 
469
        slices2 = slices + 1;
 
470
    }
 
471
 
 
472
    /* Compute length (needed for normal calculations) */
 
473
    deltaRadius = outerRadius - innerRadius;
 
474
 
 
475
    /* Cache is the vertex locations cache */
 
476
 
 
477
    angleOffset = startAngle / 180.0 * PI;
 
478
    for (i = 0; i <= slices; i++) {
 
479
        angle = angleOffset + ((PI * sweepAngle) / 180.0) * i / slices;
 
480
        sinCache[i] = SIN(angle);
 
481
        cosCache[i] = COS(angle);
 
482
    }
 
483
 
 
484
    if (sweepAngle == 360.0) {
 
485
        sinCache[slices] = sinCache[0];
 
486
        cosCache[slices] = cosCache[0];
 
487
    }
 
488
 
 
489
    switch(qobj->normals) {
 
490
      case GLU_FLAT:
 
491
      case GLU_SMOOTH:
 
492
        if (qobj->orientation == GLU_OUTSIDE) {
 
493
            glNormal3f(0.0, 0.0, 1.0);
 
494
        } else {
 
495
            glNormal3f(0.0, 0.0, -1.0);
 
496
        }
 
497
        break;
 
498
      default:
 
499
      case GLU_NONE:
 
500
        break;
 
501
    }
 
502
 
 
503
    switch (qobj->drawStyle) {
 
504
      case GLU_FILL:
 
505
        if (innerRadius == 0.0) {
 
506
            finish = loops - 1;
 
507
            /* Triangle strip for inner polygons */
 
508
            glBegin(GL_TRIANGLE_FAN);
 
509
            if (qobj->textureCoords) {
 
510
                glTexCoord2f(0.5, 0.5);
 
511
            }
 
512
            glVertex3f(0.0, 0.0, 0.0);
 
513
            radiusLow = outerRadius -
 
514
                    deltaRadius * ((float) (loops-1) / loops);
 
515
            if (qobj->textureCoords) {
 
516
                texLow = radiusLow / outerRadius / 2;
 
517
            }
 
518
 
 
519
            if (qobj->orientation == GLU_OUTSIDE) {
 
520
                for (i = slices; i >= 0; i--) {
 
521
                    if (qobj->textureCoords) {
 
522
                        glTexCoord2f(texLow * sinCache[i] + 0.5,
 
523
                                texLow * cosCache[i] + 0.5);
 
524
                    }
 
525
                    glVertex3f(radiusLow * sinCache[i],
 
526
                            radiusLow * cosCache[i], 0.0);
 
527
                }
 
528
            } else {
 
529
                for (i = 0; i <= slices; i++) {
 
530
                    if (qobj->textureCoords) {
 
531
                        glTexCoord2f(texLow * sinCache[i] + 0.5,
 
532
                                texLow * cosCache[i] + 0.5);
 
533
                    }
 
534
                    glVertex3f(radiusLow * sinCache[i],
 
535
                            radiusLow * cosCache[i], 0.0);
 
536
                }
 
537
            }
 
538
            glEnd();
 
539
        } else {
 
540
            finish = loops;
 
541
        }
 
542
        for (j = 0; j < finish; j++) {
 
543
            radiusLow = outerRadius - deltaRadius * ((float) j / loops);
 
544
            radiusHigh = outerRadius - deltaRadius * ((float) (j + 1) / loops);
 
545
            if (qobj->textureCoords) {
 
546
                texLow = radiusLow / outerRadius / 2;
 
547
                texHigh = radiusHigh / outerRadius / 2;
 
548
            }
 
549
 
 
550
            glBegin(GL_QUAD_STRIP);
 
551
            for (i = 0; i <= slices; i++) {
 
552
                if (qobj->orientation == GLU_OUTSIDE) {
 
553
                    if (qobj->textureCoords) {
 
554
                        glTexCoord2f(texLow * sinCache[i] + 0.5,
 
555
                                texLow * cosCache[i] + 0.5);
 
556
                    }
 
557
                    glVertex3f(radiusLow * sinCache[i],
 
558
                            radiusLow * cosCache[i], 0.0);
 
559
 
 
560
                    if (qobj->textureCoords) {
 
561
                        glTexCoord2f(texHigh * sinCache[i] + 0.5,
 
562
                                texHigh * cosCache[i] + 0.5);
 
563
                    }
 
564
                    glVertex3f(radiusHigh * sinCache[i],
 
565
                            radiusHigh * cosCache[i], 0.0);
 
566
                } else {
 
567
                    if (qobj->textureCoords) {
 
568
                        glTexCoord2f(texHigh * sinCache[i] + 0.5,
 
569
                                texHigh * cosCache[i] + 0.5);
 
570
                    }
 
571
                    glVertex3f(radiusHigh * sinCache[i],
 
572
                            radiusHigh * cosCache[i], 0.0);
 
573
 
 
574
                    if (qobj->textureCoords) {
 
575
                        glTexCoord2f(texLow * sinCache[i] + 0.5,
 
576
                                texLow * cosCache[i] + 0.5);
 
577
                    }
 
578
                    glVertex3f(radiusLow * sinCache[i],
 
579
                            radiusLow * cosCache[i], 0.0);
 
580
                }
 
581
            }
 
582
            glEnd();
 
583
        }
 
584
        break;
 
585
      case GLU_POINT:
 
586
        glBegin(GL_POINTS);
 
587
        for (i = 0; i < slices2; i++) {
 
588
            sintemp = sinCache[i];
 
589
            costemp = cosCache[i];
 
590
            for (j = 0; j <= loops; j++) {
 
591
                radiusLow = outerRadius - deltaRadius * ((float) j / loops);
 
592
 
 
593
                if (qobj->textureCoords) {
 
594
                    texLow = radiusLow / outerRadius / 2;
 
595
 
 
596
                    glTexCoord2f(texLow * sinCache[i] + 0.5,
 
597
                            texLow * cosCache[i] + 0.5);
 
598
                }
 
599
                glVertex3f(radiusLow * sintemp, radiusLow * costemp, 0.0);
 
600
            }
 
601
        }
 
602
        glEnd();
 
603
        break;
 
604
      case GLU_LINE:
 
605
        if (innerRadius == outerRadius) {
 
606
            glBegin(GL_LINE_STRIP);
 
607
 
 
608
            for (i = 0; i <= slices; i++) {
 
609
                if (qobj->textureCoords) {
 
610
                    glTexCoord2f(sinCache[i] / 2 + 0.5,
 
611
                            cosCache[i] / 2 + 0.5);
 
612
                }
 
613
                glVertex3f(innerRadius * sinCache[i],
 
614
                        innerRadius * cosCache[i], 0.0);
 
615
            }
 
616
            glEnd();
 
617
            break;
 
618
        }
 
619
        for (j = 0; j <= loops; j++) {
 
620
            radiusLow = outerRadius - deltaRadius * ((float) j / loops);
 
621
            if (qobj->textureCoords) {
 
622
                texLow = radiusLow / outerRadius / 2;
 
623
            }
 
624
 
 
625
            glBegin(GL_LINE_STRIP);
 
626
            for (i = 0; i <= slices; i++) {
 
627
                if (qobj->textureCoords) {
 
628
                    glTexCoord2f(texLow * sinCache[i] + 0.5,
 
629
                            texLow * cosCache[i] + 0.5);
 
630
                }
 
631
                glVertex3f(radiusLow * sinCache[i],
 
632
                        radiusLow * cosCache[i], 0.0);
 
633
            }
 
634
            glEnd();
 
635
        }
 
636
        for (i=0; i < slices2; i++) {
 
637
            sintemp = sinCache[i];
 
638
            costemp = cosCache[i];
 
639
            glBegin(GL_LINE_STRIP);
 
640
            for (j = 0; j <= loops; j++) {
 
641
                radiusLow = outerRadius - deltaRadius * ((float) j / loops);
 
642
                if (qobj->textureCoords) {
 
643
                    texLow = radiusLow / outerRadius / 2;
 
644
                }
 
645
 
 
646
                if (qobj->textureCoords) {
 
647
                    glTexCoord2f(texLow * sinCache[i] + 0.5,
 
648
                            texLow * cosCache[i] + 0.5);
 
649
                }
 
650
                glVertex3f(radiusLow * sintemp, radiusLow * costemp, 0.0);
 
651
            }
 
652
            glEnd();
 
653
        }
 
654
        break;
 
655
      case GLU_SILHOUETTE:
 
656
        if (sweepAngle < 360.0) {
 
657
            for (i = 0; i <= slices; i+= slices) {
 
658
                sintemp = sinCache[i];
 
659
                costemp = cosCache[i];
 
660
                glBegin(GL_LINE_STRIP);
 
661
                for (j = 0; j <= loops; j++) {
 
662
                    radiusLow = outerRadius - deltaRadius * ((float) j / loops);
 
663
 
 
664
                    if (qobj->textureCoords) {
 
665
                        texLow = radiusLow / outerRadius / 2;
 
666
                        glTexCoord2f(texLow * sinCache[i] + 0.5,
 
667
                                texLow * cosCache[i] + 0.5);
 
668
                    }
 
669
                    glVertex3f(radiusLow * sintemp, radiusLow * costemp, 0.0);
 
670
                }
 
671
                glEnd();
 
672
            }
 
673
        }
 
674
        for (j = 0; j <= loops; j += loops) {
 
675
            radiusLow = outerRadius - deltaRadius * ((float) j / loops);
 
676
            if (qobj->textureCoords) {
 
677
                texLow = radiusLow / outerRadius / 2;
 
678
            }
 
679
 
 
680
            glBegin(GL_LINE_STRIP);
 
681
            for (i = 0; i <= slices; i++) {
 
682
                if (qobj->textureCoords) {
 
683
                    glTexCoord2f(texLow * sinCache[i] + 0.5,
 
684
                            texLow * cosCache[i] + 0.5);
 
685
                }
 
686
                glVertex3f(radiusLow * sinCache[i],
 
687
                        radiusLow * cosCache[i], 0.0);
 
688
            }
 
689
            glEnd();
 
690
            if (innerRadius == outerRadius) break;
 
691
        }
 
692
        break;
 
693
      default:
 
694
        break;
 
695
    }
 
696
}
 
697
 
 
698
void GLAPIENTRY
 
699
gluSphere(GLUquadric *qobj, GLdouble radius, GLint slices, GLint stacks)
 
700
{
 
701
    GLint i,j;
 
702
    GLfloat sinCache1a[CACHE_SIZE];
 
703
    GLfloat cosCache1a[CACHE_SIZE];
 
704
    GLfloat sinCache2a[CACHE_SIZE];
 
705
    GLfloat cosCache2a[CACHE_SIZE];
 
706
    GLfloat sinCache3a[CACHE_SIZE];
 
707
    GLfloat cosCache3a[CACHE_SIZE];
 
708
    GLfloat sinCache1b[CACHE_SIZE];
 
709
    GLfloat cosCache1b[CACHE_SIZE];
 
710
    GLfloat sinCache2b[CACHE_SIZE];
 
711
    GLfloat cosCache2b[CACHE_SIZE];
 
712
    GLfloat sinCache3b[CACHE_SIZE];
 
713
    GLfloat cosCache3b[CACHE_SIZE];
 
714
    GLfloat angle;
 
715
    GLfloat zLow, zHigh;
 
716
    GLfloat sintemp1, sintemp2, sintemp3 = 0.0, sintemp4 = 0.0;
 
717
    GLfloat costemp1, costemp2 = 0.0, costemp3 = 0.0, costemp4 = 0.0;
 
718
    GLboolean needCache2, needCache3;
 
719
    GLint start, finish;
 
720
 
 
721
    if (slices >= CACHE_SIZE) slices = CACHE_SIZE-1;
 
722
    if (stacks >= CACHE_SIZE) stacks = CACHE_SIZE-1;
 
723
    if (slices < 2 || stacks < 1 || radius < 0.0) {
 
724
        gluQuadricError(qobj, GLU_INVALID_VALUE);
 
725
        return;
 
726
    }
 
727
 
 
728
    /* Cache is the vertex locations cache */
 
729
    /* Cache2 is the various normals at the vertices themselves */
 
730
    /* Cache3 is the various normals for the faces */
 
731
    needCache2 = needCache3 = GL_FALSE;
 
732
 
 
733
    if (qobj->normals == GLU_SMOOTH) {
 
734
        needCache2 = GL_TRUE;
 
735
    }
 
736
 
 
737
    if (qobj->normals == GLU_FLAT) {
 
738
        if (qobj->drawStyle != GLU_POINT) {
 
739
            needCache3 = GL_TRUE;
 
740
        }
 
741
        if (qobj->drawStyle == GLU_LINE) {
 
742
            needCache2 = GL_TRUE;
 
743
        }
 
744
    }
 
745
 
 
746
    for (i = 0; i < slices; i++) {
 
747
        angle = 2 * PI * i / slices;
 
748
        sinCache1a[i] = SIN(angle);
 
749
        cosCache1a[i] = COS(angle);
 
750
        if (needCache2) {
 
751
            sinCache2a[i] = sinCache1a[i];
 
752
            cosCache2a[i] = cosCache1a[i];
 
753
        }
 
754
    }
 
755
 
 
756
    for (j = 0; j <= stacks; j++) {
 
757
        angle = PI * j / stacks;
 
758
        if (needCache2) {
 
759
            if (qobj->orientation == GLU_OUTSIDE) {
 
760
                sinCache2b[j] = SIN(angle);
 
761
                cosCache2b[j] = COS(angle);
 
762
            } else {
 
763
                sinCache2b[j] = -SIN(angle);
 
764
                cosCache2b[j] = -COS(angle);
 
765
            }
 
766
        }
 
767
        sinCache1b[j] = radius * SIN(angle);
 
768
        cosCache1b[j] = radius * COS(angle);
 
769
    }
 
770
    /* Make sure it comes to a point */
 
771
    sinCache1b[0] = 0;
 
772
    sinCache1b[stacks] = 0;
 
773
 
 
774
    if (needCache3) {
 
775
        for (i = 0; i < slices; i++) {
 
776
            angle = 2 * PI * (i-0.5) / slices;
 
777
            sinCache3a[i] = SIN(angle);
 
778
            cosCache3a[i] = COS(angle);
 
779
        }
 
780
        for (j = 0; j <= stacks; j++) {
 
781
            angle = PI * (j - 0.5) / stacks;
 
782
            if (qobj->orientation == GLU_OUTSIDE) {
 
783
                sinCache3b[j] = SIN(angle);
 
784
                cosCache3b[j] = COS(angle);
 
785
            } else {
 
786
                sinCache3b[j] = -SIN(angle);
 
787
                cosCache3b[j] = -COS(angle);
 
788
            }
 
789
        }
 
790
    }
 
791
 
 
792
    sinCache1a[slices] = sinCache1a[0];
 
793
    cosCache1a[slices] = cosCache1a[0];
 
794
    if (needCache2) {
 
795
        sinCache2a[slices] = sinCache2a[0];
 
796
        cosCache2a[slices] = cosCache2a[0];
 
797
    }
 
798
    if (needCache3) {
 
799
        sinCache3a[slices] = sinCache3a[0];
 
800
        cosCache3a[slices] = cosCache3a[0];
 
801
    }
 
802
 
 
803
    switch (qobj->drawStyle) {
 
804
      case GLU_FILL:
 
805
        /* Do ends of sphere as TRIANGLE_FAN's (if not texturing)
 
806
        ** We don't do it when texturing because we need to respecify the
 
807
        ** texture coordinates of the apex for every adjacent vertex (because
 
808
        ** it isn't a constant for that point)
 
809
        */
 
810
        if (!(qobj->textureCoords)) {
 
811
            start = 1;
 
812
            finish = stacks - 1;
 
813
 
 
814
            /* Low end first (j == 0 iteration) */
 
815
            sintemp2 = sinCache1b[1];
 
816
            zHigh = cosCache1b[1];
 
817
            switch(qobj->normals) {
 
818
              case GLU_FLAT:
 
819
                sintemp3 = sinCache3b[1];
 
820
                costemp3 = cosCache3b[1];
 
821
                break;
 
822
              case GLU_SMOOTH:
 
823
                sintemp3 = sinCache2b[1];
 
824
                costemp3 = cosCache2b[1];
 
825
                glNormal3f(sinCache2a[0] * sinCache2b[0],
 
826
                        cosCache2a[0] * sinCache2b[0],
 
827
                        cosCache2b[0]);
 
828
                break;
 
829
              default:
 
830
                break;
 
831
            }
 
832
            glBegin(GL_TRIANGLE_FAN);
 
833
            glVertex3f(0.0, 0.0, radius);
 
834
            if (qobj->orientation == GLU_OUTSIDE) {
 
835
                for (i = slices; i >= 0; i--) {
 
836
                    switch(qobj->normals) {
 
837
                      case GLU_SMOOTH:
 
838
                        glNormal3f(sinCache2a[i] * sintemp3,
 
839
                                cosCache2a[i] * sintemp3,
 
840
                                costemp3);
 
841
                        break;
 
842
                      case GLU_FLAT:
 
843
                        if (i != slices) {
 
844
                            glNormal3f(sinCache3a[i+1] * sintemp3,
 
845
                                    cosCache3a[i+1] * sintemp3,
 
846
                                    costemp3);
 
847
                        }
 
848
                        break;
 
849
                      case GLU_NONE:
 
850
                      default:
 
851
                        break;
 
852
                    }
 
853
                    glVertex3f(sintemp2 * sinCache1a[i],
 
854
                            sintemp2 * cosCache1a[i], zHigh);
 
855
                }
 
856
            } else {
 
857
                for (i = 0; i <= slices; i++) {
 
858
                    switch(qobj->normals) {
 
859
                      case GLU_SMOOTH:
 
860
                        glNormal3f(sinCache2a[i] * sintemp3,
 
861
                                cosCache2a[i] * sintemp3,
 
862
                                costemp3);
 
863
                        break;
 
864
                      case GLU_FLAT:
 
865
                        glNormal3f(sinCache3a[i] * sintemp3,
 
866
                                cosCache3a[i] * sintemp3,
 
867
                                costemp3);
 
868
                        break;
 
869
                      case GLU_NONE:
 
870
                      default:
 
871
                        break;
 
872
                    }
 
873
                    glVertex3f(sintemp2 * sinCache1a[i],
 
874
                            sintemp2 * cosCache1a[i], zHigh);
 
875
                }
 
876
            }
 
877
            glEnd();
 
878
 
 
879
            /* High end next (j == stacks-1 iteration) */
 
880
            sintemp2 = sinCache1b[stacks-1];
 
881
            zHigh = cosCache1b[stacks-1];
 
882
            switch(qobj->normals) {
 
883
              case GLU_FLAT:
 
884
                sintemp3 = sinCache3b[stacks];
 
885
                costemp3 = cosCache3b[stacks];
 
886
                break;
 
887
              case GLU_SMOOTH:
 
888
                sintemp3 = sinCache2b[stacks-1];
 
889
                costemp3 = cosCache2b[stacks-1];
 
890
                glNormal3f(sinCache2a[stacks] * sinCache2b[stacks],
 
891
                        cosCache2a[stacks] * sinCache2b[stacks],
 
892
                        cosCache2b[stacks]);
 
893
                break;
 
894
              default:
 
895
                break;
 
896
            }
 
897
            glBegin(GL_TRIANGLE_FAN);
 
898
            glVertex3f(0.0, 0.0, -radius);
 
899
            if (qobj->orientation == GLU_OUTSIDE) {
 
900
                for (i = 0; i <= slices; i++) {
 
901
                    switch(qobj->normals) {
 
902
                      case GLU_SMOOTH:
 
903
                        glNormal3f(sinCache2a[i] * sintemp3,
 
904
                                cosCache2a[i] * sintemp3,
 
905
                                costemp3);
 
906
                        break;
 
907
                      case GLU_FLAT:
 
908
                        glNormal3f(sinCache3a[i] * sintemp3,
 
909
                                cosCache3a[i] * sintemp3,
 
910
                                costemp3);
 
911
                        break;
 
912
                      case GLU_NONE:
 
913
                      default:
 
914
                        break;
 
915
                    }
 
916
                    glVertex3f(sintemp2 * sinCache1a[i],
 
917
                            sintemp2 * cosCache1a[i], zHigh);
 
918
                }
 
919
            } else {
 
920
                for (i = slices; i >= 0; i--) {
 
921
                    switch(qobj->normals) {
 
922
                      case GLU_SMOOTH:
 
923
                        glNormal3f(sinCache2a[i] * sintemp3,
 
924
                                cosCache2a[i] * sintemp3,
 
925
                                costemp3);
 
926
                        break;
 
927
                      case GLU_FLAT:
 
928
                        if (i != slices) {
 
929
                            glNormal3f(sinCache3a[i+1] * sintemp3,
 
930
                                    cosCache3a[i+1] * sintemp3,
 
931
                                    costemp3);
 
932
                        }
 
933
                        break;
 
934
                      case GLU_NONE:
 
935
                      default:
 
936
                        break;
 
937
                    }
 
938
                    glVertex3f(sintemp2 * sinCache1a[i],
 
939
                            sintemp2 * cosCache1a[i], zHigh);
 
940
                }
 
941
            }
 
942
            glEnd();
 
943
        } else {
 
944
            start = 0;
 
945
            finish = stacks;
 
946
        }
 
947
        for (j = start; j < finish; j++) {
 
948
            zLow = cosCache1b[j];
 
949
            zHigh = cosCache1b[j+1];
 
950
            sintemp1 = sinCache1b[j];
 
951
            sintemp2 = sinCache1b[j+1];
 
952
            switch(qobj->normals) {
 
953
              case GLU_FLAT:
 
954
                sintemp4 = sinCache3b[j+1];
 
955
                costemp4 = cosCache3b[j+1];
 
956
                break;
 
957
              case GLU_SMOOTH:
 
958
                if (qobj->orientation == GLU_OUTSIDE) {
 
959
                    sintemp3 = sinCache2b[j+1];
 
960
                    costemp3 = cosCache2b[j+1];
 
961
                    sintemp4 = sinCache2b[j];
 
962
                    costemp4 = cosCache2b[j];
 
963
                } else {
 
964
                    sintemp3 = sinCache2b[j];
 
965
                    costemp3 = cosCache2b[j];
 
966
                    sintemp4 = sinCache2b[j+1];
 
967
                    costemp4 = cosCache2b[j+1];
 
968
                }
 
969
                break;
 
970
              default:
 
971
                break;
 
972
            }
 
973
 
 
974
            glBegin(GL_QUAD_STRIP);
 
975
            for (i = 0; i <= slices; i++) {
 
976
                switch(qobj->normals) {
 
977
                  case GLU_SMOOTH:
 
978
                    glNormal3f(sinCache2a[i] * sintemp3,
 
979
                            cosCache2a[i] * sintemp3,
 
980
                            costemp3);
 
981
                    break;
 
982
                  case GLU_FLAT:
 
983
                  case GLU_NONE:
 
984
                  default:
 
985
                    break;
 
986
                }
 
987
                if (qobj->orientation == GLU_OUTSIDE) {
 
988
                    if (qobj->textureCoords) {
 
989
                        glTexCoord2f(1 - (float) i / slices,
 
990
                                1 - (float) (j+1) / stacks);
 
991
                    }
 
992
                    glVertex3f(sintemp2 * sinCache1a[i],
 
993
                            sintemp2 * cosCache1a[i], zHigh);
 
994
                } else {
 
995
                    if (qobj->textureCoords) {
 
996
                        glTexCoord2f(1 - (float) i / slices,
 
997
                                1 - (float) j / stacks);
 
998
                    }
 
999
                    glVertex3f(sintemp1 * sinCache1a[i],
 
1000
                            sintemp1 * cosCache1a[i], zLow);
 
1001
                }
 
1002
                switch(qobj->normals) {
 
1003
                  case GLU_SMOOTH:
 
1004
                    glNormal3f(sinCache2a[i] * sintemp4,
 
1005
                            cosCache2a[i] * sintemp4,
 
1006
                            costemp4);
 
1007
                    break;
 
1008
                  case GLU_FLAT:
 
1009
                    glNormal3f(sinCache3a[i] * sintemp4,
 
1010
                            cosCache3a[i] * sintemp4,
 
1011
                            costemp4);
 
1012
                    break;
 
1013
                  case GLU_NONE:
 
1014
                  default:
 
1015
                    break;
 
1016
                }
 
1017
                if (qobj->orientation == GLU_OUTSIDE) {
 
1018
                    if (qobj->textureCoords) {
 
1019
                        glTexCoord2f(1 - (float) i / slices,
 
1020
                                1 - (float) j / stacks);
 
1021
                    }
 
1022
                    glVertex3f(sintemp1 * sinCache1a[i],
 
1023
                            sintemp1 * cosCache1a[i], zLow);
 
1024
                } else {
 
1025
                    if (qobj->textureCoords) {
 
1026
                        glTexCoord2f(1 - (float) i / slices,
 
1027
                                1 - (float) (j+1) / stacks);
 
1028
                    }
 
1029
                    glVertex3f(sintemp2 * sinCache1a[i],
 
1030
                            sintemp2 * cosCache1a[i], zHigh);
 
1031
                }
 
1032
            }
 
1033
            glEnd();
 
1034
        }
 
1035
        break;
 
1036
      case GLU_POINT:
 
1037
        glBegin(GL_POINTS);
 
1038
        for (j = 0; j <= stacks; j++) {
 
1039
            sintemp1 = sinCache1b[j];
 
1040
            costemp1 = cosCache1b[j];
 
1041
            switch(qobj->normals) {
 
1042
              case GLU_FLAT:
 
1043
              case GLU_SMOOTH:
 
1044
                sintemp2 = sinCache2b[j];
 
1045
                costemp2 = cosCache2b[j];
 
1046
                break;
 
1047
              default:
 
1048
                break;
 
1049
            }
 
1050
            for (i = 0; i < slices; i++) {
 
1051
                switch(qobj->normals) {
 
1052
                  case GLU_FLAT:
 
1053
                  case GLU_SMOOTH:
 
1054
                    glNormal3f(sinCache2a[i] * sintemp2,
 
1055
                            cosCache2a[i] * sintemp2,
 
1056
                            costemp2);
 
1057
                    break;
 
1058
                  case GLU_NONE:
 
1059
                  default:
 
1060
                    break;
 
1061
                }
 
1062
 
 
1063
                zLow = j * radius / stacks;
 
1064
 
 
1065
                if (qobj->textureCoords) {
 
1066
                    glTexCoord2f(1 - (float) i / slices,
 
1067
                            1 - (float) j / stacks);
 
1068
                }
 
1069
                glVertex3f(sintemp1 * sinCache1a[i],
 
1070
                        sintemp1 * cosCache1a[i], costemp1);
 
1071
            }
 
1072
        }
 
1073
        glEnd();
 
1074
        break;
 
1075
      case GLU_LINE:
 
1076
      case GLU_SILHOUETTE:
 
1077
        for (j = 1; j < stacks; j++) {
 
1078
            sintemp1 = sinCache1b[j];
 
1079
            costemp1 = cosCache1b[j];
 
1080
            switch(qobj->normals) {
 
1081
              case GLU_FLAT:
 
1082
              case GLU_SMOOTH:
 
1083
                sintemp2 = sinCache2b[j];
 
1084
                costemp2 = cosCache2b[j];
 
1085
                break;
 
1086
              default:
 
1087
                break;
 
1088
            }
 
1089
 
 
1090
            glBegin(GL_LINE_STRIP);
 
1091
            for (i = 0; i <= slices; i++) {
 
1092
                switch(qobj->normals) {
 
1093
                  case GLU_FLAT:
 
1094
                    glNormal3f(sinCache3a[i] * sintemp2,
 
1095
                            cosCache3a[i] * sintemp2,
 
1096
                            costemp2);
 
1097
                    break;
 
1098
                  case GLU_SMOOTH:
 
1099
                    glNormal3f(sinCache2a[i] * sintemp2,
 
1100
                            cosCache2a[i] * sintemp2,
 
1101
                            costemp2);
 
1102
                    break;
 
1103
                  case GLU_NONE:
 
1104
                  default:
 
1105
                    break;
 
1106
                }
 
1107
                if (qobj->textureCoords) {
 
1108
                    glTexCoord2f(1 - (float) i / slices,
 
1109
                            1 - (float) j / stacks);
 
1110
                }
 
1111
                glVertex3f(sintemp1 * sinCache1a[i],
 
1112
                        sintemp1 * cosCache1a[i], costemp1);
 
1113
            }
 
1114
            glEnd();
 
1115
        }
 
1116
        for (i = 0; i < slices; i++) {
 
1117
            sintemp1 = sinCache1a[i];
 
1118
            costemp1 = cosCache1a[i];
 
1119
            switch(qobj->normals) {
 
1120
              case GLU_FLAT:
 
1121
              case GLU_SMOOTH:
 
1122
                sintemp2 = sinCache2a[i];
 
1123
                costemp2 = cosCache2a[i];
 
1124
                break;
 
1125
              default:
 
1126
                break;
 
1127
            }
 
1128
 
 
1129
            glBegin(GL_LINE_STRIP);
 
1130
            for (j = 0; j <= stacks; j++) {
 
1131
                switch(qobj->normals) {
 
1132
                  case GLU_FLAT:
 
1133
                    glNormal3f(sintemp2 * sinCache3b[j],
 
1134
                            costemp2 * sinCache3b[j],
 
1135
                            cosCache3b[j]);
 
1136
                    break;
 
1137
                  case GLU_SMOOTH:
 
1138
                    glNormal3f(sintemp2 * sinCache2b[j],
 
1139
                            costemp2 * sinCache2b[j],
 
1140
                            cosCache2b[j]);
 
1141
                    break;
 
1142
                  case GLU_NONE:
 
1143
                  default:
 
1144
                    break;
 
1145
                }
 
1146
 
 
1147
                if (qobj->textureCoords) {
 
1148
                    glTexCoord2f(1 - (float) i / slices,
 
1149
                            1 - (float) j / stacks);
 
1150
                }
 
1151
                glVertex3f(sintemp1 * sinCache1b[j],
 
1152
                        costemp1 * sinCache1b[j], cosCache1b[j]);
 
1153
            }
 
1154
            glEnd();
 
1155
        }
 
1156
        break;
 
1157
      default:
 
1158
        break;
 
1159
    }
 
1160
}