]> git.xonotic.org Git - xonotic/darkplaces.git/commitdiff
convert lightmaps to sRGB for nice sRGB support
authordivverent <divverent@d7cf8633-e32d-0410-b094-e92efae38249>
Thu, 20 Oct 2011 17:40:28 +0000 (17:40 +0000)
committerdivverent <divverent@d7cf8633-e32d-0410-b094-e92efae38249>
Thu, 20 Oct 2011 17:40:28 +0000 (17:40 +0000)
git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@11446 d7cf8633-e32d-0410-b094-e92efae38249

gl_rsurf.c
image.c
image.h
model_brush.c

index f3e5611ef58af2a8412528f3c2492e720c063ea6..aad5344bf2eb22830e75e95a855c42112164c537 100644 (file)
@@ -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 c556f3930bfbc7cd0170ceaeeb439908673d9718..67c931a4d8a3e213acd7c9185fdda9034ebc7c5f 100644 (file)
--- 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 60fbcce681c1aa93311efc3d4e3e1dd6f61de373..04d33378ff1be29f4a6610dc2b97b37103c2d91f 100644 (file)
--- 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
 
index 470b8586b0cbd5a5180a3da948bcb3e30313a5d7..088671193e612439db269020e0823808c857afc1 100644 (file)
@@ -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);
+                       }
                }
        }