PDA

View Full Version : Confused about how projection works

Jengu
08-11-2005, 10:26 PM
For a small project I'm trying to draw a simple 3d graph. After reading a big chunk of the redbook and online tutorials I gathered the proper way to do this is glOrtho.

To get the view I want, I do this in code:

glRotatef(-45, 1, 0, 0);
glRotatef(135, 0, 0, 1);
glOrtho(GetHorizontalMin(), GetHorizontalMax(), GetVerticalMin(), GetVerticalMax(), -GetDepthMin(), -GetDepthMax());Where the min/max functions are min/max values in each dimension of the data to be graphed (more simply: GetHorizontalMin stores the smallest x value of all the points, GetDepthMax stores the greatest z value of all the points, etc.). I figure this way when I get to plotting points I can just do glVertex3f(point.x, point.y, point.z) and count on the point showing up in the right place.

...but things don't appear to be so simple! First, is it a bad idea for me to call glRotatef on the projection matrix? I'm not 100% confident I know what glRotate is doing -- does it move the clipping planes that glOrtho sets up so that I'll need to put my points in a different place for them to show up?

I found this site that seems to think calling anything other than glOrtho, gluPerpsective, etc. is a bad idea and I'm not sure if what I'm doing is a similar abuse:

http://sjbaker.org/steve/omniv/projection_abuse.html

Second, I'm not sure why, but I had to do negative DepthMax/Min in order to get anything to show up! If I pass them both positive, everything disappears. DepthMin is always greater than 0, DepthMax is alwas less than 100, and DepthMax is always greater than DepthMin.

Lastly, this is the code I'm using to draw the axes right now:

glColor4ub(0, 0, 255, 255);
glLineWidth(1.0);
glBegin(GL_LINES);
glVertex3f((GetHorizontalMin() + GetHorizontalMax()) / 2, (GetVerticalMin() + GetVerticalMax()) /2, (GetDepthMin() + GetDepthMax()) /2);
glVertex3f(GetHorizontalMax(), (GetVerticalMin() + GetVerticalMax()) /2, (GetDepthMin() + GetDepthMax()) /2);

glVertex3f((GetHorizontalMin() + GetHorizontalMax()) / 2, (GetVerticalMin() + GetVerticalMax()) /2, (GetDepthMin() + GetDepthMax()) /2);
glVertex3f((GetHorizontalMin() + GetHorizontalMax()) / 2, GetVerticalMax(), (GetDepthMin() + GetDepthMax()) /2);

glVertex3f((GetHorizontalMin() + GetHorizontalMax()) / 2, (GetVerticalMin() + GetVerticalMax()) /2, (GetDepthMin() + GetDepthMax()) /2);
glVertex3f((GetHorizontalMin() + GetHorizontalMax()) / 2, (GetVerticalMin() + GetVerticalMax()) /2, GetDepthMax());
glEnd();I had to do it that way to get the axes to show up! Again, I'm not sure why. What the code is doing is drawing half an axis -- from the midpoint to the end. If I try to draw a whole axis, i.e:

glVertex3f(GetHorizontalMin(), GetVerticalMin(), GetDepthMin()) // Draw x axis
glVertex3f(GetHorizontalMax(), GetVerticalMin(), GetDepthMin())then it doesn't show up!

Can someone explain my questions? I've read quite a bit about OpenGL but I think I must have some misconceptions about fundamentals.

T101
08-12-2005, 10:42 AM
First of all, you have to understand that you should not confuse the projection matrix with the modelview matrix.
They are separate, and for good reasons. Although one of the main reasons - lighting - does not seem to apply to your case.

The projection matrix maps "observer space" to screen space, and the projection matrix is what you want to call gl(u)Ortho on.

Second, you have to understand that the modelview matrix is a combination of the camera's position and rotation and the objects' position and rotation. It's job is to move object coordinates into observer space. This is the place where you'll want to set the camera angles.

It can feel a bit strange. Because you need to start with a loadidentity, then rotating then translating by the inverse of the camera's rotation and translation respectively. Only after that you apply object rotations and translations.

The big thing to understand is that the matrix operations (the translates, rotates and scales) are performed on the object coordinates in the opposite order in which they were specified. So it does not make sense to for example do a rotate and then a perspective.