blob: 1a4504175fd5686b3d8d7482165f9c43d144a124 [file] [log] [blame]
jtgafb833d1999-08-19 00:55:39 +00001/*
2 * Demo of a reflective, texture-mapped surface with OpenGL.
3 * Brian Paul August 14, 1995 This file is in the public domain.
4 *
5 * Hardware texture mapping is highly recommended!
6 *
7 * The basic steps are:
8 * 1. Render the reflective object (a polygon) from the normal viewpoint,
9 * setting the stencil planes = 1.
10 * 2. Render the scene from a special viewpoint: the viewpoint which
11 * is on the opposite side of the reflective plane. Only draw where
12 * stencil = 1. This draws the objects in the reflective surface.
13 * 3. Render the scene from the original viewpoint. This draws the
14 * objects in the normal fashion. Use blending when drawing
15 * the reflective, textured surface.
16 *
17 * This is a very crude demo. It could be much better.
18 */
19
20/*
Brian Paul7a6bb1b2000-04-12 01:08:30 +000021 * Authors:
22 * Brian Paul
23 * Dirk Reiners (reiners@igd.fhg.de) made some modifications to this code.
24 * Mark Kilgard (April 1997)
25 * Brian Paul (April 2000 - added keyboard d/s options)
Brian Paul5d7c4862005-08-24 21:32:02 +000026 * Brian Paul (August 2005 - added multi window feature)
jtgafb833d1999-08-19 00:55:39 +000027 */
28
jtgafb833d1999-08-19 00:55:39 +000029
Brian Paul5d7c4862005-08-24 21:32:02 +000030#include <assert.h>
jtgafb833d1999-08-19 00:55:39 +000031#include <math.h>
32#include <stdio.h>
33#include <stdlib.h>
34#include "GL/glut.h"
Brian Paul92eddb02005-01-09 17:37:50 +000035#include "showbuffer.h"
36#include "readtex.h"
jtgafb833d1999-08-19 00:55:39 +000037
38
39#define DEG2RAD (3.14159/180.0)
jtgafb833d1999-08-19 00:55:39 +000040#define TABLE_TEXTURE "../images/tile.rgb"
jtgafb833d1999-08-19 00:55:39 +000041#define MAX_OBJECTS 2
Brian Paul5d7c4862005-08-24 21:32:02 +000042#define INIT_WIDTH 400
43#define INIT_HEIGHT 300
jtgafb833d1999-08-19 00:55:39 +000044
45
Brian Paul5d7c4862005-08-24 21:32:02 +000046struct window {
47 int id; /* returned by glutCreateWindow() */
48 int width, height;
49 GLboolean anim;
50 GLfloat xrot, yrot;
51 GLfloat spin;
52 GLenum showBuffer;
Brian Pauld5783732005-08-31 16:42:59 +000053 GLenum drawBuffer;
Brian Paul5d7c4862005-08-24 21:32:02 +000054 GLuint table_list;
55 GLuint objects_list[MAX_OBJECTS];
56 double t0;
57 struct window *next;
58};
59
60
61static struct window *FirstWindow = NULL;
62
63
64static void
65CreateWindow(void);
66
67
68static struct window *
69CurrentWindow(void)
70{
71 int id = glutGetWindow();
72 struct window *w;
73 for (w = FirstWindow; w; w = w->next) {
74 if (w->id == id)
75 return w;
76 }
77 return NULL;
78}
79
80
81static GLboolean
82AnyAnimating(void)
83{
84 struct window *w;
85 for (w = FirstWindow; w; w = w->next) {
86 if (w->anim)
87 return 1;
88 }
89 return 0;
90}
91
92
93static void
94KillWindow(struct window *w)
95{
96 struct window *win, *prev = NULL;
97 for (win = FirstWindow; win; win = win->next) {
98 if (win == w) {
99 if (prev) {
100 prev->next = win->next;
101 }
102 else {
103 FirstWindow = win->next;
104 }
105 glutDestroyWindow(win->id);
106 win->next = NULL;
107 free(win);
108 return;
109 }
110 prev = win;
111 }
112}
113
114
115static void
116KillAllWindows(void)
117{
118 while (FirstWindow)
119 KillWindow(FirstWindow);
120}
121
122
123static GLuint
124MakeTable(void)
jtgafb833d1999-08-19 00:55:39 +0000125{
126 static GLfloat table_mat[] = { 1.0, 1.0, 1.0, 0.6 };
127 static GLfloat gray[] = { 0.4, 0.4, 0.4, 1.0 };
Brian Paul5d7c4862005-08-24 21:32:02 +0000128 GLuint table_list;
jtgafb833d1999-08-19 00:55:39 +0000129
130 table_list = glGenLists(1);
131 glNewList( table_list, GL_COMPILE );
132
133 /* load table's texture */
134 glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, table_mat );
Brian Paul5d7c4862005-08-24 21:32:02 +0000135 /*glMaterialfv( GL_FRONT, GL_EMISSION, gray );*/
jtgafb833d1999-08-19 00:55:39 +0000136 glMaterialfv( GL_FRONT, GL_DIFFUSE, table_mat );
137 glMaterialfv( GL_FRONT, GL_AMBIENT, gray );
138
139 /* draw textured square for the table */
140 glPushMatrix();
141 glScalef( 4.0, 4.0, 4.0 );
142 glBegin( GL_POLYGON );
143 glNormal3f( 0.0, 1.0, 0.0 );
144 glTexCoord2f( 0.0, 0.0 ); glVertex3f( -1.0, 0.0, 1.0 );
145 glTexCoord2f( 1.0, 0.0 ); glVertex3f( 1.0, 0.0, 1.0 );
146 glTexCoord2f( 1.0, 1.0 ); glVertex3f( 1.0, 0.0, -1.0 );
147 glTexCoord2f( 0.0, 1.0 ); glVertex3f( -1.0, 0.0, -1.0 );
148 glEnd();
149 glPopMatrix();
150
151 glDisable( GL_TEXTURE_2D );
152
153 glEndList();
Brian Paul5d7c4862005-08-24 21:32:02 +0000154 return table_list;
jtgafb833d1999-08-19 00:55:39 +0000155}
156
157
Brian Paul5d7c4862005-08-24 21:32:02 +0000158static void
159MakeObjects(GLuint *objects_list)
jtgafb833d1999-08-19 00:55:39 +0000160{
161 GLUquadricObj *q;
162
163 static GLfloat cyan[] = { 0.0, 1.0, 1.0, 1.0 };
164 static GLfloat green[] = { 0.2, 1.0, 0.2, 1.0 };
165 static GLfloat black[] = { 0.0, 0.0, 0.0, 0.0 };
166
167 q = gluNewQuadric();
168 gluQuadricDrawStyle( q, GLU_FILL );
169 gluQuadricNormals( q, GLU_SMOOTH );
170
171 objects_list[0] = glGenLists(1);
172 glNewList( objects_list[0], GL_COMPILE );
173 glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, cyan );
174 glMaterialfv( GL_FRONT, GL_EMISSION, black );
175 gluCylinder( q, 0.5, 0.5, 1.0, 15, 1 );
176 glEndList();
177
178 objects_list[1] = glGenLists(1);
179 glNewList( objects_list[1], GL_COMPILE );
180 glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green );
181 glMaterialfv( GL_FRONT, GL_EMISSION, black );
182 gluCylinder( q, 1.5, 0.0, 2.5, 15, 1 );
183 glEndList();
Brian Paul1ad3b7e2005-11-19 23:09:14 +0000184
185 gluDeleteQuadric(q);
jtgafb833d1999-08-19 00:55:39 +0000186}
187
188
Brian Paul5d7c4862005-08-24 21:32:02 +0000189static void
190InitWindow(struct window *w)
jtgafb833d1999-08-19 00:55:39 +0000191{
Brian Paul5d7c4862005-08-24 21:32:02 +0000192 GLint imgWidth, imgHeight;
193 GLenum imgFormat;
194 GLubyte *image = NULL;
jtgafb833d1999-08-19 00:55:39 +0000195
Brian Paul5d7c4862005-08-24 21:32:02 +0000196 w->table_list = MakeTable();
197 MakeObjects(w->objects_list);
198
199 image = LoadRGBImage( TABLE_TEXTURE, &imgWidth, &imgHeight, &imgFormat );
200 if (!image) {
jtgafb833d1999-08-19 00:55:39 +0000201 printf("Couldn't read %s\n", TABLE_TEXTURE);
202 exit(0);
203 }
204
Brian Paul5d7c4862005-08-24 21:32:02 +0000205 gluBuild2DMipmaps(GL_TEXTURE_2D, 3, imgWidth, imgHeight,
206 imgFormat, GL_UNSIGNED_BYTE, image);
207 free(image);
jtgafb833d1999-08-19 00:55:39 +0000208
209 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
210 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
211 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
212 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
jtgafb833d1999-08-19 00:55:39 +0000213
jtgafb833d1999-08-19 00:55:39 +0000214 glShadeModel( GL_FLAT );
215
216 glEnable( GL_LIGHT0 );
217 glEnable( GL_LIGHTING );
218
Brian Paul73ccfa02001-04-25 15:51:32 +0000219 glClearColor( 0.5, 0.5, 0.9, 0.0 );
jtgafb833d1999-08-19 00:55:39 +0000220
221 glEnable( GL_NORMALIZE );
222}
223
224
Brian Paul5d7c4862005-08-24 21:32:02 +0000225static void
226Reshape(int width, int height)
jtgafb833d1999-08-19 00:55:39 +0000227{
Brian Paul5d7c4862005-08-24 21:32:02 +0000228 struct window *w = CurrentWindow();
Brian Paul7a6bb1b2000-04-12 01:08:30 +0000229 GLfloat yAspect = 2.5;
Brian Paul5d7c4862005-08-24 21:32:02 +0000230 GLfloat xAspect = yAspect * (float) width / (float) height;
231 w->width = width;
232 w->height = height;
233 glViewport(0, 0, width, height);
jtgafb833d1999-08-19 00:55:39 +0000234 glMatrixMode(GL_PROJECTION);
235 glLoadIdentity();
Brian Paul7a6bb1b2000-04-12 01:08:30 +0000236 glFrustum( -xAspect, xAspect, -yAspect, yAspect, 10.0, 30.0 );
jtgafb833d1999-08-19 00:55:39 +0000237 glMatrixMode(GL_MODELVIEW);
238 glLoadIdentity();
239}
240
241
Brian Paul5d7c4862005-08-24 21:32:02 +0000242static void
243DrawObjects(struct window *w, GLfloat eyex, GLfloat eyey, GLfloat eyez)
jtgafb833d1999-08-19 00:55:39 +0000244{
245 (void) eyex;
246 (void) eyey;
247 (void) eyez;
248#ifndef USE_ZBUFFER
Brian Paul7a6bb1b2000-04-12 01:08:30 +0000249 if (eyex<0.5) {
jtgafb833d1999-08-19 00:55:39 +0000250#endif
Brian Paul5d7c4862005-08-24 21:32:02 +0000251 glPushMatrix();
252 glTranslatef( 1.0, 1.5, 0.0 );
253 glRotatef( w->spin, 1.0, 0.5, 0.0 );
254 glRotatef( 0.5*w->spin, 0.0, 0.5, 1.0 );
255 glCallList( w->objects_list[0] );
256 glPopMatrix();
257
258 glPushMatrix();
259 glTranslatef( -1.0, 0.85+3.0*fabs( cos(0.01*w->spin) ), 0.0 );
260 glRotatef( 0.5*w->spin, 0.0, 0.5, 1.0 );
261 glRotatef( w->spin, 1.0, 0.5, 0.0 );
262 glScalef( 0.5, 0.5, 0.5 );
263 glCallList( w->objects_list[1] );
264 glPopMatrix();
jtgafb833d1999-08-19 00:55:39 +0000265#ifndef USE_ZBUFFER
Brian Paul7a6bb1b2000-04-12 01:08:30 +0000266 }
267 else {
Brian Paul5d7c4862005-08-24 21:32:02 +0000268 glPushMatrix();
269 glTranslatef( -1.0, 0.85+3.0*fabs( cos(0.01*w->spin) ), 0.0 );
270 glRotatef( 0.5*w->spin, 0.0, 0.5, 1.0 );
271 glRotatef( w->spin, 1.0, 0.5, 0.0 );
272 glScalef( 0.5, 0.5, 0.5 );
273 glCallList( w->objects_list[1] );
274 glPopMatrix();
jtgafb833d1999-08-19 00:55:39 +0000275
Brian Paul5d7c4862005-08-24 21:32:02 +0000276 glPushMatrix();
277 glTranslatef( 1.0, 1.5, 0.0 );
278 glRotatef( w->spin, 1.0, 0.5, 0.0 );
279 glRotatef( 0.5*w->spin, 0.0, 0.5, 1.0 );
280 glCallList( w->objects_list[0] );
281 glPopMatrix();
Brian Paul7a6bb1b2000-04-12 01:08:30 +0000282 }
jtgafb833d1999-08-19 00:55:39 +0000283#endif
284}
285
286
Brian Paul5d7c4862005-08-24 21:32:02 +0000287static void
288DrawTable(struct window *w)
jtgafb833d1999-08-19 00:55:39 +0000289{
Brian Paul5d7c4862005-08-24 21:32:02 +0000290 glCallList(w->table_list);
jtgafb833d1999-08-19 00:55:39 +0000291}
292
293
Brian Paul5d7c4862005-08-24 21:32:02 +0000294static void
295DrawWindow(void)
jtgafb833d1999-08-19 00:55:39 +0000296{
Brian Paul5d7c4862005-08-24 21:32:02 +0000297 struct window *w = CurrentWindow();
Brian Paul7a6bb1b2000-04-12 01:08:30 +0000298 static GLfloat light_pos[] = { 0.0, 20.0, 0.0, 1.0 };
jtgafb833d1999-08-19 00:55:39 +0000299 GLfloat dist = 20.0;
300 GLfloat eyex, eyey, eyez;
301
Brian Pauld5783732005-08-31 16:42:59 +0000302 glDrawBuffer(w->drawBuffer);
303 glReadBuffer(w->drawBuffer);
jtgafb833d1999-08-19 00:55:39 +0000304
Brian Pauld5783732005-08-31 16:42:59 +0000305 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
jtgafb833d1999-08-19 00:55:39 +0000306
Brian Paul5d7c4862005-08-24 21:32:02 +0000307 eyex = dist * cos(w->yrot * DEG2RAD) * cos(w->xrot * DEG2RAD);
308 eyez = dist * sin(w->yrot * DEG2RAD) * cos(w->xrot * DEG2RAD);
309 eyey = dist * sin(w->xrot * DEG2RAD);
jtgafb833d1999-08-19 00:55:39 +0000310
311 /* view from top */
312 glPushMatrix();
313 gluLookAt( eyex, eyey, eyez, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0 );
314
315 glLightfv( GL_LIGHT0, GL_POSITION, light_pos );
316
317 /* draw table into stencil planes */
jtgafb833d1999-08-19 00:55:39 +0000318 glDisable( GL_DEPTH_TEST );
Brian Paul7a6bb1b2000-04-12 01:08:30 +0000319 glEnable( GL_STENCIL_TEST );
jtgafb833d1999-08-19 00:55:39 +0000320 glStencilFunc( GL_ALWAYS, 1, 0xffffffff );
321 glStencilOp( GL_REPLACE, GL_REPLACE, GL_REPLACE );
322 glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE );
Brian Paul5d7c4862005-08-24 21:32:02 +0000323 DrawTable(w);
jtgafb833d1999-08-19 00:55:39 +0000324 glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
325
jtgafb833d1999-08-19 00:55:39 +0000326 glEnable( GL_DEPTH_TEST );
jtgafb833d1999-08-19 00:55:39 +0000327
328 /* render view from below (reflected viewport) */
329 /* only draw where stencil==1 */
330 if (eyey>0.0) {
331 glPushMatrix();
332
333 glStencilFunc( GL_EQUAL, 1, 0xffffffff ); /* draw if ==1 */
334 glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
335 glScalef( 1.0, -1.0, 1.0 );
336
337 /* Reposition light in reflected space. */
338 glLightfv(GL_LIGHT0, GL_POSITION, light_pos);
339
Brian Paul5d7c4862005-08-24 21:32:02 +0000340 DrawObjects(w, eyex, eyey, eyez);
jtgafb833d1999-08-19 00:55:39 +0000341 glPopMatrix();
342
343 /* Restore light's original unreflected position. */
344 glLightfv(GL_LIGHT0, GL_POSITION, light_pos);
345 }
346
347 glDisable( GL_STENCIL_TEST );
348
349 glEnable( GL_BLEND );
350 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
351
jtgafb833d1999-08-19 00:55:39 +0000352 glEnable( GL_TEXTURE_2D );
Brian Paul5d7c4862005-08-24 21:32:02 +0000353 DrawTable(w);
jtgafb833d1999-08-19 00:55:39 +0000354 glDisable( GL_TEXTURE_2D );
355 glDisable( GL_BLEND );
356
357 /* view from top */
358 glPushMatrix();
359
Brian Paul5d7c4862005-08-24 21:32:02 +0000360 DrawObjects(w, eyex, eyey, eyez);
jtgafb833d1999-08-19 00:55:39 +0000361
362 glPopMatrix();
363
364 glPopMatrix();
365
Brian Paul5d7c4862005-08-24 21:32:02 +0000366 if (w->showBuffer == GL_DEPTH) {
367 ShowDepthBuffer(w->width, w->height, 1.0, 0.0);
Brian Paul7a6bb1b2000-04-12 01:08:30 +0000368 }
Brian Paul5d7c4862005-08-24 21:32:02 +0000369 else if (w->showBuffer == GL_STENCIL) {
370 ShowStencilBuffer(w->width, w->height, 255.0, 0.0);
Brian Paul7a6bb1b2000-04-12 01:08:30 +0000371 }
Brian Paul5d7c4862005-08-24 21:32:02 +0000372 else if (w->showBuffer == GL_ALPHA) {
373 ShowAlphaBuffer(w->width, w->height);
Brian Paul73ccfa02001-04-25 15:51:32 +0000374 }
jtgafb833d1999-08-19 00:55:39 +0000375
Brian Pauld5783732005-08-31 16:42:59 +0000376 if (w->drawBuffer == GL_BACK)
377 glutSwapBuffers();
378 else
379 glFinish();
Brian Paulcefc42f2000-09-15 16:43:57 +0000380
Brian Paul5d7c4862005-08-24 21:32:02 +0000381 /* calc/show frame rate */
Brian Paulcefc42f2000-09-15 16:43:57 +0000382 {
Brian Paul5d7c4862005-08-24 21:32:02 +0000383 static GLint t0 = 0;
384 static GLint frames = 0;
Brian Paulcefc42f2000-09-15 16:43:57 +0000385 GLint t = glutGet(GLUT_ELAPSED_TIME);
Brian Paul5d7c4862005-08-24 21:32:02 +0000386 frames++;
387 if (t - t0 >= 5000) {
388 GLfloat seconds = (t - t0) / 1000.0;
389 GLfloat fps = frames / seconds;
390 printf("%d frames in %g seconds = %g FPS\n", frames, seconds, fps);
391 t0 = t;
392 frames = 0;
Brian Paulcefc42f2000-09-15 16:43:57 +0000393 }
394 }
jtgafb833d1999-08-19 00:55:39 +0000395}
jtgafb833d1999-08-19 00:55:39 +0000396
397
Brian Paul5d7c4862005-08-24 21:32:02 +0000398static void
399Idle(void)
Brian Paul2b2e6212001-01-23 23:43:53 +0000400{
Brian Paul5d7c4862005-08-24 21:32:02 +0000401 double t = glutGet(GLUT_ELAPSED_TIME) / 1000.0;
402 struct window *w;
403 for (w = FirstWindow; w; w = w->next) {
404 if (w->anim) {
405 double dt;
406 if (w->t0 < 0.0)
407 w->t0 = t;
408 dt = t - w->t0;
409 w->t0 = t;
410 w->spin += 60.0 * dt;
411 w->yrot += 90.0 * dt;
412 assert(w->id);
413 glutSetWindow(w->id);
414 glutPostRedisplay();
415 }
416 }
Brian Paul2b2e6212001-01-23 23:43:53 +0000417}
418
419
Brian Paul5d7c4862005-08-24 21:32:02 +0000420static void
Brian Paul8e247d52005-08-25 17:46:04 +0000421UpdateIdleFunc(void)
422{
423 if (AnyAnimating())
424 glutIdleFunc(Idle);
425 else
426 glutIdleFunc(NULL);
427}
428
429static void
Brian Paul5d7c4862005-08-24 21:32:02 +0000430Key(unsigned char key, int x, int y)
jtgafb833d1999-08-19 00:55:39 +0000431{
Brian Paul5d7c4862005-08-24 21:32:02 +0000432 struct window *w = CurrentWindow();
jtgafb833d1999-08-19 00:55:39 +0000433 (void) x;
434 (void) y;
Brian Paul5d7c4862005-08-24 21:32:02 +0000435
436 switch (key) {
437 case 'd':
438 w->showBuffer = GL_DEPTH;
439 glutPostRedisplay();
440 break;
441 case 's':
442 w->showBuffer = GL_STENCIL;
443 glutPostRedisplay();
444 break;
445 case 'a':
446 w->showBuffer = GL_ALPHA;
447 glutPostRedisplay();
448 break;
449 case 'c':
450 w->showBuffer = GL_NONE;
451 glutPostRedisplay();
452 break;
Brian Pauld5783732005-08-31 16:42:59 +0000453 case 'f':
454 if (w->drawBuffer == GL_FRONT)
455 w->drawBuffer = GL_BACK;
456 else
457 w->drawBuffer = GL_FRONT;
458 glutPostRedisplay();
459 break;
Brian Paul5d7c4862005-08-24 21:32:02 +0000460 case ' ':
461 w->anim = !w->anim;
462 w->t0 = -1;
Brian Paul8e247d52005-08-25 17:46:04 +0000463 UpdateIdleFunc();
Brian Paul5d7c4862005-08-24 21:32:02 +0000464 glutPostRedisplay();
465 break;
466 case 'n':
467 CreateWindow();
Brian Paul8e247d52005-08-25 17:46:04 +0000468 UpdateIdleFunc();
Brian Paul5d7c4862005-08-24 21:32:02 +0000469 break;
470 case 'k':
471 KillWindow(w);
472 if (FirstWindow == NULL)
473 exit(0);
474 break;
475 case 27:
476 KillAllWindows();
jtgafb833d1999-08-19 00:55:39 +0000477 exit(0);
Brian Paul5d7c4862005-08-24 21:32:02 +0000478 break;
479 default:
480 ;
Brian Paul7a6bb1b2000-04-12 01:08:30 +0000481 }
jtgafb833d1999-08-19 00:55:39 +0000482}
483
484
Brian Paul5d7c4862005-08-24 21:32:02 +0000485static void
486SpecialKey(int key, int x, int y)
jtgafb833d1999-08-19 00:55:39 +0000487{
Brian Paul5d7c4862005-08-24 21:32:02 +0000488 struct window *w = CurrentWindow();
jtgafb833d1999-08-19 00:55:39 +0000489 (void) x;
490 (void) y;
491 switch (key) {
492 case GLUT_KEY_UP:
Brian Paul5d7c4862005-08-24 21:32:02 +0000493 w->xrot += 3.0;
494 if (w->xrot > 85)
495 w->xrot = 85;
jtgafb833d1999-08-19 00:55:39 +0000496 break;
497 case GLUT_KEY_DOWN:
Brian Paul5d7c4862005-08-24 21:32:02 +0000498 w->xrot -= 3.0;
499 if (w->xrot < 5)
500 w->xrot = 5;
jtgafb833d1999-08-19 00:55:39 +0000501 break;
502 case GLUT_KEY_LEFT:
Brian Paul5d7c4862005-08-24 21:32:02 +0000503 w->yrot += 3.0;
jtgafb833d1999-08-19 00:55:39 +0000504 break;
505 case GLUT_KEY_RIGHT:
Brian Paul5d7c4862005-08-24 21:32:02 +0000506 w->yrot -= 3.0;
jtgafb833d1999-08-19 00:55:39 +0000507 break;
508 }
509 glutPostRedisplay();
510}
511
512
Brian Paul5d7c4862005-08-24 21:32:02 +0000513static void
514CreateWindow(void)
jtgafb833d1999-08-19 00:55:39 +0000515{
Brian Paul5d7c4862005-08-24 21:32:02 +0000516 char title[1000];
517 struct window *w = (struct window *) calloc(1, sizeof(struct window));
518
519 glutInitWindowSize(INIT_WIDTH, INIT_HEIGHT);
520 w->id = glutCreateWindow("foo");
521 sprintf(title, "reflect window %d", w->id);
522 glutSetWindowTitle(title);
523 assert(w->id);
524 w->width = INIT_WIDTH;
525 w->height = INIT_HEIGHT;
526 w->anim = GL_TRUE;
527 w->xrot = 30.0;
528 w->yrot = 50.0;
529 w->spin = 0.0;
530 w->showBuffer = GL_NONE;
Brian Pauld5783732005-08-31 16:42:59 +0000531 w->drawBuffer = GL_BACK;
Brian Paul5d7c4862005-08-24 21:32:02 +0000532
533 InitWindow(w);
534
535 glutReshapeFunc(Reshape);
536 glutDisplayFunc(DrawWindow);
jtgafb833d1999-08-19 00:55:39 +0000537 glutKeyboardFunc(Key);
538 glutSpecialFunc(SpecialKey);
Brian Paul5d7c4862005-08-24 21:32:02 +0000539
540 /* insert at head of list */
541 w->next = FirstWindow;
542 FirstWindow = w;
543}
544
545
546static void
547Usage(void)
548{
549 printf("Keys:\n");
550 printf(" a - show alpha buffer\n");
551 printf(" d - show depth buffer\n");
552 printf(" s - show stencil buffer\n");
553 printf(" c - show color buffer\n");
Brian Pauld5783732005-08-31 16:42:59 +0000554 printf(" f - toggle rendering to front/back color buffer\n");
Brian Paul5d7c4862005-08-24 21:32:02 +0000555 printf(" n - create new window\n");
556 printf(" k - kill window\n");
557 printf(" SPACE - toggle animation\n");
558 printf(" ARROWS - rotate scene\n");
559}
560
561
562int
563main(int argc, char *argv[])
564{
565 glutInit(&argc, argv);
566 glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH |
567 GLUT_STENCIL | GLUT_ALPHA);
568 CreateWindow();
569 glutIdleFunc(Idle);
570 Usage();
jtgafb833d1999-08-19 00:55:39 +0000571 glutMainLoop();
572 return 0;
573}