quad.c revision 32001f49
1/* 2 * Copyright (c) 1991, 1992, 1993 Silicon Graphics, Inc. 3 * 4 * Permission to use, copy, modify, distribute, and sell this software and 5 * its documentation for any purpose is hereby granted without fee, provided 6 * that (i) the above copyright notices and this permission notice appear in 7 * all copies of the software and related documentation, and (ii) the name of 8 * Silicon Graphics may not be used in any advertising or 9 * publicity relating to the software without the specific, prior written 10 * permission of Silicon Graphics. 11 * 12 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF 13 * ANY KIND, 14 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 15 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. 16 * 17 * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR 18 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, 19 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 20 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 21 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 22 * OF THIS SOFTWARE. 23 */ 24 25#include <stdio.h> 26#include <string.h> 27#include <stdlib.h> 28#include "glut_wrap.h" 29 30 31#define PI 3.141592654 32#define BLACK 0 33#define GRAY 128 34#define WHITE 255 35#define RD 0xA4,0x00,0x00,0xFF 36#define WT 0xFF,0xFF,0xFF,0xFF 37#define brickImageWidth 16 38#define brickImageHeight 16 39 40 41#include "loadppm.c" 42 43GLenum rgb, doubleBuffer; 44 45#include "tkmap.c" 46 47float black[3] = { 48 0.0, 0.0, 0.0 49}; 50float blue[3] = { 51 0.0, 0.0, 1.0 52}; 53float gray[3] = { 54 0.5, 0.5, 0.5 55}; 56float white[3] = { 57 1.0, 1.0, 1.0 58}; 59 60GLenum doDither = GL_TRUE; 61GLenum shade = GL_TRUE; 62GLenum texture = GL_TRUE; 63 64float xRotation = 30.0, yRotation = 30.0, zRotation = 0.0; 65GLint radius1, radius2; 66GLdouble angle1, angle2; 67GLint slices, stacks; 68GLint height; 69GLint orientation = GLU_OUTSIDE; 70GLint whichQuadric=0; 71GLUquadricObj *quadObj; 72 73GLubyte brickImage[4*brickImageWidth*brickImageHeight] = { 74 RD, RD, RD, RD, RD, RD, RD, RD, RD, WT, RD, RD, RD, RD, RD, RD, 75 RD, RD, RD, RD, RD, RD, RD, RD, RD, WT, RD, RD, RD, RD, RD, RD, 76 RD, RD, RD, RD, RD, RD, RD, RD, RD, WT, RD, RD, RD, RD, RD, RD, 77 RD, RD, RD, RD, RD, RD, RD, RD, RD, WT, RD, RD, RD, RD, RD, RD, 78 WT, WT, WT, WT, WT, WT, WT, WT, WT, WT, WT, WT, WT, WT, WT, WT, 79 RD, RD, RD, WT, RD, RD, RD, RD, RD, RD, RD, RD, RD, WT, RD, RD, 80 RD, RD, RD, WT, RD, RD, RD, RD, RD, RD, RD, RD, RD, WT, RD, RD, 81 RD, RD, RD, WT, RD, RD, RD, RD, RD, RD, RD, RD, RD, WT, RD, RD, 82 RD, RD, RD, WT, RD, RD, RD, RD, RD, RD, RD, RD, RD, WT, RD, RD, 83 WT, WT, WT, WT, WT, WT, WT, WT, WT, WT, WT, WT, WT, WT, WT, WT, 84 RD, RD, RD, RD, RD, RD, RD, WT, RD, RD, RD, RD, RD, RD, RD, RD, 85 RD, RD, RD, RD, RD, RD, RD, WT, RD, RD, RD, RD, RD, RD, RD, RD, 86 RD, RD, RD, RD, RD, RD, RD, WT, RD, RD, RD, RD, RD, RD, RD, RD, 87 RD, RD, RD, RD, RD, RD, RD, WT, RD, RD, RD, RD, RD, RD, RD, RD, 88 WT, WT, WT, WT, WT, WT, WT, WT, WT, WT, WT, WT, WT, WT, WT, WT, 89 RD, RD, RD, RD, WT, RD, RD, RD, RD, RD, RD, RD, RD, RD, WT, RD 90}; 91char *texFileName = 0; 92 93 94static void GLAPIENTRY ErrorHandler(GLenum which) 95{ 96 97 fprintf(stderr, "Quad Error: %s\n", (char *) gluErrorString(which)); 98} 99 100static void Init(void) 101{ 102 static GLint colorIndexes[3] = {0, 200, 255}; 103 static float ambient[] = {0.1, 0.1, 0.1, 1.0}; 104 static float diffuse[] = {0.5, 1.0, 1.0, 1.0}; 105 static float position[] = {90.0, 90.0, 150.0, 0.0}; 106 static float front_mat_shininess[] = {30.0}; 107 static float front_mat_specular[] = {0.2, 0.2, 0.2, 1.0}; 108 static float front_mat_diffuse[] = {0.5, 0.28, 0.38, 1.0}; 109 static float back_mat_shininess[] = {50.0}; 110 static float back_mat_specular[] = {0.5, 0.5, 0.2, 1.0}; 111 static float back_mat_diffuse[] = {1.0, 1.0, 0.2, 1.0}; 112 static float lmodel_ambient[] = {1.0, 1.0, 1.0, 1.0}; 113 static float lmodel_twoside[] = {GL_TRUE}; 114 static float decal[] = {GL_DECAL}; 115 static float repeat[] = {GL_REPEAT}; 116 static float nearest[] = {GL_NEAREST}; 117 static PPMImage *image; 118 119 if (!rgb) { 120 SetGreyRamp(); 121 } 122 glClearColor(0.0, 0.0, 0.0, 0.0); 123 124 glEnable(GL_DEPTH_TEST); 125 126 glLightfv(GL_LIGHT0, GL_AMBIENT, ambient); 127 glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse); 128 glLightfv(GL_LIGHT0, GL_POSITION, position); 129 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient); 130 glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, lmodel_twoside); 131 glEnable(GL_LIGHTING); 132 glEnable(GL_LIGHT0); 133 134 glMaterialfv(GL_FRONT, GL_SHININESS, front_mat_shininess); 135 glMaterialfv(GL_FRONT, GL_SPECULAR, front_mat_specular); 136 glMaterialfv(GL_FRONT, GL_DIFFUSE, front_mat_diffuse); 137 glMaterialfv(GL_BACK, GL_SHININESS, back_mat_shininess); 138 glMaterialfv(GL_BACK, GL_SPECULAR, back_mat_specular); 139 glMaterialfv(GL_BACK, GL_DIFFUSE, back_mat_diffuse); 140 if (!rgb) { 141 glMaterialiv( GL_FRONT_AND_BACK, GL_COLOR_INDEXES, colorIndexes); 142 } 143 144 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, decal); 145 glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, repeat); 146 glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, repeat); 147 glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, nearest); 148 glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, nearest); 149 if (texFileName) { 150 image = LoadPPM(texFileName); 151 glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 152 gluBuild2DMipmaps(GL_TEXTURE_2D, 3, image->sizeX, image->sizeY, 153 GL_RGB, GL_UNSIGNED_BYTE, image->data); 154 } else { 155 glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 156 glTexImage2D(GL_TEXTURE_2D, 0, 4, brickImageWidth, brickImageHeight, 157 0, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid *)brickImage); 158 } 159 160 quadObj = gluNewQuadric(); 161 gluQuadricCallback(quadObj, GLU_ERROR, ErrorHandler); 162 163 radius1 = 10; 164 radius2 = 5; 165 angle1 = 90; 166 angle2 = 180; 167 slices = 16; 168 stacks = 10; 169 height = 20; 170} 171 172static void Reshape(int width, int height) 173{ 174 175 glViewport(0, 0, (GLint)width, (GLint)height); 176 177 glMatrixMode(GL_PROJECTION); 178 glLoadIdentity(); 179 glFrustum(-1, 1, -1, 1, 1, 10); 180 gluLookAt(2, 2, 2, 0, 0, 0, 0, 0, 1); 181 glMatrixMode(GL_MODELVIEW); 182} 183 184static void Key2(int key, int x, int y) 185{ 186 187 switch (key) { 188 case GLUT_KEY_LEFT: 189 yRotation += 5; 190 break; 191 case GLUT_KEY_RIGHT: 192 yRotation -= 5; 193 break; 194 case GLUT_KEY_UP: 195 xRotation += 5; 196 break; 197 case GLUT_KEY_DOWN: 198 xRotation -= 5; 199 break; 200 default: 201 return; 202 } 203 204 glutPostRedisplay(); 205} 206 207static void Key(unsigned char key, int x, int y) 208{ 209 210 switch (key) { 211 case 27: 212 exit(1); 213 214 case 'X': 215 zRotation += 5; 216 break; 217 case 'x': 218 zRotation -= 5; 219 break; 220 221 case '1': 222 gluQuadricDrawStyle(quadObj, GLU_FILL); 223 break; 224 case '2': 225 gluQuadricDrawStyle(quadObj, GLU_POINT); 226 break; 227 case '3': 228 gluQuadricDrawStyle(quadObj, GLU_LINE); 229 break; 230 case '4': 231 gluQuadricDrawStyle(quadObj, GLU_SILHOUETTE); 232 break; 233 234 case '0': 235 shade = !shade; 236 if (shade) { 237 glShadeModel(GL_SMOOTH); 238 gluQuadricNormals(quadObj, GLU_SMOOTH); 239 } else { 240 glShadeModel(GL_FLAT); 241 gluQuadricNormals(quadObj, GLU_FLAT); 242 } 243 break; 244 245 case 'A': 246 stacks++; 247 break; 248 case 'a': 249 stacks--; 250 break; 251 252 case 'S': 253 slices++; 254 break; 255 case 's': 256 slices--; 257 break; 258 259 case 'd': 260 switch(orientation) { 261 case GLU_OUTSIDE: 262 orientation = GLU_INSIDE; 263 break; 264 case GLU_INSIDE: 265 default: 266 orientation = GLU_OUTSIDE; 267 break; 268 } 269 gluQuadricOrientation(quadObj, orientation); 270 break; 271 272 case 'f': 273 whichQuadric = (whichQuadric + 1) % 4; 274 break; 275 276 case 'G': 277 radius1 += 1; 278 break; 279 case 'g': 280 radius1 -= 1; 281 break; 282 283 case 'J': 284 radius2 += 1; 285 break; 286 case 'j': 287 radius2 -= 1; 288 break; 289 290 case 'H': 291 height += 2; 292 break; 293 case 'h': 294 height -= 2; 295 break; 296 297 case 'K': 298 angle1 += 5; 299 break; 300 case 'k': 301 angle1 -= 5; 302 break; 303 304 case 'L': 305 angle2 += 5; 306 break; 307 case 'l': 308 angle2 -= 5; 309 break; 310 311 case 'z': 312 texture = !texture; 313 if (texture) { 314 gluQuadricTexture(quadObj, GL_TRUE); 315 glEnable(GL_TEXTURE_2D); 316 } else { 317 gluQuadricTexture(quadObj, GL_FALSE); 318 glDisable(GL_TEXTURE_2D); 319 } 320 break; 321 322 case 'q': 323 glDisable(GL_CULL_FACE); 324 break; 325 case 'w': 326 glEnable(GL_CULL_FACE); 327 glCullFace(GL_FRONT); 328 break; 329 case 'e': 330 glEnable(GL_CULL_FACE); 331 glCullFace(GL_BACK); 332 break; 333 334 case 'r': 335 glFrontFace(GL_CW); 336 break; 337 case 't': 338 glFrontFace(GL_CCW); 339 break; 340 341 case 'y': 342 doDither = !doDither; 343 (doDither) ? glEnable(GL_DITHER) : glDisable(GL_DITHER); 344 break; 345 default: 346 return; 347 } 348 349 glutPostRedisplay(); 350} 351 352static void Draw(void) 353{ 354 355 glLoadIdentity(); 356 glRotatef(xRotation, 1, 0, 0); 357 glRotatef(yRotation, 0, 1, 0); 358 glRotatef(zRotation, 0, 0, 1); 359 360 glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); 361 362 glColor3f(1.0, 1.0, 1.0); 363 switch (whichQuadric) { 364 case 0: 365 glTranslatef(0, 0, -height/20.0); 366 gluCylinder(quadObj, radius1/10.0, radius2/10.0, height/10.0, 367 slices, stacks); 368 break; 369 case 1: 370 gluSphere(quadObj, radius1/10.0, slices, stacks); 371 break; 372 case 2: 373 gluPartialDisk(quadObj, radius2/10.0, radius1/10.0, slices, 374 stacks, angle1, angle2); 375 break; 376 case 3: 377 gluDisk(quadObj, radius2/10.0, radius1/10.0, slices, stacks); 378 break; 379 } 380 381 glFlush(); 382 383 if (doubleBuffer) { 384 glutSwapBuffers(); 385 } 386} 387 388static GLenum Args(int argc, char **argv) 389{ 390 GLint i; 391 392 rgb = GL_TRUE; 393 doubleBuffer = GL_FALSE; 394 395 for (i = 1; i < argc; i++) { 396 if (strcmp(argv[i], "-ci") == 0) { 397 rgb = GL_FALSE; 398 } else if (strcmp(argv[i], "-rgb") == 0) { 399 rgb = GL_TRUE; 400 } else if (strcmp(argv[i], "-sb") == 0) { 401 doubleBuffer = GL_FALSE; 402 } else if (strcmp(argv[i], "-db") == 0) { 403 doubleBuffer = GL_TRUE; 404 } else if (strcmp(argv[i], "-f") == 0) { 405 if (i+1 >= argc || argv[i+1][0] == '-') { 406 printf("-f (No file name).\n"); 407 return GL_FALSE; 408 } else { 409 texFileName = argv[++i]; 410 } 411 } else { 412 printf("%s (Bad option).\n", argv[i]); 413 return GL_FALSE; 414 } 415 } 416 return GL_TRUE; 417} 418 419int main(int argc, char **argv) 420{ 421 GLenum type; 422 423 glutInit(&argc, argv); 424 425 if (Args(argc, argv) == GL_FALSE) { 426 exit(1); 427 } 428 429 glutInitWindowPosition(0, 0); glutInitWindowSize( 300, 300); 430 431 type = GLUT_DEPTH; 432 type |= (rgb) ? GLUT_RGB : GLUT_INDEX; 433 type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE; 434 glutInitDisplayMode(type); 435 436 if (glutCreateWindow("Quad Test") == GL_FALSE) { 437 exit(1); 438 } 439 440 InitMap(); 441 442 Init(); 443 444 glutReshapeFunc(Reshape); 445 glutKeyboardFunc(Key); 446 glutSpecialFunc(Key2); 447 glutDisplayFunc(Draw); 448 glutMainLoop(); 449 return 0; 450} 451