ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

quad.c
Go to the documentation of this file.
00001 /*
00002 ** License Applicability. Except to the extent portions of this file are
00003 ** made subject to an alternative license as permitted in the SGI Free
00004 ** Software License B, Version 1.1 (the "License"), the contents of this
00005 ** file are subject only to the provisions of the License. You may not use
00006 ** this file except in compliance with the License. You may obtain a copy
00007 ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
00008 ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
00009 **
00010 ** http://oss.sgi.com/projects/FreeB
00011 **
00012 ** Note that, as provided in the License, the Software is distributed on an
00013 ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
00014 ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
00015 ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
00016 ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
00017 **
00018 ** Original Code. The Original Code is: OpenGL Sample Implementation,
00019 ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
00020 ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
00021 ** Copyright in any portions created by third parties is as indicated
00022 ** elsewhere herein. All Rights Reserved.
00023 **
00024 ** Additional Notice Provisions: The application programming interfaces
00025 ** established by SGI in conjunction with the Original Code are The
00026 ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
00027 ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
00028 ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
00029 ** Window System(R) (Version 1.3), released October 19, 1998. This software
00030 ** was created using the OpenGL(R) version 1.2.1 Sample Implementation
00031 ** published by SGI, but has not been independently verified as being
00032 ** compliant with the OpenGL(R) version 1.2.1 Specification.
00033 **
00034 */
00035 
00036 #include "gluos.h"
00037 #include "gluint.h"
00038 #include <stdio.h>
00039 #include <stdlib.h>
00040 #include <math.h>
00041 #include <GL/gl.h>
00042 #include <GL/glu.h>
00043 
00044 #ifndef GLU_ERROR
00045 #define GLU_ERROR                          100103
00046 #endif
00047 
00048 /* Make it not a power of two to avoid cache thrashing on the chip */
00049 #define CACHE_SIZE  240
00050 
00051 #undef  PI
00052 #define PI        3.14159265358979323846
00053 
00054 struct GLUquadric {
00055     GLint   normals;
00056     GLboolean   textureCoords;
00057     GLint   orientation;
00058     GLint   drawStyle;
00059     void    (GLAPIENTRY *errorCallback)( GLint );
00060 };
00061 
00062 GLUquadric * GLAPIENTRY
00063 gluNewQuadric(void)
00064 {
00065     GLUquadric *newstate;
00066 
00067     newstate = (GLUquadric *) malloc(sizeof(GLUquadric));
00068     if (newstate == NULL) {
00069     /* Can't report an error at this point... */
00070     return NULL;
00071     }
00072     newstate->normals = GLU_SMOOTH;
00073     newstate->textureCoords = GL_FALSE;
00074     newstate->orientation = GLU_OUTSIDE;
00075     newstate->drawStyle = GLU_FILL;
00076     newstate->errorCallback = NULL;
00077     return newstate;
00078 }
00079 
00080 
00081 void GLAPIENTRY
00082 gluDeleteQuadric(GLUquadric *state)
00083 {
00084     free(state);
00085 }
00086 
00087 static void gluQuadricError(GLUquadric *qobj, GLenum which)
00088 {
00089     if (qobj->errorCallback) {
00090     qobj->errorCallback(which);
00091     }
00092 }
00093 
00094 void GLAPIENTRY
00095 gluQuadricCallback(GLUquadric *qobj, GLenum which, _GLUfuncptr fn)
00096 {
00097     switch (which) {
00098       case GLU_ERROR:
00099     qobj->errorCallback = (void (GLAPIENTRY *)(GLint)) fn;
00100     break;
00101       default:
00102     gluQuadricError(qobj, GLU_INVALID_ENUM);
00103     return;
00104     }
00105 }
00106 
00107 void GLAPIENTRY
00108 gluQuadricNormals(GLUquadric *qobj, GLenum normals)
00109 {
00110     switch (normals) {
00111       case GLU_SMOOTH:
00112       case GLU_FLAT:
00113       case GLU_NONE:
00114     break;
00115       default:
00116     gluQuadricError(qobj, GLU_INVALID_ENUM);
00117     return;
00118     }
00119     qobj->normals = normals;
00120 }
00121 
00122 void GLAPIENTRY
00123 gluQuadricTexture(GLUquadric *qobj, GLboolean textureCoords)
00124 {
00125     qobj->textureCoords = textureCoords;
00126 }
00127 
00128 void GLAPIENTRY
00129 gluQuadricOrientation(GLUquadric *qobj, GLenum orientation)
00130 {
00131     switch(orientation) {
00132       case GLU_OUTSIDE:
00133       case GLU_INSIDE:
00134     break;
00135       default:
00136     gluQuadricError(qobj, GLU_INVALID_ENUM);
00137     return;
00138     }
00139     qobj->orientation = orientation;
00140 }
00141 
00142 void GLAPIENTRY
00143 gluQuadricDrawStyle(GLUquadric *qobj, GLenum drawStyle)
00144 {
00145     switch(drawStyle) {
00146       case GLU_POINT:
00147       case GLU_LINE:
00148       case GLU_FILL:
00149       case GLU_SILHOUETTE:
00150     break;
00151       default:
00152     gluQuadricError(qobj, GLU_INVALID_ENUM);
00153     return;
00154     }
00155     qobj->drawStyle = drawStyle;
00156 }
00157 
00158 void GLAPIENTRY
00159 gluCylinder(GLUquadric *qobj, GLdouble baseRadius, GLdouble topRadius,
00160         GLdouble height, GLint slices, GLint stacks)
00161 {
00162     GLint i,j;
00163     GLfloat sinCache[CACHE_SIZE];
00164     GLfloat cosCache[CACHE_SIZE];
00165     GLfloat sinCache2[CACHE_SIZE];
00166     GLfloat cosCache2[CACHE_SIZE];
00167     GLfloat sinCache3[CACHE_SIZE];
00168     GLfloat cosCache3[CACHE_SIZE];
00169     GLfloat angle;
00170     GLfloat zLow, zHigh;
00171     GLfloat sintemp, costemp;
00172     GLfloat length;
00173     GLfloat deltaRadius;
00174     GLfloat zNormal;
00175     GLfloat xyNormalRatio;
00176     GLfloat radiusLow, radiusHigh;
00177     int needCache2, needCache3;
00178 
00179     if (slices >= CACHE_SIZE) slices = CACHE_SIZE-1;
00180 
00181     if (slices < 2 || stacks < 1 || baseRadius < 0.0 || topRadius < 0.0 ||
00182         height < 0.0) {
00183     gluQuadricError(qobj, GLU_INVALID_VALUE);
00184     return;
00185     }
00186 
00187     /* Compute length (needed for normal calculations) */
00188     deltaRadius = baseRadius - topRadius;
00189     length = SQRT(deltaRadius*deltaRadius + height*height);
00190     if (length == 0.0) {
00191     gluQuadricError(qobj, GLU_INVALID_VALUE);
00192     return;
00193     }
00194 
00195     /* Cache is the vertex locations cache */
00196     /* Cache2 is the various normals at the vertices themselves */
00197     /* Cache3 is the various normals for the faces */
00198     needCache2 = needCache3 = 0;
00199     if (qobj->normals == GLU_SMOOTH) {
00200     needCache2 = 1;
00201     }
00202 
00203     if (qobj->normals == GLU_FLAT) {
00204     if (qobj->drawStyle != GLU_POINT) {
00205         needCache3 = 1;
00206     }
00207     if (qobj->drawStyle == GLU_LINE) {
00208         needCache2 = 1;
00209     }
00210     }
00211 
00212     zNormal = deltaRadius / length;
00213     xyNormalRatio = height / length;
00214 
00215     for (i = 0; i < slices; i++) {
00216     angle = 2 * PI * i / slices;
00217     if (needCache2) {
00218         if (qobj->orientation == GLU_OUTSIDE) {
00219         sinCache2[i] = xyNormalRatio * SIN(angle);
00220         cosCache2[i] = xyNormalRatio * COS(angle);
00221         } else {
00222         sinCache2[i] = -xyNormalRatio * SIN(angle);
00223         cosCache2[i] = -xyNormalRatio * COS(angle);
00224         }
00225     }
00226     sinCache[i] = SIN(angle);
00227     cosCache[i] = COS(angle);
00228     }
00229 
00230     if (needCache3) {
00231     for (i = 0; i < slices; i++) {
00232         angle = 2 * PI * (i-0.5) / slices;
00233         if (qobj->orientation == GLU_OUTSIDE) {
00234         sinCache3[i] = xyNormalRatio * SIN(angle);
00235         cosCache3[i] = xyNormalRatio * COS(angle);
00236         } else {
00237         sinCache3[i] = -xyNormalRatio * SIN(angle);
00238         cosCache3[i] = -xyNormalRatio * COS(angle);
00239         }
00240     }
00241     }
00242 
00243     sinCache[slices] = sinCache[0];
00244     cosCache[slices] = cosCache[0];
00245     if (needCache2) {
00246     sinCache2[slices] = sinCache2[0];
00247     cosCache2[slices] = cosCache2[0];
00248     }
00249     if (needCache3) {
00250     sinCache3[slices] = sinCache3[0];
00251     cosCache3[slices] = cosCache3[0];
00252     }
00253 
00254     switch (qobj->drawStyle) {
00255       case GLU_FILL:
00256     /* Note:
00257     ** An argument could be made for using a TRIANGLE_FAN for the end
00258     ** of the cylinder of either radii is 0.0 (a cone).  However, a
00259     ** TRIANGLE_FAN would not work in smooth shading mode (the common
00260     ** case) because the normal for the apex is different for every
00261     ** triangle (and TRIANGLE_FAN doesn't let me respecify that normal).
00262     ** Now, my choice is GL_TRIANGLES, or leave the GL_QUAD_STRIP and
00263     ** just let the GL trivially reject one of the two triangles of the
00264     ** QUAD.  GL_QUAD_STRIP is probably faster, so I will leave this code
00265     ** alone.
00266     */
00267     for (j = 0; j < stacks; j++) {
00268         zLow = j * height / stacks;
00269         zHigh = (j + 1) * height / stacks;
00270         radiusLow = baseRadius - deltaRadius * ((float) j / stacks);
00271         radiusHigh = baseRadius - deltaRadius * ((float) (j + 1) / stacks);
00272 
00273         glBegin(GL_QUAD_STRIP);
00274         for (i = 0; i <= slices; i++) {
00275         switch(qobj->normals) {
00276           case GLU_FLAT:
00277             glNormal3f(sinCache3[i], cosCache3[i], zNormal);
00278             break;
00279           case GLU_SMOOTH:
00280             glNormal3f(sinCache2[i], cosCache2[i], zNormal);
00281             break;
00282           case GLU_NONE:
00283           default:
00284             break;
00285         }
00286         if (qobj->orientation == GLU_OUTSIDE) {
00287             if (qobj->textureCoords) {
00288             glTexCoord2f(1 - (float) i / slices,
00289                 (float) j / stacks);
00290             }
00291             glVertex3f(radiusLow * sinCache[i],
00292                 radiusLow * cosCache[i], zLow);
00293             if (qobj->textureCoords) {
00294             glTexCoord2f(1 - (float) i / slices,
00295                 (float) (j+1) / stacks);
00296             }
00297             glVertex3f(radiusHigh * sinCache[i],
00298                 radiusHigh * cosCache[i], zHigh);
00299         } else {
00300             if (qobj->textureCoords) {
00301             glTexCoord2f(1 - (float) i / slices,
00302                 (float) (j+1) / stacks);
00303             }
00304             glVertex3f(radiusHigh * sinCache[i],
00305                 radiusHigh * cosCache[i], zHigh);
00306             if (qobj->textureCoords) {
00307             glTexCoord2f(1 - (float) i / slices,
00308                 (float) j / stacks);
00309             }
00310             glVertex3f(radiusLow * sinCache[i],
00311                 radiusLow * cosCache[i], zLow);
00312         }
00313         }
00314         glEnd();
00315     }
00316     break;
00317       case GLU_POINT:
00318     glBegin(GL_POINTS);
00319     for (i = 0; i < slices; i++) {
00320         switch(qobj->normals) {
00321           case GLU_FLAT:
00322           case GLU_SMOOTH:
00323         glNormal3f(sinCache2[i], cosCache2[i], zNormal);
00324         break;
00325           case GLU_NONE:
00326           default:
00327         break;
00328         }
00329         sintemp = sinCache[i];
00330         costemp = cosCache[i];
00331         for (j = 0; j <= stacks; j++) {
00332         zLow = j * height / stacks;
00333         radiusLow = baseRadius - deltaRadius * ((float) j / stacks);
00334 
00335         if (qobj->textureCoords) {
00336             glTexCoord2f(1 - (float) i / slices,
00337                 (float) j / stacks);
00338         }
00339         glVertex3f(radiusLow * sintemp,
00340             radiusLow * costemp, zLow);
00341         }
00342     }
00343     glEnd();
00344     break;
00345       case GLU_LINE:
00346     for (j = 1; j < stacks; j++) {
00347         zLow = j * height / stacks;
00348         radiusLow = baseRadius - deltaRadius * ((float) j / stacks);
00349 
00350         glBegin(GL_LINE_STRIP);
00351         for (i = 0; i <= slices; i++) {
00352         switch(qobj->normals) {
00353           case GLU_FLAT:
00354             glNormal3f(sinCache3[i], cosCache3[i], zNormal);
00355             break;
00356           case GLU_SMOOTH:
00357             glNormal3f(sinCache2[i], cosCache2[i], zNormal);
00358             break;
00359           case GLU_NONE:
00360           default:
00361             break;
00362         }
00363         if (qobj->textureCoords) {
00364             glTexCoord2f(1 - (float) i / slices,
00365                 (float) j / stacks);
00366         }
00367         glVertex3f(radiusLow * sinCache[i],
00368             radiusLow * cosCache[i], zLow);
00369         }
00370         glEnd();
00371     }
00372     /* Intentionally fall through here... */
00373       case GLU_SILHOUETTE:
00374     for (j = 0; j <= stacks; j += stacks) {
00375         zLow = j * height / stacks;
00376         radiusLow = baseRadius - deltaRadius * ((float) j / stacks);
00377 
00378         glBegin(GL_LINE_STRIP);
00379         for (i = 0; i <= slices; i++) {
00380         switch(qobj->normals) {
00381           case GLU_FLAT:
00382             glNormal3f(sinCache3[i], cosCache3[i], zNormal);
00383             break;
00384           case GLU_SMOOTH:
00385             glNormal3f(sinCache2[i], cosCache2[i], zNormal);
00386             break;
00387           case GLU_NONE:
00388           default:
00389             break;
00390         }
00391         if (qobj->textureCoords) {
00392             glTexCoord2f(1 - (float) i / slices,
00393                 (float) j / stacks);
00394         }
00395         glVertex3f(radiusLow * sinCache[i], radiusLow * cosCache[i],
00396             zLow);
00397         }
00398         glEnd();
00399     }
00400     for (i = 0; i < slices; i++) {
00401         switch(qobj->normals) {
00402           case GLU_FLAT:
00403           case GLU_SMOOTH:
00404         glNormal3f(sinCache2[i], cosCache2[i], 0.0);
00405         break;
00406           case GLU_NONE:
00407           default:
00408         break;
00409         }
00410         sintemp = sinCache[i];
00411         costemp = cosCache[i];
00412         glBegin(GL_LINE_STRIP);
00413         for (j = 0; j <= stacks; j++) {
00414         zLow = j * height / stacks;
00415         radiusLow = baseRadius - deltaRadius * ((float) j / stacks);
00416 
00417         if (qobj->textureCoords) {
00418             glTexCoord2f(1 - (float) i / slices,
00419                 (float) j / stacks);
00420         }
00421         glVertex3f(radiusLow * sintemp,
00422             radiusLow * costemp, zLow);
00423         }
00424         glEnd();
00425     }
00426     break;
00427       default:
00428     break;
00429     }
00430 }
00431 
00432 void GLAPIENTRY
00433 gluDisk(GLUquadric *qobj, GLdouble innerRadius, GLdouble outerRadius,
00434         GLint slices, GLint loops)
00435 {
00436     gluPartialDisk(qobj, innerRadius, outerRadius, slices, loops, 0.0, 360.0);
00437 }
00438 
00439 void GLAPIENTRY
00440 gluPartialDisk(GLUquadric *qobj, GLdouble innerRadius,
00441            GLdouble outerRadius, GLint slices, GLint loops,
00442            GLdouble startAngle, GLdouble sweepAngle)
00443 {
00444     GLint i,j;
00445     GLfloat sinCache[CACHE_SIZE];
00446     GLfloat cosCache[CACHE_SIZE];
00447     GLfloat angle;
00448     GLfloat sintemp, costemp;
00449     GLfloat deltaRadius;
00450     GLfloat radiusLow, radiusHigh;
00451     GLfloat texLow = 0, texHigh = 0;
00452     GLfloat angleOffset;
00453     GLint slices2;
00454     GLint finish;
00455 
00456     if (slices >= CACHE_SIZE) slices = CACHE_SIZE-1;
00457     if (slices < 2 || loops < 1 || outerRadius <= 0.0 || innerRadius < 0.0 ||
00458         innerRadius > outerRadius) {
00459     gluQuadricError(qobj, GLU_INVALID_VALUE);
00460     return;
00461     }
00462 
00463     if (sweepAngle < -360.0) sweepAngle = 360.0;
00464     if (sweepAngle > 360.0) sweepAngle = 360.0;
00465     if (sweepAngle < 0) {
00466     startAngle += sweepAngle;
00467     sweepAngle = -sweepAngle;
00468     }
00469 
00470     if (sweepAngle == 360.0) {
00471     slices2 = slices;
00472     } else {
00473     slices2 = slices + 1;
00474     }
00475 
00476     /* Compute length (needed for normal calculations) */
00477     deltaRadius = outerRadius - innerRadius;
00478 
00479     /* Cache is the vertex locations cache */
00480 
00481     angleOffset = startAngle / 180.0 * PI;
00482     for (i = 0; i <= slices; i++) {
00483     angle = angleOffset + ((PI * sweepAngle) / 180.0) * i / slices;
00484     sinCache[i] = SIN(angle);
00485     cosCache[i] = COS(angle);
00486     }
00487 
00488     if (sweepAngle == 360.0) {
00489     sinCache[slices] = sinCache[0];
00490     cosCache[slices] = cosCache[0];
00491     }
00492 
00493     switch(qobj->normals) {
00494       case GLU_FLAT:
00495       case GLU_SMOOTH:
00496     if (qobj->orientation == GLU_OUTSIDE) {
00497         glNormal3f(0.0, 0.0, 1.0);
00498     } else {
00499         glNormal3f(0.0, 0.0, -1.0);
00500     }
00501     break;
00502       default:
00503       case GLU_NONE:
00504     break;
00505     }
00506 
00507     switch (qobj->drawStyle) {
00508       case GLU_FILL:
00509     if (innerRadius == 0.0) {
00510         finish = loops - 1;
00511         /* Triangle strip for inner polygons */
00512         glBegin(GL_TRIANGLE_FAN);
00513         if (qobj->textureCoords) {
00514         glTexCoord2f(0.5, 0.5);
00515         }
00516         glVertex3f(0.0, 0.0, 0.0);
00517         radiusLow = outerRadius -
00518             deltaRadius * ((float) (loops-1) / loops);
00519         if (qobj->textureCoords) {
00520         texLow = radiusLow / outerRadius / 2;
00521         }
00522 
00523         if (qobj->orientation == GLU_OUTSIDE) {
00524         for (i = slices; i >= 0; i--) {
00525             if (qobj->textureCoords) {
00526             glTexCoord2f(texLow * sinCache[i] + 0.5,
00527                 texLow * cosCache[i] + 0.5);
00528             }
00529             glVertex3f(radiusLow * sinCache[i],
00530                 radiusLow * cosCache[i], 0.0);
00531         }
00532         } else {
00533         for (i = 0; i <= slices; i++) {
00534             if (qobj->textureCoords) {
00535             glTexCoord2f(texLow * sinCache[i] + 0.5,
00536                 texLow * cosCache[i] + 0.5);
00537             }
00538             glVertex3f(radiusLow * sinCache[i],
00539                 radiusLow * cosCache[i], 0.0);
00540         }
00541         }
00542         glEnd();
00543     } else {
00544         finish = loops;
00545     }
00546     for (j = 0; j < finish; j++) {
00547         radiusLow = outerRadius - deltaRadius * ((float) j / loops);
00548         radiusHigh = outerRadius - deltaRadius * ((float) (j + 1) / loops);
00549         if (qobj->textureCoords) {
00550         texLow = radiusLow / outerRadius / 2;
00551         texHigh = radiusHigh / outerRadius / 2;
00552         }
00553 
00554         glBegin(GL_QUAD_STRIP);
00555         for (i = 0; i <= slices; i++) {
00556         if (qobj->orientation == GLU_OUTSIDE) {
00557             if (qobj->textureCoords) {
00558             glTexCoord2f(texLow * sinCache[i] + 0.5,
00559                 texLow * cosCache[i] + 0.5);
00560             }
00561             glVertex3f(radiusLow * sinCache[i],
00562                 radiusLow * cosCache[i], 0.0);
00563 
00564             if (qobj->textureCoords) {
00565             glTexCoord2f(texHigh * sinCache[i] + 0.5,
00566                 texHigh * cosCache[i] + 0.5);
00567             }
00568             glVertex3f(radiusHigh * sinCache[i],
00569                 radiusHigh * cosCache[i], 0.0);
00570         } else {
00571             if (qobj->textureCoords) {
00572             glTexCoord2f(texHigh * sinCache[i] + 0.5,
00573                 texHigh * cosCache[i] + 0.5);
00574             }
00575             glVertex3f(radiusHigh * sinCache[i],
00576                 radiusHigh * cosCache[i], 0.0);
00577 
00578             if (qobj->textureCoords) {
00579             glTexCoord2f(texLow * sinCache[i] + 0.5,
00580                 texLow * cosCache[i] + 0.5);
00581             }
00582             glVertex3f(radiusLow * sinCache[i],
00583                 radiusLow * cosCache[i], 0.0);
00584         }
00585         }
00586         glEnd();
00587     }
00588     break;
00589       case GLU_POINT:
00590     glBegin(GL_POINTS);
00591     for (i = 0; i < slices2; i++) {
00592         sintemp = sinCache[i];
00593         costemp = cosCache[i];
00594         for (j = 0; j <= loops; j++) {
00595         radiusLow = outerRadius - deltaRadius * ((float) j / loops);
00596 
00597         if (qobj->textureCoords) {
00598             texLow = radiusLow / outerRadius / 2;
00599 
00600             glTexCoord2f(texLow * sinCache[i] + 0.5,
00601                 texLow * cosCache[i] + 0.5);
00602         }
00603         glVertex3f(radiusLow * sintemp, radiusLow * costemp, 0.0);
00604         }
00605     }
00606     glEnd();
00607     break;
00608       case GLU_LINE:
00609     if (innerRadius == outerRadius) {
00610         glBegin(GL_LINE_STRIP);
00611 
00612         for (i = 0; i <= slices; i++) {
00613         if (qobj->textureCoords) {
00614             glTexCoord2f(sinCache[i] / 2 + 0.5,
00615                 cosCache[i] / 2 + 0.5);
00616         }
00617         glVertex3f(innerRadius * sinCache[i],
00618             innerRadius * cosCache[i], 0.0);
00619         }
00620         glEnd();
00621         break;
00622     }
00623     for (j = 0; j <= loops; j++) {
00624         radiusLow = outerRadius - deltaRadius * ((float) j / loops);
00625         if (qobj->textureCoords) {
00626         texLow = radiusLow / outerRadius / 2;
00627         }
00628 
00629         glBegin(GL_LINE_STRIP);
00630         for (i = 0; i <= slices; i++) {
00631         if (qobj->textureCoords) {
00632             glTexCoord2f(texLow * sinCache[i] + 0.5,
00633                 texLow * cosCache[i] + 0.5);
00634         }
00635         glVertex3f(radiusLow * sinCache[i],
00636             radiusLow * cosCache[i], 0.0);
00637         }
00638         glEnd();
00639     }
00640     for (i=0; i < slices2; i++) {
00641         sintemp = sinCache[i];
00642         costemp = cosCache[i];
00643         glBegin(GL_LINE_STRIP);
00644         for (j = 0; j <= loops; j++) {
00645         radiusLow = outerRadius - deltaRadius * ((float) j / loops);
00646         if (qobj->textureCoords) {
00647             texLow = radiusLow / outerRadius / 2;
00648         }
00649 
00650         if (qobj->textureCoords) {
00651             glTexCoord2f(texLow * sinCache[i] + 0.5,
00652                 texLow * cosCache[i] + 0.5);
00653         }
00654         glVertex3f(radiusLow * sintemp, radiusLow * costemp, 0.0);
00655         }
00656         glEnd();
00657     }
00658     break;
00659       case GLU_SILHOUETTE:
00660     if (sweepAngle < 360.0) {
00661         for (i = 0; i <= slices; i+= slices) {
00662         sintemp = sinCache[i];
00663         costemp = cosCache[i];
00664         glBegin(GL_LINE_STRIP);
00665         for (j = 0; j <= loops; j++) {
00666             radiusLow = outerRadius - deltaRadius * ((float) j / loops);
00667 
00668             if (qobj->textureCoords) {
00669             texLow = radiusLow / outerRadius / 2;
00670             glTexCoord2f(texLow * sinCache[i] + 0.5,
00671                 texLow * cosCache[i] + 0.5);
00672             }
00673             glVertex3f(radiusLow * sintemp, radiusLow * costemp, 0.0);
00674         }
00675         glEnd();
00676         }
00677     }
00678     for (j = 0; j <= loops; j += loops) {
00679         radiusLow = outerRadius - deltaRadius * ((float) j / loops);
00680         if (qobj->textureCoords) {
00681         texLow = radiusLow / outerRadius / 2;
00682         }
00683 
00684         glBegin(GL_LINE_STRIP);
00685         for (i = 0; i <= slices; i++) {
00686         if (qobj->textureCoords) {
00687             glTexCoord2f(texLow * sinCache[i] + 0.5,
00688                 texLow * cosCache[i] + 0.5);
00689         }
00690         glVertex3f(radiusLow * sinCache[i],
00691             radiusLow * cosCache[i], 0.0);
00692         }
00693         glEnd();
00694         if (innerRadius == outerRadius) break;
00695     }
00696     break;
00697       default:
00698     break;
00699     }
00700 }
00701 
00702 void GLAPIENTRY
00703 gluSphere(GLUquadric *qobj, GLdouble radius, GLint slices, GLint stacks)
00704 {
00705     GLint i,j;
00706     GLfloat sinCache1a[CACHE_SIZE];
00707     GLfloat cosCache1a[CACHE_SIZE];
00708     GLfloat sinCache2a[CACHE_SIZE];
00709     GLfloat cosCache2a[CACHE_SIZE];
00710     GLfloat sinCache3a[CACHE_SIZE];
00711     GLfloat cosCache3a[CACHE_SIZE];
00712     GLfloat sinCache1b[CACHE_SIZE];
00713     GLfloat cosCache1b[CACHE_SIZE];
00714     GLfloat sinCache2b[CACHE_SIZE];
00715     GLfloat cosCache2b[CACHE_SIZE];
00716     GLfloat sinCache3b[CACHE_SIZE];
00717     GLfloat cosCache3b[CACHE_SIZE];
00718     GLfloat angle;
00719     GLfloat zLow, zHigh;
00720     GLfloat sintemp1, sintemp2=0, sintemp3=0, sintemp4=0;
00721     GLfloat costemp1, costemp2=0, costemp3=0, costemp4=0;
00722     GLboolean needCache2, needCache3;
00723     GLint start, finish;
00724 
00725     if (slices >= CACHE_SIZE) slices = CACHE_SIZE-1;
00726     if (stacks >= CACHE_SIZE) stacks = CACHE_SIZE-1;
00727     if (slices < 2 || stacks < 1 || radius < 0.0) {
00728     gluQuadricError(qobj, GLU_INVALID_VALUE);
00729     return;
00730     }
00731 
00732     /* Cache is the vertex locations cache */
00733     /* Cache2 is the various normals at the vertices themselves */
00734     /* Cache3 is the various normals for the faces */
00735     needCache2 = needCache3 = GL_FALSE;
00736 
00737     if (qobj->normals == GLU_SMOOTH) {
00738     needCache2 = GL_TRUE;
00739     }
00740 
00741     if (qobj->normals == GLU_FLAT) {
00742     if (qobj->drawStyle != GLU_POINT) {
00743         needCache3 = GL_TRUE;
00744     }
00745     if (qobj->drawStyle == GLU_LINE) {
00746         needCache2 = GL_TRUE;
00747     }
00748     }
00749 
00750     for (i = 0; i < slices; i++) {
00751     angle = 2 * PI * i / slices;
00752     sinCache1a[i] = SIN(angle);
00753     cosCache1a[i] = COS(angle);
00754     if (needCache2) {
00755         sinCache2a[i] = sinCache1a[i];
00756         cosCache2a[i] = cosCache1a[i];
00757     }
00758     }
00759 
00760     for (j = 0; j <= stacks; j++) {
00761     angle = PI * j / stacks;
00762     if (needCache2) {
00763         if (qobj->orientation == GLU_OUTSIDE) {
00764         sinCache2b[j] = SIN(angle);
00765         cosCache2b[j] = COS(angle);
00766         } else {
00767         sinCache2b[j] = -SIN(angle);
00768         cosCache2b[j] = -COS(angle);
00769         }
00770     }
00771     sinCache1b[j] = radius * SIN(angle);
00772     cosCache1b[j] = radius * COS(angle);
00773     }
00774     /* Make sure it comes to a point */
00775     sinCache1b[0] = 0;
00776     sinCache1b[stacks] = 0;
00777 
00778     if (needCache3) {
00779     for (i = 0; i < slices; i++) {
00780         angle = 2 * PI * (i-0.5) / slices;
00781         sinCache3a[i] = SIN(angle);
00782         cosCache3a[i] = COS(angle);
00783     }
00784     for (j = 0; j <= stacks; j++) {
00785         angle = PI * (j - 0.5) / stacks;
00786         if (qobj->orientation == GLU_OUTSIDE) {
00787         sinCache3b[j] = SIN(angle);
00788         cosCache3b[j] = COS(angle);
00789         } else {
00790         sinCache3b[j] = -SIN(angle);
00791         cosCache3b[j] = -COS(angle);
00792         }
00793     }
00794     }
00795 
00796     sinCache1a[slices] = sinCache1a[0];
00797     cosCache1a[slices] = cosCache1a[0];
00798     if (needCache2) {
00799     sinCache2a[slices] = sinCache2a[0];
00800     cosCache2a[slices] = cosCache2a[0];
00801     }
00802     if (needCache3) {
00803     sinCache3a[slices] = sinCache3a[0];
00804     cosCache3a[slices] = cosCache3a[0];
00805     }
00806 
00807     switch (qobj->drawStyle) {
00808       case GLU_FILL:
00809     /* Do ends of sphere as TRIANGLE_FAN's (if not texturing)
00810     ** We don't do it when texturing because we need to respecify the
00811     ** texture coordinates of the apex for every adjacent vertex (because
00812     ** it isn't a constant for that point)
00813     */
00814     if (!(qobj->textureCoords)) {
00815         start = 1;
00816         finish = stacks - 1;
00817 
00818         /* Low end first (j == 0 iteration) */
00819         sintemp2 = sinCache1b[1];
00820         zHigh = cosCache1b[1];
00821         switch(qobj->normals) {
00822           case GLU_FLAT:
00823         sintemp3 = sinCache3b[1];
00824         costemp3 = cosCache3b[1];
00825         break;
00826           case GLU_SMOOTH:
00827         sintemp3 = sinCache2b[1];
00828         costemp3 = cosCache2b[1];
00829         glNormal3f(sinCache2a[0] * sinCache2b[0],
00830             cosCache2a[0] * sinCache2b[0],
00831             cosCache2b[0]);
00832         break;
00833           default:
00834         break;
00835         }
00836         glBegin(GL_TRIANGLE_FAN);
00837         glVertex3f(0.0, 0.0, radius);
00838         if (qobj->orientation == GLU_OUTSIDE) {
00839         for (i = slices; i >= 0; i--) {
00840             switch(qobj->normals) {
00841               case GLU_SMOOTH:
00842             glNormal3f(sinCache2a[i] * sintemp3,
00843                 cosCache2a[i] * sintemp3,
00844                 costemp3);
00845             break;
00846               case GLU_FLAT:
00847             if (i != slices) {
00848                 glNormal3f(sinCache3a[i+1] * sintemp3,
00849                     cosCache3a[i+1] * sintemp3,
00850                     costemp3);
00851             }
00852             break;
00853               case GLU_NONE:
00854               default:
00855             break;
00856             }
00857             glVertex3f(sintemp2 * sinCache1a[i],
00858                 sintemp2 * cosCache1a[i], zHigh);
00859         }
00860         } else {
00861         for (i = 0; i <= slices; i++) {
00862             switch(qobj->normals) {
00863               case GLU_SMOOTH:
00864             glNormal3f(sinCache2a[i] * sintemp3,
00865                 cosCache2a[i] * sintemp3,
00866                 costemp3);
00867             break;
00868               case GLU_FLAT:
00869             glNormal3f(sinCache3a[i] * sintemp3,
00870                 cosCache3a[i] * sintemp3,
00871                 costemp3);
00872             break;
00873               case GLU_NONE:
00874               default:
00875             break;
00876             }
00877             glVertex3f(sintemp2 * sinCache1a[i],
00878                 sintemp2 * cosCache1a[i], zHigh);
00879         }
00880         }
00881         glEnd();
00882 
00883         /* High end next (j == stacks-1 iteration) */
00884         sintemp2 = sinCache1b[stacks-1];
00885         zHigh = cosCache1b[stacks-1];
00886         switch(qobj->normals) {
00887           case GLU_FLAT:
00888         sintemp3 = sinCache3b[stacks];
00889         costemp3 = cosCache3b[stacks];
00890         break;
00891           case GLU_SMOOTH:
00892         sintemp3 = sinCache2b[stacks-1];
00893         costemp3 = cosCache2b[stacks-1];
00894         glNormal3f(sinCache2a[stacks] * sinCache2b[stacks],
00895             cosCache2a[stacks] * sinCache2b[stacks],
00896             cosCache2b[stacks]);
00897         break;
00898           default:
00899         break;
00900         }
00901         glBegin(GL_TRIANGLE_FAN);
00902         glVertex3f(0.0, 0.0, -radius);
00903         if (qobj->orientation == GLU_OUTSIDE) {
00904         for (i = 0; i <= slices; i++) {
00905             switch(qobj->normals) {
00906               case GLU_SMOOTH:
00907             glNormal3f(sinCache2a[i] * sintemp3,
00908                 cosCache2a[i] * sintemp3,
00909                 costemp3);
00910             break;
00911               case GLU_FLAT:
00912             glNormal3f(sinCache3a[i] * sintemp3,
00913                 cosCache3a[i] * sintemp3,
00914                 costemp3);
00915             break;
00916               case GLU_NONE:
00917               default:
00918             break;
00919             }
00920             glVertex3f(sintemp2 * sinCache1a[i],
00921                 sintemp2 * cosCache1a[i], zHigh);
00922         }
00923         } else {
00924         for (i = slices; i >= 0; i--) {
00925             switch(qobj->normals) {
00926               case GLU_SMOOTH:
00927             glNormal3f(sinCache2a[i] * sintemp3,
00928                 cosCache2a[i] * sintemp3,
00929                 costemp3);
00930             break;
00931               case GLU_FLAT:
00932             if (i != slices) {
00933                 glNormal3f(sinCache3a[i+1] * sintemp3,
00934                     cosCache3a[i+1] * sintemp3,
00935                     costemp3);
00936             }
00937             break;
00938               case GLU_NONE:
00939               default:
00940             break;
00941             }
00942             glVertex3f(sintemp2 * sinCache1a[i],
00943                 sintemp2 * cosCache1a[i], zHigh);
00944         }
00945         }
00946         glEnd();
00947     } else {
00948         start = 0;
00949         finish = stacks;
00950     }
00951     for (j = start; j < finish; j++) {
00952         zLow = cosCache1b[j];
00953         zHigh = cosCache1b[j+1];
00954         sintemp1 = sinCache1b[j];
00955         sintemp2 = sinCache1b[j+1];
00956         switch(qobj->normals) {
00957           case GLU_FLAT:
00958         sintemp4 = sinCache3b[j+1];
00959         costemp4 = cosCache3b[j+1];
00960         break;
00961           case GLU_SMOOTH:
00962         if (qobj->orientation == GLU_OUTSIDE) {
00963             sintemp3 = sinCache2b[j+1];
00964             costemp3 = cosCache2b[j+1];
00965             sintemp4 = sinCache2b[j];
00966             costemp4 = cosCache2b[j];
00967         } else {
00968             sintemp3 = sinCache2b[j];
00969             costemp3 = cosCache2b[j];
00970             sintemp4 = sinCache2b[j+1];
00971             costemp4 = cosCache2b[j+1];
00972         }
00973         break;
00974           default:
00975         break;
00976         }
00977 
00978         glBegin(GL_QUAD_STRIP);
00979         for (i = 0; i <= slices; i++) {
00980         switch(qobj->normals) {
00981           case GLU_SMOOTH:
00982             glNormal3f(sinCache2a[i] * sintemp3,
00983                 cosCache2a[i] * sintemp3,
00984                 costemp3);
00985             break;
00986           case GLU_FLAT:
00987           case GLU_NONE:
00988           default:
00989             break;
00990         }
00991         if (qobj->orientation == GLU_OUTSIDE) {
00992             if (qobj->textureCoords) {
00993             glTexCoord2f(1 - (float) i / slices,
00994                 1 - (float) (j+1) / stacks);
00995             }
00996             glVertex3f(sintemp2 * sinCache1a[i],
00997                 sintemp2 * cosCache1a[i], zHigh);
00998         } else {
00999             if (qobj->textureCoords) {
01000             glTexCoord2f(1 - (float) i / slices,
01001                 1 - (float) j / stacks);
01002             }
01003             glVertex3f(sintemp1 * sinCache1a[i],
01004                 sintemp1 * cosCache1a[i], zLow);
01005         }
01006         switch(qobj->normals) {
01007           case GLU_SMOOTH:
01008             glNormal3f(sinCache2a[i] * sintemp4,
01009                 cosCache2a[i] * sintemp4,
01010                 costemp4);
01011             break;
01012           case GLU_FLAT:
01013             glNormal3f(sinCache3a[i] * sintemp4,
01014                 cosCache3a[i] * sintemp4,
01015                 costemp4);
01016             break;
01017           case GLU_NONE:
01018           default:
01019             break;
01020         }
01021         if (qobj->orientation == GLU_OUTSIDE) {
01022             if (qobj->textureCoords) {
01023             glTexCoord2f(1 - (float) i / slices,
01024                 1 - (float) j / stacks);
01025             }
01026             glVertex3f(sintemp1 * sinCache1a[i],
01027                 sintemp1 * cosCache1a[i], zLow);
01028         } else {
01029             if (qobj->textureCoords) {
01030             glTexCoord2f(1 - (float) i / slices,
01031                 1 - (float) (j+1) / stacks);
01032             }
01033             glVertex3f(sintemp2 * sinCache1a[i],
01034                 sintemp2 * cosCache1a[i], zHigh);
01035         }
01036         }
01037         glEnd();
01038     }
01039     break;
01040       case GLU_POINT:
01041     glBegin(GL_POINTS);
01042     for (j = 0; j <= stacks; j++) {
01043         sintemp1 = sinCache1b[j];
01044         costemp1 = cosCache1b[j];
01045         switch(qobj->normals) {
01046           case GLU_FLAT:
01047           case GLU_SMOOTH:
01048         sintemp2 = sinCache2b[j];
01049         costemp2 = cosCache2b[j];
01050         break;
01051           default:
01052         break;
01053         }
01054         for (i = 0; i < slices; i++) {
01055         switch(qobj->normals) {
01056           case GLU_FLAT:
01057           case GLU_SMOOTH:
01058             glNormal3f(sinCache2a[i] * sintemp2,
01059                 cosCache2a[i] * sintemp2,
01060                 costemp2);
01061             break;
01062           case GLU_NONE:
01063           default:
01064             break;
01065         }
01066 
01067         zLow = j * radius / stacks;
01068 
01069         if (qobj->textureCoords) {
01070             glTexCoord2f(1 - (float) i / slices,
01071                 1 - (float) j / stacks);
01072         }
01073         glVertex3f(sintemp1 * sinCache1a[i],
01074             sintemp1 * cosCache1a[i], costemp1);
01075         }
01076     }
01077     glEnd();
01078     break;
01079       case GLU_LINE:
01080       case GLU_SILHOUETTE:
01081     for (j = 1; j < stacks; j++) {
01082         sintemp1 = sinCache1b[j];
01083         costemp1 = cosCache1b[j];
01084         switch(qobj->normals) {
01085           case GLU_FLAT:
01086           case GLU_SMOOTH:
01087         sintemp2 = sinCache2b[j];
01088         costemp2 = cosCache2b[j];
01089         break;
01090           default:
01091         break;
01092         }
01093 
01094         glBegin(GL_LINE_STRIP);
01095         for (i = 0; i <= slices; i++) {
01096         switch(qobj->normals) {
01097           case GLU_FLAT:
01098             glNormal3f(sinCache3a[i] * sintemp2,
01099                 cosCache3a[i] * sintemp2,
01100                 costemp2);
01101             break;
01102           case GLU_SMOOTH:
01103             glNormal3f(sinCache2a[i] * sintemp2,
01104                 cosCache2a[i] * sintemp2,
01105                 costemp2);
01106             break;
01107           case GLU_NONE:
01108           default:
01109             break;
01110         }
01111         if (qobj->textureCoords) {
01112             glTexCoord2f(1 - (float) i / slices,
01113                 1 - (float) j / stacks);
01114         }
01115         glVertex3f(sintemp1 * sinCache1a[i],
01116             sintemp1 * cosCache1a[i], costemp1);
01117         }
01118         glEnd();
01119     }
01120     for (i = 0; i < slices; i++) {
01121         sintemp1 = sinCache1a[i];
01122         costemp1 = cosCache1a[i];
01123         switch(qobj->normals) {
01124           case GLU_FLAT:
01125           case GLU_SMOOTH:
01126         sintemp2 = sinCache2a[i];
01127         costemp2 = cosCache2a[i];
01128         break;
01129           default:
01130         break;
01131         }
01132 
01133         glBegin(GL_LINE_STRIP);
01134         for (j = 0; j <= stacks; j++) {
01135         switch(qobj->normals) {
01136           case GLU_FLAT:
01137             glNormal3f(sintemp2 * sinCache3b[j],
01138                 costemp2 * sinCache3b[j],
01139                 cosCache3b[j]);
01140             break;
01141           case GLU_SMOOTH:
01142             glNormal3f(sintemp2 * sinCache2b[j],
01143                 costemp2 * sinCache2b[j],
01144                 cosCache2b[j]);
01145             break;
01146           case GLU_NONE:
01147           default:
01148             break;
01149         }
01150 
01151         if (qobj->textureCoords) {
01152             glTexCoord2f(1 - (float) i / slices,
01153                 1 - (float) j / stacks);
01154         }
01155         glVertex3f(sintemp1 * sinCache1b[j],
01156             costemp1 * sinCache1b[j], cosCache1b[j]);
01157         }
01158         glEnd();
01159     }
01160     break;
01161       default:
01162     break;
01163     }
01164 }

Generated on Fri May 25 2012 04:21:58 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.