What's different with my lookAt and perspectiv

2019-09-18 19:05发布

问题:

Side note: hey everyone, if you found my question/answer helpful, please don't forget to up vote. I kind of need it...

So there seems to be something different with my implementation of both matrix [projection and model] (other than the stuff I've commented out for debugging purposes). Below is a screenshot of the bug I see when drawing a cube. Keep in mind I do keep the viewport and matrix up to date with the window size and calculate screen ratio with float and not int, so don't bother asking, I've checked the usual suspects.....

Screen Shot

Files (linux build, see readme in ./build)
side note: while debugging, I've changed the cube's distance. To reproduce the screen shot, on line 76 of workspace.cpp set mDistance to about 90 and stretch the window frame to dimensions noted at lower right corner of the window.

Please keep in mind the screen shot and the debug text output are seperate events as I'm constantly debugging this problem and getting new numbers.

The code:

#define _AP_MAA 0
#define _AP_MAB 1
#define _AP_MAC 2
#define _AP_MAD 3
#define _AP_MBA 4
#define _AP_MBB 5
#define _AP_MBC 6
#define _AP_MBD 7
#define _AP_MCA 8
#define _AP_MCB 9
#define _AP_MCC 10
#define _AP_MCD 11
#define _AP_MDA 12
#define _AP_MDB 13
#define _AP_MDC 14
#define _AP_MDD 15

Setting up the camera perspective:

void APCamera::setPerspective(GMFloat_t fov, GMFloat_t aspect, GMFloat_t near, GMFloat_t far)
{
   GMFloat_t difZ = near - far;

   GMFloat_t *data;

   mProjection->clear(); //set to identity matrix
   data = mProjection->getData();

   GMFloat_t v = 1.0f / tan(fov / 2.0f);

   data[_AP_MAA] = v / aspect;
   data[_AP_MBB] = v;
   data[_AP_MCC] = (far + near) / (difZ);
   data[_AP_MCD] = -1.0f;
   data[_AP_MDD] = 0.0f;
   data[_AP_MDC] = (2.0f * far * near)/ (difZ);

   mRatio = aspect;

   mInvProjOutdated = true;
   mIsPerspective = true;
}

Setting up the camera direction:

bool APCamera::lookTo(Coordinate &to, Coordinate &from, Coordinate &up)  
 {
      Coordinate f, unitUp, right;  
      GMFloat_t *data;

      CoordinateOp::diff(&to, &from, &f);
      VectorOp::toUnit(&f, &f);
      VectorOp::toUnit(&up, &unitUp);
      VectorOp::cross(&f, &unitUp, &right);

      if((fabs(right.x) < FLOAT_THRESHOLD) && (fabs(right.y) < FLOAT_THRESHOLD) && (fabs(right.z) < FLOAT_THRESHOLD))
     {
         return false;
     }

     mCamPt = from;

     VectorOp::toUnit(&right, &mRight);
     mForward = f;
     VectorOp::cross(&mRight, &mForward, &mUp);

     mModelView->clear();
     data = mModelView->getData();

     data[_AP_MAA] = mRight.x;
     data[_AP_MBA] = mRight.y;
     data[_AP_MCA] = mRight.z;

     data[_AP_MAB] = mUp.x;
     data[_AP_MBB] = mUp.y;
     data[_AP_MCB] = mUp.z;

     data[_AP_MAC] = -mForward.x;
     data[_AP_MBC] = -mForward.y;
     data[_AP_MCC] = -mForward.z;

     //translation part is commented out to narrow bugs down, "camera" is kept at the center (0,0,0)
     //data[_AP_MDA] = (data[_AP_MAA] * -mCamPt.x) + (data[_AP_MBA] * -mCamPt.y) + (data[_AP_MCA] * -mCamPt.z);
     //data[_AP_MDB] = (data[_AP_MAB] * -mCamPt.x) + (data[_AP_MBB] * -mCamPt.y) + (data[_AP_MCB] * -mCamPt.z);
     //data[_AP_MDC] = (data[_AP_MAC] * -mCamPt.x) + (data[_AP_MBC] * -mCamPt.y) + (data[_AP_MCC] * -mCamPt.z);

  mInvViewOutdated = true;
  return true;
}  

The debug output:

LookTo() From:<0,0,0> To:<-1,0,0>:
0.000000 0.000000 -1.000000 0.000000
0.000000 1.000000 0.000000 0.000000
1.000000 -0.000000 -0.000000 0.000000
0.000000 0.000000 0.000000 1.000000

setPerspective() fov:0.785398 ratio:1.185185 near:0.500000 far:100.000000:
2.036993 0.000000 0.000000 0.000000
0.000000 2.414213 0.000000 0.000000
0.000000 0.000000 -1.010050 -1.005025
0.000000 0.000000 -1.000000 0.000000

回答1:

In the end, it looks like the trouble maker was just the FOV. So the quick answer is NO I didn't do anything different from the documented perspective and look at function. For anyone having a similar problem 2.0f * atan(tan(DEFAULT_FOV_RAD/mRatio) * mRatio) did the job for me.



标签: c++ opengl qt4