diff --git a/engine/client/image.c b/engine/client/image.c index 1a25f7aa5..72f135c85 100644 --- a/engine/client/image.c +++ b/engine/client/image.c @@ -1545,8 +1545,72 @@ qbyte *ReadBMPFile(qbyte *buf, int length, int *width, int *height) return NULL; }*/ +// saturate function, stolen from jitspoe +void SaturateR8G8B8(qbyte *data, int size, float sat) +{ + int i; + float r, g, b, v; + if (sat > 1) + { + for(i=0; i < size; i+=3) + { + r = data[i]; + g = data[i+1]; + b = data[i+2]; + v = r * 0.30 + g * 0.59 + b * 0.11; + r = v + (r - v) * sat; + g = v + (g - v) * sat; + b = v + (b - v) * sat; + + // bounds check + if (r < 0) + r = 0; + else if (r > 255) + r = 255; + + if (g < 0) + g = 0; + else if (g > 255) + g = 255; + + if (b < 0) + b = 0; + else if (b > 255) + b = 255; + + // scale down to avoid overbright lightmaps + v = v / (r * 0.30 + g * 0.59 + b * 0.11); + if (v > 1) + v = 1; + else + v *= v; + + data[i] = r*v; + data[i+1] = g*v; + data[i+2] = b*v; + } + } + else // avoid bounds check for desaturation + { + if (sat < 0) + sat = 0; + + for(i=0; i < size; i+=3) + { + r = data[i]; + g = data[i+1]; + b = data[i+2]; + + v = r * 0.30 + g * 0.59 + b * 0.11; + + data[i] = v + (r - v) * sat; + data[i+1] = v + (g - v) * sat; + data[i+2] = v + (b - v) * sat; + } + } +} void BoostGamma(qbyte *rgba, int width, int height) { diff --git a/engine/client/render.h b/engine/client/render.h index bc81bf375..8ab60828c 100644 --- a/engine/client/render.h +++ b/engine/client/render.h @@ -290,6 +290,7 @@ qbyte *ReadPNGFile(qbyte *buf, int length, int *width, int *height); qbyte *ReadPCXPalette(qbyte *buf, int len, qbyte *out); void BoostGamma(qbyte *rgba, int width, int height); +void SaturateR8G8B8(qbyte *data, int size, float sat); void CL_NewDlightRGB (int key, float x, float y, float z, float radius, float time, float r, float g, float b); @@ -337,7 +338,7 @@ extern cvar_t gl_playermip; extern cvar_t r_palconvbits; extern cvar_t r_palconvwrite; - +extern cvar_t r_lightmap_saturation; enum { RSPEED_TOTALREFRESH, diff --git a/engine/client/renderer.c b/engine/client/renderer.c index 3a00c1de9..7d049691a 100644 --- a/engine/client/renderer.c +++ b/engine/client/renderer.c @@ -208,6 +208,8 @@ cvar_t r_transtablewrite = {"r_transtablewrite", "1"}; cvar_t r_palconvbits = {"r_palconvbits", "565"}; cvar_t r_palconvwrite = {"r_palconvwrite", "1"}; +cvar_t r_lightmap_saturation = {"r_lightmap_saturation", "1"}; + extern cvar_t bul_text1; extern cvar_t bul_text2; extern cvar_t bul_text3; @@ -240,6 +242,7 @@ cvar_t gl_lerpimages = {"gl_lerpimages", "1"}; extern cvar_t r_waterlayers; cvar_t gl_triplebuffer = {"gl_triplebuffer", "1", NULL, CVAR_ARCHIVE}; cvar_t vid_hardwaregamma = {"vid_hardwaregamma", "1", NULL, CVAR_ARCHIVE}; + void GLRenderer_Init(void) { extern cvar_t gl_contrast; @@ -432,7 +435,6 @@ void Renderer_Init(void) SWRenderer_Init(); #endif - //but register ALL vid_ commands. Cvar_Register (&vid_wait, VIDCOMMANDGROUP); Cvar_Register (&vid_nopageflip, VIDCOMMANDGROUP); @@ -501,6 +503,7 @@ void Renderer_Init(void) Cvar_Register (&r_netgraph, SCREENOPTIONS); Cvar_Register (&r_dynamic, GRAPHICALNICETIES); + Cvar_Register (&r_lightmap_saturation, GRAPHICALNICETIES); Cvar_Register (&r_nolerp, GRAPHICALNICETIES); Cvar_Register (&r_nolightdir, GRAPHICALNICETIES); diff --git a/engine/gl/gl_model.c b/engine/gl/gl_model.c index 9a5c114b6..ade0c7187 100644 --- a/engine/gl/gl_model.c +++ b/engine/gl/gl_model.c @@ -1486,7 +1486,15 @@ void GLMod_LoadLighting (lump_t *l) #endif if (loadmodel->lightdata) + { + if (loadmodel->rgblighting && r_lightmap_saturation.value != 1.0f) + { + // desaturate lightmap according to cvar + SaturateR8G8B8(loadmodel->lightdata, l->filelen, r_lightmap_saturation.value); + } + return; + } loadmodel->lightdata = Hunk_AllocName ( l->filelen, loadname); @@ -1500,6 +1508,9 @@ void GLMod_LoadLighting (lump_t *l) { *out++ = lmgamma[*in++]; } + + if (loadmodel->rgblighting && r_lightmap_saturation.value != 1.0f) + SaturateR8G8B8(loadmodel->lightdata, l->filelen, r_lightmap_saturation.value); } //memcpy (loadmodel->lightdata, mod_base + l->fileofs, l->filelen); } diff --git a/engine/sw/sw_model.c b/engine/sw/sw_model.c index c47855d9b..2a6066a51 100644 --- a/engine/sw/sw_model.c +++ b/engine/sw/sw_model.c @@ -901,6 +901,9 @@ void SWMod_LoadLighting (lump_t *l) dest+=3; } } + + if (r_lightmap_saturation.value != 1.0f) + SaturateR8G8B8(loadmodel->lightdata, l->filelen, r_lightmap_saturation.value); } else {