// Interactive program to // fly over a drawer corner containing toys: a gun and a levitating color cube // Uses kayboard callback and perspective projection // //Needs the header scene_demo_1.h // Computer Grpahics #include #include #include #include "scene_demo_1.h" GLUquadricObj *p; // Pointer for quadric objects // Prototypes void myinit(); void PrintInstructions(); void display(); void nav_kbd(unsigned char key, int x, int y); //navigation routine // ********** MAIN ************************************************************ int main(int argc, char **argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB); // double buffering glutInitWindowSize(700,700); glutInitWindowPosition(0,0); glutCreateWindow("Toy box"); glutKeyboardFunc(nav_kbd); glutDisplayFunc(display); myinit(); glutMainLoop(); return 0; } // ***** Initialization function ********************************************* void myinit() { glEnable(GL_DEPTH_TEST); //enable z-buffer glClearColor(1.0,1.0,1.0,0.0); viewer[0] =0.0; //default position for camera viewer[1] =-2; viewer[2] =12; //creates a qudraic object for the cylindric components of the gun //see page 486ff of the Red book p = gluNewQuadric(); gluQuadricDrawStyle(p, GLU_FILL); glMatrixMode(GL_PROJECTION); glLoadIdentity(); // glOrtho(-5,5,-5,5.0,-5.0,5.0); gluPerspective(45,1,0.1,17); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); PrintInstructions(); } //****** Function to print instructions for user ****************************** void PrintInstructions() { cout << "Depth motion (along the world Z axis)" << endl; cout << "Press y to move forward (i.e. in the -Z direction)" << endl; cout << "Press b to move backward(i.e. in the +Z direction)\n" << endl; cout << "Lateral motion (along the world X axis)" << endl; cout << "Press h to move in the +X direction" << endl; cout << "Press g to move in the -X direction\n" << endl; cout << "Change of altitude (motion along the world Y axis)" << endl; cout << "Press u to go up" << endl; cout << "Press j to go down\n" << endl; cout << "\n\nPress the spacebar to return to default position\n\n" << endl; return; } //**** Display callback function ********************************************** void display() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // update modelview matrix glLoadIdentity(); gluLookAt(viewer[0],viewer[1],viewer[2],0,0,0,0,1,0); //draw walls walls(); //draw color cube glPushMatrix(); glTranslated(0,-1,0); glScalef(0.3,0.3,0.3); cubedraw(); glPopMatrix(); //draw a gun glPushMatrix(); glTranslatef(0.5,-1.8,1.1); glRotatef(70, 0,1,0); glScalef(0.2,0.2,0.2); draw_gun(); glPopMatrix(); glFlush(); glutSwapBuffers(); } // ****** Keyboard callback function****************************************** // used for navigation depending on user input from keyboard void nav_kbd(unsigned char key, int x, int y) { if (key=='y') viewer[2] -=0.05; //step forwrd else if (key== 'b') viewer[2] +=0.05; //step back else if (key== 'g') viewer[0] -=0.05; //step to the left else if (key== 'h') viewer[0] +=0.05; //step to the right else if (key== 'j') viewer[1] -=0.05; //step down else if (key== 'u') viewer[1] +=0.05; //step up else if (key== ' ') { viewer[0] = 0.0;//1.0; viewer[1] =-2.0;//1.2; //return to origin viewer[2] =12;//1.2; } glutPostRedisplay(); } //***** cube drwaing functions************************************************* void quad(int a, int b, int c, int d) { glBegin(GL_QUADS); glColor3fv(colors[a]); glVertex3fv(vertices[a]); glColor3fv(colors[b]); glVertex3fv(vertices[b]); glColor3fv(colors[c]); glVertex3fv(vertices[c]); glColor3fv(colors[d]); glVertex3fv(vertices[d]); glEnd(); glBegin(GL_LINE_LOOP); glColor3f(0,0,0); glVertex3fv(vertices[a]); glVertex3fv(vertices[b]); glVertex3fv(vertices[c]); glVertex3fv(vertices[d]); glEnd(); } void cubedraw() { quad(0,3,2,1); quad(2,3,5,6); quad(0,4,7,1); quad(1,2,6,7); quad(4,5,6,7); quad(0,3,5,4); } // ****** wall functions ****************************************************** // wall draws a single unit square wall // input parameters are thikness and color of the wall. // the color is either red, green, or gray void wall(double thickness, char col) { glPushMatrix(); glPushAttrib(GL_COLOR); if (col == 'r') glColor3f(1,0,0); else if (col == 'g') glColor3f(0,1,0); else glColor3f(0.6,0.6,0.6); glTranslated(0.5,0.5*thickness, 0.5); glScaled(1.0,thickness, 1.0); glutSolidCube(1.0); glPopMatrix(); glPopAttrib(); } // walls builds a box corner where three orthogonal walls built with wall meet. // there are two side walls and a floor void walls() { //draw floor glPushMatrix(); glTranslated(-1.1,0,-1.1); glTranslated(0,-2,0); glScalef(3,1,3); wall(0.02,'b'); glPopMatrix(); //draw sidewall glPushMatrix(); glTranslated(-1.1,0,-1.1); glScalef(12,1,3.0); glTranslated(0,-2,0); glRotatef(90,0,0,1); wall(0.002,'g'); glPopMatrix(); //draw backwall glPushMatrix(); glTranslated(-1.1,0,-1.1); glTranslated(0,-2,0); glScalef(3,1,1); glRotatef(-90,1,0,0); glScalef(1,6,1); wall(0.02,'r'); glPopMatrix(); } // ********** gun ************************************************************ void draw_gun() { // The gun is facing +Z, and up is +Y. //Barrel glPushMatrix(); glPushAttrib(GL_COLOR); glTranslatef(0.0, 0.0, 1.0); glRotatef(-45.0, 1.0, 0.0, 0.0); glColor3f(0.0, 0.0, 1.0); gluCylinder(p, 1, 1., 4.0, 10, 12); glTranslatef(0.0, 0.0, 2.5); glColor3f(0.1, 0.1, 0.2); gluDisk(p, 0.0, 1.0, 25, 5); glPopMatrix(); glPopAttrib(); // Wheels -- this is getting exciting isn't it? glPushMatrix(); glPushAttrib(GL_COLOR); glTranslatef(0,0, 1+sqrt(2.0)); glTranslatef(0,1,0); glRotatef(90,0,1,0); glTranslatef(0,0,-2); glColor3f(0.4, 0.4, 0.4); gluCylinder(p, 0.3, 0.3, 4.0, 10, 1); glColor3f(0.0, 0.0, 0.0); gluDisk(p, 0.0, 2.0, 20, 5); glTranslatef(0.0, 0.0, 4.0); gluDisk(p, 0.0, 2.0, 20, 5); glPopMatrix(); glPopAttrib(); }