//////////////////////////////////////////////////// // rectangle.cpp // // Displays a user-editable rectangle. // //////////////////////////////////////////////////// #ifdef WIN32 #include #endif #include #include #include #include #include #include #include extern void setupUI (int mainWindowID); ///////////////////////////////////////////////////////////// // // The Top-Right and Bottom-Left (x,y) coordinates of the // rectangle. These are the variables you will modify // when the user makes a change. // // You will probably need to add other variables to keep // track of what the user is doing. // ///////////////////////////////////////////////////////////// double recTRx,recTRy,recBLx,recBLy; ///////////////////////////////////////////////////////////// // // Variables that control the window, rectangle controls, // and the background. // // *** DO NOT CHANGE *** // ///////////////////////////////////////////////////////////// int winWidth,winHeight; // window (x,y) size bool showHandles = true; bool showGrid = true; float handleSize = 0.05; float pixPerMeter = 200.0; double eye[3] = {0.5,0.5,1.0}; double at[3] = {0.5,0.5,0.5}; double up[3] = {0.0,1.0,0.0}; ////////////////////////////////////////////////////////////////////// // // Convenience function, to convert mouse coordinates to world coords. // // *** DO NOT CHANGE *** // ////////////////////////////////////////////////////////////////////// void viewportToWorldCoords(int vx, int vy, double *wx, double *wy) { *wx = (vx-winWidth/2 )/(double)pixPerMeter + at[0]; *wy = (winHeight/2-vy)/(double)pixPerMeter + at[1]; } ////////////////////////////////////////////////////////////////////// // // Set all variables to their default values. // // *** DO NOT CHANGE *** // ////////////////////////////////////////////////////////////////////// void reset() { showHandles = true; showGrid = true; handleSize = 0.05; pixPerMeter = 200.0; winWidth = winHeight = (int)(pixPerMeter*2); recTRx = eye[0] + 0.25; recTRy = eye[1] + 0.25; recBLx = eye[0] - 0.25; recBLy = eye[1] - 0.25; } ////////////////////////////////////////////////////////////////////// // // Draw a filled square // (One of the control handles to manipulate the rectangle) // // *** DO NOT CHANGE *** // ////////////////////////////////////////////////////////////////////// void drawSquare(double x, double y, double s) { glBegin(GL_POLYGON); glVertex2d(x-s/2, y-s/2); glVertex2d(x+s/2, y-s/2); glVertex2d(x+s/2, y+s/2); glVertex2d(x-s/2, y+s/2); glEnd(); } ////////////////////////////////////////////////////////////////////// // // Draw the coordinate grid. // // *** DO NOT CHANGE *** // ////////////////////////////////////////////////////////////////////// void drawCoordGrid() { double x,y; glColor3f(.5f,.5f,.7f); glBegin(GL_LINES); for (x=-3.0; x<=3.0; x+=0.1) { glVertex2d(x,-3.0); glVertex2d(x, 3.0); } for (y=-3.0; y<=3.0; y+=0.1) { glVertex2d(-3.0,y); glVertex2d( 3.0,y); } glColor3f(.7f,.7f,.9f); for (x=-3.0; x<=3.0; x+=1) { glVertex2d(x,-3.0); glVertex2d(x, 3.0); } for (y=-3.0; y<=3.0; y+=1) { glVertex2d(-3.0,y); glVertex2d( 3.0,y); } glColor3f(.9f,.7f,.7f); glVertex2d(0.0,-3.0); glVertex2d(0.0, 3.0); glVertex2d(-3.0,0.0); glVertex2d( 3.0,0.0); glEnd(); } ////////////////////////////////////////////////////////////////////// // // This gets called by the GLUT event handler to draw the scene. // // *** DO NOT CHANGE *** // ////////////////////////////////////////////////////////////////////// void display(void) { // // Set the background colour to dark gray. // 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], at[0],at[1],at[2], up[0],up[1],up[2]); // // draw the coordinate grid, if necessary. // if (showGrid) { drawCoordGrid(); } // // Set the drawing colour to yellow. // glColor3f(1.0f, 1.0f, 0.0f); // // Now, draw our rectangle. // glBegin(GL_LINE_LOOP); glVertex2d(recTRx,recTRy); glVertex2d(recTRx,recBLy); glVertex2d(recBLx,recBLy); glVertex2d(recBLx,recTRy); glEnd(); // // Draw the control handles, if desired. // if (showHandles) { glColor3f(0.f,0.f,0.f); // black // corner handles. drawSquare(recTRx,recTRy, handleSize); drawSquare(recTRx,recBLy, handleSize); drawSquare(recBLx,recBLy, handleSize); drawSquare(recBLx,recTRy, handleSize); // edge handles. drawSquare((recTRx+recBLx)/2, recTRy, handleSize); drawSquare((recTRx+recBLx)/2, recBLy, handleSize); drawSquare(recTRx, (recTRy+recBLy)/2, handleSize); drawSquare(recBLx, (recTRy+recBLy)/2, handleSize); // centre handle. drawSquare((recTRx+recBLx)/2, (recTRy+recBLy)/2, handleSize); } // // Execute any GL functions that are in the queue. // glFlush(); // // Now, show the frame buffer that we just drew into. // (this avoids flicker). // glutSwapBuffers(); } ////////////////////////////////////////////////////////////////////// // // This gets called when the user presses a key. // // *** DO NOT CHANGE *** // ////////////////////////////////////////////////////////////////////// void handleKey(unsigned char key, int x, int y) { if (key == 'q' || key == 'Q') { exit(0); } } ////////////////////////////////////////////////////////////////////// // // Convenience function to check if the mouse is on a handle. // // Inputs: // x,y - mouse coordinates (they are passed in to handleMouseAction // or handleMouseMotion // hx,hy - coordinates of the CENTRE of the handle. // // Returns: // true - the mouse x,y lies within the square centred on // the handle's hx,hy (ie, if the mouse is on the handle). // // NOTE: // You will have to call this function nine (9) times, to // identify which handle the user clicked on. // // *** DO NOT CHANGE *** // ////////////////////////////////////////////////////////////////////// bool onHandle(int x, int y, double hx, double hy) { double wx,wy; double s = handleSize/2; viewportToWorldCoords(x,y, &wx,&wy); return hx-s <= wx && wx <= hx+s && hy-s <= wy && wy <= hy+s; } ////////////////////////////////////////////////////////////////////// // // Update the projection matrix. // // *** DO NOT CHANGE *** // ////////////////////////////////////////////////////////////////////// void setCamera() { glViewport(0,0, winWidth,winHeight); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(-winWidth /2/pixPerMeter, winWidth /2/pixPerMeter, -winHeight/2/pixPerMeter, winHeight/2/pixPerMeter); } ////////////////////////////////////////////////////////////////////// // // This gets called when the user re-sizes the window. // // *** DO NOT CHANGE *** // ////////////////////////////////////////////////////////////////////// void handleReshape(int w, int h) { winWidth = w; winHeight = h; setCamera(); } ////////////////////////////////////////////////////////////////////// // // Set the view volume and projection. // // *** DO NOT CHANGE *** // ////////////////////////////////////////////////////////////////////// void orthoView() { glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(-1.0,1.0, -1.0,1.0); } //******************************************************************** //** CODE FOR YOU TO CHANGE IS BELOW THIS LINE ********************** //******************************************************************** ////////////////////////////////////////////////////////////////////// // // ************************ YOU SHOULD CHANGE THIS ******************* // **** ADD OTHER FUNCTIONS IF NECCESSARY ************************** // // This function is called when the user presses or releases a // mouse button. // Parameters: // // button: possible values: GLUT_LEFT, GLUT_MIDDLE or GLUT_RIGHT // Identifies the button. // // state: possible values: GLUT_UP or GLUT_DOWN // The state of the button. // // x,y: The position of the mouse. // x goes from 0 on the left to winWidth-1 on the right. // y goes from 0 on the top to winHeight-1 on the bottom. // ////////////////////////////////////////////////////////////////////// void handleMouseAction (int button, int state, int x, int y) { // // Leave the following call in place. It tells GLUT that // we've done something, and that the window needs to be // re-drawn. GLUT will call display(). // glutPostRedisplay(); } ////////////////////////////////////////////////////////////////////// // // ************************ YOU SHOULD CHANGE THIS ******************* // **** ADD OTHER FUNCTIONS IF NECCESSARY ************************** // // This is called when the use moves the mouse. // // x,y: The position of the mouse (see handleMouseAction) // ////////////////////////////////////////////////////////////////////// void handleMouseMotion (int x, int y) { // // Leave the following call in place. It tells GLUT that // we've done something, and that the window needs to be // re-drawn. GLUT will call display(). // glutPostRedisplay(); } ////////////////////////////////////////////////////////////////////// // // Initialization. // // *** DO NOT CHANGE *** // ////////////////////////////////////////////////////////////////////// int main(int argc, char** argv) { reset(); // // Initialize the GLUT window. We want a double-buffered window, // with R,G,B and alpha per pixel, and the depth buffer (z-buffer) // enabled. // glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH); // // Put the window at the top left corner of the screen. // glutInitWindowPosition (0, 0); // // Specify the window dimensions. // glutInitWindowSize(winWidth,winHeight); // // And now create the window. // int mainWindowID = glutCreateWindow(argv[0]); // // Set up an orthogonal projection. // orthoView(); // // Register callbacks with the GLUT event handler. // // In other words, tell GLUT what to do when something happens. // // // When the user re-sizes the window, call handleReshape // glutReshapeFunc (handleReshape); // // When the user presses a key, call handleKey. // glutKeyboardFunc (handleKey); // // When the user presses or releases a mouse button, call handleMouseAction // glutMouseFunc (handleMouseAction); // // When the user moves the mouse, call handleMouseMotion // glutMotionFunc (handleMouseMotion); // // When GLUT decides it's time to re-draw the window, it will call "display" // glutDisplayFunc (display); // // Now set up a user-interface window, using the GLUI library. // setupUI(mainWindowID); // glutMainLoop(); // We would need this if we weren't using GLUI. return 0; // never reached }