/* extra6a.c */ /* Purpose: This program constructs a simple robot arm that can be rotated at the elbow and wrist. It displays the angles at the foot of the screen. */ #ifdef __APPLE__ #include #else #include #endif #include #include #define KEY_ESC 27 /* glut doesn't define this one */ /* Global Constants and Variables */ static GLfloat mEangle; /* elbow angle */ static GLfloat mSangle; /* shoulder angle */ static GLfloat mWangle; /* wrist angle */ static const GLfloat mSegmentLength = 2.0; /* length of robot arm segments */ static const GLsizei mStatusBarHeight = 25; /* height of box that we write the angle info in */ void printHelp( void ) { fprintf(stdout, "\nRobot Arm\n\n" "Escape key - exit the program\n\n" "s - rotate the shoulder\n" "e - rotate the elbow\n" "w - rotate the wrist\n"); } GLvoid keyboard( GLubyte key, GLint x, GLint y) { switch (key) { case KEY_ESC: /* exit when escape key is pressed */ exit(0); break; case 'e': case 'E': mEangle += 2.0; if (mEangle > 360.0) mEangle -= 360.0; break; case 's': case 'S': mSangle += 2.0; if (mSangle > 360.0) mSangle -= 360.0; break; case 'w': case 'W': mWangle += 2.0; if (mWangle > 360.0) mWangle -= 360.0; break; } glutPostRedisplay(); } GLvoid specialkeys( GLint key, GLint x, GLint y) { switch (key) { case GLUT_KEY_F1: /* print Help information */ printHelp ( ); break; } } GLvoid checkError( const char* const label ) { GLenum error; error = glGetError(); while ( GL_NO_ERROR != error ) { fprintf( stderr,"%s: %s\n", label, gluErrorString(error) ); error = glGetError(); } } void reshape(GLint width, GLint height) { GLdouble aspect; aspect = (GLdouble)width / (GLdouble)height; /* We still want the output to cover the whole window */ glViewport(0, 0, width, height); glMatrixMode( GL_PROJECTION ); glLoadIdentity(); /* Get the viewing volume set up to match the aspect ratio of the viewport */ if (width > height) { glOrtho(-6 * aspect, 6 * aspect, -6, 6, -2, 2); } else { glOrtho(-6, 6, -6 / aspect, 6 / aspect, -2, 2); } glMatrixMode( GL_MODELVIEW ); } void displayStr(char *str, GLfloat x, GLfloat y) { /* choose what font we wish to use */ void* fontName = GLUT_BITMAP_HELVETICA_18; unsigned int index = 0; /* where do we want the text to go */ glRasterPos2f(x, y); /* Display the string on the screen */ while (str[index] != 0 && index < 1000) { glutBitmapCharacter(fontName, str[index]); ++index; } } GLvoid drawSegment( GLvoid ) { glPushMatrix(); glScalef(mSegmentLength, 0.2, 0.2); glutWireCube(1.0); glPopMatrix(); } GLvoid display( GLvoid ) { GLsizei ww; GLsizei wh; char str[255]; ww = glutGet( GLUT_WINDOW_WIDTH ); wh = glutGet( GLUT_WINDOW_HEIGHT ); /* Main view of robot arm */ glViewport(0.0, mStatusBarHeight, ww, wh-mStatusBarHeight); glClear(GL_COLOR_BUFFER_BIT); glPushMatrix(); /* Draw the elbow to shoulder segment */ glRotatef(mSangle, 0.0, 0.0, 1.0); glTranslatef(mSegmentLength/2, 0.0, 0.0); drawSegment(); /* Draw the wrist to elbow segment */ glTranslatef(mSegmentLength/2, 0.0, 0.0); glRotatef(mEangle, 0.0, 0.0, 1.0); glTranslatef(mSegmentLength/2, 0.0, 0.0); drawSegment(); /* Draw the wrist to fingers segment */ glTranslatef(mSegmentLength/2, 0.0, 0.0); glRotatef(mWangle, 0.0, 0.0, 1.0); glTranslatef(mSegmentLength/2, 0.0, 0.0); drawSegment(); glPopMatrix(); glViewport(0.0, 0.0, ww, mStatusBarHeight); sprintf(str, "s: %f\t e: %f\t w: %f", mSangle, mEangle, mWangle); displayStr(str, -6, 0); checkError( "display" ); glFlush(); } void init( void ) { glClearColor( 1.0, 1.0, 1.0, 1.0); glColor3f(1.0,0.0,0.0); glLineWidth(3.0); } int main( int argc, char *argv[] ) { glutInit( &argc, argv ); glutInitDisplayMode( GLUT_SINGLE | GLUT_RGB ); glutCreateWindow( argv[0] ); init(); glutKeyboardFunc( keyboard ); glutSpecialFunc( specialkeys ); glutReshapeFunc( reshape ); glutDisplayFunc( display ); printHelp( ); glutMainLoop(); return 0; }