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