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

This topic is 1705 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

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?

##### Share on other sites

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.

##### Share on other sites

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);
gluOrtho2D(0, w, h, 0);
glMatrixMode(GL_MODELVIEW);
}


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

##### Share on other sites

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?

Edited by Brother Bob

##### Share on other sites

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:
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. Edited by Olof Hedman

##### Share on other sites

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

##### Share on other sites

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.

##### Share on other sites

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.

Edited by Brother Bob

##### Share on other sites
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 :) Edited by Olof Hedman

##### Share on other sites

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.

##### Share on other sites

Thanks for the replies.

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

That's exactly what I want: be able to see my layers from different perspectives and choose one among them with a nice interface.

However, I couldn't make it work yet. Tried both approaches, from Bob and Olof, but stills nothing.

I don't know if I'm doing the calculations ok. Let me try to explain exactly how it's being done so far:

The layer l1 is drawn over the layer l2. Every layer have it's own attributes, i.e, xPosition, yPosition, width, height, and angle, so I must (I guess) apply the properly transformations in the modelview matrix before each draw.

As posted before, that's my perspective function, called before anything:

void setPerspective(int w, int h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
// gluOrtho2D(0, w, h, 0); (the old guy)
gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 0.001, 5000.0);
glMatrixMode(GL_MODELVIEW);
... (transformations suggested by you)
}


And that's the mess with which my layer is drawn, working perfectly with ortho2D:

            glLoadIdentity();
setPerspective(dst->width, dst->height);

// Dest transformations
glTranslatef(dst->cx, dst->cy, 0);  // cx = width/2   cy = height/2
glRotatef(-dst->angle, 0, 0, 1);
glTranslatef(-dst->cx, -dst->cy, 0);
glTranslatef(-dst->x, -dst->y, 0.0f);

// Source transformations
glTranslatef(src->x, src->y, 0.0f);
glTranslatef(src->cx, src->cy, 0);
glRotatef(src->angle, 0, 0, 1);
glTranslatef(-src->cx, -src->cy, 0);

glBindTexture(GL_TEXTURE_2D, src->texID;

glTexCoord2f(0.0f, 1.0f);  glVertex2i(0,0);
glTexCoord2f(1.0f, 1.0f);  glVertex2i(src->width,0);
glTexCoord2f(1.0f, 0.0f);  glVertex2i(src->width,src->height);
glTexCoord2f(0.0f, 0.0f);  glVertex2i(0,src->height);
glEnd();

glBindTexture(GL_TEXTURE_2D, 0);



Edited by ak09

##### Share on other sites

This topic is 1705 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.