[PATCH] Gamma correction for GLQuake

Implement hardware independent gamma correction for GLQuake. This comes at a
fill-rate cost since we cover the whole scene with an alpha blended poly.

diff -urN b/NQ/gl_rmain.c head/NQ/gl_rmain.c
--- b/NQ/gl_rmain.c	2005-12-29 12:28:31.000000000 +1030
+++ head/NQ/gl_rmain.c	2005-12-29 12:47:05.000000000 +1030
@@ -736,6 +736,21 @@
     glDepthRange(gldepthmin, gldepthmax);
 }
 
+/*
+ * GL_DrawBlendPoly
+ * - Render a polygon covering the whole screen
+ * - Used for full-screen color blending and approximated gamma correction
+ */
+static void
+GL_DrawBlendPoly(void)
+{
+    glBegin(GL_QUADS);
+    glVertex3f(10, 100, 100);
+    glVertex3f(10, -100, 100);
+    glVertex3f(10, -100, -100);
+    glVertex3f(10, 100, -100);
+    glEnd();
+}
 
 /*
 ============
@@ -745,36 +760,42 @@
 static void
 R_PolyBlend(void)
 {
-    if (!gl_polyblend.value)
-	return;
-    if (!v_blend[3])
-	return;
+    float gamma = v_gamma.value * v_gamma.value;
 
-    GL_DisableMultitexture();
+    if (gamma < 0.25)
+	gamma = 0.25;
+    else if (gamma > 1.0)
+	gamma = 1.0;
 
-    glDisable(GL_ALPHA_TEST);
-    glEnable(GL_BLEND);
-    glDisable(GL_DEPTH_TEST);
-    glDisable(GL_TEXTURE_2D);
-
-    glLoadIdentity();
+    if ((gl_polyblend.value && v_blend[3]) || gamma < 1.0) {
+	GL_DisableMultitexture();
 
-    glRotatef(-90, 1, 0, 0);	// put Z going up
-    glRotatef(90, 0, 0, 1);	// put Z going up
+	glDisable(GL_ALPHA_TEST);
+	glEnable(GL_BLEND);
+	glDisable(GL_DEPTH_TEST);
+	glDisable(GL_TEXTURE_2D);
 
-    glColor4fv(v_blend);
+	glLoadIdentity();
+	glRotatef(-90, 1, 0, 0);	// put Z going up
+	glRotatef(90, 0, 0, 1);		// put Z going up
+
+	if (gl_polyblend.value && v_blend[3]) {
+	    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+	    glColor4fv(v_blend);
+	    GL_DrawBlendPoly();
+	}
+	if (gamma < 1.0) {
+	    glBlendFunc(GL_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA);
+	    glColor4f(1, 1, 1, gamma);
+	    GL_DrawBlendPoly();
+	}
 
-    glBegin(GL_QUADS);
+	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 
-    glVertex3f(10, 100, 100);
-    glVertex3f(10, -100, 100);
-    glVertex3f(10, -100, -100);
-    glVertex3f(10, 100, -100);
-    glEnd();
-
-    glDisable(GL_BLEND);
-    glEnable(GL_TEXTURE_2D);
-    glEnable(GL_ALPHA_TEST);
+	glDisable(GL_BLEND);
+	glEnable(GL_TEXTURE_2D);
+	glEnable(GL_ALPHA_TEST);
+    }
 }
 
 
diff -urN b/QW/client/gl_rmain.c head/QW/client/gl_rmain.c
--- b/QW/client/gl_rmain.c	2005-12-29 12:28:32.000000000 +1030
+++ head/QW/client/gl_rmain.c	2005-12-29 12:47:09.000000000 +1030
@@ -749,6 +749,21 @@
     glDepthRange(gldepthmin, gldepthmax);
 }
 
+/*
+ * GL_DrawBlendPoly
+ * - Render a polygon covering the whole screen
+ * - Used for full-screen color blending and approximated gamma correction
+ */
+static void
+GL_DrawBlendPoly(void)
+{
+    glBegin(GL_QUADS);
+    glVertex3f(10, 100, 100);
+    glVertex3f(10, -100, 100);
+    glVertex3f(10, -100, -100);
+    glVertex3f(10, 100, -100);
+    glEnd();
+}
 
 /*
 ============
@@ -758,36 +773,42 @@
 static void
 R_PolyBlend(void)
 {
-    if (!gl_polyblend.value)
-	return;
-    if (!v_blend[3])
-	return;
-
-    GL_DisableMultitexture();
-
-    glDisable(GL_ALPHA_TEST);
-    glEnable(GL_BLEND);
-    glDisable(GL_DEPTH_TEST);
-    glDisable(GL_TEXTURE_2D);
+    float gamma = v_gamma.value * v_gamma.value;
 
-    glLoadIdentity();
+    if (gamma < 0.25)
+	gamma = 0.25;
+    else if (gamma > 1.0)
+	gamma = 1.0;
 
-    glRotatef(-90, 1, 0, 0);	// put Z going up
-    glRotatef(90, 0, 0, 1);	// put Z going up
+    if ((gl_polyblend.value && v_blend[3]) || gamma < 1.0) {
+	GL_DisableMultitexture();
 
-    glColor4fv(v_blend);
+	glDisable(GL_ALPHA_TEST);
+	glEnable(GL_BLEND);
+	glDisable(GL_DEPTH_TEST);
+	glDisable(GL_TEXTURE_2D);
 
-    glBegin(GL_QUADS);
+	glLoadIdentity();
+	glRotatef(-90, 1, 0, 0);	// put Z going up
+	glRotatef(90, 0, 0, 1);		// put Z going up
+
+	if (gl_polyblend.value && v_blend[3]) {
+	    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+	    glColor4fv(v_blend);
+	    GL_DrawBlendPoly();
+	}
+	if (gamma < 1.0) {
+	    glBlendFunc(GL_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA);
+	    glColor4f(1, 1, 1, gamma);
+	    GL_DrawBlendPoly();
+	}
 
-    glVertex3f(10, 100, 100);
-    glVertex3f(10, -100, 100);
-    glVertex3f(10, -100, -100);
-    glVertex3f(10, 100, -100);
-    glEnd();
+	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 
-    glDisable(GL_BLEND);
-    glEnable(GL_TEXTURE_2D);
-    glEnable(GL_ALPHA_TEST);
+	glDisable(GL_BLEND);
+	glEnable(GL_TEXTURE_2D);
+	glEnable(GL_ALPHA_TEST);
+    }
 }
 
 
