#include #include #include #include #include #define WORLD_WIDTH 10 #define WORLD_HEIGHT 10 void Reshape(int width, int height) { /* glViewport defines part of the window we are going to use */ /* we are going to use the whole window */ glViewport(0,0,width,height); /* initialize the viewing transformation (camera position) to identity; this corresponds to camera looking down negative z axis */ glMatrixMode(GL_MODELVIEW); glLoadIdentity(); /* specify the projection transformation (camera parameters); */ glMatrixMode(GL_PROJECTION); glLoadIdentity(); /* this defines a camera with orthogonal projection that captures the part of the virtual world inside the box from -WORLD_WIDTH/2 to WORLD_WIDTH/2 in the X direction -WORLD_HEIGHT/2 to WORLD_HEIGHT/2 in the Y direction and from 0 to 1 (default in Z direction */ gluOrtho2D(-WORLD_WIDTH/2, WORLD_WIDTH/2,-WORLD_HEIGHT/2,WORLD_HEIGHT/2); } /* draw coordinate axes along X and Y; X in green Y in blue */ void drawAxes() { glBegin(GL_LINES); /* x axis */ glColor3d( 0,1,0); glVertex3d(-WORLD_WIDTH/2,0,0); glVertex3d(WORLD_WIDTH/2,0,0); /* y axis */ glColor3d( 0,0,1); glVertex3d(0,-WORLD_HEIGHT/2,0); glVertex3d(0,WORLD_HEIGHT/2,0); glEnd(); } /* draw a unit square with lower-left corner at the origin */ void drawQuad() { glBegin(GL_POLYGON); glVertex3d(0,0,0); glVertex3d(1,0,0); glVertex3d(1,1,0); glVertex3d(0,1,0); glEnd(); } /* some constants we are going to use in our drawing routines */ static double LightBlue[] = { 0.5,0.5,1.0 }; static double LightRed[] = { 1.0,0.5,0.5 }; #define LOWER_ARM_LENGTH 3 #define LOWER_ARM_WIDTH 1 #define UPPER_ARM_LENGTH 2 #define UPPER_ARM_WIDTH 1 #define LOWER_ARM_ROTATION 30 /* degrees */ /* draw an ar; this routine will be used twice to draw both left and right */ void drawArm() { glColor3dv(LightBlue); glPushMatrix(); glTranslated(UPPER_ARM_LENGTH,0,0); glRotated(LOWER_ARM_ROTATION, 0,0,1 ); glScaled(LOWER_ARM_LENGTH,LOWER_ARM_WIDTH,1); drawQuad(); glPopMatrix(); glColor3dv(LightRed); glPushMatrix(); glScaled(UPPER_ARM_LENGTH,UPPER_ARM_WIDTH,1); drawQuad(); glPopMatrix(); } /* rotation rate for the right arm, rotations per second */ #define ROTATION_RATE 0.25 /* window redraw even callback; is called when the window is created, maximized, resized etc.; also called if glutPostRedisplay generates the necessary event */ void Draw() { /* in the double buffer mode all drawing happens in the invisible back buffer */ glClearColor( 0.0, 0.0,0.0,0.0); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); drawAxes(); /* draw the right arm translated to the right by 1*/ glPushMatrix(); glTranslated(1,0,0); /* time-dependent transformation -- this ensures that each time Draw() is called, the rotation angle is proportional to the elapsed time */ glRotated( clock()/(double)CLOCKS_PER_SEC*ROTATION_RATE*360, 0,0,1); drawArm(); glPopMatrix(); /* draw the left arm displaced by 1 unit to the left */ glPushMatrix(); glTranslated(-1,0,0); /* the left arm is the mirror image of the right arm */ glScaled(-1,1,1); drawArm(); glPopMatrix(); /* once we are done drawing we swap the back and front buffers */ glutSwapBuffers(); } /* callback for button clicks; gets called each time a mouse button is pressed or released */ /* this function does nothing; we can start and stop animation if we call glutIdleFunc() in the right place here; to disable idel callback, call glutIdleFunc(0) */ void Mouse( int button, int state, int x, int y) { if( button == GLUT_LEFT_BUTTON ) { if( state == GLUT_UP ) { } else if (state == GLUT_DOWN) { } else { assert(0); } } else if( button == GLUT_MIDDLE_BUTTON ) { } else if( button == GLUT_RIGHT_BUTTON) { if( state == GLUT_UP ) { } else if (state == GLUT_DOWN) { } else { assert(0); } } else { assert(0); } } int main(int argc, char* argv[]) { /* initialize glut and parse command-line aguments that glut understands */ glutInit(&argc, argv); /* initialize dislay mode: 4 color components, double buffer and depth buffer */ glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE|GLUT_DEPTH); glutInitWindowSize(256,256); glutCreateWindow("a simple window "); /* register all callbacks */ glutDisplayFunc(Draw); /* this registers an "idle" callback, that is, a function that gets called when there are no events to process on the queue; we use Draw() but it can be a different function */ glutIdleFunc(Draw); glutReshapeFunc(Reshape); glutMouseFunc(Mouse); /* this is an infinte loop get event - dispatch event which never returns */ glutMainLoop(); return 0; }