From b252f6823904f7cddfe55fb81b86aed8fed27204 Mon Sep 17 00:00:00 2001 From: divverent Date: Thu, 20 Oct 2011 17:40:28 +0000 Subject: [PATCH] convert lightmaps to sRGB for nice sRGB support git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@11446 d7cf8633-e32d-0410-b094-e92efae38249 --- gl_rsurf.c | 4 ++++ image.c | 17 +++++++++++++++++ image.h | 2 ++ model_brush.c | 5 +++++ 4 files changed, 28 insertions(+) diff --git a/gl_rsurf.c b/gl_rsurf.c index f3e5611e..aad5344b 100644 --- a/gl_rsurf.c +++ b/gl_rsurf.c @@ -23,6 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "r_shadow.h" #include "portals.h" #include "csprogs.h" +#include "image.h" cvar_t r_ambient = {0, "r_ambient", "0", "brightens map, value is 0-128"}; cvar_t r_lockpvs = {0, "r_lockpvs", "0", "disables pvs switching, allows you to walk around and inspect what is visible from a given location in the map (anything not visible from your current location will not be drawn)"}; @@ -30,6 +31,7 @@ cvar_t r_lockvisibility = {0, "r_lockvisibility", "0", "disables visibility upda cvar_t r_useportalculling = {0, "r_useportalculling", "2", "improve framerate with r_novis 1 by using portal culling - still not as good as compiled visibility data in the map, but it helps (a value of 2 forces use of this even with vis data, which improves framerates in maps without too much complexity, but hurts in extremely complex maps, which is why 2 is not the default mode)"}; cvar_t r_usesurfaceculling = {0, "r_usesurfaceculling", "1", "skip off-screen surfaces (1 = cull surfaces if the map is likely to benefit, 2 = always cull surfaces)"}; cvar_t r_q3bsp_renderskydepth = {0, "r_q3bsp_renderskydepth", "0", "draws sky depth masking in q3 maps (as in q1 maps), this means for example that sky polygons can hide other things"}; +extern cvar_t vid_sRGB; /* =============== @@ -120,6 +122,8 @@ void R_BuildLightMap (const entity_render_t *ent, msurface_t *surface) } } + if(vid_sRGB.integer && !vid.sRGBcapable3D) + Image_MakesRGBColorsFromLinear(templight, templight, size); R_UpdateTexture(surface->lightmaptexture, templight, surface->lightmapinfo->lightmaporigin[0], surface->lightmapinfo->lightmaporigin[1], 0, smax, tmax, 1); // update the surface's deluxemap if it has one diff --git a/image.c b/image.c index c556f393..67c931a4 100644 --- a/image.c +++ b/image.c @@ -797,6 +797,7 @@ void Image_StripImageExtension (const char *in, char *out, size_t size_out) } static unsigned char image_linearfromsrgb[256]; +static unsigned char image_srgbfromlinear[256]; void Image_MakeLinearColorsFromsRGB(unsigned char *pout, const unsigned char *pin, int numpixels) { @@ -814,6 +815,22 @@ void Image_MakeLinearColorsFromsRGB(unsigned char *pout, const unsigned char *pi } } +void Image_MakesRGBColorsFromLinear(unsigned char *pout, const unsigned char *pin, int numpixels) +{ + int i; + // this math from http://www.opengl.org/registry/specs/EXT/texture_sRGB.txt + if (!image_srgbfromlinear[255]) + for (i = 0;i < 256;i++) + image_srgbfromlinear[i] = (unsigned char)bound(0, Image_sRGBFloatFromLinear(i*2) * 128.0f, 255); + for (i = 0;i < numpixels;i++) + { + pout[i*4+0] = image_srgbfromlinear[pin[i*4+0]]; + pout[i*4+1] = image_srgbfromlinear[pin[i*4+1]]; + pout[i*4+2] = image_srgbfromlinear[pin[i*4+2]]; + pout[i*4+3] = pin[i*4+3]; + } +} + typedef struct imageformat_s { const char *formatstring; diff --git a/image.h b/image.h index 60fbcce6..04d33378 100644 --- a/image.h +++ b/image.h @@ -50,8 +50,10 @@ void Image_FixTransparentPixels_f(void); extern cvar_t r_fixtrans_auto; #define Image_LinearFloatFromsRGB(c) (((c) < 11) ? (c) * 0.000302341331f : (float)pow(((c)*(1.0f/256.0f) + 0.055f)*(1.0f/1.0555f), 2.4f)) +#define Image_sRGBFloatFromLinear(c) (((c) < 1) ? (c) * 0.05046875f : 1.055f * (float)pow((c)*(1.0f/256.0f), 1.0f/2.4f) - 0.055f) void Image_MakeLinearColorsFromsRGB(unsigned char *pout, const unsigned char *pin, int numpixels); +void Image_MakesRGBColorsFromLinear(unsigned char *pout, const unsigned char *pin, int numpixels); #endif diff --git a/model_brush.c b/model_brush.c index 470b8586..08867119 100644 --- a/model_brush.c +++ b/model_brush.c @@ -57,6 +57,7 @@ cvar_t mod_q3shader_force_addalpha = {0, "mod_q3shader_force_addalpha", "0", "tr cvar_t mod_q1bsp_polygoncollisions = {0, "mod_q1bsp_polygoncollisions", "0", "disables use of precomputed cliphulls and instead collides with polygons (uses Bounding Interval Hierarchy optimizations)"}; cvar_t mod_collision_bih = {0, "mod_collision_bih", "1", "enables use of generated Bounding Interval Hierarchy tree instead of compiled bsp tree in collision code"}; cvar_t mod_recalculatenodeboxes = {0, "mod_recalculatenodeboxes", "1", "enables use of generated node bounding boxes based on BSP tree portal reconstruction, rather than the node boxes supplied by the map compiler"}; +extern cvar_t vid_sRGB; static texture_t mod_q1bsp_texture_solid; static texture_t mod_q1bsp_texture_sky; @@ -5009,7 +5010,11 @@ static void Mod_Q3BSP_LoadLightmaps(lump_t *l, lump_t *faceslump) if (loadmodel->brushq3.deluxemapping && (i & 1)) loadmodel->brushq3.data_deluxemaps[lightmapindex] = R_LoadTexture2D(loadmodel->texturepool, va("deluxemap%04i", lightmapindex), mergedwidth, mergedheight, mergeddeluxepixels, TEXTYPE_BGRA, TEXF_FORCELINEAR | (gl_texturecompression_q3bspdeluxemaps.integer ? TEXF_COMPRESS : 0), -1, NULL); else + { + if(vid_sRGB.integer && !vid.sRGBcapable3D) + Image_MakesRGBColorsFromLinear(mergedpixels, mergedpixels, mergedwidth * mergedheight); loadmodel->brushq3.data_lightmaps [lightmapindex] = R_LoadTexture2D(loadmodel->texturepool, va("lightmap%04i", lightmapindex), mergedwidth, mergedheight, mergedpixels, TEXTYPE_BGRA, TEXF_FORCELINEAR | (gl_texturecompression_q3bsplightmaps.integer ? TEXF_COMPRESS : 0), -1, NULL); + } } } -- 2.39.2