Forum

GLQuake and deadbodies not being colored

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

Moderator: InsideQC Admins

GLQuake and deadbodies not being colored

Postby Baker » Sun Jul 04, 2010 11:58 pm

I have always found it annoying that dead bodies don't get colored in GLQuake. Quakeworld, they do. And DarkPlaces since something like build 73 way, way long ago in something like 2002 ... they do.

The reason deadbodies don't get colored in GLQuake works like this:

1. With OpenGL, you must have player texture slots. GLQuake uses 16 (Quakeworld uses 128).
2. If a player changes color, the player texture gets recolored and re-uploaded. This has a performance cost.

Taking a very conservative approach with the following boundaries and sticking with the 16 player texture slots, it is possible to essentially get colored player bodies for free because the dead body's colored skin is already uploaded as the player skin so you just bind to it.

Well ...
1) If you are running id1 Quake and not something with several player skins
2) Or something with multiple player models (FVF comes to mind, so does Slide).

And ... if you stick within the bounds of 16 player textures and ONLY using those slots to color bodies, you also have the problem that the client doesn't always know what player model a player is using (if a player isn't in view, for example).

For example, if someone gets the invisibility ring, they switch to eyes.mdl

Interesting problem ... if sticking to the 16 player textures concept. Almost requires at least a mild skin manager like Quakeworld uses.
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 r00k » Mon Jul 05, 2010 5:10 am

IIRC, in QuakeC this is an easy fix.

corpse.skin = self.skin; (for predetermined team skins)

or

corpse.team = self.team;
r00k
 
Posts: 1110
Joined: Sat Nov 13, 2004 10:39 pm

Postby mh » Mon Jul 05, 2010 9:23 am

The main reason why this happens is because GLQuake checks the entity number for the MDL and only applies a playerskin if it's in one of the first 16 slots. When a player gets killed the dead body is moved to a new entity slot outside of those first 16, and so you get no colours.

I believe that it's valid to check instead for a model called "progs/player.mdl"; the hard-coding of the name makes me wince, but then again it's already hard-coded in SV_CreateBaseline so not really that big a deal. It could likely be avoided by caching out the model name(s) used in those first 16 slots, but I'd need to write some code to be certain.

There may be some other jiggerypokery needed to determine which of the players the new dead body belongs to; I fixed this myself some time ago but my skin manager is quite different to GLQuake's so I can't say for certain.
Last edited by mh on Mon Jul 05, 2010 10:17 am, edited 1 time in total.
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 Spike » Mon Jul 05, 2010 9:52 am

SV_CreateBaseline is purely an optimisation, noone notices, so long as the model is actually precached.
QuakeWorld has progs/player.mdl hardcoded all over the place. Its vile. Custom skins apply only to this model. Custom models are thus not really viable (breaks skin forcing, oh noes!).
Spike
 
Posts: 2892
Joined: Fri Nov 05, 2004 3:12 am
Location: UK

Postby Baker » Mon Jul 05, 2010 11:04 am

I'm a going to take the rougher road and probably do something better than the Quakeworld method alone but probably less sophisticated than the DP method.

It occurs to me that whenever a player is colormapped, regardless of the model ... that texture gets uploaded. And GLQuake doesn't ever use glDeleteTextures.

But I also want *MULTIPLAYER* save games and whatever dead bodies should be colored (multiplayer save games, while not hard to do, would be a great server feature). So I'm thinking I might as well go the full way and do it "all".

It will be fun to address and interesting to write up a tutorial on.

But combined with .... viewtopic.php?t=1902 ... the number of player textures uploaded just isn't a big deal. If you clear world textures on every new map, there is no sane way to ever hit even 500 total uploaded textures that I can think of (and hitting even 300 is mighty hard) --- and GL_MAXTEXTURES even in GLQuake is 1000.
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 mh » Mon Jul 05, 2010 11:43 am

What I do is keep 256 texture slots spare for player textures (16 shirt * 16 pants). Whenever a player colour changes it checks to see if a texture is already available in that slot; if so it uses it, if not it translates the base skin and saves to that slot. All 256 slots are cleared down on a map change.

Since a texture is initially uploaded when a player joins the game this means that the actual brief stall during gameplay is kept to a minimum and definitively doesn't happen when a player dies and is respawned. It just pulls the correct pre-uploaded texture from the appropriate slot instead.

It's quite possible to DoS a person using this method of course; a malicious player could quite easily switch between all 256 available colours over a short time period and flood your video RAM. But that needs to be balanced against the genuine requirement for honest players to not have stalls and hitches during busy games when people are being killed and respawning continuously.

A possible solution would be to only keep the 16 (== MAX_SCOREBOARD) most recently used skin textures, and also to automatically clear down a skin texture if it hasn't been used in a certain period of time; say, 5 seconds. I'm dubious about the latter but the former should work.

Looking forward to seeing what Baker comes up with here. :D
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 Spike » Mon Jul 05, 2010 12:01 pm

from the sounds of it, baker is going to generate a new image for each and every entity.
Personally, I think some code that uses the private texture of the player when the ent matches the model for that colourmap's model is sufficient, and regenerate the player's private texture any time the players model changes to anything with a size above 16*16*16 (ie: not a head/gib) (if they're not visible and their colour changes, like at first spawn, then assume they're using the baseline model and generate colours based on that, so corpses change instantly before seeing the player).

A few colourmapping hackable facts...
Corpses of a player will have a colormap set to the same as the player's ent number (cl.scoreboard[colormap-1] refers to the client's player-specific info for that corpse).
Corpses or players can be gibbed heads. Such gibs will have the same colourmap.
TeamFortress and other mods use the colormap field for sentry guns. This is most noticable, for me, with CuTF's teleporter pads.
Nexuiz uses colourmaps for dropped weapons.
Generaating new colourmaps on the fly will induce a stall. You'll not really notice it for a single player (think lightmaps) but for multiple players all doing it at the same time it might be noticable. Certainly avoid disk access.
Spike
 
Posts: 2892
Joined: Fri Nov 05, 2004 3:12 am
Location: UK

Postby mh » Mon Jul 05, 2010 12:22 pm

The fact that player textures need to be resampled to powers of 2 doesn't help either, as well as the fact that GLQuake sends them through glTexImage instead of through glTexSubImage. All horrible horrible stuff.

I'd already got the corpse colormap == player number thing, but it's good useful info for everyone.
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 frag.machine » Mon Jul 05, 2010 12:47 pm

Don't shoot me if this is a dumb idea, but...
Code: Select all
1 ) during load time, for every model skin:
  1.1 ) read the original texture;
  1.2 ) create 2 grayscaled masks from the shirts and pants pixels;

2 ) to render the model:
  2.1 ) render the model using the original texture;
  2.2 ) glColor3f (<pants color>);
  2.3 ) render the model again, using the pants skin;
  2.4 ) glColor3f (<shirts color>);
  2.5 ) render the model again, using the shirt skin;
  2.6 ) glColor3f (1, 1, 1);

3 ) rinse and repeat for every player model.

An additional bonus would be the ability to set any RGB color to either shirts or pants (maybe via 2 cvars), much like the modern Doom engines allow.

Obviously, this is a pretty naive approach and I ommited a lot of details (like the current light level or colored lights support), but I think that for the current card generation the cost of 3 pass rendering for the player mdl would negligible. And I imagine that you guys can manage to do that in a much more efficient way than I described above. ;)
I know FrikaC made a cgi-bin version of the quakec interpreter once and wrote part of his website in QuakeC :) (LordHavoc)
User avatar
frag.machine
 
Posts: 2090
Joined: Sat Nov 25, 2006 1:49 pm

Postby mh » Mon Jul 05, 2010 12:55 pm

You could abuse the alpha channel and do it in a shader pretty damn efficiently (one pass and all).
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 » Tue Jul 06, 2010 2:33 am

mh wrote:It's quite possible to DoS a person using this method of course; a malicious player could quite easily switch between all 256 available colours over a short time period and flood your video RAM.


And in stock GLQuake, a player wouldn't need to switch between all 256 colors. Any color change is uploaded redundantly, I believe.
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 » Tue Jul 06, 2010 3:04 am

tbh though, its only 196 colours, not 256 colours. so no dos attack possible! :P
but yeah, shaders wouldn't require any uploads nor any special regeneration or anything at all like that. just tell it the rgb colours to use and it'll use them. oh, and it'll do the interpolation and lighting too. shaders rock! :P
Spike
 
Posts: 2892
Joined: Fri Nov 05, 2004 3:12 am
Location: UK

Postby Baker » Tue Jul 06, 2010 3:25 am

Spike wrote:tbh though, its only 196 colours, not 256 colours. so no dos attack possible! :P
but yeah, shaders wouldn't require any uploads nor any special regeneration or anything at all like that. just tell it the rgb colours to use and it'll use them. oh, and it'll do the interpolation and lighting too. shaders rock! :P


For NQ, some servers actually allow colors 14/15 on the server (quake.ihoc.net is one, it's been like that since at least 2003 and maybe since '99) so surprisingly 256 is the effective range.

[Client support isn't required, only the server need allow that color range and it works even in GLQuake.]
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


Return to Engine Programming

Who is online

Users browsing this forum: No registered users and 1 guest