Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenquad.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
1.7.6.1
|