We're now going to talk about how OpenGL interacts with the Window system, really how GLUT interacts with the system, and how we can define callbacks and control, for example, mouse motion. First I would like to mention that Window system interaction is not part of OpenGL. Therefore you have to use a toolkit; GLUT is the one we use. It defines callback functions for events. This is a very similar architecture to other kinds of programming environments such as X, Java, etc. Therefore you can define callbacks for the keyboard, for the mouse, for opening, initializing, re-sizing the window. If you just look at our main function, we had a callback for display, we had a callback for reshape, callback for the keyboard, for the mouse, and dragging the mouse. Let's first discuss the keyboard function because it's a basic example of what a callback function looks like. You have as inputs, the key, and then you also have the x and y coordinates of where the key was pressed, since it may behave differently at different locations. In our case, we do almost nothing with the keyboard. If you hit Escape, the ASCII code for Escape is 27, that's why I have said case 27, then I will exit. The reshape is another callback, so if I reshape the window with some width and some height. I set my glViewport command to that width and height. That is one place where we use glViewport. Look what happens next. I go to the projection matrix, I load it with the identify, and then I give the gluPerspective command, where the only thing I change is the aspect ratio of width to height. Let's look into that in a little bit more detail. First let's consider this number 30. We know that that is the field of view in the y direction. So it is the field of view in the y direction and that's the first parameter to gluLookAt. Now let's consider this next one which is where w and h really come into play, and we know that width by height (w / h), this is the aspect ratio and that's where they really come into play, so you are affecting the aspect and this ensures that the image will be filled up and the window will display the image with the proper proportions. The near plane and the far plane. Okay? So I can write that as, let me just write it as n and f. And that's been a brief refresher of the different commands, to, or the different arguments to gluPerspective. Note that the model view matrix is not affected because the camera location hasn't changed, and only the perspective matrix, or the projection matrix changes. Here is the mouse motion. Let me go over each of these steps in detail. We have the state of the mouse, the button that was handled, the coordinates. If the button is the left button of the mouse, well if the state is up, you do nothing, but if the state is down, you get ready to begin a drag. And look at the way this is handled. The old x, which is the starting point of the drag, is set to the current value. And what that means is that the drag is relative. When you stop pressing the mouse, from that point on your relative shift will control how the object moves. If you press the right button and it's down, then I just reset gluLookAt. So I will reset eye location to its initial value, go to the model view matrix and load the identity, and then reset it with my original gluLookAt. Note the command gluPostRedisplay. This is a very important command. And essentially it tells GLUT to queue up the display function as soon as possible. This is important because I have changed all my parameters, but now I need to redraw the scene. I will show you the demo of the mouse program. So let's look at my scene. I just have a plane here. I actually have one plane above it which we've not seen, and what I am going to do is just move my mouse. So here's the position, and I click left at this point in time, and I can zoom in and I can zoom out and that's relative to where I clicked. Now I am going to release the button, move to another location and click. Note that nothing happens when I first click. It's only when I drag that it zooms in, and when I drag, then it zooms out. Zoom in. Zoom out. Zoom in. Zoom out. So I already showed you the demo of dragging the mouse, and here's what the function looks like. Notice that the y location is now given by y minus the old value, so it's the increment. And, the eye location, increments, by some, function, times the Y location. I don't let it get less than 0. I set it back to 0. After I'm done with this drag, I reset the mouseoldy, so the drag is always relative to the previous location. Finally, I have to go and set the eye location, so I go to the model view matrix, load it with the identity, reset gluLookAt and queue the display function.