ReactOS  0.4.15-dev-1150-g593bcce
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 
45 struct 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 
72 void GLAPIENTRY
74 {
75  free(state);
76 }
77 
79 {
80  if (qobj->errorCallback) {
81  qobj->errorCallback(which);
82  }
83 }
84 
85 void 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 
98 void 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 
113 void GLAPIENTRY
115 {
116  qobj->textureCoords = textureCoords;
117 }
118 
119 void 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 
133 void 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 
149 void GLAPIENTRY
150 gluCylinder(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];
160  GLfloat angle;
161  GLfloat zLow, zHigh;
162  GLfloat sintemp, costemp;
163  GLfloat length;
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 
423 void GLAPIENTRY
424 gluDisk(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 
430 void GLAPIENTRY
431 gluPartialDisk(GLUquadric *qobj, GLdouble innerRadius,
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];
438  GLfloat angle;
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;
445  GLint finish;
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 
693 void GLAPIENTRY
694 gluSphere(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];
709  GLfloat angle;
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;
714  GLint start, finish;
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:
1032  glBegin(GL_POINTS);
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 }
double GLdouble
Definition: gl.h:163
GLint orientation
Definition: quad.c:48
static void gluQuadricError(GLUquadric *qobj, GLenum which)
Definition: quad.c:78
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
void GLAPIENTRY gluQuadricDrawStyle(GLUquadric *qobj, GLenum drawStyle)
Definition: quad.c:134
#define SQRT
Definition: gluint.h:45
#define PI
Definition: quad.c:43
#define GL_POINTS
Definition: gl.h:190
GLAPI void GLAPIENTRY glVertex3f(GLfloat x, GLfloat y, GLfloat z)
static GLenum _GLUfuncptr fn
Definition: wgl_font.c:159
static GLenum which
Definition: wgl_font.c:159
#define GL_FALSE
Definition: gl.h:173
void GLAPIENTRY gluQuadricTexture(GLUquadric *qobj, GLboolean textureCoords)
Definition: quad.c:114
#define free
Definition: debug_ros.c:5
GLint normals
Definition: quad.c:46
void GLAPIENTRY gluDeleteQuadric(GLUquadric *state)
Definition: quad.c:73
#define GLU_FILL
Definition: glu.h:198
GLfloat angle
Definition: glext.h:10853
#define GLU_POINT
Definition: glu.h:196
GLboolean textureCoords
Definition: quad.c:47
#define GLU_INSIDE
Definition: glu.h:211
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
#define CACHE_SIZE
Definition: quad.c:40
unsigned char GLboolean
Definition: gl.h:151
#define COS
Definition: gluint.h:43
smooth NULL
Definition: ftsmooth.c:416
#define SIN
Definition: gluint.h:44
#define GL_TRIANGLE_FAN
Definition: gl.h:196
GLAPI void GLAPIENTRY glNormal3f(GLfloat nx, GLfloat ny, GLfloat nz)
#define GL_LINE_STRIP
Definition: gl.h:193
void GLAPIENTRY gluPartialDisk(GLUquadric *qobj, GLdouble innerRadius, GLdouble outerRadius, GLint slices, GLint loops, GLdouble startAngle, GLdouble sweepAngle)
Definition: quad.c:431
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 GLU_ERROR
Definition: glu.h:101
void GLAPIENTRY gluQuadricCallback(GLUquadric *qobj, GLenum which, _GLUfuncptr fn)
Definition: quad.c:86
void GLAPIENTRY gluDisk(GLUquadric *qobj, GLdouble innerRadius, GLdouble outerRadius, GLint slices, GLint loops)
Definition: quad.c:424
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
#define GLU_NONE
Definition: glu.h:207
#define GLU_LINE
Definition: glu.h:197
void(WINAPI * _GLUfuncptr)(void)
Definition: wgl_font.c:148
GLAPI void GLAPIENTRY glBegin(GLenum mode)
static int state
Definition: maze.c:121
unsigned int GLenum
Definition: gl.h:150
GLUquadric *GLAPIENTRY gluNewQuadric(void)
Definition: quad.c:54
#define GLU_INVALID_VALUE
Definition: glu.h:89
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
void GLAPIENTRY gluQuadricNormals(GLUquadric *qobj, GLenum normals)
Definition: quad.c:99
#define GLU_SILHOUETTE
Definition: glu.h:199
#define GL_QUAD_STRIP
Definition: gl.h:198
GLint drawStyle
Definition: quad.c:49
static float(__cdecl *square_half_float)(float x
void GLAPIENTRY gluCylinder(GLUquadric *qobj, GLdouble baseRadius, GLdouble topRadius, GLdouble height, GLint slices, GLint stacks)
Definition: quad.c:150
#define GLU_SMOOTH
Definition: glu.h:205
GLuint start
Definition: gl.h:1545
#define GL_TRUE
Definition: gl.h:174
GLAPI void GLAPIENTRY glTexCoord2f(GLfloat s, GLfloat t)
float GLfloat
Definition: gl.h:161
#define GLU_INVALID_ENUM
Definition: glu.h:88
void(GLAPIENTRY *errorCallback)(GLint)
void GLAPIENTRY gluQuadricOrientation(GLUquadric *qobj, GLenum orientation)
Definition: quad.c:120
GLAPI void GLAPIENTRY glEnd(void)
int GLint
Definition: gl.h:156
#define malloc
Definition: debug_ros.c:4
#define GLU_FLAT
Definition: glu.h:206
#define GLU_OUTSIDE
Definition: glu.h:210
void GLAPIENTRY gluSphere(GLUquadric *qobj, GLdouble radius, GLint slices, GLint stacks)
Definition: quad.c:694
#define GLAPIENTRY
Definition: glu.h:44