Technolithic's picture

Zooming with Perspective

This is really an OpenGL question involving Perspective Projection, but I'm using this omnipotent framework called OpenTK and hope to find a straightforward answer to my quandary.

I think zooming can be accomplished using the Perspective Projection by altering the 1st parameter. I believe it should operate between the range of 0.0 and 180.0, exclusive. This is how I understand it; however, in practice the viewing becomes smaller after each time the fZoom variable is updated and the display method is called!

I'm using the mouse to generate events to modify fZoom, incrementing by 1 or so each time. I've tried different ranges and increments, but the result is the same... the model appears to be drifting away, no matter which direction the fZoom value is going.

Is there an easy understanding of how the Perspective Projection can be used for this, are folks just blowing smoke, or am I just smoking crack?

I'm not finding anywhere else where the fZoom variable could be altered... In fact, I'm outputting the value to a label to prove that the value increments and decrements properly just after the call to Perspective.

Here is the code I call in my window update, just before the OpenGL primative calls for points and lines:
Anyone have any ideas?

            Glu.LookAt(0.0, 0.0, 500.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
 
            GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
 
            GL.PushMatrix();
 
            GL.MatrixMode(MatrixMode.Modelview);
            GL.LoadIdentity();
 
            // Set panning position
            GL.Translate(fTransX, fTransY, 0f);
 
            // Rotate the mesh model about it's own axis
            GL.Rotate(fRotateX, 1f, 0f, 0f);
            GL.Rotate(fRotateY, 0f, 1f, 0f);           
            GL.Rotate(fRotateZ, 0f, 0f, 1f);
 
            Glu.Perspective((double)fZoom, 1.0, 0.1, 9000.0);
            lblZoom.Text = "fZoom: " + fZoom.ToString();
            GL.PopMatrix();

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
straka.milan's picture

I think zooming can be accomplished using the Perspective Projection by altering the 1st parameter. I believe it should operate between the range of 0.0 and 180.0, exclusive. This is how I understand it; however, in practice the viewing becomes smaller after each time the fZoom variable is updated and the display method is called!

The first parameter of gluProjection is not a zoom factor. As the docs of gluProjection say, the first parameter is 'field of view in the y axis'. The second parameter is the aspect ratio x to y, so the 'field of view in the x axis' is the first parameter multiplied by the second parameter of gluPerspective.

The projection is of a square pyramid shape. The apex (top) of the pyriamid is in the (0,0,0) and the base of the pyramid is perpendicular to the z axis. The 'fovx' and 'fovy' parameters determine the angle between the opposite faces of the pyramid.

To be thorough, the third and fourth parameter of gluPerspective determine what do you see in the pyramid: you see everything, which z-coordinate is in the range specified by the third and fourth parameter.

Glu.Perspective((double)fZoom, 1.0, 0.1, 9000.0);

The second parameter "1.0" should be the ratio of vieoport width and vieport height, so the code is correct only when the viewport is of the same witdh and height.

And BTW the 0.1 and 9000 range is quite large -- as the specs say, approx log (9000/0.1) ~ 16.45 bits of depth buffer precision is lost -- your code would not probably work with 16bit depth buffer.

 

What exactly do you want to achieve? When thinking about it, a "zoom" is probably really a change of 'fovx' and 'fovy', but according to your question you are not satisfied with that result :)

Technolithic's picture

Thanks for the reply and for the insight!

OpenGL is new to me, so I'm in the learning stages about some of the basics. I neglected to give any thought about the depth buffer. I will have to take a look at exactly what values I need for depth. I don't believe precision is really an issue, as long as it's close enough. Actually, with the scale of the model being used in my project, it seems unreal that I need high precision with a large available space, but I do need the ability to zoom in pretty far.

What I'm trying to accomplish is being able to zoom in to the rendered object, which will span the screen many times when zoomed in. When zoomed out, the entire object can be viewed on the screen. I suppose I can do this with a translation along the z-axis, but it seems like the angle of viewing of the peripherals gets unrealistic and distorts around this area, making the rendering appear almost bubble-vision-like.

I think I'm getting closer to the solution I like by changing the fovy, the first parameter of Glu.Perspective(), but I need to keep working with it. I just changed some things around and I'm finally getting somewhere with it. It seems like a smaller value for this parameter creates the narrow view I'm looking for. Honestly, it's a little confusing to me how it really works. I'll have to stare at the formulas and diagrams a while longer till the revelation is encountered.

the Fiddler's picture

The field of vision controls the "opening" of the view frustum. A FOV of 180 degrees, means that you can see everything starting from your left ear to your right. A FOV of 10 degrees, would be like tunnel vision (or looking through a telescope). A FOV of 360 is all-around vision (front, left, right and the back of your head).

You can achieve a zoom-in effect by lowering the FOV. Hope this makes some sense. :)

Technolithic's picture

It makes absolutely perfect sense. With the zooming control, just changing the FOV makes it work great!

Thanks for the help, guys!

Once again, this forum rocks!