views:

1778

answers:

3

Using OpenGL I'm attempting to draw a primitive map of my campus.

Can anyone explain to me how panning, zooming and rotating is usually implemented?

For example, with panning and zooming, is that simply me adjusting my viewport? So I plot and draw all my lines that compose my map, and then as the user clicks and drags it adjusts my viewport?

For panning, does it shift the x/y values of my viewport and for zooming does it increase/decrease my viewport by some amount? What about for rotation?

For rotation, do I have to do affine transforms for each polyline that represents my campus map? Won't this be expensive to do on the fly on a decent sized map?

Or, is the viewport left the same and panning/zooming/rotation is done in some otherway?


For example, if you go to this link you'll see him describe panning and zooming exactly how I have above, by modifying the viewport.

Is this not correct?

+1  A: 

Generally there are three steps that are applied whenever you reference any point in 3d space within opengl.

Given a Local point

  • Local -> World Transform
  • World -> Camera Transform
  • Camera -> Screen Transform (usually a projection. depends on if you're using perspective or orthogonal)

Each of these transforms is taking your 3d point, and multiplying by a matrix.

When you are rotating the camera, it is generally changing the world -> camera transform by multiplying the transform matrix by your rotation/pan/zoom affine transformation. Since all of your points are re-rendered each frame, the new matrix gets applied to your points, and it gives the appearance of a rotation.

FryGuy
+1  A: 

All of these "actions" can be achieved using model-view matrix transformation functions. You should read about glTranslatef (panning), glScalef (zoom), glRotatef (rotation). You also should need to read some basic tutorial about OpenGL, you might find this link useful.

Dmitriy Matveev
+4  A: 

They're achieved by applying a series of glTranslate, glRotate commands (that represent camera position and orientation) before drawing the scene. (technically, you're rotating the whole scene!)

There are utility functions like gluLookAt which sorta abstract some details about this.

To simplyify things, assume you have two vectors representing your camera: position and direction.

gluLookAt takes the position, destination, and up vector.

If you implement a vector class, destinaion = position + direction should give you a destination point.

Again to make things simple, you can assume the up vector to always be (0,1,0)

Then, before rendering anything in your scene, load the identity matrix and call gluLookAt

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt( source.x, source.y, source.z, destination.x, destination.y, destination.z, 0, 1, 0 );

Then start drawing your objects

You can let the user span by changing the position slightly to the right or to the left. Rotation is a bit more complicated as you have to rotate the direction vector. Assuming that what you're rotating is the camera, not some object in the scene.

One problem is, if you only have a direction vector "forward" how do you move it? where is the right and left?

My approach in this case is to just take the cross product of "direction" and (0,1,0).

Now you can move the camera to the left and to the right using something like:

position = position + right * amount; //amount < 0 moves to the left

You can move forward using the "direction vector", but IMO it's better to restrict movement to a horizontal plane, so get the forward vector the same way we got the right vector:

forward = cross( up, right )

To be honest, this is somewhat of a hackish approach.

The proper approach is to use a more "sophisticated" data structure to represent the "orientation" of the camera, not just the forward direction. However, since you're just starting out, it's good to take things one step at a time.

hasen j
Let me add that at no point the "viewport" (as set through glViewport) comes into this process. The viewport determines into what region of your window you will render (this is not actually true, but think of it this way for now) and will usually span the entire window.
Thomas