NQ Colored Dead Bodies

Discuss programming topics for the various GPL'd game engine sources.
mh
Posts: 2292
Joined: Sat Jan 12, 2008 1:38 am

Re: NQ Colored Dead Bodies

Post by mh »

The old way I solved this was to create 256 texture names in an array (no uploads just yet) (yeah, 256 is too many, but it's just names for now so no big deal), take (shirt * 16) + pants as an index into the array for each player, see if a texture had been loaded for that index, if not load it, then return the texture name.

The major downside is that it's not immune to someone spamming colour changes and if they manage to fill all texture slots they can impose a high overhead on your video RAM. It also needs to do the initial texture uploads at runtime which can cause a slight jerk the first time a shirt/pants combo is used. And you probably better glDeleteTextures the lot in R_NewMap too.

Nowadays I just do colormapping in a pixel shader. It's fast, it's immune to colour change spamming, it doesn't need any runtime uploads, it works with mipmaps, and it can in theory be extended to support models other than the player (in practice I don't do that yet). There's small overhead in needing an extra texture to mask off areas of the original, needing palette row textures for the colour transformation, and a few extra texture lookups too (not to mention the increased hardware requirements), but it's a very small overhead and a fair tradeoff.
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
r00k
Posts: 1111
Joined: Sat Nov 13, 2004 10:39 pm

Re: NQ Colored Dead Bodies

Post by r00k »

I'm trying to fix this but i get a random crash with this code:

Code: Select all

i = (bits & U_COLORMAP) ? MSG_ReadByte() : ent->baseline.colormap;

	if (!i)
		ent->colormap = 0;

	if (i && i <= cl.maxclients && ent->model && ent->model->modhint == MOD_PLAYER)
	{
		ent->colormap = (byte *)i;
	}
	else
		ent->colormap = vid.colormap;
am i fubaring that pointer?
It works if i remove the typecasting but then i get a warning in my compile, and we cant have that!! ;)

hmm actuall i think it's here:

Code: Select all

	if (i && (ent->model->modhint == MOD_PLAYER))//R00k: changed 10/1/2012 so 24bit dead bodies are colored too.
	{
		ent->shirtcolor = (cl.scores[i - 1].colors & 0xf0) >> 4;
		ent->pantscolor = (cl.scores[i - 1].colors & 15);
	}
the " i " will be out of range....
Spike
Posts: 2914
Joined: Fri Nov 05, 2004 3:12 am
Location: UK
Contact:

Re: NQ Colored Dead Bodies

Post by Spike »

why is ent->colormap even a pointer? that only makes sense with software rendering.
r00k
Posts: 1111
Joined: Sat Nov 13, 2004 10:39 pm

Re: NQ Colored Dead Bodies

Post by r00k »

i tried changing it to int and then other areas of the code complain. :( dunno nothing really dereferences it but it's all kinda legacy hacky anyways...
Baker
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Re: NQ Colored Dead Bodies

Post by Baker »

R00k, check out this source: http://quake-1.com/docs/utils/fitzquake_mark_v.zip

Searched for "SUPPORTS_COLORED"

Due to MH's notes, I stripped out a ton of WinQuake software renderer overhead.

The method I did in ProQuake 4.90 is a bit different than FitzQuake Mark V. FitzQuake Mark V will colormap everything. ProQuake 4.90 color maps only the 16 player skins (but ignores eyes.mdl and gib1.mdl, etc.) so if you get the ring of shadows, your dead bodies will still be colored.

Changes are pretty much in cl_parse.c and cl_main.c and the gl_model.c (on load looks at name of model). The changes in many ways are more about deleting things, surprisingly.
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 ..
r00k
Posts: 1111
Joined: Sat Nov 13, 2004 10:39 pm

Re: NQ Colored Dead Bodies

Post by r00k »

Ok,
But honestly, that single line "ent->colormap = (byte *)i;" fixed dead bodies for me.
and this obv...

Code: Select all

			if (ent->model->modhint == MOD_PLAYER)
			{
				texture = playertextures - 1 + (int)ent->colormap;//Colored Dead Bodies
			}
The problem i was really having was for the 24bit skins to use colored deadbodies, and in the case of "cl.scores", i was out of range.... :(

It's all working now. I pretty much left ent->colormap = vid.colormap alone as no idea what its for, (besides a texture of the .lmp)... :/
Spike
Posts: 2914
Joined: Fri Nov 05, 2004 3:12 am
Location: UK
Contact:

Re: NQ Colored Dead Bodies

Post by Spike »

the colourmap table in software rendering is a lookup of the palette index against light level (if you've already got a lookup, you can just use a different table for each player). not really needed for gl.
vid.colormap is just the default table, and not useful to gl (other than maybe to see which pixels are fullbright).

Check for sign extension?
r00k
Posts: 1111
Joined: Sat Nov 13, 2004 10:39 pm

Re: NQ Colored Dead Bodies

Post by r00k »

oof, sorrry to dig up an old post but, i was having problems with white bodies and heads that were black with garbled rainbow textures....

ALL IS FIXED AND WORKING NOW! :D

i back tracked and left all the ent->colormap = vid.colormap instead of setting those to 0. I guess vid.colormap actually points to the base texture thats loaded when the model is loaded :/

in cl_parse i have this

Code: Select all

	i = (bits & U_COLORMAP) ? MSG_ReadByte() : ent->baseline.colormap;

	if ((i > 0 && i <= cl.maxclients) && (ent->model) && (ent->model->modhint == MOD_PLAYER))
	{
		ent->shirtcolor = (cl.scores[i - 1].colors & 0xf0) >> 4;
		ent->pantscolor = (cl.scores[i - 1].colors & 15);
		ent->colormap = i;//Index of the player's colormap for "texture = playertextures - 1 + (int)ent->colormap; in gl_rmain.c"
	}
	else
	{	
		ent->colormap = (int)vid.colormap;
	}
and in gl_rmain i have this

Code: Select all

	// we can't dynamically colormap textures, so they are cached
	// seperately for the players. Heads are just uncolored.
	if (ent->colormap != (int)vid.colormap && !gl_nocolors.value && !cl_teamskin.value)
	{
		i = ent - cl_entities;

		if (i > 0 && i <= cl.maxclients)
		{
			texture = playertextures - 1 + i;
			fb_texture = fb_skins[i-1];
		}
		else
		{
			if (gl_color_deadbodies.value)
			if (ent->model->modhint == MOD_PLAYER)
			{
				texture = playertextures - 1 + (int)ent->colormap;//Colored Dead Bodies
			}
		}
	}
I missed this bug as using 24bit skins is a competely diff code and didnt have white bodies :(
Baker
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Re: NQ Colored Dead Bodies

Post by Baker »

r00k wrote:vid.colormap actually points to the base texture thats loaded when the model is loaded :/
All that vid.colormap stuff can be scrapped, that's WinQuake stuff. :D I used MH's notes in ... I think it was the RMQ Engine ... to entirely gut out all the WinQuake relics relating to the colormap.
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 ..
Spike
Posts: 2914
Joined: Fri Nov 05, 2004 3:12 am
Location: UK
Contact:

Re: NQ Colored Dead Bodies

Post by Spike »

either way, casting it to an int is always wrong. :s
but yeah, just store the 1-based player number (or 0, for non-players) in there instead of a pointer to some mystical-but-redundant colourmap.

in nq you can probably get away with instantly expanding the colormap to shirt+pants as soon as you receive the entity, without even storing the colormap anywhere (note that dp's colormap=1024|(shirt<<4)|(pants) thing pretty much does this).
in fact, combined with a network protocol that doesn't spam changes when nothing happened, doing so would solve corpses 'randomly' changing colours.
(of course, not quite an option with QW, where the colormap is needed for player skins also)
r00k
Posts: 1111
Joined: Sat Nov 13, 2004 10:39 pm

Re: NQ Colored Dead Bodies

Post by r00k »

so wojld it be better to use ent->baseline.colormap for non player ents? setting to 0 simply made black head model until the player respawned. or would type casting crash the engine afterwards?
basically colormap for players points to the player slot which is also passed from qc when a coprse is created.
Spike
Posts: 2914
Joined: Fri Nov 05, 2004 3:12 am
Location: UK
Contact:

Re: NQ Colored Dead Bodies

Post by Spike »

the only use for colormap is as a player colour (or in qw, skin too) lookup.
using the _baseline_ value won't work, as the bodyqueue will have 0 values in there.
but I would recommend just storing the .colormap value and using that directly. If its greater than MAX_SCOREBOARD, set it to 0 in your parser, but otherwise just check it against 0 for 'default' and otherwise treat it as a simple 1-based player index. vid.colormap is completely redundant in a gl renderer.

yes, you have to be careful about multiple ents with different models using the same colormap value (like players vs gibbed heads, or TF's sentry guns etc). glquake simply uses the playertextures array only if the model is "progs/player.mdl". Which sucks, especially for quakerally. But any other solution requires some sort of per-model per-colour per-skin lookup, although I suppose you can update that playertextures array only if the correct entity has that colormap set and read-as-0 if the model of your non-player-entity with the same colormap differs. that would get quakerally working properly at least. :P
not that anyone really cares about quakerally.
r00k
Posts: 1111
Joined: Sat Nov 13, 2004 10:39 pm

Re: NQ Colored Dead Bodies

Post by r00k »

hacky workaround so deadbodies dont go all black if someone has eyes

Code: Select all

			if (gl_color_deadbodies.value)
			{
				if (ent->colormap > 0)
				{
					i = (ent->colormap - 1);
					if (cl_entities[ent->colormap].model->modhint == MOD_PLAYER)
						texture = (playertextures) + i;//Colored Dead Bodies
					else
					texture	= paliashdr->gl_texturenum[skinnum][anim];					
Baker
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Re: NQ Colored Dead Bodies

Post by Baker »

GL ProQuake 4.93 doesn't have that issue yet uses a simple colored dead bodies strategy like GL Quakeworld used.

If the player isn't a player model, it doesn't use the player texture slots and instead just uses the normal, uncolormapped skin for eyes.mdl and such.

The player texture slots are reserved only only for the player.mdl last skin that was colormapped.

(Mark V does the thorough method and colormaps any skin/model combination that needs a color map, so there can be several textures per "player".)
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 ..
Baker
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Re: NQ Colored Dead Bodies

Post by Baker »

Might add, thinking back ...

If you are trying to do colored dead bodies the "cheap way", one scenario to watch out for:

You join a server and you see a dead body before seeing a the actual player. If you say, "I'll just use the last skin/current skin" ... there isn't one because the player has never come into view yet.

So you will get a white skin in an engine that uses the GLQuake way of reserving some texture slots for player textures (vs. say a FitzQuake engine which, I'm not too sure what would happen. It uses pointers to textures, but I can't remember if those pointers are setup early or what.)
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