Tutorial: Killing z-fighting in a stock Quake engine

Post tutorials on how to do certain tasks within game or engine code here.
r00k
Posts: 1111
Joined: Sat Nov 13, 2004 10:39 pm

Re: Tutorial: Killing z-fighting in a stock Quake engine

Post by r00k »

make a command of it and stack parms for known map, building an array of maps maybe 16384...

in a simple autoexec.cfg you could have this

disable_polygon_offset dm2
enable_polygon_offset e1m1 endif e3m2
or no parm for all on or all off
mankrip
Posts: 924
Joined: Fri Jul 04, 2008 3:02 am

Re: Tutorial: Killing z-fighting in a stock Quake engine

Post by mankrip »

Or just use external .ent files.
Ph'nglui mglw'nafh mankrip Hell's end wgah'nagl fhtagn.
==-=-=-=-=-=-=-=-=-=-==
Dev blog / Twitter / YouTube
frag.machine
Posts: 2126
Joined: Sat Nov 25, 2006 1:49 pm

Re: Tutorial: Killing z-fighting in a stock Quake engine

Post by frag.machine »

mankrip wrote:Or just use external .ent files.
Aaaaand we have a winner! :)

You're right, and this is one of the rare cases where the simplest solution is also the best.
I know FrikaC made a cgi-bin version of the quakec interpreter once and wrote part of his website in QuakeC :) (LordHavoc)
Baker
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Re: Tutorial: Killing z-fighting in a stock Quake engine

Post by Baker »

Most people don't like engines that require external files to function in the manner of presentation intended. I am in that group too. :)

And in the case of z-fighting, if I exclude a zfighting fix then I'll have 2 problems without an in-engine solution:

1. The burden of explaining why the existing zfighting fixes don't work --- which still won't stop criticism.
2. Some including myself will be perpetually irked by the look of the E1M1 quad area.

Sometimes a tasteful well prepared hack is the best solution, it does wonders for the shotgun shell boxes in FitzQuake, JoeQuake/Qrack, ezQuake, Enhanced GLQuake, etc. :mrgreen:

But to each their own. 8)
(Months back Sock made me aware that the zfighting fix in a previous version of Mark V was showing secret doors in his maps, and I see minor artifacts on secret doors in Quakespasm due to its zfighting 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 ..
LordHavoc
Posts: 322
Joined: Fri Nov 05, 2004 3:12 am
Location: western Oregon, USA
Contact:

Re: Tutorial: Killing z-fighting in a stock Quake engine

Post by LordHavoc »

Software Quake recurses the brush model polygons down the world bsp tree and deletes the parts that end up in solid, this is why level designers encounter limits on how many brush model polys they can have on screen at once in software Quake, it can only handle so many.

In other words - it fixes the zfighting by bruteforce polygon clipping, otherwise it would have suffered the same fate.
frag.machine
Posts: 2126
Joined: Sat Nov 25, 2006 1:49 pm

Re: Tutorial: Killing z-fighting in a stock Quake engine

Post by frag.machine »

LordHavoc wrote:Software Quake recurses the brush model polygons down the world bsp tree and deletes the parts that end up in solid, this is why level designers encounter limits on how many brush model polys they can have on screen at once in software Quake, it can only handle so many.

In other words - it fixes the zfighting by bruteforce polygon clipping, otherwise it would have suffered the same fate.
And probably that's why most of the z-fighting problems in stock maps went unnoticed.
I know FrikaC made a cgi-bin version of the quakec interpreter once and wrote part of his website in QuakeC :) (LordHavoc)
frag.machine
Posts: 2126
Joined: Sat Nov 25, 2006 1:49 pm

Re: Tutorial: Killing z-fighting in a stock Quake engine

Post by frag.machine »

Baker wrote:Most people don't like engines that require external files to function in the manner of presentation intended. I am in that group too. :)
Well as you said, to each their own. Maybe would be interesting to hack an external tool to fix the maps based in the .ent files ?
The only other correct way I see to fix it engine side is to detect the cases during map loading (check model planes against world planes) and, maybe based in the moving angles/directions, apply a small offset (1 or 2 qu).
But even then you won't never fix all cases, and there always be people complaining.
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:

Re: Tutorial: Killing z-fighting in a stock Quake engine

Post by Spirit »

LordHavoc wrote:Software Quake recurses the brush model polygons down the world bsp tree and deletes the parts that end up in solid, this is why level designers encounter limits on how many brush model polys they can have on screen at once in software Quake, it can only handle so many.

In other words - it fixes the zfighting by bruteforce polygon clipping, otherwise it would have suffered the same fate.
(Why) can't this be done on GL?
Improve Quaddicted, send me a pull request: https://github.com/SpiritQuaddicted/Quaddicted-reviews
Spike
Posts: 2914
Joined: Fri Nov 05, 2004 3:12 am
Location: UK
Contact:

Re: Tutorial: Killing z-fighting in a stock Quake engine

Post by Spike »

it 'cant be done' because noone is crazy enough to actually attempt it.
Baker
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Re: Tutorial: Killing z-fighting in a stock Quake engine

Post by Baker »

frag.machine wrote:But even then you won't never fix all cases, and there always be people complaining.
It's true. Such an adaptation is an attempt to rig the litmus test by solving the primary and most noticeable test case --- a place that the z-fighting is so bad it personally aggravates me quite a bit too. :D

But yes, there will always be people complaining. Which is a definitely a positive, because the reverse of this is no one complaining. I'll leave it to others to figure out the implications of that scenario.
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 ..
Spirit
Posts: 1065
Joined: Sat Nov 20, 2004 9:00 pm
Contact:

Re: Tutorial: Killing z-fighting in a stock Quake engine

Post by Spirit »

Spike wrote:it 'cant be done' because noone is crazy enough to actually attempt it.
Soooooooo, are you done with it yet? :) :wink:
Improve Quaddicted, send me a pull request: https://github.com/SpiritQuaddicted/Quaddicted-reviews
Spike
Posts: 2914
Joined: Fri Nov 05, 2004 3:12 am
Location: UK
Contact:

Re: Tutorial: Killing z-fighting in a stock Quake engine

Post by Spike »

the rendition verité port did something like that, reusing most of the software renderer instead of being a complete renderer rewrite like glquake.
Baker
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Re: Tutorial: Killing z-fighting in a stock Quake engine

Post by Baker »

A fairly clean implementation that keeps itself open to future expansion. Not that I'm interested in future expansion --- I'm not actually interested in "fixing up" maps at all.

However, good design requires a bit of forward thinking and frag machine suggested a bit if flexibility.

Anyway, it does what I want --- it kills the z-fighting in E1M1 quad area in a way with no other side effects, unlike the various "stop zfighting" methods which typically act up and show secret doors or render wrong on a different video card.

Code: Select all

/*
================
SV_SpawnServer

This is called at the start of each level
================
*/
typedef struct 
{ 
	const char *modelname;			// "maps/e1m1.bsp"
	const char *checkstring;		// This string must be found in the entities (i.e. the problem to address)
	const char *patch_before_this;	// Insert before this text
	const char *patch;				// The "FIX"
} map_patches_t;

map_patches_t map_patches[] = 
{
	{	"maps/e1m1.bsp",	
		"{\n\"classname\" \"func_door\"\n\"targetname\" \"t4\"\n\"angle\" \"-2\"\n\"spawnflags\" \"1\"\n\"sounds\" \"2\"\n\"model\" \"*15\"\n}", 
		"\"model\" \"*15\"",	
		"\"lip\" \"-4\"\n\"origin\" \"0 0 -2\"\n"
	},
	{ NULL }, // Terminator
};

static char* MapPatch (const char* modelname, char* entstring)
{
	char *insertion_point, *newbuf, temp;
	int entstrlen, patchstrlen, newbufsize;
	map_patches_t* map_patch;

	Con_Printf ("Map patch check\n");
	for (map_patch = &map_patches[0]; map_patch->modelname; map_patch++)
	{
		if (Q_strcasecmp (map_patch->modelname, modelname) != 0)
			continue; // Model name doesn't match

		if (strstr (entstring, map_patch->checkstring) == NULL)
			continue;

		insertion_point = strstr (entstring, map_patch->patch_before_this);

		if (insertion_point == NULL)
			continue;

		entstrlen = strlen (entstring);
		patchstrlen = strlen (map_patch->patch); 
		newbufsize = entstrlen + patchstrlen + 2; // +1 for null term
		newbuf = malloc ( newbufsize);
		temp = insertion_point[0], insertion_point[0] = 0;
		q_strlcpy (newbuf, entstring, newbufsize);
		q_strlcat (newbuf, map_patch->patch, newbufsize);
		insertion_point[0] = temp;
		q_strlcat (newbuf, insertion_point, newbufsize);
		return newbuf;
	}

	return NULL;
}
And the application of it in SV_SpawnServer

Code: Select all

// Earliest point we can read the entity string, since we need the model loaded.
// Read entity_string from memory
	{
		int mark = Hunk_LowMark ();
		char* patched;

		if (sv_external_ents.value && 
			(entity_string = (char *)COM_LoadHunkFile_Limited (va ("maps/%s.ent", sv.name), sv.worldmodel->loadinfo.searchpath ) )      )
			Con_Printf ("External .ent file: Using entfile maps/%s.ent\n", sv.name);
		else entity_string = sv.worldmodel->entities; // Point it to the standard entities string

		patched = MapPatch(sv.modelname, entity_string);
		if (patched)
		{
			Hunk_FreeToLowMark (mark);
			entity_string = Hunk_Strdup (patched, "ent patch string");

			free (patched);
			Con_Printf ("Map entity string patched.\n");
		}
	}
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 ..
LordHavoc
Posts: 322
Joined: Fri Nov 05, 2004 3:12 am
Location: western Oregon, USA
Contact:

Re: Tutorial: Killing z-fighting in a stock Quake engine

Post by LordHavoc »

Call me weird if you like but I tend to consider the map's coordinates for entity placement to be kind of sacred and don't mess with them.

This could have (extremely subtle) gameplay impact.

While on the subject - I still regret the fact that DarkPlaces' improved collision code requires map fixups at load (all automated however, not an intentional edit) in cases of erroneous placement.
Baker
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Re: Tutorial: Killing z-fighting in a stock Quake engine

Post by Baker »

LordHavoc wrote:Call me weird if you like but I tend to consider the map's coordinates for entity placement to be kind of sacred and don't mess with them.
I thought about that too and carefully tested the amount to make sure even stepping off the lift didn't change.

And I viewed the lift from several different angles. Moving it by 4 I could visually notice it wasn't aligned. And I could feel a change walking off the lift. At 2, I could neither visually tell nor feel anything while walking.

So that isn't unusual, I was worried about it too.

Then again, that area if you stand under the viewscreen you shoot, AND JUMP, you hit your head on an invisible brush. :D
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 ..
Post Reply