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