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