Sometimes you need to decompose the OpenGL projection matrix into its original components to adjust some values. Here's how to do that. I found a thread on stackoverflow on the subject. The formulas there are in row-major format though, but OpenGL is column-major, so they need to be swapped around:

For a perspective matrix:

For an orthographic matrix:

When you now use a standard C-Array for storage, the indices become:

For the perspective matrix:

For the orthographic matrix:

To calculate a matrix again from those values, use an identity matrix and set:

For a perspective matrix:

For an orthographic matrix:

If you want even more options, read this.

For a perspective matrix:

near = m43 / (m33 - 1);

far = m43 / (m33 + 1);

bottom = near * (m32 - 1) / m22;

top = near * (m32 + 1) / m22;

left = near * (m31 - 1) / m11;

right = near * (m31 + 1) / m11;

For an orthographic matrix:

near = (1 + m43) / m33;

far = -(1 - m43) / m33;

bottom = (1 - m42) / m22;

top = -(1 + m42) / m22;

left = -(1 + m41) / m11;

right = (1 - m41) / m11;

When you now use a standard C-Array for storage, the indices become:

For the perspective matrix:

GLfloat projection[16];

GLfloat near = projection[14] / (projection[10] - 1.0f);

GLfloat far = projection[14] / (projection[10] + 1.0f);

GLfloat bottom = nearPlane * (projection[9] - 1.0f) / projection[5];

GLfloat top = nearPlane * (projection[9] + 1.0f) / projection[5];

GLfloat left = nearPlane * (projection[8] - 1.0f) / projection[0];

GLfloat right = nearPlane * (projection[8] + 1.0f) / projection[0];

For the orthographic matrix:

GLfloat projection[16];

GLfloat near = (1.0f + projection[14]) / projection[10];

GLfloat far = -(1.0f - projection[14]) / projection[10];

GLfloat bottom = (1.0f - projection[13]) / projection[5];

GLfloat top = -(1.0f + projection[13]) / projection[5];

GLfloat left = -(1.0f + projection[12]) / projection[0];

GLfloat right = (1.0f - projection[12]) / projection[0];

To calculate a matrix again from those values, use an identity matrix and set:

For a perspective matrix:

matrixProjection[0] = 2.0f * near / (right - left);

matrixProjection[5] = 2.0f * near / (top - bottom);

matrixProjection[8] = (right + left) / (right - left);

matrixProjection[9] = (top + bottom) / (top - bottom);

matrixProjection[10] = -(far + near) / (far - near);

matrixProjection[11] = -1.0f;

matrixProjection[13] = -(2.0f * far * near) / (far - near);

matrixProjection[15] = 0.0f;

For an orthographic matrix:

matrixProjection[0] = 2.0f / (right - left);

matrixProjection[5] = 2.0f / (top - bottom);

matrixProjection[10] = -2.0f / (far - near);

matrixProjection[12] = -(right + left) / (right - left);

matrixProjection[13] = -(top + bottom) / (top - bottom);

matrixProjection[14] = -(far + near) / (far - near);

If you want even more options, read this.

## Comments

## Post a Comment