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:
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.