static bool KeyCallbacksInitialized=false; static twKeyFunc twKeyCallbackArray[128]; static char* twKeyCallbackDoc[128]; //keyboard settings void twKeyCallback(char key, twKeyFunc fun, char* doc) { if( KeyCallbacksInitialized ) { twKeyCallbackArray[key] = fun; twKeyCallbackDoc[key] = doc; } else { printf("Keyboard Callbacks not yet initialized. Call this after twMainInit\n"); } } void twHelp(unsigned char key, int x, int y) { int i; printf("This software is designed to help in learning and teaching\nabout using OpenGL to build 3D graphics programs.\nCopyright (C) 2006 Scott D. Anderson\nscott.anderson@acm.org\nThis is free software distributed under the GNU General Public License.\n"); for(i=0;i<128;i++) if( twKeyCallbackArray[i] != 0 ) { if(isgraph(i)) { printf("%3c: %s\n",i,twKeyCallbackDoc[i]); } else { switch(i) { case 32: printf("SPC: %s\n",twKeyCallbackDoc[i]); break; case 9: printf("TAB: %s\n",twKeyCallbackDoc[i]); break; case 27: printf("ESC: %s\n",twKeyCallbackDoc[i]); break; default: printf("^%c : %s\n",i+64,twKeyCallbackDoc[i]); break; } } } } void twQuit(unsigned char key, int x, int y) { exit(0); } void twStopAndRefresh(unsigned char key, int x, int y) { glutIdleFunc(NULL); glutPostRedisplay(); } void twPause(unsigned char key, int x, int y) { glutIdleFunc(NULL); } void twBoundingBoxToggle(unsigned char key, int x, int y) { Toggles[BB] = ! Toggles[BB]; glutPostRedisplay(); } void twLightingToggle(unsigned char key, int x, int y) { Toggles[LIGHTING] = ! Toggles[LIGHTING]; glutPostRedisplay(); } void twShadingToggle(unsigned char key, int x, int y) { Toggles[SMOOTH] = ! Toggles[SMOOTH]; glutPostRedisplay(); } void twReset (unsigned char key, int x, int y) { glutIdleFunc(NULL); twZview(); glutPostRedisplay(); } // does a 10 degree rotation around y axis void twRotViewY(unsigned char key, int x, int y) { twTriple yAxis={0,1,0}; twRotateViewpoint(10,yAxis); } // does a 10 degree rotation around x axis void twRotViewX(unsigned char key, int x, int y) { twTriple xAxis={1,0,0}; twRotateViewpoint(10,xAxis); } // does a 10 degree pan (yaw) around y axis void twPanView(unsigned char key, int x, int y) { twTriple yAxis={0,1,0}; twRotateVPN(10,yAxis); } // Zoom in by the given number of degrees, relative to current // FieldOfView. If the field of view would drop to zero or less, it // returns, leaving the field of view unchanged. If the field of view void twZoom(GLfloat degrees) { GLfloat newFOV = FieldOfView - degrees; if(newFOV <= 0) return; FieldOfView = newFOV; glutPostRedisplay(); } void twZoom1() { twZoom(1); } void twStartZooming(unsigned char key, int x, int y) { glutIdleFunc(twZoom1); } void twNextFrame(unsigned char key, int x, int y) { twNextFrame(); } void twKeyboardCallback (unsigned char key, int x, int y) { twKeyFunc fun; if (key>128) return; fun = twKeyCallbackArray[key]; if (fun==0) { printf("No callback for %c (%d)\n",key,key); return; } fun(key,x,y); } void twSaveFrame(int width, int height, char *fname, bool verbose) { FILE *fp; register int y; unsigned char *pixels; int n; if( verbose ) printf("Saving image %s\n",fname); fp = fopen(fname,"w"); if (!fp) { printf("Unable to open file '%s'\n",fname); return; } fprintf(fp, "P6"); fprintf(fp, "%d %d ", width, height); fprintf(fp, "%d", 255); /* max value */ putc(13,fp); /* carriage return character */ pixels = (unsigned char*) malloc(3*width); for ( y = height-1; y >=0; y-- ) { glReadPixels(0,y,width,1,GL_RGB,GL_UNSIGNED_BYTE, (GLvoid *) pixels); for (n=0; n<3*width; n++) { putc(pixels[n],fp); } // fwrite(pixels, 3, width, fp); } fclose(fp); } static int frameNumber = 1; void twSave (unsigned char key, int x, int y) { char file[19]; sprintf(file, "saved-frame%03d.ppm", frameNumber++); twSaveFrame(windowWidth, windowHeight, file, false); glutPostRedisplay(); } void twKeyInit() { int i; for(i=0;i<128;i++) twKeyCallbackArray[i] = 0; KeyCallbacksInitialized = true; twKeyCallback(27, twQuit, "Quit"); twKeyCallback(32, twStopAndRefresh, "Stop animation, if any, and refresh"); twKeyCallback('+', twSpinCommand, "double spin step"); twKeyCallback('-', twSpinCommand, "halve spin step"); twKeyCallback('b', twBoundingBoxToggle, "Toggle Bounding Box"); twKeyCallback('l', twLightingToggle, "Toggle Lighting"); twKeyCallback('s', twShadingToggle, "Toggle Smooth Shading"); twKeyCallback('q', twQuit, "Quit"); twKeyCallback('p', twPause, "Pause animation"); twKeyCallback('r', twReset, "Reset to original screen"); twKeyCallback('n', twNextFrame, "next frame of animation"); twKeyCallback('x', twSpinCommand, "Spin around the x axis"); twKeyCallback('y', twSpinCommand, "Spin around the y axis"); twKeyCallback('z', twSpinCommand, "Spin around the z axis"); twKeyCallback('X', twViewCommand, "View from positive X axis"); twKeyCallback('Y', twViewCommand, "View from positive Y axis"); twKeyCallback('Z', twViewCommand, "View from positive Z axis"); //twKeyCallback('s', twRotViewY, "10 degrees around y"); //twKeyCallback('t', twRotViewX, "10 degrees around x"); //twKeyCallback('P', twPanView, "10 degrees pan around y"); twKeyCallback('?', twHelp,"Help"); twKeyCallback('i', twStartZooming, "start zooming in"); twKeyCallback('S', twSave, "save frame"); }