//////////////////////////////////////////////////// // robot.cpp // Template code for drawing an articulated creature. //////////////////////////////////////////////////// #ifdef WIN32 #include #endif #include #include #include #include #include #include #include #define PI 3.14159265 void save_image(); void setupUI(int winID); /////////////////////////////////////////// // These are the variables that the user controls. // // ***** NOTE!!!! *********** // // When the angles are all zero, the robot // should be standing upright, with arms straight // down by its sides, and legs straight, // looking straight ahead. // ////////////////////////////////////////// float rightShoulderAngle; // angle under the right armpit float leftShoulderAngle; // angle under the left armpit float rightElbowAngle; // angle at the right elbow float leftElbowAngle; // angle at the left elbow float headTurnAngle; // left-right head angle float headTiltAngle; // forward-back head angle float rightLegAngle; // upper right leg angle float leftLegAngle; // upper left leg angle float rightKneeAngle; // right knee angle float leftKneeAngle; // left knee angle. float eye[3] = {2.5,2.0,10.0}; float ref[3] = {0.5,0.5,0.5}; float up[3] = {0.0,1.0,0.0}; GLfloat lightPos[4] = {1.0, 1.0, 5.0, 1.0}; int winWidth,winHeight; float leftX,rightX,bottomY,topY,nearZ,farZ; ///////////////////////////////////////////////////////// // // PROC: set_colour(); // DOES: sets all material properties to the given colour // // *** DO NOT CHaNGE **** ///////////////////////////////////////////////////////// void setColour(float r, float g, float b) { float ambient = 0.2f; float diffuse = 0.8f; float specular = 0.4f; GLfloat mat[4]; /**** set ambient lighting parameters ****/ mat[0] = ambient*r; mat[1] = ambient*g; mat[2] = ambient*b; mat[3] = 1.0; glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT, mat); /**** set diffuse lighting parameters ******/ mat[0] = diffuse*r; mat[1] = diffuse*g; mat[2] = diffuse*b; mat[3] = 1.0; glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, mat); /**** set specular lighting parameters *****/ mat[0] = specular*r; mat[1] = specular*g; mat[2] = specular*b; mat[3] = 1.0; glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, mat); glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, 0.5); } ///////////////////////////////////////////////////////// // // Draw the three coordinate axes. // // *** DO NOT CHANGE *** // ///////////////////////////////////////////////////////// void drawAxes() { glBegin(GL_LINES); glColor3f(1.0f,0,0); glVertex3d(-20,0,0); glVertex3d( 20,0,0); glColor3f(0,1.0f,0); glVertex3d(0,-20,0); glVertex3d(0, 20,0); glColor3f(0,0,1.0f); glVertex3d(0,0,-20); glVertex3d(0,0, 20); glEnd(); } ///////////////////////////////////////////////////////// // // You will have to write a function to draw a standard- // size cylinder, for the head and the joints. // // ********************** YOU MUST CHANGE THIS!!!! ****** // ///////////////////////////////////////////////////////// void drawCylinder() { } ///////////////////////////////////////////////////////// // // Code to draw the figure, using all the degrees of // freedom supplied by the user. // // ********************** YOU MUST CHANGE THIS!!!! ****** // ///////////////////////////////////////////////////////// void drawFigure() { setColour(1,0.2,0); glPushMatrix(); glScaled(2,2,1); glutSolidCube(1); glPopMatrix(); setColour(0.2,1,0); glPushMatrix(); glTranslated(1,1,0); glRotated(-90, 0,0,1); glRotated(rightShoulderAngle,0,0,1); glTranslated(1,0.5,0); glScaled(2,1,1); glutSolidCube(1); glPopMatrix(); } ////////////////////////////////////////////////////// // PROC: glut_key_action() // DOES: this function gets called for any keypresses // // **** DO NOT CHANGE **** ////////////////////////////////////////////////////// void glut_key_action(unsigned char key, int x, int y) { return; } ///////////////////////////////////////// // PROC: save_image // DOES: saves the current image to a ppm file // // **** DO NOT CHANGE **** ///////////////////////////////////////// void save_image() { FILE *fp; char fname[255]; const int maxVal=255; register int y; unsigned char *pixels; strcpy(fname,"scene.ppm"); printf("Saving image %s: %d x %d\n", fname,winWidth,winHeight); fp = fopen(fname,"wb"); if (!fp) { printf("Unable to open file '%s'\n",fname); return; } fprintf(fp, "P6\n"); fprintf(fp, "%d %d\n", winWidth,winHeight); fprintf(fp, "%d\n", maxVal); pixels = new unsigned char [3*winWidth]; for ( y = winHeight-1; y>=0; y-- ) { glReadPixels(0,y,winWidth,1,GL_RGB,GL_UNSIGNED_BYTE, (GLvoid *) pixels); fwrite(pixels, 3, winWidth, fp); } free(pixels); fclose(fp); } ///////////////////////////////////////// // // PROC: initLights() // DOES: performs most of the OpenGL intialization // // **** DO NOT CHANGE **** ///////////////////////////////////////// void initLights(void) { GLfloat ambient[] = { 0.2, 0.2, 0.2, 1.0 }; GLfloat diffuse[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat specular[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat position[] = { 0.0, 3.0, 3.0, 0.0 }; GLfloat lmodel_ambient[] = { 0.2f, 0.2f, 0.2f, 1.0f }; GLfloat local_view[] = { 0.0 }; /**** set lighting parameters ****/ glLightfv(GL_LIGHT0, GL_AMBIENT, ambient); glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse); glLightfv(GL_LIGHT0, GL_POSITION, position); glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient); glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER, local_view); /* glFrontFace (GL_CW); */ glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_AUTO_NORMAL); glEnable(GL_NORMALIZE); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); } ////////////////////////////////////////////////////////////////////// // // Update the projection matrix. // // *** DO NOT CHANGE *** // ////////////////////////////////////////////////////////////////////// void setCamera() { glViewport(0,0, winWidth,winHeight); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glFrustum(leftX,rightX, bottomY,topY, nearZ,farZ); } ////////////////////////////////////////////////////////////////////// // // This gets called by the GLUT event handler to draw the scene. // // *** YOU PROBABLY DON'T NEED TO CHANGE THIS **** // ////////////////////////////////////////////////////////////////////// void display(void) { setCamera(); // // Set the background colour to grey-blue. // glClearColor(.4f,.4f, 0.7f,1.f); // // OK, now clear the screen with the background colour // glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // // Position the camera eye and look-at point. // glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(eye[0],eye[1],eye[2], ref[0],ref[1],ref[2], up[0],up[1],up[2]); glLightfv(GL_LIGHT0, GL_POSITION, lightPos); drawAxes(); drawFigure(); // // Execute any GL functions that are in the queue. // glFlush(); // // Now, show the frame buffer that we just drew into. // (this avoids flicker). // glutSwapBuffers(); } ////////////////////////////////////////////////////////////////////// // // PROC: myReshape() // DOES: handles the window being resized // // *** DO NOT CHANGE *** ////////////////////////////////////////////////////////////////////// void myReshape(int w, int h) { winWidth = w; winHeight = h; glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); /*** this defines the field of view of the camera ***/ /*** Making the first 4 parameters larger will give ***/ /*** a larger field of view, therefore making the ***/ /*** objects in the scene appear smaller ***/ glFrustum(-1,1,-1,1,4,100); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } ////////////////////////////////////////////////////////////////////// // // Set all variables to their default values. // // *** DO NOT CHANGE *** // ////////////////////////////////////////////////////////////////////// void reset() { leftX = -1; rightX = 1; bottomY = -1; topY = 1; nearZ = 1.0; farZ = 20; eye[0] = 2.5; eye[1] = 2.0; eye[2] = 10.0; ref[0] = 0.5; ref[1] = 0.5; ref[2] = 0.5; up[0] = 0.0; up[1] = 1.0; up[2] = 0.0; initLights(); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_AUTO_NORMAL); glEnable(GL_NORMALIZE); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } /********************************************************* PROC: main() DOES: calls initialization, then hands over control to the event handle, which calls display() whenever the screen needs to be redrawn **********************************************************/ int main(int argc, char** argv) { glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH); glutInitWindowPosition (0, 0); glutInitWindowSize(300,300); int winID = glutCreateWindow(argv[0]); initLights(); reset(); glutReshapeFunc (myReshape); glutKeyboardFunc( glut_key_action ); glutDisplayFunc(display); setupUI(winID); // glutMainLoop(); return 0; // never reached }