Using GLM with Direct3D11

Started by
4 comments, last by 21st Century Moose 10 years, 4 months ago

I'm trying to use GLM with Direct3D11 to write a cross platform wrapper for graphics APIs. I ran into a problem though, because when I use the XNA math functions to create a view matrix and a projection matrix, it works fine and everything renders properly. However, when I use the GLM perspective and lookat methods using the same parameters I can't see anything on my screen at all.

For example: this call works


XMMatrixPerspectiveFovLH( XM_PIDIV2, 1024.0f/768.0f, 0.01f, 100.0f );

But this call doesn't


glm::perspective(core::MathUtils::pi/2, 1024.0f/768.0f, 0.01f, 100.0f);

This call works:


XMVECTOR Eye = XMVectorSet( 0.0f, 1.0f, -5.0f, 0.0f );
XMVECTOR At = XMVectorSet( 0.0f, 1.0f, 0.0f, 0.0f );
XMVECTOR Up = XMVectorSet( 0.0f, 1.0f, 0.0f, 0.0f );
cb.m_view = XMMatrixTranspose(XMMatrixLookAtLH( Eye, At, Up ));

But this one doesn't


glm::vec3 eye(0.0f, 1.0f, 5.0f);
glm::vec3 at(0.0f, 1.0f, 0.0f);
glm::vec3 up(0.0f, 1.0f, 0.0f);
m_driver->setViewMatrix(glm::lookAt(eye, at, up));

I've already checked to see if I was just setting the matrices wrong when I pass them to the shader, but my world matrix gets passed along just fine.

Advertisement

I think it would be easier to find the problem if you showed us the resulting matrices.

The view matrix generated by GLM is:

[1.0, 0.0, 0.0, 0.0]

[0.0, 1.0, 0.0, 0.0]

[0.0, 0.0, 1.0, 0.0]

[0.0, -1.0, -5.0, 1.0]

The view matrix generated by XNA math is:

[1.0, 0.0, 0.0, 0.0]

[0.0, 1.0, 0.0, -1.0]

[0.0, 0.0, 1.0, 5.0]

[0.0, 0.0, 0.0, 1.0]

The GLM projection matrix is:

[54.71001, 0.0, 0.0, 0.0]

[0.0, 72.946686, 0.0, 0.0]

[0.0, 0.0, -1.0002, -1.0]

[0.0, 0.0, -0.020002, 0.0]

And the XNA math projection matrix is:

[0.75, 0.0, 0.0, 0.0]

[0.0, 1.0, 0.0, 0.0]

[0.0, 0.0, 1.0001, -0.010001]

[0.0, 0.0, 1.0, 0.0]

I transpose the matrices before I set them, but I also tried without transposing and it still wouldn't work. I have no idea why it isn't working. All the parameters are correct and work perfectly fine with XNA math.

Dunno if it's your only issue, but you should define GLM_FORCE_RADIANS or pass values in degrees to GLM.

GLM is making a projection matrix that targets OpenGL's normalized device coordinates, which are not the same as DirectX's. In OpenGL the near plane maps to -1 and the far plane to 1, whereas in DirectX the near plane maps to 0 and the far plane to 1. Also, as Mona2000 pointed out, GLM is expecting the FOV to be in degrees, not radians (at least from the looks of the matrix values you posted). The radians are easy to fix, but the problem with the normalized device coordinates isn't. You might have to write your own perspective matrix function.

Also, glm will be using a right-handed co-ordinate system whereas you're using the left-handed variants of the XNA functions. I'd actually advise that converting your D3D code to right-handed (i.e. using XMMatrixPerspectiveFovRH instead of XMMatrixPerspectiveFovLH) would be a better first step here.

To be honest, I'm having a difficult time seeing why you're even needing to use two different matrix libraries. They're just software libraries and really have nothing to do with the 3D API you're using; the best approach is to pick one matrix library and use it for both OpenGL and D3D. XNA math will work with OpenGL and glm will work with D3D as in the modern versions of both APIs the old "GL is RH/CM, D3D is LH/RM" guidance is just nonsense - both APIs support both variations of both handedness and majorness.

Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls.

This topic is closed to new replies.

Advertisement