Jump to content
  • Advertisement
Sign in to follow this  
Headkaze

gluPerspective and rotation

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

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have my projection matrix setup the following way:

#define FOV 15.0f
#define NEAR_PLANE 1.0f
#define FAR_PLANE 20.0f

gluPerspective(FOV, g_displayScreen->DisplaySize.width / g_displayScreen->DisplaySize.height, NEAR_PLANE, FAR_PLANE);


My problem is when the device rotates from portrait mode to landscape the width and height are swapped changing the aspect ratio. While my camera is still at the same distance from Z=0 it appears to zoom out. If I use the same aspect the display is stretched.

How do I manage the rotation but have the display appear to be the same distance from the camera visually?

I've tried

glViewport(0, 0, g_displayScreen->DisplaySize.height, g_displayScreen->DisplaySize.height);

But it doesn't make any difference.

Share this post


Link to post
Share on other sites
Advertisement

I have my projection matrix setup the following way:

#define FOV                    15.0f
#define NEAR_PLANE            1.0f
#define FAR_PLANE            20.0f

gluPerspective(FOV, g_displayScreen->DisplaySize.width / g_displayScreen->DisplaySize.height, NEAR_PLANE, FAR_PLANE);


My problem is when the device rotates from portrait mode to landscape the width and height are swapped changing the aspect ratio. While my camera is still at the same distance from Z=0 it appears to zoom out. If I use the same aspect the display is stretched.


I've tried

glViewport(0, 0, g_displayScreen->DisplaySize.height, g_displayScreen->DisplaySize.height);

But it doesn't make any difference.

I'm sure your "g_displayScreen->DisplaySize.width" and "g_displayScreen->DisplaySize.height" are integer types. But you must know that dividing integers and floating points units in C++ like (1/2) are not equal... where (integer returns 0 and floating point with 1.0f/2.0f returns 0.5f). So, you need to convert these types from integer to floating point:


gluPerspective(FOV, double(g_displayScreen->DisplaySize.width) / double(g_displayScreen->DisplaySize.height), NEAR_PLANE, FAR_PLANE);
Is your camera setting starts from identity matrices? (projection, modelview)





-me

Share this post


Link to post
Share on other sites

I'm sure your "g_displayScreen->DisplaySize.width" and "g_displayScreen->DisplaySize.height" are integer types.


The're actually floating point types (a SizeF struct made of width and height floats to be exact)


Is your camera setting starts from identity matrices? (projection, modelview)


Yes the camera starts from an identity matrix which is then just a glTranslatef in the modelview matrix.

So when I rotate the iPhone from portrait to landscape the device rotates the view and I swap the DisplaySize width and height values. The display is fine apart from it being "zoomed out" more.

Some hardware specific information.. I am using a UIViewController to rotate the view. If I custom rotate using glRotate I can keep the ratio in the gluPerspective() call the same. So rotating that way is fine; the camera appears at the same distance when I rotate the device from portrait to landcape. But I need to add a view over the top of my EAGLView (OpenGL view) and so I want the UIViewController to take care of rotation. This means the actual view is rotating and so I need to modify the ratio accordingly. This causes the display to appear "zoomed out" more in landscape mode even though the distance of the camera is the same as it was in portrait. It must be the calculation of ratio as I don't modify the viewport or anything else. I'm just wondering if there is a simple way to maintain the viewable distance after the rotation preferably without manually translating the camera further out in landscape mode.

Share this post


Link to post
Share on other sites

I think you just need to adjust your fov for each mode, since the view height changes.


It seems like it would be something like that. So I wonder what formula I could use to calculate the new FOV?

Share this post


Link to post
Share on other sites
You can look at the figure 3-12 in the Red Book as a reference. If you know your trigonometry, you can see that the field of view is twice the angle of the ratio between the near plane distance and half the near plane height. So, to step through the process with that in mind, it goes like this
  1. Calculate the half-height of the near plane given the near plane distance and the FOV: height=near*tan(FOV/2)
  2. The new height of the rotated screen is scaled by the aspect ratio: newheight=aspect*height
  3. Calculate the new FOV from the new height and the near plane distance: newFOV=atan(newheight/near)*2
That should be it, though I may have some division or multiplication the wrong way. Just double check the formulas. Note that you can cancel the multiplication and the division by near, the angles must be of the correct unit (radians vs. degrees), and that you need to reverse the aspect ratio calculation to gluPerspective as well (the aspect ratios between landscape and portrait are reciprocal).

Share this post


Link to post
Share on other sites
Thanks Brother Bob you were a great help. Out of interest here is the solution.

[source]float aspect = g_displayScreen->DisplaySize.width / g_displayScreen->DisplaySize.height;

if(g_displayScreen->IsVertical)
{
gluPerspective(FOV, aspect, NEAR_PLANE, FAR_PLANE);
}
else
{
float tangent = tanf(FOV * PI / 180.0f / 2.0f);
float height = NEAR_PLANE * tangent;
float width = height * aspect;
float fov = 2.0f * atanf(width * 0.5f / NEAR_PLANE) / PI * 180.0f;
gluPerspective(fov, aspect, NEAR_PLANE, FAR_PLANE);
}[/source]

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!