From d95375e7e5107fa1f9795796f51ee62d5b8605c4 Mon Sep 17 00:00:00 2001
From: havoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Date: Fri, 27 May 2011 07:44:27 +0000
Subject: [PATCH] apply vid_sRGB correction to viewblends and particles

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@11167 d7cf8633-e32d-0410-b094-e92efae38249
::stable-branch::merge=bebdddd7765df0b347089323bad3a5ae626f7822
---
 cl_particles.c | 17 ++++++++++++++++-
 image.c        |  2 +-
 image.h        |  2 ++
 view.c         | 19 ++++++++++++++++---
 4 files changed, 35 insertions(+), 5 deletions(-)

diff --git a/cl_particles.c b/cl_particles.c
index ebdaad00..20869e0f 100644
--- a/cl_particles.c
+++ b/cl_particles.c
@@ -602,6 +602,12 @@ particle_t *CL_NewParticle(const vec3_t sortorigin, unsigned short ptypeindex, i
 	part->color[0] = ((((pcolor1 >> 16) & 0xFF) * l1 + ((pcolor2 >> 16) & 0xFF) * l2) >> 8) & 0xFF;
 	part->color[1] = ((((pcolor1 >>  8) & 0xFF) * l1 + ((pcolor2 >>  8) & 0xFF) * l2) >> 8) & 0xFF;
 	part->color[2] = ((((pcolor1 >>  0) & 0xFF) * l1 + ((pcolor2 >>  0) & 0xFF) * l2) >> 8) & 0xFF;
+	if (vid.sRGB3D)
+	{
+		part->color[0] = (unsigned char)(Image_LinearFloatFromsRGB(part->color[0]) * 256.0f);
+		part->color[1] = (unsigned char)(Image_LinearFloatFromsRGB(part->color[1]) * 256.0f);
+		part->color[2] = (unsigned char)(Image_LinearFloatFromsRGB(part->color[2]) * 256.0f);
+	}
 	part->alpha = palpha;
 	part->alphafade = palphafade;
 	part->staintexnum = staintex;
@@ -758,7 +764,10 @@ void CL_SpawnDecalParticleForSurface(int hitent, const vec3_t org, const vec3_t
 
 	if (cl_decals_newsystem.integer)
 	{
-		R_DecalSystem_SplatEntities(org, normal, color[0]*(1.0f/255.0f), color[1]*(1.0f/255.0f), color[2]*(1.0f/255.0f), alpha*(1.0f/255.0f), particletexture[texnum].s1, particletexture[texnum].t1, particletexture[texnum].s2, particletexture[texnum].t2, size);
+		if (vid.sRGB3D)
+			R_DecalSystem_SplatEntities(org, normal, Image_LinearFloatFromsRGB(color[0]), Image_LinearFloatFromsRGB(color[1]), Image_LinearFloatFromsRGB(color[2]), alpha*(1.0f/255.0f), particletexture[texnum].s1, particletexture[texnum].t1, particletexture[texnum].s2, particletexture[texnum].t2, size);
+		else
+			R_DecalSystem_SplatEntities(org, normal, color[0]*(1.0f/255.0f), color[1]*(1.0f/255.0f), color[2]*(1.0f/255.0f), alpha*(1.0f/255.0f), particletexture[texnum].s1, particletexture[texnum].t1, particletexture[texnum].s2, particletexture[texnum].t2, size);
 		return;
 	}
 
@@ -780,6 +789,12 @@ void CL_SpawnDecalParticleForSurface(int hitent, const vec3_t org, const vec3_t
 	decal->color[0] = color[0];
 	decal->color[1] = color[1];
 	decal->color[2] = color[2];
+	if (vid.sRGB3D)
+	{
+		decal->color[0] = (unsigned char)(Image_LinearFloatFromsRGB(decal->color[0]) * 256.0f);
+		decal->color[1] = (unsigned char)(Image_LinearFloatFromsRGB(decal->color[1]) * 256.0f);
+		decal->color[2] = (unsigned char)(Image_LinearFloatFromsRGB(decal->color[2]) * 256.0f);
+	}
 	decal->owner = hitent;
 	decal->clusterindex = -1000; // no vis culling unless we're sure
 	if (hitent)
diff --git a/image.c b/image.c
index e35dd33d..c556f393 100644
--- a/image.c
+++ b/image.c
@@ -804,7 +804,7 @@ void Image_MakeLinearColorsFromsRGB(unsigned char *pout, const unsigned char *pi
 	// this math from http://www.opengl.org/registry/specs/EXT/texture_sRGB.txt
 	if (!image_linearfromsrgb[255])
 		for (i = 0;i < 256;i++)
-			image_linearfromsrgb[i] = i < 11 ? (int)(i / 12.92f) : (int)(pow((i/256.0f + 0.055f)/1.0555f, 2.4f)*256.0f);
+			image_linearfromsrgb[i] = (unsigned char)(Image_LinearFloatFromsRGB(i) * 256.0f);
 	for (i = 0;i < numpixels;i++)
 	{
 		pout[i*4+0] = image_linearfromsrgb[pin[i*4+0]];
diff --git a/image.h b/image.h
index 10d190dd..60fbcce6 100644
--- a/image.h
+++ b/image.h
@@ -49,6 +49,8 @@ void Image_HeightmapToNormalmap_BGRA(const unsigned char *inpixels, unsigned cha
 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))
+
 void Image_MakeLinearColorsFromsRGB(unsigned char *pout, const unsigned char *pin, int numpixels);
 
 #endif
diff --git a/view.c b/view.c
index 56b8ce05..e31c9e42 100644
--- a/view.c
+++ b/view.c
@@ -21,6 +21,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 #include "quakedef.h"
 #include "cl_collision.h"
+#include "image.h"
 
 void CL_VM_UpdateDmgGlobals (int dmg_take, int dmg_save, vec3_t dmg_origin);
 
@@ -923,10 +924,22 @@ void V_CalcViewBlend(void)
 			a2 = 1 / r_refdef.viewblend[3];
 			VectorScale(r_refdef.viewblend, a2, r_refdef.viewblend);
 		}
-		r_refdef.viewblend[0] = bound(0.0f, r_refdef.viewblend[0] * (1.0f/255.0f), 1.0f);
-		r_refdef.viewblend[1] = bound(0.0f, r_refdef.viewblend[1] * (1.0f/255.0f), 1.0f);
-		r_refdef.viewblend[2] = bound(0.0f, r_refdef.viewblend[2] * (1.0f/255.0f), 1.0f);
+		r_refdef.viewblend[0] = bound(0.0f, r_refdef.viewblend[0], 255.0f);
+		r_refdef.viewblend[1] = bound(0.0f, r_refdef.viewblend[1], 255.0f);
+		r_refdef.viewblend[2] = bound(0.0f, r_refdef.viewblend[2], 255.0f);
 		r_refdef.viewblend[3] = bound(0.0f, r_refdef.viewblend[3] * gl_polyblend.value, 1.0f);
+		if (vid.sRGB3D)
+		{
+			r_refdef.viewblend[0] = Image_LinearFloatFromsRGB(r_refdef.viewblend[0]);
+			r_refdef.viewblend[1] = Image_LinearFloatFromsRGB(r_refdef.viewblend[1]);
+			r_refdef.viewblend[2] = Image_LinearFloatFromsRGB(r_refdef.viewblend[2]);
+		}
+		else
+		{
+			r_refdef.viewblend[0] *= (1.0f/256.0f);
+			r_refdef.viewblend[1] *= (1.0f/256.0f);
+			r_refdef.viewblend[2] *= (1.0f/256.0f);
+		}
 		
 		// Samual: Ugly hack, I know. But it's the best we can do since
 		// there is no way to detect client states from the engine.
-- 
2.39.5