Re: Q: Expressing modelview coordinates as Quartz coordinates
# Re: Q: Expressing modelview coordinates as Quartz coordinates

**Subject**: **Re: Q: Expressing modelview coordinates as Quartz coordinates**
- From: "jason cipriani" <email@hidden>
- Date: Fri, 13 Jan 2006 20:58:02 -0500
- Delivered-to: email@hidden
- Delivered-to: email@hidden

Your gluLookAt wasn't working because it wasn't doing what you thought it was doing. When you are setting up a perspective transformation, typically the "eyepoint" is at the center of the screen (it's the place where the frustum would come to a point, or where the "camera" is). But when you set up a transformation matrix using glOrtho the origin is wherever you specify it. In your case you specified it as the lower-left corner so the "eyepoint" was the lower left corner. That means that when you do:
gluLookAt(eyex, eyey, eyez, eyex, eyey, 0, 0, 1, 0);
What you are doing is positioning it so that eyex,eyey,eyez is at the origin, which is actually the lower left corner. What you want is:
gluLookAt(0, 0, rect.width, 0, 0, 0, 0, 1, 0);
The gluLookAt man page states:
"The matrix maps the reference point to the negative Z axis and the eyepoint to the ORIGIN [the lower-left corner in your case]. When a typical projection matrix is used, the center of the scene therefore maps to the center of the viewport [not the case with your ortho matrix]."
While it's hard to explain it makes a lot of sense if you look at the math. gluLookAt is equivalent to:
glMultMatrixf(M);
glTranslated(-eyex, -eyey, -eyez);
Where M is constructed as follows:
F = [ centerx-eyex centery-eyey centerz - eyez ]
f = F / ||F|| <-- makes F unit length
UP' = UP / ||UP|| <-- makes UP unit length
s = f X UP'
u = s X f
[ s[0] s[1] s[2] 0 ]
M = [ u[0] u[1] u[2] 0 ]
[ -f[0] -f[1] -f[2] 0 ]
[ 0 0 0 1 ]
So for your gluLookAt:
F = [ 0 0 -width ]
f = [ 0 0 -1 ]
UP = [ 0 1 0 ]
UP' = [ 0 1 0 ]
s = [ 0 0 -1 ] X [ 0 1 0 ] = [ 1 0 0 ]
u = [ 1 0 0 ] X [ 0 0 -1 ] = [ 0 1 0 ]
[ 1 0 0 0 ]
M = [ 0 1 0 0 ]
[ 0 0 1 0 ]
[ 0 0 0 1 ]
And what do you know, it's identity. And that makes sense since you are looking directly along +Z. So then that means that your gluLookAt call is actually equivalent to:
glMultMatrixf(identity); // <--- does nothing
glTranslatef(-width/2, -height/2, -width);
And since it's just a translation, now you can see why it shifted your rectangle left and down. gluLookAt was intended for perspective transformations and other transformations that placed the origin at the center of the window; if the origin isn't in the middle then it doesn't -really- mean "look at" any more.
So, you said you were using gluLookAt to adjust the camera position to keep the objects in the clipping plane when you zoom in on something. Firstly, you'd be better off just using glTranslate since the math is more apparent and that's all you want to be doing anyway, (glTranslate(0,0,zoffset)). But the other problem is, if you are "zooming in" on something by moving the objects in your scene closer to the camera, applying a translation (via gluLookAt or glTranslatef or whatever) will basically undo your zooming since all you are really doing is moving the objects closer to the camera, then moving the camera that much farther from the objects.
Also, with an orthographic projection matrix like that, zooming isn't going to make things bigger because there is no perspective, the objects will be the same size no matter how far from the camera they are. One way to do this is to simply scale all your objects in the X and Y direction (and maybe Z, depending on what you are trying to do). Note that scaling occurs from the origin so you will have to align the center of the view with the origin, apply the scaling, then move the origin back to the bottom-left:
glOrtho(0, width, 0, height, width, 0);
glTranslatef(width/2, height/2, 0);
glScalef(zoom, zoom, 1);
glTranslatef(-width/2, -height/2, 0);
An alternative way to do it (the math works out the same) is:
float halfw = width/2;
float halfh = height/2;
glOrtho(-halfw/zoom, -halfh/zoom, halfw/zoom, halfh/zoom, width, 0);
glTranslatef(-halfw, -halfh, 0);
One thing that you should be careful of is when you set nearz > farz, you are flipping the Z axis but not the X or Y axis so the coordinate system becomes left-handed (GL is base on a right-handed coordinate system). So face culling and lighting may not work correctly. That may or may not be a problem for you, depending on what you are trying to do.
I hope that helps more,
Jason
----- Original Message -----
From: "Christopher Hunt" <email@hidden>
To: "jason cipriani" <email@hidden>
Subject: Re: Q: Expressing modelview coordinates as Quartz coordinates
Date: Sat, 14 Jan 2006 09:17:54 +1100
>
> Hi Jason,
>
> Thanks for your replies.
>
> First, as another responder pointed out, I am working with an origin in the
> bottom left as per my original glOrtho:
>
> glOrtho(
> 0.0, theRect.size.width,
> 0.0, theRect.size.height,
> theRect.size.width, 0.0
> );
>
> The reason I ended up using gluLookAt was because my near plane was being
> clipped when I zoomed in on something. So, I always made sure that I shifted
> my camera position back the further I zoomed in on something. I presumed
> that I had to do this given that the camera is effectively at 0,0,0 by
> default.
>
> I accept that I might not actually need to use gluLookAt, and I'll
> investigate this possibility. However I'm still interested to learn why my
> gluLookAt wasn't working.
>
> Cheers,
> -C
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Mac-opengl mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden