Projection DirectX and OpenGL
Posted: Sat Apr 05, 2008 6:10 pm
Hi,
I'm trying to get head tracking to work with Irrlicht (see Johnny Lee's Wii remote head tracking on youtube).
When figuring out the projection matrix I read that OpenGl and DirectX have different conventions:
OpenGL has the viewing direction in negative z direction (right handed) and projects into a left handed canonical view volume with ranges ( [-1,1], [-1,1],[-1,1] )
( see http://www.ugrad.cs.ubc.ca/~cs314/notes/ogl_vvol.html )
while DirectX has the viewing direction in positive z direction (left handed) and project into a left handed canonical view volume with ranges ( [-1,1],[-1,1],[0,1] )
( see http://www.codeguru.com/cpp/misc/misc/m ... c10123__3/ )
Irrlicht seems to use DirectX style projection matrices and accounts for the z-Flip for OpenGL in COpenGLDriver::setTransform:
1. The matrix element glMat[12] being (0,3) is 0 for the normal frustum projection (see links above). So this does not flip anything. Is this really correct?
2. I've tried to generate a customized frustum projection matrix, from both the DirectX and OpenGL convention, but neither works as expected on OpenGl under linux (nvidia driver).
So far I have come up with:
That gives the right x and y values from camera.getViewFrustum() (that uses ??? convention) but the z-Values are not as expected.
What strikes me, is that the OpenGL specification doesn't work at all, not even with a manual z-Flip. Does Irrlicht do anything else strange with the matrix?
3. (For the future)
Suppose I want a customized frustum projection that works both for OpenGl and DirectX, what am I to do? Is it possible for Irrlicht to translate between the two?
thanks in advance,
Andy
I'm trying to get head tracking to work with Irrlicht (see Johnny Lee's Wii remote head tracking on youtube).
When figuring out the projection matrix I read that OpenGl and DirectX have different conventions:
OpenGL has the viewing direction in negative z direction (right handed) and projects into a left handed canonical view volume with ranges ( [-1,1], [-1,1],[-1,1] )
( see http://www.ugrad.cs.ubc.ca/~cs314/notes/ogl_vvol.html )
while DirectX has the viewing direction in positive z direction (left handed) and project into a left handed canonical view volume with ranges ( [-1,1],[-1,1],[0,1] )
( see http://www.codeguru.com/cpp/misc/misc/m ... c10123__3/ )
Irrlicht seems to use DirectX style projection matrices and accounts for the z-Flip for OpenGL in COpenGLDriver::setTransform:
Code: Select all
case ETS_PROJECTION:
createGLMatrix(glmat, mat);
// flip z to compensate OpenGLs right-hand coordinate system
glmat[12] *= -1.0f;
glMatrixMode(GL_PROJECTION);
glLoadMatrixf(glmat);
break;
2. I've tried to generate a customized frustum projection matrix, from both the DirectX and OpenGL convention, but neither works as expected on OpenGl under linux (nvidia driver).
So far I have come up with:
Code: Select all
matrix4 make_projection_matrix( float left, float right,
float bottom, float top,
float nearval, float farval )
{
float x, y, a, b, c, d;
float m[16];
x = (2.0*nearval) / (right-left);
y = (2.0*nearval) / (top-bottom);
a = (right+left) / (right-left);
b = (top+bottom) / (top-bottom);
c = (farval+nearval) / ( farval-nearval);
d = -(2.0*farval*nearval) / (farval-nearval);
matrix4 M;
m[0] = x;
m[1] = 0.0F;
m[2] = 0.0F;
m[3] = 0.0F;
m[4] = 0.0F;
m[5] = y;
m[6] = 0.0F;
m[7] = 0.0F;
m[8] = a;
m[9] = b;
m[10] = c;
m[11] = 1.0F; // originally -1.0F
m[12] = 0.0F;
m[13] = 0.0F;
m[14] = d;
m[15] = 0.0F;
M.setM(m);
return M;
}
What strikes me, is that the OpenGL specification doesn't work at all, not even with a manual z-Flip. Does Irrlicht do anything else strange with the matrix?
3. (For the future)
Suppose I want a customized frustum projection that works both for OpenGl and DirectX, what am I to do? Is it possible for Irrlicht to translate between the two?
thanks in advance,
Andy