Page 2 of 2

Re: NQ Colored Dead Bodies

Posted: Fri Jul 20, 2012 12:21 am
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.

Re: NQ Colored Dead Bodies

Posted: Mon Oct 01, 2012 5:42 pm
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....

Re: NQ Colored Dead Bodies

Posted: Mon Oct 01, 2012 6:42 pm
by Spike
why is ent->colormap even a pointer? that only makes sense with software rendering.

Re: NQ Colored Dead Bodies

Posted: Mon Oct 01, 2012 7:28 pm
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...

Re: NQ Colored Dead Bodies

Posted: Mon Oct 01, 2012 9:40 pm
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.

Re: NQ Colored Dead Bodies

Posted: Mon Oct 01, 2012 10:39 pm
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)... :/

Re: NQ Colored Dead Bodies

Posted: Tue Oct 02, 2012 12:16 am
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?

Re: NQ Colored Dead Bodies

Posted: Fri May 17, 2013 4:46 pm
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 :(

Re: NQ Colored Dead Bodies

Posted: Fri May 17, 2013 5:50 pm
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.

Re: NQ Colored Dead Bodies

Posted: Fri May 17, 2013 7:17 pm
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)

Re: NQ Colored Dead Bodies

Posted: Sat May 18, 2013 2:59 am
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.

Re: NQ Colored Dead Bodies

Posted: Sat May 18, 2013 7:39 am
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.

Re: NQ Colored Dead Bodies

Posted: Mon Mar 23, 2015 9:40 pm
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];					

Re: NQ Colored Dead Bodies

Posted: Tue Mar 24, 2015 4:38 am
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".)

Re: NQ Colored Dead Bodies

Posted: Wed Mar 25, 2015 11:55 am
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.)