Page 1 of 1

GLQuake Underwater Warp

Posted: Mon Oct 04, 2010 10:53 pm
by mh
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.

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);
}
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.

Posted: Tue Oct 05, 2010 3:33 am
by qbism
glFisheyeQuake? 270fov, bulge center of matrix

Posted: Tue Oct 05, 2010 11:57 am
by Spike
You can't do fisheye with just the projection matrix. Not properly anyway. The projection matrix affects only the locations of verticies, it does not affect the triangles between them.
FTE attempts fisheye using cubemaps and a fragment program. There's no other (practical/easy) way to bend straight lines.

Posted: Tue Oct 05, 2010 12:19 pm
by frag.machine
You know, I am not so good at the point of visualize the effect by just reading the code. The Force is not so strong with me :D Could you please post a couple screenshots, MH ?

Posted: Tue Oct 05, 2010 12:51 pm
by Spirit
Aww, no images (or better yet, a video). :)

Posted: Tue Oct 05, 2010 2:06 pm
by mh
Screenshots might be no good as it's one of those effects that you need to see moving. I'll put something up later on today and we'll how it is.

Posted: Tue Oct 05, 2010 2:38 pm
by frag.machine
No rush, I am just curious.

Thinking about that I guess a murky, brown fog effect (maybe adding small translucent particles floating around in brownian movement) has more to do with Quake's intended atmosphere than water warping. But hey, I am just thinking loud, so please ignore it... :)

Posted: Tue Oct 05, 2010 4:45 pm
by mh
Here we go:

Image

Posted: Tue Oct 05, 2010 6:16 pm
by revelator
seems to work fine :) tried it on my realm engine.

allthough not sure if its intended that the view warps when not below waterlevel but just going through it warps the view ? maybe i need better surface level checking.

also im a bit lost what to do with the aspect calculation so i left it out but seems to work fine without.

Posted: Sun Nov 28, 2010 6:12 pm
by revelator
one question.

if i need to resize the viewport how can it be done with this code ?

edit: doh fov = field of view :lol: scrap my question.

and i fixed it warping when near a water surf in realm ;)

the content check for the warp code was modified a bit by me to fit the leaf checking in realm but i was checking both above and below waterlevel argh. is fixed now.

in fact everything works fine now.

besides finishing the menu code (got some strange bugger with the dynamic changing of video variables) it locks up so i cant revert it if say i changed to windowed mode then it stays in windowed mode because the variable cannot be modified but for the life of me i cannot find the culprit.