Jump to content
  • Advertisement
Sign in to follow this  
Ganoosh_

guts of gluPerspective

This topic is 4674 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'm trying to avoid using gluPerspective and use my own call to glFrustum, however I can't seem to get it right. I read the replacement article on NeHe, but that didn't work at all for whatever reason. So I tried my hand at it and almost got it. It works for the particular angle I was testing, but thats about it and it's a little smaller than it's supposed to be so it wasn't even completely correct for that angle. Can anyone explain how I should go about figuring out the clipping planes correctly or how gluPerspective figures it? Thanks in advance

Share this post


Link to post
Share on other sites
Advertisement
Here's my 'perspective matrix' function, which wraps a call to a frustum function:


void Matrix4::perspective_yfov_RH(float yfov, float aspect, float n, float f)
{
yfov = Math::DegToRad(yfov);
float hh = tanf(yfov*0.5f)*n;
float hw = hh*aspect;
perspective_frustum_RH(-hw,hw,-hh,hh,n,f);
}




perspective_frustum_RH(), I think, takes the same arguments in the same order as glFrustum(), so you should be able to just substitute the latter for the former. To be honest I can't remember if this particular function has been tested, but you might try it out, or adjust your own code to reflect it, and see what happens. Let me know if it works.

Share this post


Link to post
Share on other sites
It does basically what the NeHe example did. I would think you would use cos but I'm not sure, every angle produces almost the same result, but it clips correctly with cos. It's actually very confusing

Share this post


Link to post
Share on other sites
GLdouble fH = cos((90/180*PI)*0.5) * 0.001;
GLdouble fW = fH * ((double)settings.resWidth/(double)settings.resHeight);
glFrustum(-fW, fW, -fH, fH, 0.001, (double)settings.viewDistance);



It's kinda hardcoded, but I think you can figure it out. the 90 is the angle, the /180*PI converts to radians, 0.001 is the zNear.
I just thought it over, mathematically correct it should be tan, but it's causing problems, I'm gonna keep working on it though.

Share this post


Link to post
Share on other sites
Yeah, I'm pretty sure it's tan(), so you might change to that if you haven't already. Also, keep in mind that the 90 you have there is the vertical rather than horizontal field of view, which could throw off your results depending on what you're expecting. And, I have no idea if this has anything to do with it, but your z-near looks kind of small (although I suppose it depends on what your z-far is).

Other than that, it could be some problem outside the code you posted, such as the wrong gl matrix mode, not loading the identity matrix before calling glFrustum(), or something of that sort.

Share this post


Link to post
Share on other sites
Yeah I changed it already, and I know it's the vertical so that's not the problem. I tried different zNears but it didn't seem to do much. I'm pretty sure all the other stuff is correct, but here's the whole thing to make sure:

glViewport(0, 0, settings.resWidth, settings.resHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
GLdouble fH = tan(90*0.5) * 0.001;
GLdouble fW = fH * ((double)settings.resWidth/(double)settings.resHeight);
glFrustum(-fW, fW, -fH, fH, 0.001, (double)settings.viewDistance);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

Share this post


Link to post
Share on other sites
You may also refer to my function (almost identical to jyk):


//------------------------------------------------------------------
//Create a Perspective View - Identical to gluPerspective ()
//------------------------------------------------------------------
#define PI (static_cast<double> (3.1415926535897932384626433832795))
void PerspectiveView ( double const fovY,
double const AspectWH,
double const zNear,
double const zFar)
{
//Some assertions
//CUSTOM_ASSERT (fovY > 0.0, "PerspectiveView: fovY is invalid.") ;
//CUSTOM_ASSERT (AspectWH > 0.0, "PerspectiveView: Aspect is invalid.") ;
//CUSTOM_ASSERT (zNear > 0.0, "PerspectiveView: zNear is invalid.") ;
//CUSTOM_ASSERT (zFar > 0.0, "PerspectiveView: zFar is invalid.") ;
//CUSTOM_ASSERT (zFar > zNear, "PerspectiveView: zFar is less than (or equal to) zNear.") ;

//Assume that the current matrix is GL_PROJECTION
//Projection matrix
//glMatrixMode (GL_PROJECTION) ;
//glLoadIdentity () ;

//Calculate the viewing frustum
double const Top = zNear * tan ((fovY / 2.0) * (PI / 180.0)) ;
double const Bottom = -Top ;
double const Right = Top * AspectWH ;
double const Left = -Right ;

//Setup the GL_PROJECTION matrix
glFrustum (Left, Right, Bottom, Top, zNear, zFar) ;
}
#undef PI





Only the lines from 'Calculate the viewing frustum...' downward make sense. You may compare it with gluPerspective (). I'm pretty sure they're the same. Good luck.

[Edit]: I think this line is causing your problem:
GLdouble fH = tan(90*0.5) * 0.001;

  • tan () receives a radian in double so you should convert it to radian first.
  • We are calculating half of the Field Of View, so FOV should be 45 degree (fW and fH specify the width and height from the center so they should be cut by half as they are by now).
    You may try replacing it with this line:
    GLdouble const fH = tan ((90.0 * 0.5) * (PI / 180.0)) * 0.001;


    [Edited by - Skeleton_V@T on January 2, 2006 1:29:39 AM]

    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.

    We are the game development community.

    Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

    Sign me up!