Here's another option.
Code: Select all
void GL_SetPerspective (float fovx, float fovy)
{
#define NEARCLIP 4
float r_projection_matrix[16];
float left, right, bottom, top;
float nudge = 1.0 - 1.0 / (1 << 23);
right = NEARCLIP * tan (fovx * M_PI / 360.0);
left = -right;
top = NEARCLIP * tan (fovy * M_PI / 360.0);
bottom = -top;
r_projection_matrix[0] = (2 * NEARCLIP) / (right - left);
r_projection_matrix[4] = 0;
r_projection_matrix[8] = (right + left) / (right - left);
r_projection_matrix[12] = 0;
r_projection_matrix[1] = 0;
r_projection_matrix[5] = (2 * NEARCLIP) / (top - bottom);
r_projection_matrix[9] = (top + bottom) / (top - bottom);
r_projection_matrix[13] = 0;
r_projection_matrix[2] = 0;
r_projection_matrix[6] = 0;
r_projection_matrix[10] = -1 * nudge;
r_projection_matrix[14] = -2 * NEARCLIP * nudge;
r_projection_matrix[3] = 0;
r_projection_matrix[7] = 0;
r_projection_matrix[11] = -1;
r_projection_matrix[15] = 0;
if (r_waterwarp.value)
{
int contents = Mod_PointInLeaf (r_origin, cl.worldmodel)->contents;
if ((contents == CONTENTS_WATER || contents == CONTENTS_SLIME || contents == CONTENTS_LAVA || cl.inwater) && v_blend[3])
{
r_projection_matrix[4] = sin (cl.time) * 0.075f;
r_projection_matrix[1] = cos (cl.time) * 0.075f;
}
}
glLoadMatrixf (r_projection_matrix);
}
As a bonus it works with RMQ water brushes and also gives an infinite projection matrix.
Just replace your call to MYgluPerspective, glFrustum or whatever you use with this, and pass it the values of r_refdef.fov_x and r_refdef.fov_y.