0

my question is why I got three different matrices, and what is the difference, which is the correct one for converting coordinates from clip to eye space.

Details:

I am trying to get projection matrix of OpenGL to implement a virtual scanner, I use this matrix to convert coordinates from clip to eye space. I found three ways to get it:

  1. glGetFloatv (GL_PROJECTION_MATRIX, projection_tmp);

  2. glm::mat4 Proj = glm::perspective( fov, aspect, zNear, zFar);

  3. compute it manually through the method given by this page: gluperspective source code

Parameters passed to these three method follows:

const double zNear = 1;
const double zFar = 10001;//for computational convenience
const double fov = _model.getCamera().getFieldOfViewAngle();//60
//w(523)h(489) 
const double aspect = static_cast<double>(w) / static_cast<double>(h);

Then I get three different matrices:

glGetFloatv:

1.61945       0       0       0
      0 1.73205       0       0
      0       0 -1.0002      -1
      0       0 -2.0002       0

GLM:

-0.145971         0         0         0
        0  -0.15612         0         0
        0         0   -1.0002        -1
        0         0   -2.0002         0

Manual:

0.504724        0        0        0
       0  0.57735        0        0
       0        0  -1.0002        1
       0        0  -2.0002        0

Thanks!

Community
  • 1
  • 1
YanmingJIA
  • 13
  • 2
  • `glGetFloatv` returns the current projection matrix. But how did you set it up? – Yakov Galka May 19 '17 at 09:05
  • @ybungalobill I have render a model by opengl , the matrix seems be set by gluperspective I called in rendering process with qt opengl. I googled it, and many people said it is deprecated scene OpenGL3.0, so why it is worked in my 4.4 version environment? I am new to OpenGL, this really confuse me>_ – YanmingJIA May 19 '17 at 11:15

1 Answers1

2

The glGetFloatv version is the only correct one among the three.

The GLM version expects the angle to be in radians, so you should correct the fovy by a factor of tau/360.

The third version is not exactly the one from the linked answer. The code in the linked answer writes negative one to m[11] whereas you posted a positive one. Let's assume that it's a typo and look at the other numbers. Here that code is simply wrong: it multiplies by tan(fov/2) instead of dividing by it. This is why it gets 0.57735 = 1/1.73205.

I don't know why people have trouble implementing it. Just take the formula from the gluPerspective specification and write it in code:

void gluPerspectivInRadians(double m[16],
    double fovy, double aspect, double zNear, double zFar)
{
    double f = 1/tan(fovy/2);
    m[0] = f/aspect; m[1] = 0; m[2] = 0; m[3] = 0;
    m[4] = 0; m[5] = f; m[6] = 0; m[7] = 0;
    m[8] = 0; m[9] = 0; m[10] = (zFar+zNear)/(zNear-zFar); m[11] = -1;
    m[12] = 0; m[13] = 0; m[14] = 2*zFar*zNear/(zNear-zFar); m[15] = 0;
}
Yakov Galka
  • 70,775
  • 16
  • 139
  • 220
  • Really appreciate your answer! I have got these three matrices identical. Another question : Which matrix or matrix manipulation is deprecated ? [link](http://stackoverflow.com/questions/4202456/how-do-you-get-the-modelview-and-projection-matrices-in-opengl) .Could you please take some time explain the first answer of this page? – YanmingJIA May 19 '17 at 11:45
  • @YanmingJIA: it four words: don't use legacy OpenGL. – Yakov Galka May 19 '17 at 14:52