📄 modelviewer.c
字号:
glutInitWindowPosition( WIN_LEFT, WIN_TOP ); /* open the window and set its title: */ GrWindow = glutCreateWindow( WINDOWTITLE ); glutSetWindowTitle( WINDOWTITLE ); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); /* setup the clear values: */ glClearColor( BACKGROUND_COLOR ); /* initialize the pop-up menus: */ ProjMenu = glutCreateMenu( DoProjMenu ); glutAddMenuEntry( "Orthographic", ORTHO ); glutAddMenuEntry( "Perspective", PERSP ); ColorMenu = glutCreateMenu( DoColorMenu ); glutAddMenuEntry( "Red", RED ); glutAddMenuEntry( "Yellow", YELLOW ); glutAddMenuEntry( "Green", GREEN ); glutAddMenuEntry( "Cyan", CYAN ); glutAddMenuEntry( "Blue", BLUE ); glutAddMenuEntry( "Magenta", MAGENTA ); glutAddMenuEntry( "White", WHITE ); glutAddMenuEntry( "Black", BLACK ); AxesMenu = glutCreateMenu( DoAxesMenu ); glutAddMenuEntry( "Off", OFF ); glutAddMenuEntry( "On", ON ); TransformModeMenu = glutCreateMenu( DoTransformModeMenu ); glutAddMenuEntry( "Rotate", ROTATE ); glutAddMenuEntry( "Scale", SCALE ); MainMenu = glutCreateMenu( DoMainMenu ); glutAddSubMenu( "Projection", ProjMenu ); glutAddSubMenu( "Transform Mode", TransformModeMenu ); glutAddSubMenu( "Set Color", ColorMenu ); glutAddSubMenu( "Axes", AxesMenu ); glutAddMenuEntry( "Reset", RESET ); glutAddMenuEntry( "Quit", QUIT ); /* attach the pop-up menu to the right mouse button: */ glutAttachMenu( GLUT_RIGHT_BUTTON ); /* create the display structures that will not change: */ whichObj=0; InitLists(); whichObj=1; InitLists(); whichObj=2; InitLists(); /* setup the callback routines: */ /* DisplayFunc -- redraw the window */ /* ReshapeFunc -- handle the user resizing the window */ /* KeyboardFunc -- handle a keyboard input */ /* MouseFunc -- handle the mouse button going down or up */ /* MotionFunc -- handle the mouse moving with a button down */ /* PassiveMotionFunc -- handle the mouse moving with a button up*/ /* VisibilityFunc -- handle a change in window visibility */ /* EntryFunc -- handle the cursor entering or leaving the window */ /* SpecialFunc -- handle special keys on the keyboard */ /* SpaceballMotionFunc -- handle spaceball translation */ /* SpaceballRotateFunc -- handle spaceball rotation */ /* SpaceballButtonFunc -- handle spaceball button hits */ /* ButtonBoxFunc -- handle button box hits */ /* DialsFunc -- handle dial rotations */ /* TabletMotionFunc -- handle digitizing tablet motion */ /* TabletButtonFunc -- handle digitizing tablet button hits */ /* MenuStateFunc -- declare when a pop-up menu is in use */ /* IdleFunc -- what to do when nothing else is going on */ /* TimerFunc -- trigger something to happen every so often */ glutSetWindow( GrWindow ); glutDisplayFunc( Display ); glutReshapeFunc( Resize ); glutKeyboardFunc( Keyboard ); glutMouseFunc( MouseButton ); glutMotionFunc( MouseMotion ); glutPassiveMotionFunc( NULL ); glutVisibilityFunc( Visibility ); glutEntryFunc( NULL ); glutSpecialFunc( Keyboard2 ); glutSpaceballMotionFunc( NULL ); glutSpaceballRotateFunc( NULL ); glutSpaceballButtonFunc( NULL ); glutButtonBoxFunc( NULL ); glutDialsFunc( NULL ); glutTabletMotionFunc( NULL ); glutTabletButtonFunc( NULL ); glutMenuStateFunc( NULL ); glutIdleFunc( Animate ); /* change "NULL" to "Animate" if doing animation */ glutTimerFunc( 0, NULL, 0 );}/** ** initialize the display lists that will not change: ** Note: glGenLists() is used to generate a unique integer identifier ** for each display list, thus avoiding any possible collision ** with an identifier assigned elsewhere **/voidInitLists( void ){ int num_verts; float x, y, z; int test; /* create the object: */ FILE * datafile = fopen(model[whichObj], "r"); if(datafile == NULL){ fprintf(stderr, "Can't open datafile\n");; exit(1); } test = fscanf(datafile, "%d\n", &num_verts); if(test == 0){ fprintf(stderr, "Couldn't get num_verts\n"); exit(1); } fprintf(stderr, "Num Verts = %d\n", num_verts); ObjList[whichObj] = glGenLists( 1 ); glNewList( ObjList[whichObj], GL_COMPILE ); glBegin(GL_TRIANGLES); { int i; for(i=0; i<num_verts; i++){ float len=0; test = fscanf(datafile, "%f, %f, %f\n", &x, &y, &z); if(test == 0){ fprintf(stderr, "Couldn't get num_verts\n"); exit(1); } len=sqrt(x*x+y*y+z*z); glNormal3f(x/len,y/len,z/len); glVertex3f(x,y,z); } } glEnd(); fclose(datafile); datafile = fopen(model[whichObj], "rb"); glColor3f(1.0, 0.0, 0.0); glPointSize(10.0f);/* glBegin(GL_POINTS); { int i; for(i=0; i<num_verts; i++){ test = fscanf(datafile, "%f, %f, %f\n", &x, &y, &z); if(test == 0){ fprintf(stderr, "Couldn't get num_verts\n"); exit(1); } glVertex3f(x,y,z); } } glEnd(); */ glEndList(); fclose(datafile); /* create the axes: */ AxesList = glGenLists( 1 ); glNewList( AxesList, GL_COMPILE ); glColor3f( AXES_COLOR ); glLineWidth( AXES_WIDTH ); Axes( AXES_SIZE ); glLineWidth( 1. ); glEndList();}/** ** callback to handle keyboard hits: ** Note: this callback only handles ketters, numbers, and punctuation. ** Special characters, like the arrow keys are handled in Keyboard2() **/voidKeyboard( unsigned char c, int x, int y ){ if( Debug ) fprintf( stderr, "Keyboard: '%c' (0x%0x)\n", c, c ); switch( c ) { case 'a': case 'A': AxesOnOff = ! AxesOnOff; break; case 'd': case 'D': Debug = ! Debug; break; case 'o': case 'O': Projection = ORTHO; break; case 'p': case 'P': Projection = PERSP; break; case 'q': case 'Q': case ESCAPE: Quit(); /* will not return here */ case 'r': case 'R': TransformMode = ROTATE; break; case '1': whichObj=0; break; case '2': whichObj=1; break; case '3': whichObj=2; break; case 's': case 'S': TransformMode = SCALE; break; case 'm': case 'M': { wire=!wire; } break; default: fprintf( stderr, "Don't know what to do with keyboard hit: '%c' (0x%0x)\n", c, c ); } glutSetWindow( GrWindow ); glutPostRedisplay();}/** ** callback to handle special keyboard hits: **/voidKeyboard2( int c, int x, int y ){ if( Debug ) fprintf( stderr, "Keyboard: '%c' (0x%0x)\n", c, c ); switch( c ) { case GLUT_KEY_LEFT: case GLUT_KEY_RIGHT: case GLUT_KEY_DOWN: case GLUT_KEY_UP: fprintf( stderr, "Arrow key hit\n" ); break; default: fprintf( stderr, "Don't know what to do with special keyboard hit: 0x%0x\n", c ); } glutSetWindow( GrWindow ); glutPostRedisplay();}/** ** called when the mouse button transitions down or up: **/voidMouseButton( int button, /* GLUT_*_BUTTON */ int state, /* GLUT_UP or GLUT_DOWN */ int x, /* where mouse was when button was hit */ int y /* where mouse was when button was hit */){ int b; /* LEFT, MIDDLE, or RIGHT */ /* get the proper button bit mask: */ switch( button ) { case GLUT_LEFT_BUTTON: b = LEFT; break; case GLUT_MIDDLE_BUTTON: b = MIDDLE; break; case GLUT_RIGHT_BUTTON: b = RIGHT; break; default: b = 0; fprintf( stderr, "Unknown mouse button: %d\n", button ); } /* button down sets the bit, up clears the bit: */ if( state == GLUT_DOWN ) { Xmouse = x; Ymouse = y; ActiveButton |= b; /* set the proper bit */ } else ActiveButton &= ~b; /* clear the proper bit */}/** ** called when the mouse moves while a button is down: **/voidMouseMotion( int x, int y ) /* x and y are mouse coords */{ int dx, dy; /* change in mouse coordinates */ dx = x - Xmouse; /* change in mouse coords */ dy = y - Ymouse; if( ActiveButton & LEFT ) { if( TransformMode == ROTATE ) { Xrot += ( ANGFACT*dy ); Yrot += ( ANGFACT*dx ); } else { Scale += SCLFACT * (float) ( dx - dy ); if( Scale < MIN_SCALE ) Scale = MIN_SCALE; /* do not invert */ } } if( ActiveButton & MIDDLE ) { Scale += SCLFACT * (float) ( dx - dy ); if( Scale < MIN_SCALE ) Scale = MIN_SCALE; /* do not invert */ } Xmouse = x; /* new current position */ Ymouse = y; glutSetWindow( GrWindow ); glutPostRedisplay();}/** ** quit the program gracefully: **/voidQuit( ){ /* gracefully close out the graphics: */ glFinish(); /* gracefully close the graphics window: */ glutDestroyWindow( GrWindow ); /* gracefully exit the program: */ exit( 0 );}/** ** reset the transformations and the colors: ** ** this only sets the global variables -- ** the main loop is responsible for redrawing the scene **/voidReset( void ){ ActiveButton = 0; AxesOnOff = OFF; Projection = ORTHO; Red = 1.; Green = 1.; Blue = 1.; /* white */ Scale = .15; TransformMode = ROTATE; Xrot = 270.; Yrot = 0.; //Xrot = 55.; Yrot = 35.; glutSetWindow( GrWindow ); glutPostRedisplay();}/** ** called when user resizes the window: **/voidResize( int width, /* new value for window width */ int height /* new value for window height */){ glutSetWindow( GrWindow ); glutPostRedisplay();}/** ** handle a change to the window's visibility: **/voidVisibility( int state /* GLUT_VISIBLE or GLUT_NOT_VISIBLE */){ if( state == GLUT_VISIBLE ) { glutSetWindow( GrWindow ); glutPostRedisplay(); } else { /* could optimize by keeping track of the fact */ /* that the window is not visible and avoid */ /* redrawing it later ... */ }}/* the stroke characters 'X' 'Y' 'Z' : */static float xx[] ={ 0.f, 1.f, 0.f, 1.f};static float xy[] ={ -.5f, .5f, .5f, -.5f};static int xorder[] ={ 1, 2, -3, 4};static float yx[] ={ 0.f, 0.f, -.5f, .5f};static float yy[] ={ 0.f, .6f, 1.f, 1.f};static int yorder[] ={ 1, 2, 3, -2, 4};static float zx[] ={ 1.f, 0.f, 1.f, 0.f, .25f, .75f};static float zy[] ={ .5f, .5f, -.5f, -.5f, 0.f, 0.f};static int zorder[] ={ 1, 2, 3, 4, -5, 6};/* fraction of the length to use as height of the characters: */#define LENFRAC 0.10/* fraction of length to use as start location of the characters: */#define BASEFRAC 1.10/** ** Draw a set of 3D axes: ** (length is the axis length in world coordinates) **/voidAxes( float length ){ int i, j; /* counters */ float fact; /* character scale factor */ float base; /* character start location */ glBegin( GL_LINE_STRIP ); glVertex3f( length, 0., 0. ); glVertex3f( 0., 0., 0. ); glVertex3f( 0., length, 0. ); glEnd(); glBegin( GL_LINE_STRIP ); glVertex3f( 0., 0., 0. ); glVertex3f( 0., 0., length ); glEnd(); fact = LENFRAC * length; base = BASEFRAC * length; glBegin( GL_LINE_STRIP ); for( i = 0; i < 4; i++ ) { j = xorder[i]; if( j < 0 ) { glEnd(); glBegin( GL_LINE_STRIP ); j = -j; } j--; glVertex3f( base + fact*xx[j], fact*xy[j], 0.0 ); } glEnd(); glBegin( GL_LINE_STRIP ); for( i = 0; i < 5; i++ ) { j = yorder[i]; if( j < 0 ) { glEnd(); glBegin( GL_LINE_STRIP ); j = -j; } j--; glVertex3f( fact*yx[j], base + fact*yy[j], 0.0 ); } glEnd(); glBegin( GL_LINE_STRIP ); for( i = 0; i < 6; i++ ) { j = zorder[i]; if( j < 0 ) { glEnd(); glBegin( GL_LINE_STRIP ); j = -j; } j--; glVertex3f( 0.0, fact*zy[j], base + fact*zx[j] ); } glEnd();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -