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