GLQuake Underwater Warp
Posted: Mon Oct 04, 2010 10:53 pm
We all know that underwater warp doesn't work properly in GLQuake. Some engines leave it be, some disable it entirely, some stretch and squeeze the FOV, and some use render to texture.
Here's another option.
This one will give you a deformed warping projection matrix instead; it's very lightweight, works on all objects in the scene and looks good. It does need a bit of tweaking for FOV values other than 90, and that 0.075f value can probably be cvar-ized too.
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.
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.
