diff --git a/README b/README index 58af58f7..7e4c19b3 100644 --- a/README +++ b/README @@ -181,7 +181,8 @@ New cvars r_ext_texture_filter_anisotropic - anisotropic texture filtering r_zProj - distance of observer camera to projection plane in quake3 standard units - r_greyscale - render black and white images + r_greyscale - desaturate textures, useful for anaglyph, + supports values in the range of 0 to 1 r_stereoEnabled - enable stereo rendering for techniques like shutter glasses (untested) r_anaglyphMode - Enable rendering of anaglyph images diff --git a/code/qcommon/q_shared.h b/code/qcommon/q_shared.h index a3935c91..56734dce 100644 --- a/code/qcommon/q_shared.h +++ b/code/qcommon/q_shared.h @@ -1307,4 +1307,7 @@ typedef enum _flag_status { #define CDCHKSUM_LEN 2 +#define LERP( a, b, w ) ( ( a ) * ( 1.0f - ( w ) ) + ( b ) * ( w ) ) +#define LUMA( red, green, blue ) ( 0.2126f * ( red ) + 0.7152f * ( green ) + 0.0722f * ( blue ) ) + #endif // __Q_SHARED_H diff --git a/code/renderer/tr_image.c b/code/renderer/tr_image.c index c86e32a6..4dd12237 100644 --- a/code/renderer/tr_image.c +++ b/code/renderer/tr_image.c @@ -560,6 +560,27 @@ static void Upload32( unsigned *data, scan = ((byte *)data); samples = 3; + if( r_greyscale->integer ) + { + for ( i = 0; i < c; i++ ) + { + byte luma = LUMA(scan[i*4], scan[i*4 + 1], scan[i*4 + 2]); + scan[i*4] = luma; + scan[i*4 + 1] = luma; + scan[i*4 + 2] = luma; + } + } + else if( r_greyscale->value ) + { + for ( i = 0; i < c; i++ ) + { + float luma = LUMA(scan[i*4], scan[i*4 + 1], scan[i*4 + 2]); + scan[i*4] = LERP(scan[i*4], luma, r_greyscale->value); + scan[i*4 + 1] = LERP(scan[i*4 + 1], luma, r_greyscale->value); + scan[i*4 + 2] = LERP(scan[i*4 + 2], luma, r_greyscale->value); + } + } + if(lightMap) { if(r_greyscale->integer) diff --git a/code/renderer/tr_init.c b/code/renderer/tr_init.c index 8c0cf687..d28998ee 100644 --- a/code/renderer/tr_init.c +++ b/code/renderer/tr_init.c @@ -920,6 +920,7 @@ void R_Register( void ) r_stereoEnabled = ri.Cvar_Get( "r_stereoEnabled", "0", CVAR_ARCHIVE | CVAR_LATCH); r_ignoreFastPath = ri.Cvar_Get( "r_ignoreFastPath", "1", CVAR_ARCHIVE | CVAR_LATCH ); r_greyscale = ri.Cvar_Get("r_greyscale", "0", CVAR_ARCHIVE | CVAR_LATCH); + ri.Cvar_CheckRange(r_greyscale, 0, 1, qfalse); // // temporary latched variables that can only change over a restart diff --git a/code/renderer/tr_noise.c b/code/renderer/tr_noise.c index af2f84e4..fca9eac6 100644 --- a/code/renderer/tr_noise.c +++ b/code/renderer/tr_noise.c @@ -31,8 +31,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA static float s_noise_table[NOISE_SIZE]; static int s_noise_perm[NOISE_SIZE]; -#define LERP( a, b, w ) ( a * ( 1.0f - w ) + b * w ) - static float GetNoiseValue( int x, int y, int z, int t ) { int index = INDEX( ( int ) x, ( int ) y, ( int ) z, ( int ) t ); diff --git a/code/renderer/tr_shade.c b/code/renderer/tr_shade.c index 33a7f2bf..2a53c97f 100644 --- a/code/renderer/tr_shade.c +++ b/code/renderer/tr_shade.c @@ -459,9 +459,18 @@ static void ProjectDlightTexture_altivec( void ) { { float luminance; - luminance = (dl->color[0] * 255.0f + dl->color[1] * 255.0f + dl->color[2] * 255.0f) / 3; + luminance = LUMA(dl->color[0], dl->color[1], dl->color[2]) * 255.0f; floatColor[0] = floatColor[1] = floatColor[2] = luminance; } + else if(r_greyscale->value) + { + float luminance; + + luminance = LUMA(dl->color[0], dl->color[1], dl->color[2]) * 255.0f; + floatColor[0] = LERP(dl->color[0] * 255.0f, luminance, r_greyscale->value); + floatColor[1] = LERP(dl->color[1] * 255.0f, luminance, r_greyscale->value); + floatColor[2] = LERP(dl->color[2] * 255.0f, luminance, r_greyscale->value); + } else { floatColor[0] = dl->color[0] * 255.0f; @@ -612,10 +621,19 @@ static void ProjectDlightTexture_scalar( void ) { if(r_greyscale->integer) { float luminance; - - luminance = (dl->color[0] * 255.0f + dl->color[1] * 255.0f + dl->color[2] * 255.0f) / 3; + + luminance = LUMA(dl->color[0], dl->color[1], dl->color[2]) * 255.0f; floatColor[0] = floatColor[1] = floatColor[2] = luminance; } + else if(r_greyscale->value) + { + float luminance; + + luminance = LUMA(dl->color[0], dl->color[1], dl->color[2]) * 255.0f; + floatColor[0] = LERP(dl->color[0] * 255.0f, luminance, r_greyscale->value); + floatColor[1] = LERP(dl->color[1] * 255.0f, luminance, r_greyscale->value); + floatColor[2] = LERP(dl->color[2] * 255.0f, luminance, r_greyscale->value); + } else { floatColor[0] = dl->color[0] * 255.0f; @@ -964,11 +982,22 @@ static void ComputeColors( shaderStage_t *pStage ) if(r_greyscale->integer) { int scale; + for(i = 0; i < tess.numVertexes; i++) + { + scale = LUMA(tess.svars.colors[i][0], tess.svars.colors[i][1], tess.svars.colors[i][2]); + tess.svars.colors[i][0] = tess.svars.colors[i][1] = tess.svars.colors[i][2] = scale; + } + } + else if(r_greyscale->value) + { + float scale; for(i = 0; i < tess.numVertexes; i++) { - scale = (tess.svars.colors[i][0] + tess.svars.colors[i][1] + tess.svars.colors[i][2]) / 3; - tess.svars.colors[i][0] = tess.svars.colors[i][1] = tess.svars.colors[i][2] = scale; + scale = LUMA(tess.svars.colors[i][0], tess.svars.colors[i][1], tess.svars.colors[i][2]); + tess.svars.colors[i][0] = LERP(tess.svars.colors[i][0], scale, r_greyscale->value); + tess.svars.colors[i][1] = LERP(tess.svars.colors[i][1], scale, r_greyscale->value); + tess.svars.colors[i][2] = LERP(tess.svars.colors[i][2], scale, r_greyscale->value); } } }