/* some additional variables */ struct point { float x; float y; float z; } eyept, dir; float azimuth, elevation, roll; /* a method for identifying keys independent of operating system */ KeySym keysym; char buf [256]; XComposeStatus compose; XLookupString ((XKeyEvent *) &report, buf, 256, &keysym, &compose); if (keysym == 'q' || keysym == 'Q') { exit (); } /* how to recognize mouse movement and compute azimuth; add code for elevation */ eventmask = ExposureMask | KeyPressMask | PointerMotionMask | ButtonPressMask | ButtonReleaseMask; XSelectInput (display, in_win, eventmask); ... case MotionNotify: currentx = report.xmotion.x; currenty = report.xmotion.y; /* compute new azimuth/elevation */ glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); do_cube (eyept, azimuth, elevation, roll); glXSwapBuffers (display, win); break; /* how to recognize the left button press on the mouse */ case ButtonPress: if (report.xbutton.button == 1) { while (!XCheckMaskEvent (display, ButtonReleaseMask, &report)) { eyept.x += ZOOM_INC * dir.x; eyept.y += ZOOM_INC * dir.y; eyept.z += ZOOM_INC * dir.z; glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); do_cube (eyept, azimuth, elevation, roll); glXSwapBuffers (display, win); } break; } /* initialize function to get things set up (called once) */ glinit () { float xangle; eyept.x = 0.0; eyept.y = 0.0; eyept.z = 4.0; dir.x = 0.0; dir.y = 0.0; dir.z = -1.0; azimuth = M_PI; elevation = 0.0; roll = 0.0; glShadeModel (GL_SMOOTH); glEnable (GL_DEPTH_TEST); glClearColor (0.3, 0.2, 0.3, 0.0); /* background color */ do_material (); glMatrixMode (GL_MODELVIEW); glLoadIdentity (); do_lights (); picasso (); glMatrixMode (GL_PROJECTION); glLoadIdentity (); /* carve out gob */ gluPerspective (45.0, 1.0, 0.1, 20.0); } /* how to draw triangle i */ glBegin (GL_TRIANGLES); glNormal3fv (pyramid_norm [i]); for (j = 0; j < 3; j++) { glVertex3fv (pyramid_vertex [pyramid_faces [i] [j]]); }; glEnd (); /* do_cube */ do_cube (eye, az, el, ro) struct point eye; float az, el, ro; { float sinA, cosA, sinE, cosE, sinR, cosR; sinA = sin (az); cosA = cos (az); sinE = sin (el); cosE = cos (el); sinR = sin (ro); cosR = cos (ro); dir.x = -sinA * cosE; dir.y = sinE; dir.z = cosA * cosE; ... glPushMatrix(); gluLookAt (eye.x, eye.y, eye.z, dir.x + eye.x, dir.y + eye.y, dir.z + eye.z, up.x, up.y, up.z); picasso (); glPopMatrix(); } /* white light */ GLfloat light0_ambient[] = { 0.0, 0.0, 0.0, 0.0 }; GLfloat light0_diffuse[] = { 1.0, 1.0, 1.0, 0.0 }; GLfloat light0_specular[] = { 1.0, 1.0, 1.0, 0.0 }; GLfloat light0_position[] = { 2.0, 2.0, 2.0, 1.0 }; GLfloat light0_direction[] = { -1.0, -1.0, -1.0, 1.0}; /* blue light */ GLfloat light1_ambient[] = { 0.0, 0.0, 0.0, 0.0 }; GLfloat light1_diffuse[] = { 0.0, 0.0, 1.0, 0.0 }; GLfloat light1_specular[] = { 1.0, 1.0, 1.0, 0.0 }; GLfloat light1_position[] = { -2.0, 2.0, 2.0, 1.0 }; GLfloat light1_direction[] = { 1.0, -1.0, -1.0, 1.0}; do_lights () { /* turn off scene default ambient */ glLightModelfv (GL_LIGHT_MODEL_AMBIENT, light0_ambient); /* make specular correct for spots */ glLightModeli (GL_LIGHT_MODEL_LOCAL_VIEWER, 1); glLightfv (GL_LIGHT0, GL_AMBIENT, light0_ambient); glLightfv (GL_LIGHT0, GL_DIFFUSE, light0_diffuse); glLightfv (GL_LIGHT0, GL_SPECULAR, light0_specular); glLightfv (GL_LIGHT0, GL_POSITION, light0_position); glLightfv (GL_LIGHT0, GL_SPOT_DIRECTION, light0_direction); glLightf (GL_LIGHT0, GL_SPOT_EXPONENT, 5.0); glLightf (GL_LIGHT0, GL_SPOT_CUTOFF, 15.0); glLightf (GL_LIGHT0, GL_CONSTANT_ATTENUATION, 1.0); glLightf (GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.1); glLightf (GL_LIGHT0, GL_QUADRATIC_ATTENUATION, 0.01); glLightfv (GL_LIGHT1, GL_AMBIENT, light1_ambient); glLightfv (GL_LIGHT1, GL_DIFFUSE, light1_diffuse); glLightfv (GL_LIGHT1, GL_SPECULAR, light1_specular); glLightfv (GL_LIGHT1, GL_POSITION, light1_position); glLightfv (GL_LIGHT1, GL_SPOT_DIRECTION, light1_direction); glLightf (GL_LIGHT1, GL_SPOT_EXPONENT, 5.0); glLightf (GL_LIGHT1, GL_SPOT_CUTOFF, 15.0); glLightf (GL_LIGHT1, GL_CONSTANT_ATTENUATION, 1.0); glLightf (GL_LIGHT1, GL_LINEAR_ATTENUATION, 0.1); glLightf (GL_LIGHT1, GL_QUADRATIC_ATTENUATION, 0.01); glEnable (GL_LIGHTING); glEnable (GL_LIGHT0); glEnable (GL_LIGHT1); } GLfloat mat_ambient [] = {0.0, 0.0, 0.0, 1.0}; GLfloat mat_diffuse [] = {0.0, 1.0, 0.7, 1.0}; GLfloat mat_specular [] = {1.0, 1.0, 1.0, 1.0}; GLfloat mat_shininess [] = {127.0}; do_material () { glMaterialfv (GL_FRONT, GL_AMBIENT, mat_ambient); glMaterialfv (GL_FRONT, GL_DIFFUSE, mat_diffuse); glMaterialfv (GL_FRONT, GL_SPECULAR, mat_specular); glMaterialfv (GL_FRONT, GL_SHININESS, mat_shininess); } /* material update function */ int decrease_red () { if (mat_diffuse [0] > 0.0) mat_diffuse [0] -= 0.1; do_material (); }