Page 77 - Computer Graphics Handout
P. 77

exit(0);
          }
          If any other mouse event—such as a depression of one of the other buttons—occurs, no response action will occur, because no
          action corresponding to these events has been defined in the callback function. We will now develop an example that incorporates
          many of the aspects of CAD programs and adds some interactivity. Along the way, we will introduce some additional callbacks. We
          start by developing a simple program that will display a single triangle whose vertices are entered interactively using the pointing
          device. We will use the same shaders so most of the code will be similar to our previous examples. We specify a global array to hold
          the three two-dimensional vertices
          point2 points[3];

          We can then use the mouse callback to capture the data each time the left mouse button is depressed. Consider the code
          int w, h;
          int count = 0;
          void mouse(int button, int state, int x, int y)
          {
          if(button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN)
          {
          exit(0);
          }
          if(button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
          {
          points[count].x = (float) x / (w/2) - 1.0;
          points[count].y = (float) (h-y) / (h/2) - 1.0;
          count++;
          }
          if(count == 3)
          {
          glutPostRedisplay();
          count = 0;
          }
          }
          The right mouse button is used to end the program. The left mouse button is used to provide the vertex data for our triangle.We
          use the globals h and w to hold the height and width of the OpenGL window. Hence, in our main we might see the code
          w = 512;
          h = 512;
          glutInitWindowSize(w, h);
          in our main function, which would give us the same 512 × 512 window we used previously. The basic idea is that each time the left
          mouse button is depressed, we put the scaled location of the mouse into points and then move on to the next vertex.Scaling is
          necessary because the mouse callback returns the position of the mouse in screen coordinates measured from the top-left corner
          of  the  window.  Thus,  for  our  w  ×  h  window,  the  top-left  corner  has  coordinates  (0,  0)  whereas  the  bottom  right  corner  has
          coordinates (w-1, h-1). This number of increasing y values from top to bottom is common in window systems and has its origins in
          television systems that display images top to bottom. The window we use in our application program has its origin in the center, the
          bottom-left corner is at (−1.0,−1.0) and the top-right corner has coordinates (1.0, 1.0). Because any primitives outside this region
          are clipped out, we want to scale the values returned by the mouse callback to this region and makesure to flip the y values so that
          our triangles appear upright. The two lines
          points[count].x = (float) x / (w/2) - 1.0;
          points[count].y = (float) (h-y) / (h/2) - 1.0;
          carry out this transformation of coordinates.
          Once we have the data for three vertices, we can draw the triangle. We cause the drawing of the triangle through the display
          callback. However, instead of invoking the display callback directly through an execution of display, we instead use
          glutPostRedisplay();
          What this function does is set an internal flag indicating that the display needs to be redrawn. Each time the system goes through
          the event loop, multiple events may occur whose callbacks require refreshing the display. Rather than each of these callbacks
          explicitly executing the display function, each uses glutPostRedisplay to set the




                                                              77
   72   73   74   75   76   77   78   79   80   81   82