How can I change [-1,1] range from gluPerspective?

Started by
9 comments, last by ak09 10 years, 11 months ago

I'm drawing 2D, on different layers, dealing with real coordinates [(0,0), (screenWidth, screenHeight)] instead of the standard [-1,1]. And everything is ok when using gluOrtho2D(0, w, h, 0).

However, I want to be able to render those layers in a 3D space, so the user can merge in the scene. The problem is: with gluPerspective, all my coordinates are changed, and for the reason I'd have to change them all in my code, this is strictly unwanted.

So, is there a (simple) way to solve my thing?

Advertisement

That is the job of the view matrix.

A scaling and a translation will make sure that the coordinates in x/y-plane from 0,0 to w,h is mapped to the screen.

That is the job of the view matrix.

A scaling and a translation will make sure that the coordinates in x/y-plane from 0,0 to w,h is mapped to the screen.

Sorry, but this is a little vague to me.
All I'm doing is making a perspective change before every texture draw — since they can have different sizes — with:


void setPerspective(int w, int h)
{
    glViewport(0, 0, w, h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(0, w, h, 0);
    glMatrixMode(GL_MODELVIEW);
}
 

By replacing my gluOrtho2D with gluPerspective, what changes shoud I make and where?

You need to use different coordinates for your vertices since the coordinate systems are completely different. For a given vertical FOV and aspect ratio, you can calculate the range in X and Y direction at a certain depth Z.


yrange = Z*tan(fov/2);
xrange = yrange*aspect;

The range of the coordinate system at depth Z is from -xrange to xrange in the X direction, and from -yrange to yrange in the Y direction.

But why do this and not use an orthographic projection for your 2D, and a perspective projection for your 3D?

By replacing my gluOrtho2D with gluPerspective, what changes shoud I make and where?


You also need to set up the modelview matrix.

After glMatrixMode(GL_MODELVIEW); you need some calls to glScale and glTranslate, to make sure your coordinates are scaled into the -1,1 range.

something like:
glLoadIdentity();
glTranslate(w/2,h/2,0);
glScalef(w,h,1);

Anything positioned on z-depth 0 can have the same coordinates as if they were set up in a ortho view.

You need to use different coordinates for your vertices since the coordinate systems are completely different. For a given vertical FOV and aspect ratio, you can calculate the range in X and Y direction at a certain depth Z.


They are only completely different if you choose to make them completely different.
(By for example not setting up the modelview-matrix.)

I'm assuming he want 2d planes in a 3d space, and feels it is convenient to use screen points to position those panes.

They only become equivalent for a very specific depth, everywhere else your scaling and offsets will be completely off.

True, that is the point of a perspective transform after all. (give a visual queue of the depth by scaling things accordingly)

But they still aren't "completely" different, and doesn't have to be changed.

I assumed this is what he wants, for example to be able to do a 2D UI with nice 3D transitions.

Yes, I assume that as well. But a difference in projection does not have to mean a difference in coordinates. With proper setup, he can indeed draw the same things and get the same result and that was the point of your and my reply. They are fundamentally different types of projection because you cannot blindly replace one with the other. The w and d in your code has to be calculated. That's fine, and the calculations is going to involve, in one way or another, the expressions I gave: w and d are going to depend on the FOV and the Z, and will only be valid for that particular FOV and Z. Your w and d are nothing more that compensation for the differences between orthographic and perspective projection.

He said he wanted 2D with layers, so your w and d, or my xrange and zrange, will necessarily have to be recalculated for each Z. An orthographic projection still allows layering and depth, but there's no need to recalculate anything for different depths, and the coordinate system can be directly and explicitly specified with the desired ranges. That is why I ultimately asked the question if his perspective approach is really necessary, or just based on the no-so-uncommon erroneous belief that your program cannot have multiple types of projections.

Yes, the end result is the same, its just a matter of where you choose to make the calculation... I just reacted to the statement "You need to use different coordinates for your vertices", since they don't strictly _have_ to be changed. specially not if all you want is transitions and movements in 3d, in that case you want the panel to grow if you move it closer, and shrink when you move it away from the xy-plane at z=0. vertices data can then be left untouched if the recalculation is baked into the modelview


He said he wanted 2D with layers, so your w and d, or my xrange and zrange, will necessarily have to be recalculated for each Z. An orthographic projection still allows layering and depth, but there's no need to recalculate anything for different depths, and the coordinate system can be directly and explicitly specified with the desired ranges. That is why I ultimately asked the question if his perspective approach is really necessary, or just based on the no-so-uncommon erroneous belief that your program cannot have multiple types of projections.

That is a good point, if all he wants is layering, an ortho view is probably easier.

I'm not sure what he wants from the original question, so hopefully he is properly helped now with our combined perspectives :)

Yes, that statement was not correct in that context and I even contradicted myself later, but it was more in the context of just replacing one with the other. Compensate properly for a specific case, and it works for that specific case: we both agree on that.

This topic is closed to new replies.

Advertisement