blob: ce0239211fff68dffdf536a57d4770f440d19a91 [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
Karl Schultzb6875312006-03-29 03:42:32 +000045#ifdef _WIN32
46#undef CreateWindowA
47#endif
jtgafb833d1999-08-19 00:55:39 +000048
Brian Paul5d7c4862005-08-24 21:32:02 +000049struct window {
50 int id; /* returned by glutCreateWindow() */
51 int width, height;
52 GLboolean anim;
53 GLfloat xrot, yrot;
54 GLfloat spin;
55 GLenum showBuffer;
Brian Pauld5783732005-08-31 16:42:59 +000056 GLenum drawBuffer;
Brian Paul5d7c4862005-08-24 21:32:02 +000057 GLuint table_list;
58 GLuint objects_list[MAX_OBJECTS];
59 double t0;
60 struct window *next;
61};
62
63
64static struct window *FirstWindow = NULL;
65
66
67static void
68CreateWindow(void);
69
70
71static struct window *
72CurrentWindow(void)
73{
74 int id = glutGetWindow();
75 struct window *w;
76 for (w = FirstWindow; w; w = w->next) {
77 if (w->id == id)
78 return w;
79 }
80 return NULL;
81}
82
83
84static GLboolean
85AnyAnimating(void)
86{
87 struct window *w;
88 for (w = FirstWindow; w; w = w->next) {
89 if (w->anim)
90 return 1;
91 }
92 return 0;
93}
94
95
96static void
97KillWindow(struct window *w)
98{
99 struct window *win, *prev = NULL;
100 for (win = FirstWindow; win; win = win->next) {
101 if (win == w) {
102 if (prev) {
103 prev->next = win->next;
104 }
105 else {
106 FirstWindow = win->next;
107 }
108 glutDestroyWindow(win->id);
109 win->next = NULL;
110 free(win);
111 return;
112 }
113 prev = win;
114 }
115}
116
117
118static void
119KillAllWindows(void)
120{
121 while (FirstWindow)
122 KillWindow(FirstWindow);
123}
124
125
126static GLuint
127MakeTable(void)
jtgafb833d1999-08-19 00:55:39 +0000128{
129 static GLfloat table_mat[] = { 1.0, 1.0, 1.0, 0.6 };
130 static GLfloat gray[] = { 0.4, 0.4, 0.4, 1.0 };
Brian Paul5d7c4862005-08-24 21:32:02 +0000131 GLuint table_list;
jtgafb833d1999-08-19 00:55:39 +0000132
133 table_list = glGenLists(1);
134 glNewList( table_list, GL_COMPILE );
135
136 /* load table's texture */
137 glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, table_mat );
Brian Paul5d7c4862005-08-24 21:32:02 +0000138 /*glMaterialfv( GL_FRONT, GL_EMISSION, gray );*/
jtgafb833d1999-08-19 00:55:39 +0000139 glMaterialfv( GL_FRONT, GL_DIFFUSE, table_mat );
140 glMaterialfv( GL_FRONT, GL_AMBIENT, gray );
141
142 /* draw textured square for the table */
143 glPushMatrix();
144 glScalef( 4.0, 4.0, 4.0 );
145 glBegin( GL_POLYGON );
146 glNormal3f( 0.0, 1.0, 0.0 );
147 glTexCoord2f( 0.0, 0.0 ); glVertex3f( -1.0, 0.0, 1.0 );
148 glTexCoord2f( 1.0, 0.0 ); glVertex3f( 1.0, 0.0, 1.0 );
149 glTexCoord2f( 1.0, 1.0 ); glVertex3f( 1.0, 0.0, -1.0 );
150 glTexCoord2f( 0.0, 1.0 ); glVertex3f( -1.0, 0.0, -1.0 );
151 glEnd();
152 glPopMatrix();
153
154 glDisable( GL_TEXTURE_2D );
155
156 glEndList();
Brian Paul5d7c4862005-08-24 21:32:02 +0000157 return table_list;
jtgafb833d1999-08-19 00:55:39 +0000158}
159
160
Brian Paul5d7c4862005-08-24 21:32:02 +0000161static void
162MakeObjects(GLuint *objects_list)
jtgafb833d1999-08-19 00:55:39 +0000163{
164 GLUquadricObj *q;
165
166 static GLfloat cyan[] = { 0.0, 1.0, 1.0, 1.0 };
167 static GLfloat green[] = { 0.2, 1.0, 0.2, 1.0 };
168 static GLfloat black[] = { 0.0, 0.0, 0.0, 0.0 };
169
170 q = gluNewQuadric();
171 gluQuadricDrawStyle( q, GLU_FILL );
172 gluQuadricNormals( q, GLU_SMOOTH );
173
174 objects_list[0] = glGenLists(1);
175 glNewList( objects_list[0], GL_COMPILE );
176 glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, cyan );
177 glMaterialfv( GL_FRONT, GL_EMISSION, black );
178 gluCylinder( q, 0.5, 0.5, 1.0, 15, 1 );
179 glEndList();
180
181 objects_list[1] = glGenLists(1);
182 glNewList( objects_list[1], GL_COMPILE );
183 glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green );
184 glMaterialfv( GL_FRONT, GL_EMISSION, black );
185 gluCylinder( q, 1.5, 0.0, 2.5, 15, 1 );
186 glEndList();
Brian Paul1ad3b7e2005-11-19 23:09:14 +0000187
188 gluDeleteQuadric(q);
jtgafb833d1999-08-19 00:55:39 +0000189}
190
191
Brian Paul5d7c4862005-08-24 21:32:02 +0000192static void
193InitWindow(struct window *w)
jtgafb833d1999-08-19 00:55:39 +0000194{
Brian Paul5d7c4862005-08-24 21:32:02 +0000195 GLint imgWidth, imgHeight;
196 GLenum imgFormat;
197 GLubyte *image = NULL;
jtgafb833d1999-08-19 00:55:39 +0000198
Brian Paul5d7c4862005-08-24 21:32:02 +0000199 w->table_list = MakeTable();
200 MakeObjects(w->objects_list);
201
202 image = LoadRGBImage( TABLE_TEXTURE, &imgWidth, &imgHeight, &imgFormat );
203 if (!image) {
jtgafb833d1999-08-19 00:55:39 +0000204 printf("Couldn't read %s\n", TABLE_TEXTURE);
205 exit(0);
206 }
207
Brian Paul5d7c4862005-08-24 21:32:02 +0000208 gluBuild2DMipmaps(GL_TEXTURE_2D, 3, imgWidth, imgHeight,
209 imgFormat, GL_UNSIGNED_BYTE, image);
210 free(image);
jtgafb833d1999-08-19 00:55:39 +0000211
212 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
213 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
214 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
215 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
jtgafb833d1999-08-19 00:55:39 +0000216
jtgafb833d1999-08-19 00:55:39 +0000217 glShadeModel( GL_FLAT );
218
219 glEnable( GL_LIGHT0 );
220 glEnable( GL_LIGHTING );
221
Brian Paul73ccfa02001-04-25 15:51:32 +0000222 glClearColor( 0.5, 0.5, 0.9, 0.0 );
jtgafb833d1999-08-19 00:55:39 +0000223
224 glEnable( GL_NORMALIZE );
225}
226
227
Brian Paul5d7c4862005-08-24 21:32:02 +0000228static void
229Reshape(int width, int height)
jtgafb833d1999-08-19 00:55:39 +0000230{
Brian Paul5d7c4862005-08-24 21:32:02 +0000231 struct window *w = CurrentWindow();
Brian Paul7a6bb1b2000-04-12 01:08:30 +0000232 GLfloat yAspect = 2.5;
Brian Paul5d7c4862005-08-24 21:32:02 +0000233 GLfloat xAspect = yAspect * (float) width / (float) height;
234 w->width = width;
235 w->height = height;
236 glViewport(0, 0, width, height);
jtgafb833d1999-08-19 00:55:39 +0000237 glMatrixMode(GL_PROJECTION);
238 glLoadIdentity();
Brian Paul7a6bb1b2000-04-12 01:08:30 +0000239 glFrustum( -xAspect, xAspect, -yAspect, yAspect, 10.0, 30.0 );
jtgafb833d1999-08-19 00:55:39 +0000240 glMatrixMode(GL_MODELVIEW);
241 glLoadIdentity();
242}
243
244
Brian Paul5d7c4862005-08-24 21:32:02 +0000245static void
246DrawObjects(struct window *w, GLfloat eyex, GLfloat eyey, GLfloat eyez)
jtgafb833d1999-08-19 00:55:39 +0000247{
248 (void) eyex;
249 (void) eyey;
250 (void) eyez;
251#ifndef USE_ZBUFFER
Brian Paul7a6bb1b2000-04-12 01:08:30 +0000252 if (eyex<0.5) {
jtgafb833d1999-08-19 00:55:39 +0000253#endif
Brian Paul5d7c4862005-08-24 21:32:02 +0000254 glPushMatrix();
255 glTranslatef( 1.0, 1.5, 0.0 );
256 glRotatef( w->spin, 1.0, 0.5, 0.0 );
257 glRotatef( 0.5*w->spin, 0.0, 0.5, 1.0 );
258 glCallList( w->objects_list[0] );
259 glPopMatrix();
260
261 glPushMatrix();
262 glTranslatef( -1.0, 0.85+3.0*fabs( cos(0.01*w->spin) ), 0.0 );
263 glRotatef( 0.5*w->spin, 0.0, 0.5, 1.0 );
264 glRotatef( w->spin, 1.0, 0.5, 0.0 );
265 glScalef( 0.5, 0.5, 0.5 );
266 glCallList( w->objects_list[1] );
267 glPopMatrix();
jtgafb833d1999-08-19 00:55:39 +0000268#ifndef USE_ZBUFFER
Brian Paul7a6bb1b2000-04-12 01:08:30 +0000269 }
270 else {
Brian Paul5d7c4862005-08-24 21:32:02 +0000271 glPushMatrix();
272 glTranslatef( -1.0, 0.85+3.0*fabs( cos(0.01*w->spin) ), 0.0 );
273 glRotatef( 0.5*w->spin, 0.0, 0.5, 1.0 );
274 glRotatef( w->spin, 1.0, 0.5, 0.0 );
275 glScalef( 0.5, 0.5, 0.5 );
276 glCallList( w->objects_list[1] );
277 glPopMatrix();
jtgafb833d1999-08-19 00:55:39 +0000278
Brian Paul5d7c4862005-08-24 21:32:02 +0000279 glPushMatrix();
280 glTranslatef( 1.0, 1.5, 0.0 );
281 glRotatef( w->spin, 1.0, 0.5, 0.0 );
282 glRotatef( 0.5*w->spin, 0.0, 0.5, 1.0 );
283 glCallList( w->objects_list[0] );
284 glPopMatrix();
Brian Paul7a6bb1b2000-04-12 01:08:30 +0000285 }
jtgafb833d1999-08-19 00:55:39 +0000286#endif
287}
288
289
Brian Paul5d7c4862005-08-24 21:32:02 +0000290static void
291DrawTable(struct window *w)
jtgafb833d1999-08-19 00:55:39 +0000292{
Brian Paul5d7c4862005-08-24 21:32:02 +0000293 glCallList(w->table_list);
jtgafb833d1999-08-19 00:55:39 +0000294}
295
296
Brian Paul5d7c4862005-08-24 21:32:02 +0000297static void
298DrawWindow(void)
jtgafb833d1999-08-19 00:55:39 +0000299{
Brian Paul5d7c4862005-08-24 21:32:02 +0000300 struct window *w = CurrentWindow();
Brian Paul7a6bb1b2000-04-12 01:08:30 +0000301 static GLfloat light_pos[] = { 0.0, 20.0, 0.0, 1.0 };
jtgafb833d1999-08-19 00:55:39 +0000302 GLfloat dist = 20.0;
303 GLfloat eyex, eyey, eyez;
304
Brian Pauld5783732005-08-31 16:42:59 +0000305 glDrawBuffer(w->drawBuffer);
306 glReadBuffer(w->drawBuffer);
jtgafb833d1999-08-19 00:55:39 +0000307
Brian Pauld5783732005-08-31 16:42:59 +0000308 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
jtgafb833d1999-08-19 00:55:39 +0000309
Brian Paul5d7c4862005-08-24 21:32:02 +0000310 eyex = dist * cos(w->yrot * DEG2RAD) * cos(w->xrot * DEG2RAD);
311 eyez = dist * sin(w->yrot * DEG2RAD) * cos(w->xrot * DEG2RAD);
312 eyey = dist * sin(w->xrot * DEG2RAD);
jtgafb833d1999-08-19 00:55:39 +0000313
314 /* view from top */
315 glPushMatrix();
316 gluLookAt( eyex, eyey, eyez, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0 );
317
318 glLightfv( GL_LIGHT0, GL_POSITION, light_pos );
319
320 /* draw table into stencil planes */
jtgafb833d1999-08-19 00:55:39 +0000321 glDisable( GL_DEPTH_TEST );
Brian Paul7a6bb1b2000-04-12 01:08:30 +0000322 glEnable( GL_STENCIL_TEST );
jtgafb833d1999-08-19 00:55:39 +0000323 glStencilFunc( GL_ALWAYS, 1, 0xffffffff );
324 glStencilOp( GL_REPLACE, GL_REPLACE, GL_REPLACE );
325 glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE );
Brian Paul5d7c4862005-08-24 21:32:02 +0000326 DrawTable(w);
jtgafb833d1999-08-19 00:55:39 +0000327 glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
328
jtgafb833d1999-08-19 00:55:39 +0000329 glEnable( GL_DEPTH_TEST );
jtgafb833d1999-08-19 00:55:39 +0000330
331 /* render view from below (reflected viewport) */
332 /* only draw where stencil==1 */
333 if (eyey>0.0) {
334 glPushMatrix();
335
336 glStencilFunc( GL_EQUAL, 1, 0xffffffff ); /* draw if ==1 */
337 glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
338 glScalef( 1.0, -1.0, 1.0 );
339
340 /* Reposition light in reflected space. */
341 glLightfv(GL_LIGHT0, GL_POSITION, light_pos);
342
Brian Paul5d7c4862005-08-24 21:32:02 +0000343 DrawObjects(w, eyex, eyey, eyez);
jtgafb833d1999-08-19 00:55:39 +0000344 glPopMatrix();
345
346 /* Restore light's original unreflected position. */
347 glLightfv(GL_LIGHT0, GL_POSITION, light_pos);
348 }
349
350 glDisable( GL_STENCIL_TEST );
351
352 glEnable( GL_BLEND );
353 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
354
jtgafb833d1999-08-19 00:55:39 +0000355 glEnable( GL_TEXTURE_2D );
Brian Paul5d7c4862005-08-24 21:32:02 +0000356 DrawTable(w);
jtgafb833d1999-08-19 00:55:39 +0000357 glDisable( GL_TEXTURE_2D );
358 glDisable( GL_BLEND );
359
360 /* view from top */
361 glPushMatrix();
362
Brian Paul5d7c4862005-08-24 21:32:02 +0000363 DrawObjects(w, eyex, eyey, eyez);
jtgafb833d1999-08-19 00:55:39 +0000364
365 glPopMatrix();
366
367 glPopMatrix();
368
Brian Paul5d7c4862005-08-24 21:32:02 +0000369 if (w->showBuffer == GL_DEPTH) {
370 ShowDepthBuffer(w->width, w->height, 1.0, 0.0);
Brian Paul7a6bb1b2000-04-12 01:08:30 +0000371 }
Brian Paul5d7c4862005-08-24 21:32:02 +0000372 else if (w->showBuffer == GL_STENCIL) {
373 ShowStencilBuffer(w->width, w->height, 255.0, 0.0);
Brian Paul7a6bb1b2000-04-12 01:08:30 +0000374 }
Brian Paul5d7c4862005-08-24 21:32:02 +0000375 else if (w->showBuffer == GL_ALPHA) {
376 ShowAlphaBuffer(w->width, w->height);
Brian Paul73ccfa02001-04-25 15:51:32 +0000377 }
jtgafb833d1999-08-19 00:55:39 +0000378
Brian Pauld5783732005-08-31 16:42:59 +0000379 if (w->drawBuffer == GL_BACK)
380 glutSwapBuffers();
381 else
382 glFinish();
Brian Paulcefc42f2000-09-15 16:43:57 +0000383
Brian Paul5d7c4862005-08-24 21:32:02 +0000384 /* calc/show frame rate */
Brian Paulcefc42f2000-09-15 16:43:57 +0000385 {
Brian Paul5d7c4862005-08-24 21:32:02 +0000386 static GLint t0 = 0;
387 static GLint frames = 0;
Brian Paulcefc42f2000-09-15 16:43:57 +0000388 GLint t = glutGet(GLUT_ELAPSED_TIME);
Brian Paul5d7c4862005-08-24 21:32:02 +0000389 frames++;
390 if (t - t0 >= 5000) {
391 GLfloat seconds = (t - t0) / 1000.0;
392 GLfloat fps = frames / seconds;
393 printf("%d frames in %g seconds = %g FPS\n", frames, seconds, fps);
394 t0 = t;
395 frames = 0;
Brian Paulcefc42f2000-09-15 16:43:57 +0000396 }
397 }
jtgafb833d1999-08-19 00:55:39 +0000398}
jtgafb833d1999-08-19 00:55:39 +0000399
400
Brian Paul5d7c4862005-08-24 21:32:02 +0000401static void
402Idle(void)
Brian Paul2b2e6212001-01-23 23:43:53 +0000403{
Brian Paul5d7c4862005-08-24 21:32:02 +0000404 double t = glutGet(GLUT_ELAPSED_TIME) / 1000.0;
405 struct window *w;
406 for (w = FirstWindow; w; w = w->next) {
407 if (w->anim) {
408 double dt;
409 if (w->t0 < 0.0)
410 w->t0 = t;
411 dt = t - w->t0;
412 w->t0 = t;
413 w->spin += 60.0 * dt;
414 w->yrot += 90.0 * dt;
415 assert(w->id);
416 glutSetWindow(w->id);
417 glutPostRedisplay();
418 }
419 }
Brian Paul2b2e6212001-01-23 23:43:53 +0000420}
421
422
Brian Paul5d7c4862005-08-24 21:32:02 +0000423static void
Brian Paul8e247d52005-08-25 17:46:04 +0000424UpdateIdleFunc(void)
425{
426 if (AnyAnimating())
427 glutIdleFunc(Idle);
428 else
429 glutIdleFunc(NULL);
430}
431
432static void
Brian Paul5d7c4862005-08-24 21:32:02 +0000433Key(unsigned char key, int x, int y)
jtgafb833d1999-08-19 00:55:39 +0000434{
Brian Paul5d7c4862005-08-24 21:32:02 +0000435 struct window *w = CurrentWindow();
jtgafb833d1999-08-19 00:55:39 +0000436 (void) x;
437 (void) y;
Brian Paul5d7c4862005-08-24 21:32:02 +0000438
439 switch (key) {
440 case 'd':
441 w->showBuffer = GL_DEPTH;
442 glutPostRedisplay();
443 break;
444 case 's':
445 w->showBuffer = GL_STENCIL;
446 glutPostRedisplay();
447 break;
448 case 'a':
449 w->showBuffer = GL_ALPHA;
450 glutPostRedisplay();
451 break;
452 case 'c':
453 w->showBuffer = GL_NONE;
454 glutPostRedisplay();
455 break;
Brian Pauld5783732005-08-31 16:42:59 +0000456 case 'f':
457 if (w->drawBuffer == GL_FRONT)
458 w->drawBuffer = GL_BACK;
459 else
460 w->drawBuffer = GL_FRONT;
461 glutPostRedisplay();
462 break;
Brian Paul5d7c4862005-08-24 21:32:02 +0000463 case ' ':
464 w->anim = !w->anim;
465 w->t0 = -1;
Brian Paul8e247d52005-08-25 17:46:04 +0000466 UpdateIdleFunc();
Brian Paul5d7c4862005-08-24 21:32:02 +0000467 glutPostRedisplay();
468 break;
469 case 'n':
470 CreateWindow();
Brian Paul8e247d52005-08-25 17:46:04 +0000471 UpdateIdleFunc();
Brian Paul5d7c4862005-08-24 21:32:02 +0000472 break;
473 case 'k':
474 KillWindow(w);
475 if (FirstWindow == NULL)
476 exit(0);
477 break;
478 case 27:
479 KillAllWindows();
jtgafb833d1999-08-19 00:55:39 +0000480 exit(0);
Brian Paul5d7c4862005-08-24 21:32:02 +0000481 break;
482 default:
483 ;
Brian Paul7a6bb1b2000-04-12 01:08:30 +0000484 }
jtgafb833d1999-08-19 00:55:39 +0000485}
486
487
Brian Paul5d7c4862005-08-24 21:32:02 +0000488static void
489SpecialKey(int key, int x, int y)
jtgafb833d1999-08-19 00:55:39 +0000490{
Brian Paul5d7c4862005-08-24 21:32:02 +0000491 struct window *w = CurrentWindow();
jtgafb833d1999-08-19 00:55:39 +0000492 (void) x;
493 (void) y;
494 switch (key) {
495 case GLUT_KEY_UP:
Brian Paul5d7c4862005-08-24 21:32:02 +0000496 w->xrot += 3.0;
497 if (w->xrot > 85)
498 w->xrot = 85;
jtgafb833d1999-08-19 00:55:39 +0000499 break;
500 case GLUT_KEY_DOWN:
Brian Paul5d7c4862005-08-24 21:32:02 +0000501 w->xrot -= 3.0;
502 if (w->xrot < 5)
503 w->xrot = 5;
jtgafb833d1999-08-19 00:55:39 +0000504 break;
505 case GLUT_KEY_LEFT:
Brian Paul5d7c4862005-08-24 21:32:02 +0000506 w->yrot += 3.0;
jtgafb833d1999-08-19 00:55:39 +0000507 break;
508 case GLUT_KEY_RIGHT:
Brian Paul5d7c4862005-08-24 21:32:02 +0000509 w->yrot -= 3.0;
jtgafb833d1999-08-19 00:55:39 +0000510 break;
511 }
512 glutPostRedisplay();
513}
514
515
Brian Paul5d7c4862005-08-24 21:32:02 +0000516static void
517CreateWindow(void)
jtgafb833d1999-08-19 00:55:39 +0000518{
Brian Paul5d7c4862005-08-24 21:32:02 +0000519 char title[1000];
520 struct window *w = (struct window *) calloc(1, sizeof(struct window));
521
522 glutInitWindowSize(INIT_WIDTH, INIT_HEIGHT);
523 w->id = glutCreateWindow("foo");
524 sprintf(title, "reflect window %d", w->id);
525 glutSetWindowTitle(title);
526 assert(w->id);
527 w->width = INIT_WIDTH;
528 w->height = INIT_HEIGHT;
529 w->anim = GL_TRUE;
530 w->xrot = 30.0;
531 w->yrot = 50.0;
532 w->spin = 0.0;
533 w->showBuffer = GL_NONE;
Brian Pauld5783732005-08-31 16:42:59 +0000534 w->drawBuffer = GL_BACK;
Brian Paul5d7c4862005-08-24 21:32:02 +0000535
536 InitWindow(w);
537
538 glutReshapeFunc(Reshape);
539 glutDisplayFunc(DrawWindow);
jtgafb833d1999-08-19 00:55:39 +0000540 glutKeyboardFunc(Key);
541 glutSpecialFunc(SpecialKey);
Brian Paul5d7c4862005-08-24 21:32:02 +0000542
543 /* insert at head of list */
544 w->next = FirstWindow;
545 FirstWindow = w;
546}
547
548
549static void
550Usage(void)
551{
552 printf("Keys:\n");
553 printf(" a - show alpha buffer\n");
554 printf(" d - show depth buffer\n");
555 printf(" s - show stencil buffer\n");
556 printf(" c - show color buffer\n");
Brian Pauld5783732005-08-31 16:42:59 +0000557 printf(" f - toggle rendering to front/back color buffer\n");
Brian Paul5d7c4862005-08-24 21:32:02 +0000558 printf(" n - create new window\n");
559 printf(" k - kill window\n");
560 printf(" SPACE - toggle animation\n");
561 printf(" ARROWS - rotate scene\n");
562}
563
564
565int
566main(int argc, char *argv[])
567{
568 glutInit(&argc, argv);
569 glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH |
570 GLUT_STENCIL | GLUT_ALPHA);
571 CreateWindow();
572 glutIdleFunc(Idle);
573 Usage();
jtgafb833d1999-08-19 00:55:39 +0000574 glutMainLoop();
575 return 0;
576}