1

I have a basic camera class, of which has the following notable functions:

    // Get near and far plane dimensions in view space coordinates.
float GetNearWindowWidth()const;
float GetNearWindowHeight()const;
float GetFarWindowWidth()const;
float GetFarWindowHeight()const;

// Set frustum.
void SetLens(float fovY, float aspect, float zn, float zf);

Where the params zn and zf in the SetLens function correspond to the near and far clip plane distance, respectively.

SetLens basically creates a perspective projection matrix, along with computing both the far and near clip plane's height:

void Camera::SetLens(float fovY, float aspect, float zn, float zf)
{
    // cache properties
    mFovY = fovY;
    mAspect = aspect;
    mNearZ = zn;
    mFarZ = zf;

    float tanHalfFovy = tanf( 0.5f * glm::radians( fovY ) );

    mNearWindowHeight = 2.0f * mNearZ * tanHalfFovy;
    mFarWindowHeight  = 2.0f * mFarZ * tanHalfFovy;

    mProj = glm::perspective( fovY, aspect, zn, zf );
}

So, GetFarWindowHeight() and GetNearWindowHeight() naturally return their respective height class member values. Their width counterparts, however, return the respective height value multiplied by the view aspect ratio. So, for GetNearWindowWidth():

float Camera::GetNearWindowWidth()const
{
    return mAspect * mNearWindowHeight;
}  

Where GetFarWindowWidth() performs the same computation, of course replacing mNearWindowHeight with mFarWindowHeight.

Now that's all out of the way, something tells me that I'm computing the height and width of the near and far clip planes improperly. In particular, I think what causes this confusion is the fact that I'm specifying the field of view on the y axis in degrees, and then converting it to radians in the tangent function. Where I think this is causing problems is in my frustum culling function, which uses the width/height of the near and far planes to obtain points for the top, right, left and bottom planes as well.

So, am I correct in that I'm doing this completely wrong? If so, what should I do to fix it?

Disclaimer

This code originally stems from a D3D11 book, which I decided to quit reading and move back to OpenGL. In order to make the process less painful, I figured converting some of the original code to be more OpenGL compliant would be nice. So far, it's worked fairly well, with this one minor issue...

Edit

I should have originally mentioned a few things:

  • This is not my first time with OpenGL; I'm well aware of the transformation processes, as well the as the coordinate system differences between GL and D3D.

  • This isn't my entire camera class, although the only other thing which I think may be questionable in this context is using my camera's mOrientation matrix to compute the look, up, and right direction vectors, via transforming each on a +x, +y, and -z basis, respectively. So, as an example, to compute my look vector I would do: mOrientation * vec4(0.0f, 0.0f, -1.0f, 1.0f), and then convert that to a vec3. The context that I'm referring to here involves how these basis vectors would be used in conjunction with culling the frustum.

zeboidlund
  • 9,731
  • 31
  • 118
  • 180
  • Surely this cannot be your entire camera class. You also have to multiply the projection matrix by a model/view matrix, and this is the source of a lot of problems when porting from DX to GL. Direct3D uses row-major matrices so the canonical form is `Model * View * Projection`, GL uses column-major so its canonical form is `Projection * View * Model`. Likewise, this applies to the order of Scale, Rotate and Translate - they are reversed between the two APIs. – Andon M. Coleman Nov 16 '13 at 22:27
  • @AndonM.Coleman, sorry for the ambiguity - I updated my question accordingly with some distinct clarifications. – zeboidlund Nov 16 '13 at 22:35
  • `mNearWindowHeight = 2.0f * mNearZ * tanHalfFovy;` how did you come up with the `2.0f`? – Jaa-c Nov 16 '13 at 22:36
  • @Jaa-c, that was actually what the original Camera class had used in the book I snagged the code from :), so I assumed that it was part of the formula for computing the height. – zeboidlund Nov 16 '13 at 22:38
  • @blissfreak: I'm sorry, my mistake, it's OK. I seems to me your math is OK. – Jaa-c Nov 16 '13 at 22:41
  • @Jaa-c No worries at all, I appreciate you giving it an extra look. – zeboidlund Nov 16 '13 at 22:42
  • 1
    @blissfreak: Check this [link](http://zach.in.tu-clausthal.de/teaching/cg_literatur/lighthouse3d_view_frustum_culling/), there is all the math you need. What you have here seems OK, I would look for an error elsewhere... – Jaa-c Nov 16 '13 at 22:47
  • 1
    That is correct, as the name implies `mNearZ * tanHalfFovy` only gives you half of the vertical field-of-view. It basically tells you the maximum distance vertically (+/-) you can see for a point projected some distance forward from the eye. If you want the height from top to bottom of your viewing plane, you need to add both sides together. Here is a [good diagram](http://i.stack.imgur.com/sDZ1z.png) that illustrates this. – Andon M. Coleman Nov 16 '13 at 22:48
  • Thanks for the links, peeps. I'll do some digging on Lighthouse and see what else I can come up with. – zeboidlund Nov 17 '13 at 01:07

0 Answers0