2
votes

I am messing around in a program that performs all rendering using a matrix set by gluOrtho2D(). What I would like to do is to rotate a specific texture around the y-axis (0,1,0) so that it looks like the original matrix was provided by gluPerspective() instead. I realize that this is not possible with an orthographic projection matrix and that I will have to set up a new perspective projection matrix. I want the textures I draw to look exactly the same as when drawn with the orthographic matrix, except sometimes when I have rotated them around the y-axis.

So to summarize:
How do I find a perspective projection matrix that is equivalent to a given orthographic matrix when shapes are drawn in the xy-plane, but gives me perspective when not in the xy-plane?

3
Why would you want to do this?Nobody moving away from SE
Your summary sounds very different from your preceding notes to me.Nobody moving away from SE
The preceding notes might be slightly unclear, but what it all boils down to is the summary. I want to get perspective projections in a large program which uses orthographic projections for all rendering, while changing the minimum amount of code. It was a couple of years since I last took a course in computer vision so I am quite rusty.Leo
Well then please have a look at my updated answer and tell me if I got you right and solved your problem.Nobody moving away from SE

3 Answers

4
votes

Basically what I understand is: You want to have a perspective matrix that yields the same image as the orthographic projection, when the object lies in the XY-Plane.

So lets begin: You want to draw your plane in the XY-plane and you had gluOrtho2D(-w, w, -h, h); (asymmetric orthographic projection is a bit harder, if you need it, then say so). What you need to do now is:

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(2 * atan(h / 2)  * 180.0 / PI, w / h, 1, 3);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0, 0, -2);

What I have done here is matching the center of the projective view frustum on the section of the XY-plane that was visible in the orthographic projection.

Take the graphs of the projection frustums and some math and you can do this yourself :)


Just as a reminder I will leave my answer to the old question here.

Either you have ortho or perspective projection. You have to decide for one. You will not gain perspective by rotating on any axis.

Why would you have to change a whole program just to change the projection mode?

One possible solution: I assume the old GL with different matrix modes and so on:

glMatrixMode(GL_PROJECTION); //switch to projection matrix mode
glPushMatrix(); //push the old matrix
glLoadIdentity();
//apply the perspective projection
//do your rendering
glPopMatrix(); //pop the old matrix

With the newer GL scheme you will have to do most of this on your own but it should be easy though.

0
votes

Is this possible in some easy way without having to convert all of the program to using gluPerspective()?

I'm already getting tired of telling this, but:

The projection is not something defined one time and then enforced on the whole rendering process. You can switchi it anytime you like, and for any anvanced rendering scheme will do this multiple times throughout a single frame.

I think most newbies are confused by this:

reshape(width, height):
    glViewport(0,0,width,height)
    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()
    projection_setup()

They see the projection done in the reshape function and think it's the only place to do it. Please speak with me: The projection matrix is just some state used for drawing as anything else. It can be changed as easily as the current color or texture.

Just set the projection you need for a certain sequence of drawing commands as you need it, right before you do the drawing.

0
votes

It is possible to have perspective effect, i.e. rotate around x or y axis, even though your projection matrix is orthographic, the trick is to multiple your view matrix by this magic matrix before/after any other view transformation:

// The matrix is
// -z,  0,  x,  0
//  0, -z,  y,  0
//  0,  0,  1,  0
//  0,  0,  1, -z

where :

  • x is half viewport width,
  • y is half viewport height,
  • z might be any negative number except -0.

Several notes:

  1. if u r calling glRotate*, this matrix goes first as these built-in calls are right hand multiplication. if u r tracking ur own view matrix using left hand multiplication as suggested on text-books, this matrix goes last. In either way, this matrix will actually be multiplied by your orthographic project matrix, so u can pre-calculate as well
  2. z is actually the simulated z depths, so bigger it is in magnitude, further the objects are, as a consequence, rotation looks more like orthographic. Z cannot be positive because this will make w in NDC negative, OpenGL does not allow that, it will get clipped so nothing will draw
  3. In the end, there is no magic, this matrix is just a compensate, after u do: M(ortho) X M(magic), u get a perspective matrix
  4. This trick is crucial if 99% of your code is for orthographic but only one place or two need perspective effect, then u don't need to switch between two modes, if u r using fixed-pipeline, GL_PROJECTION_MATRIX will be left unchanged
  5. this matrix is taken from Android Open Source Project so hopefully this will give u much confidence