Forum

GLQuake "HOM" near water surfaces

Discuss programming topics for the various GPL'd game engine sources.

Moderator: InsideQC Admins

GLQuake "HOM" near water surfaces

Postby Baker » Wed Jun 30, 2010 3:51 pm

This is just the cliff notes version.

I'm certain this was a tutorial at QuakeSrc.org or even somewhere older. But I can't find it.

This isn't a tutorial, but rather the rough skeleton of what needs to be done.

I noticed in PSP Quake including the Kurok engine, you can see entities you shouldn't see underwater when near the water line.

The basics of the fix are highlighted in yellow ... for gl_rsurf.c which corresponds to video_hardware_surfaces.cpp for the PSP. I haven't tried this yet on the PSP, there could be some oddball reason this won't work but I doubt it.

/*
===============
R_MarkLeaves
===============
*/
void R_MarkLeaves (void)
{
byte *vis;
mnode_t *node;
msurface_t **mark;
int i;
byte solid[MAX_MAP_LEAFS / 2];
qboolean nearwaterportal = false;

// Check if near water to avoid HOMs when crossing the surface
for (i=0, mark = r_viewleaf->firstmarksurface; i < r_viewleaf->nummarksurfaces; i++, mark++)
{
if ((*mark)->flags & SURF_DRAWTURB)
{
nearwaterportal = TRUE;
// Con_SafePrintf ("R_MarkLeaves: nearwaterportal, surfs=%d\n", r_viewleaf->nummarksurfaces);
break;
}
}

if (r_oldviewleaf == r_viewleaf && !r_novis.value && !nearwaterportal)

return;

if (mirror)
return;

r_visframecount++;
r_oldviewleaf = r_viewleaf;

if (r_novis.value)
{
vis = solid;
memset (solid, 0xff, (cl.worldmodel->numleafs+7)>>3);
}
else if (nearwaterportal)
vis = SV_FatPVS (r_origin, cl.worldmodel);

else
vis = Mod_LeafPVS (r_viewleaf, cl.worldmodel);

for (i=0 ; i<cl.worldmodel->numleafs ; i++)
{
if (vis[i>>3] & (1<<(i&7)))
{
node = (mnode_t *)&cl.worldmodel->leafs[i+1];
do
{
if (node->visframe == r_visframecount)
break;
node->visframe = r_visframecount;
node = node->parent;
} while (node);
}
}
}


And SV_FatPVS gets modified to pass the worldmodel (cl.worldmodel for the client or sv.worldmodel for the server) and likewise SV_AddToFatPVS and naturally SV_WriteEntitiesToClient.

Since I haven't been able to dig up this information or tutorial via Google, I reversed it out Enhanced GLQuake 1.30 versus Enhanced GLQuake 1.32.

(Plus, and I know this sounds strange to some ... I don't have this in my engine yet either because I don't want any rendering changes that aren't a cvar. Even undesirable stuff as a general rule of thumb. And if I don't understand it, I can't cvar it. Somehow I kind of like the crappy GLQuake "issues" and want to have the option to have the authentic looking 1997 GLQuake experience.)
The night is young. How else can I annoy the world before sunsrise? 8) Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
User avatar
Baker
 
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Postby Spike » Wed Jun 30, 2010 4:18 pm

This is an issue with the near clip plane.
3dfx had a few hacks in its driver. There is no near clip plane, so whatever is drawn can come right up to the very front of the camera, hence how it works just fine on a banshe.
Every other card does have a near clip plane, and its set to 4 units away by default.
Thus if the view is within 4 units of the water surface, the surfaces on the other side of the water should be drawn too.
The bug is that the PVS used is from a single leaf, and does not include the one on the other side of the surface.
FatPVS will do a bit more work and then merge the pvs of all the nearby leafs, instead of taking a single one only.
Which is how your fix works.

Your check is not quite correct, as the viewleaf might be angled such that its close to the surface but contains no actual water surfaces. I could probably make a map to cause this, but it wouldn't be easy.
Also, you recalculate the pvs and mark all leafs+nodes every single frame while your view is inside a leaf with water surfaces. Which is not fast, but does get rid of the glitch.

Quake2 tracks two viewleafs instead of just one. One for above and one for below, and merges only those two, which catches all sane configurations of water, but can still potentially fail on vertical water surfaces (read: teleporters).
Spike
 
Posts: 2892
Joined: Fri Nov 05, 2004 3:12 am
Location: UK

Postby Baker » Wed Jun 30, 2010 4:43 pm

I hadn't taken a look at the methods other engines use yet.

It looks like Enhanced GLQuake and FitzQuake use the above method while FTEQW,Fuh/EZ/Joe/Qrack use the "r_viewleaf2 / r_oldviewleaf2" method [and with DP's code being rather unintelligible to mere mortals like myself].

Yeah, I don't want a performance hit if there is a better way, obviously.

I don't see this type of fix in TomazQuake or QIP Quake or GLQuake113 ... kind of weird considering I would have thought this fix or information would have been readily spread in the heavy Q1 engine modding days. :?:
The night is young. How else can I annoy the world before sunsrise? 8) Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
User avatar
Baker
 
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Postby Baker » Wed Jun 30, 2010 5:15 pm

Note: at least on e1m2 I've compared and contrasted the frames per second and the CPU usage and I'm not seeing even a measurable difference in terms of either (non-fixed versus the FitzQuake/aguirRe fix).
The night is young. How else can I annoy the world before sunsrise? 8) Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
User avatar
Baker
 
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Postby revelator » Wed Jun 30, 2010 10:10 pm

i think it originally came from aguires engine not sure though but that's where i got it from.

tbh im not sure i noticed any difference with this piece of code, normally i used the hom check from joequake.
User avatar
revelator
 
Posts: 2567
Joined: Thu Jan 24, 2008 12:04 pm
Location: inside tha debugger


Return to Engine Programming

Who is online

Users browsing this forum: No registered users and 1 guest