Forum

Automatic water transparency

Discuss anything not covered by any of the other categories.

Moderator: InsideQC Admins

Automatic water transparency

Postby Baker » Wed Feb 06, 2008 12:18 pm

Ok ... QuakeSrc.org is dead so I can't dig for the answer ...

I'd like to detect whether or not a map is vised for transparent water in the engine and then store that so r_wateralpha is automatically ignored if r_novis 0.

And at the moment archive.org isn't even working so I can't see if it was a standard tutorial.

Is there any engine with a living web site with a simple implementation of this? If I recall, Tomaz Quake had this but I can't find the source code anywhere (that isn't a dead site).
User avatar
Baker
 
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Postby mh » Wed Feb 06, 2008 6:56 pm

A simple way of doing this, when you're building your texturechains for the world is:

1) Keep a global r_renderflags variable, which is initialized to 0 at the start of each frame.
2) In R_RecursiveWorldNode, bitwise-OR it with a flag indicating if a SURF_UNDERWATER surf has been seen.
3) Also bitwise-OR it with another flag indicating if an above-water surf has been seen (if (!(surf-flags & SURF_UNDERWATER))).
4) When it comes to time to draw your water, check the r_renderflags. If both flags are present, you can switch on translucent water, otherwise don't.

I've run through this solution on all of the e1 maps, several other ID1 maps, some hipnotic and some custom maps, and it's been good for all of them. The nice thing is that it's effectively "for free", and doesn't involve any load-time processing.
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
User avatar
mh
 
Posts: 2292
Joined: Sat Jan 12, 2008 1:38 am

Postby Baker » Thu Feb 07, 2008 8:27 pm

Hey MH! I found the code in JoeQuake 0.15 and in Vengeance R2 and it looks like you were the author.

/*
=================
Mod_DetectWaterTrans

detect if a model has been vised for translucent water
=================
*/
qboolean Mod_DetectWaterTrans (model_t *mod)
{
int i, j;
byte *vis;
mleaf_t *leaf;
msurface_t **surf;

// no visdata
if (!mod->visdata)
return true;

for (i = 0 ; i < mod->numleafs ; i++)
{
// leaf 0 is the solid leaf, leafs go to numleafs + 1
leaf = &mod->leafs[i+1];

// not interested in these leafs
if (leaf->contents >= CONTENTS_EMPTY || leaf->contents == CONTENTS_SOLID || leaf->contents == CONTENTS_SKY)
continue;

// check marksurfaces for a water texture
surf = leaf->firstmarksurface;

for (j = 0 ; j < leaf->nummarksurfaces ; j++, surf++)
{
// bad surf/texinfo/texture (some old maps have this from a bad qbsp)
if (!surf || !(*surf) || !(*surf)->texinfo || !(*surf)->texinfo->texture)
continue;

// not interested in teleports
if (!ISTELETEX((*surf)->texinfo->texture->name))
goto LeafOK;
}

// no water/etc textures here
continue;

LeafOK:
// get the decompressed vis
vis = Mod_DecompressVis (leaf->compressed_vis, mod);

// check the other leafs
for (j = 0 ; j < mod->numleafs ; j++)
{
// in the PVS
if (vis[j>>3] & (1 << (j & 7)))
{
mleaf_t *visleaf = &mod->leafs[j + 1];

// the leaf we hit originally was under water/slime/lava, and a
// leaf in it's pvs is above water/slime/lava.
if (visleaf->contents == CONTENTS_EMPTY)
return true;
}
}
}

// found nothing
return false;
}



But I tried it and it didn't seem to work for me. Any ideas? Vengeance R2 has the word "BROKEN" in the notes.
User avatar
Baker
 
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Postby mh » Fri Feb 08, 2008 12:49 am

Yup, that was one of mine.

I don't recommend it, it's far from 100% reliable. The method I described above is much much better.
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
User avatar
mh
 
Posts: 2292
Joined: Sat Jan 12, 2008 1:38 am

Postby Baker » Fri Feb 08, 2008 2:35 am

mh wrote:Yup, that was one of mine.

I don't recommend it, it's far from 100% reliable. The method I described above is much much better.


I'll try the method you described and give it a shot.

I'm a little weak on the .bsp (hence my apprehension), but I think you've described enough that I think I can do it. I would really love to have this feature.

Thank you for your help.
User avatar
Baker
 
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Postby Baker » Fri Feb 08, 2008 8:08 am

It works perfect with the few tests I've done. :D :D
User avatar
Baker
 
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Postby r00k » Fri Feb 08, 2008 4:41 pm

Works like a champ...

Code: Select all
int r_renderflags;
#define RF_UNDERWATER   2
#define RF_ABOVEWATER   4

void R_DrawWaterSurfaces (void)
//...
if ((r_novis.value == 0) && (!((r_renderflags & RF_UNDERWATER) && (r_renderflags & RF_ABOVEWATER))))
     alpha = 1;

void R_RecursiveWorldNode (mnode_t *node, int clipflags)
//...
if (surf->flags & SURF_UNDERWATER)
   r_renderflags |= RF_UNDERWATER;
else
   r_renderflags |= RF_ABOVEWATER;

void R_DrawWorld (void)
//..
r_renderflags = 0;


Can you explain WHY this works? Are all "leaf"s set to SURF_UNDERWATER by default at loadtime, and unset in the model->visdata?
r00k
 
Posts: 1110
Joined: Sat Nov 13, 2004 10:39 pm

Postby mh » Fri Feb 08, 2008 7:03 pm

Take a look in Mod_LoadLeafs. There's a check at the end of it which runs through all leafs, checks the contents member, then sets the SURF_UNDERWATER flag for marksurfaces.
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
User avatar
mh
 
Posts: 2292
Joined: Sat Jan 12, 2008 1:38 am


Return to General Discussion

Who is online

Users browsing this forum: No registered users and 1 guest