GLQuake Underwater Warp

Post tutorials on how to do certain tasks within game or engine code here.
Post Reply
mh
Posts: 2292
Joined: Sat Jan 12, 2008 1:38 am

GLQuake Underwater Warp

Post 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.
We had the power, we had the space, we had a sense of time and place
We knew the words, we knew the score, we knew what we were fighting for
qbism
Posts: 1236
Joined: Thu Nov 04, 2004 5:51 am
Contact:

Post by qbism »

glFisheyeQuake? 270fov, bulge center of matrix
Spike
Posts: 2914
Joined: Fri Nov 05, 2004 3:12 am
Location: UK
Contact:

Post 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.
frag.machine
Posts: 2126
Joined: Sat Nov 25, 2006 1:49 pm

Post 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 ?
I know FrikaC made a cgi-bin version of the quakec interpreter once and wrote part of his website in QuakeC :) (LordHavoc)
Spirit
Posts: 1065
Joined: Sat Nov 20, 2004 9:00 pm
Contact:

Post by Spirit »

Aww, no images (or better yet, a video). :)
Improve Quaddicted, send me a pull request: https://github.com/SpiritQuaddicted/Quaddicted-reviews
mh
Posts: 2292
Joined: Sat Jan 12, 2008 1:38 am

Post 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.
We had the power, we had the space, we had a sense of time and place
We knew the words, we knew the score, we knew what we were fighting for
frag.machine
Posts: 2126
Joined: Sat Nov 25, 2006 1:49 pm

Post 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... :)
I know FrikaC made a cgi-bin version of the quakec interpreter once and wrote part of his website in QuakeC :) (LordHavoc)
mh
Posts: 2292
Joined: Sat Jan 12, 2008 1:38 am

Post by mh »

Here we go:

Image
We had the power, we had the space, we had a sense of time and place
We knew the words, we knew the score, we knew what we were fighting for
revelator
Posts: 2621
Joined: Thu Jan 24, 2008 12:04 pm
Location: inside tha debugger

Post 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.
revelator
Posts: 2621
Joined: Thu Jan 24, 2008 12:04 pm
Location: inside tha debugger

Post 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.
Post Reply