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
43 GLenum rgb, doubleBuffer;
44
45 #include "tkmap.c"
46
47 float black[3] = {
48 0.0, 0.0, 0.0
49 };
50 float blue[3] = {
51 0.0, 0.0, 1.0
52 };
53 float gray[3] = {
54 0.5, 0.5, 0.5
55 };
56 float white[3] = {
57 1.0, 1.0, 1.0
58 };
59
60 GLenum doDither = GL_TRUE;
61 GLenum shade = GL_TRUE;
62 GLenum texture = GL_TRUE;
63
64 float xRotation = 30.0, yRotation = 30.0, zRotation = 0.0;
65 GLint radius1, radius2;
66 GLdouble angle1, angle2;
67 GLint slices, stacks;
68 GLint height;
69 GLint orientation = GLU_OUTSIDE;
70 GLint whichQuadric=0;
71 GLUquadricObj *quadObj;
72
73 GLubyte 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 };
91 char *texFileName = 0;
92
93
ErrorHandler(GLenum which)94 static void GLAPIENTRY ErrorHandler(GLenum which)
95 {
96
97 fprintf(stderr, "Quad Error: %s\n", (char *) gluErrorString(which));
98 }
99
Init(void)100 static 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
Reshape(int width,int height)172 static 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
Key2(int key,int x,int y)184 static 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
Key(unsigned char key,int x,int y)207 static 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
Draw(void)352 static 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
Args(int argc,char ** argv)388 static 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
main(int argc,char ** argv)419 int 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