diff --git a/engine/client/cl_render.c b/engine/client/cl_render.c index d328632a..f25eb3b0 100644 --- a/engine/client/cl_render.c +++ b/engine/client/cl_render.c @@ -215,6 +215,11 @@ intptr_t CL_RenderGetParm( const int parm, const int arg, const qboolean checkRe return (intptr_t)&clgame.palette; case PARM_GET_VIEWENT_PTR: return (intptr_t)&clgame.viewent; + case PARM_GET_TEXGAMMATABLE_PTR: + case PARM_GET_LIGHTGAMMATABLE_PTR: + case PARM_GET_SCREENGAMMATABLE_PTR: + case PARM_GET_LINEARGAMMATABLE_PTR: + return V_GetGammaPtr( parm ); } } return 0; diff --git a/engine/client/gamma.c b/engine/client/gamma.c index 0d69d0a5..3cce4d85 100644 --- a/engine/client/gamma.c +++ b/engine/client/gamma.c @@ -223,6 +223,23 @@ uint LinearGammaTable( uint b ) return lineargammatable[b]; } +intptr_t V_GetGammaPtr( int parm ) +{ + switch( parm ) + { + case PARM_GET_TEXGAMMATABLE_PTR: + return (intptr_t)texgammatable; + case PARM_GET_LIGHTGAMMATABLE_PTR: + return (intptr_t)lightgammatable; + case PARM_GET_SCREENGAMMATABLE_PTR: + return (intptr_t)screengammatable; + case PARM_GET_LINEARGAMMATABLE_PTR: + return (intptr_t)lineargammatable; + } + + return 0; +} + #if XASH_ENGINE_TESTS #include "tests.h" diff --git a/engine/common/common.h b/engine/common/common.h index 25461772..74c13d4b 100644 --- a/engine/common/common.h +++ b/engine/common/common.h @@ -828,6 +828,7 @@ uint LinearGammaTable( uint ); void V_Init( void ); void V_CheckGamma( void ); void V_CheckGammaEnd( void ); +intptr_t V_GetGammaPtr( int parm ); // // identification.c diff --git a/engine/ref_api.h b/engine/ref_api.h index 2f162740..c7d4a1ee 100644 --- a/engine/ref_api.h +++ b/engine/ref_api.h @@ -291,6 +291,11 @@ typedef enum PARM_GET_PALETTE_PTR = -14, // clgame.palette PARM_GET_VIEWENT_PTR = -15, // clgame.viewent + PARM_GET_TEXGAMMATABLE_PTR = -16, + PARM_GET_LIGHTGAMMATABLE_PTR = -17, + PARM_GET_SCREENGAMMATABLE_PTR = -18, + PARM_GET_LINEARGAMMATABLE_PTR = -19, + // implemented by ref_dll // returns non-null integer if filtering is enabled for texture diff --git a/ref/gl/gl_alias.c b/ref/gl/gl_alias.c index 88a44500..a675e0f1 100644 --- a/ref/gl/gl_alias.c +++ b/ref/gl/gl_alias.c @@ -800,7 +800,7 @@ static void R_AliasLighting( float *lv, const vec3_t normal ) illum = bound( 0.0f, illum, 255.0f ); - *lv = gEngfuncs.LightToTexGammaEx( illum * 4 ) / 1023.0f; + *lv = LightToTexGamma( illum * 4 ) / 1023.0f; } /* diff --git a/ref/gl/gl_local.h b/ref/gl/gl_local.h index c776d45b..1ca813b6 100644 --- a/ref/gl/gl_local.h +++ b/ref/gl/gl_local.h @@ -257,6 +257,10 @@ typedef struct movevars_t *movevars; color24 *palette; cl_entity_t *viewent; + byte *texgammatable; + uint *lightgammatable; + uint *lineargammatable; + uint *screengammatable; uint max_entities; } gl_globals_t; @@ -730,6 +734,35 @@ static inline model_t *CL_ModelHandle( int index ) return gp_cl->models[index]; } +static inline byte TextureToGamma( byte b ) +{ + return !FBitSet( gp_host->features, ENGINE_LINEAR_GAMMA_SPACE ) ? tr.texgammatable[b] : b; +} + +static inline uint LightToTexGamma( uint b ) +{ + if( unlikely( b >= 1024 )) + return 0; + + return !FBitSet( gp_host->features, ENGINE_LINEAR_GAMMA_SPACE ) ? tr.lightgammatable[b] : b; +} + +static inline uint ScreenGammaTable( uint b ) +{ + if( unlikely( b >= 1024 )) + return 0; + + return !FBitSet( gp_host->features, ENGINE_LINEAR_GAMMA_SPACE ) ? tr.screengammatable[b] : b; +} + +static inline uint LinearGammaTable( uint b ) +{ + if( unlikely( b >= 1024 )) + return 0; + + return !FBitSet( gp_host->features, ENGINE_LINEAR_GAMMA_SPACE ) ? tr.lineargammatable[b] : b; +} + #define WORLDMODEL (gp_cl->models[1]) // diff --git a/ref/gl/gl_opengl.c b/ref/gl/gl_opengl.c index 237f557f..8e739815 100644 --- a/ref/gl/gl_opengl.c +++ b/ref/gl/gl_opengl.c @@ -1300,6 +1300,10 @@ qboolean R_Init( void ) tr.movevars = (movevars_t *)ENGINE_GET_PARM( PARM_GET_MOVEVARS_PTR ); tr.palette = (color24 *)ENGINE_GET_PARM( PARM_GET_PALETTE_PTR ); tr.viewent = (cl_entity_t *)ENGINE_GET_PARM( PARM_GET_VIEWENT_PTR ); + tr.texgammatable = (byte *)ENGINE_GET_PARM( PARM_GET_TEXGAMMATABLE_PTR ); + tr.lightgammatable = (uint *)ENGINE_GET_PARM( PARM_GET_LIGHTGAMMATABLE_PTR ); + tr.screengammatable = (uint *)ENGINE_GET_PARM( PARM_GET_SCREENGAMMATABLE_PTR ); + tr.lineargammatable = (uint *)ENGINE_GET_PARM( PARM_GET_LINEARGAMMATABLE_PTR ); GL_SetDefaults(); R_CheckVBO(); diff --git a/ref/gl/gl_rsurf.c b/ref/gl/gl_rsurf.c index 3fa8e8f5..cebfeaf0 100644 --- a/ref/gl/gl_rsurf.c +++ b/ref/gl/gl_rsurf.c @@ -787,7 +787,7 @@ static void R_BuildLightMap( const msurface_t *surf, byte *dest, int stride, qbo if( t > 1023 ) t = 1023; - dst[i] = gEngfuncs.LightToTexGammaEx( t ) >> 2; + dst[i] = LightToTexGamma( t ) >> 2; } dst[3] = 255; } diff --git a/ref/gl/gl_studio.c b/ref/gl/gl_studio.c index b3e92376..a07c4c3e 100644 --- a/ref/gl/gl_studio.c +++ b/ref/gl/gl_studio.c @@ -1572,9 +1572,9 @@ static void R_StudioEntityLight( alight_t *lightinfo ) if( k != -1 ) { - g_studio.locallightcolor[k][0] = gEngfuncs.LinearGammaTable( el->color.r << 2 ); - g_studio.locallightcolor[k][1] = gEngfuncs.LinearGammaTable( el->color.g << 2 ); - g_studio.locallightcolor[k][2] = gEngfuncs.LinearGammaTable( el->color.b << 2 ); + g_studio.locallightcolor[k][0] = LinearGammaTable( el->color.r << 2 ); + g_studio.locallightcolor[k][1] = LinearGammaTable( el->color.g << 2 ); + g_studio.locallightcolor[k][2] = LinearGammaTable( el->color.b << 2 ); g_studio.locallightR2[k] = r2; g_studio.locallight[k] = el; lstrength[k] = minstrength; @@ -1670,7 +1670,7 @@ static void R_StudioLighting( float *lv, int bone, int flags, vec3_t normal ) illum = Q_min( illum, 255.0f ); - *lv = gEngfuncs.LightToTexGammaEx( illum * 4 ) / 1023.0f; + *lv = LightToTexGamma( illum * 4 ) / 1023.0f; } /* @@ -1725,12 +1725,12 @@ static void R_LightLambert( vec4_t light[MAX_LOCALLIGHTS], const vec3_t normal, { for( i = 0; i < 3; i++ ) { - float c = finalLight[i] + gEngfuncs.LinearGammaTable( color[i] * 1023.0f ); + float c = finalLight[i] + LinearGammaTable( color[i] * 1023.0f ); if( c > 1023.0f ) out[i] = 255; else - out[i] = gEngfuncs.ScreenGammaTable( c ) >> 2; + out[i] = ScreenGammaTable( c ) >> 2; } } else diff --git a/ref/soft/r_local.h b/ref/soft/r_local.h index e2b4a095..5cae907b 100644 --- a/ref/soft/r_local.h +++ b/ref/soft/r_local.h @@ -297,6 +297,10 @@ typedef struct movevars_t *movevars; color24 *palette; cl_entity_t *viewent; + byte *texgammatable; + uint *lightgammatable; + uint *lineargammatable; + uint *screengammatable; uint max_entities; } gl_globals_t; @@ -691,6 +695,35 @@ static inline model_t *CL_ModelHandle( int index ) return gp_cl->models[index]; } +static inline byte TextureToGamma( byte b ) +{ + return !FBitSet( gp_host->features, ENGINE_LINEAR_GAMMA_SPACE ) ? tr.texgammatable[b] : b; +} + +static inline uint LightToTexGamma( uint b ) +{ + if( unlikely( b >= 1024 )) + return 0; + + return !FBitSet( gp_host->features, ENGINE_LINEAR_GAMMA_SPACE ) ? tr.lightgammatable[b] : b; +} + +static inline uint ScreenGammaTable( uint b ) +{ + if( unlikely( b >= 1024 )) + return 0; + + return !FBitSet( gp_host->features, ENGINE_LINEAR_GAMMA_SPACE ) ? tr.screengammatable[b] : b; +} + +static inline uint LinearGammaTable( uint b ) +{ + if( unlikely( b >= 1024 )) + return 0; + + return !FBitSet( gp_host->features, ENGINE_LINEAR_GAMMA_SPACE ) ? tr.lineargammatable[b] : b; +} + #define WORLDMODEL (gp_cl->models[1]) // todo: gl_cull.c diff --git a/ref/soft/r_main.c b/ref/soft/r_main.c index 594de007..68085e34 100644 --- a/ref/soft/r_main.c +++ b/ref/soft/r_main.c @@ -1897,6 +1897,10 @@ qboolean GAME_EXPORT R_Init( void ) tr.movevars = (movevars_t *)ENGINE_GET_PARM( PARM_GET_MOVEVARS_PTR ); tr.palette = (color24 *)ENGINE_GET_PARM( PARM_GET_PALETTE_PTR ); tr.viewent = (cl_entity_t *)ENGINE_GET_PARM( PARM_GET_VIEWENT_PTR ); + tr.texgammatable = (byte *)ENGINE_GET_PARM( PARM_GET_TEXGAMMATABLE_PTR ); + tr.lightgammatable = (uint *)ENGINE_GET_PARM( PARM_GET_LIGHTGAMMATABLE_PTR ); + tr.screengammatable = (uint *)ENGINE_GET_PARM( PARM_GET_SCREENGAMMATABLE_PTR ); + tr.lineargammatable = (uint *)ENGINE_GET_PARM( PARM_GET_LINEARGAMMATABLE_PTR ); if( !R_InitBlit( glblit )) { diff --git a/ref/soft/r_part.c b/ref/soft/r_part.c index f4e91b01..9f3670ce 100644 --- a/ref/soft/r_part.c +++ b/ref/soft/r_part.c @@ -90,9 +90,9 @@ void GAME_EXPORT CL_DrawParticles( double frametime, particle_t *cl_active_parti if( alpha > 255 || p->type == pt_static ) alpha = 255; - //TriColor4ub( gEngfuncs.LightToTexGamma( color.r ), - // gEngfuncs.LightToTexGamma( color.g ), - // gEngfuncs.LightToTexGamma( color.b ), alpha ); + //TriColor4ub( LightToTexGamma( color.r ), + // LightToTexGamma( color.g ), + // LightToTexGamma( color.b ), alpha ); //TriBrightness( alpha / 255.0f ); _TriColor4f(1.0f*alpha/255/255*color.r,1.0f*alpha/255/255*color.g,1.0f*alpha/255/255* color.b,1.0f ); diff --git a/ref/soft/r_studio.c b/ref/soft/r_studio.c index 9d799f71..15fe6993 100644 --- a/ref/soft/r_studio.c +++ b/ref/soft/r_studio.c @@ -1571,9 +1571,9 @@ static void R_StudioEntityLight( alight_t *lightinfo ) if( k != -1 ) { - g_studio.locallightcolor[k][0] = gEngfuncs.LinearGammaTable( el->color.r << 2 ); - g_studio.locallightcolor[k][1] = gEngfuncs.LinearGammaTable( el->color.g << 2 ); - g_studio.locallightcolor[k][2] = gEngfuncs.LinearGammaTable( el->color.b << 2 ); + g_studio.locallightcolor[k][0] = LinearGammaTable( el->color.r << 2 ); + g_studio.locallightcolor[k][1] = LinearGammaTable( el->color.g << 2 ); + g_studio.locallightcolor[k][2] = LinearGammaTable( el->color.b << 2 ); g_studio.locallightR2[k] = r2; g_studio.locallight[k] = el; lstrength[k] = minstrength; @@ -1669,7 +1669,7 @@ static void R_StudioLighting( float *lv, int bone, int flags, vec3_t normal ) illum = Q_min( illum, 255.0f ); - *lv = gEngfuncs.LightToTexGammaEx( illum * 4 ) / 1023.0f; + *lv = LightToTexGamma( illum * 4 ) / 1023.0f; } /* @@ -1724,12 +1724,12 @@ static void R_LightLambert( vec4_t light[MAX_LOCALLIGHTS], const vec3_t normal, { for( i = 0; i < 3; i++ ) { - float c = finalLight[i] + gEngfuncs.LinearGammaTable( color[i] * 1023.0f ); + float c = finalLight[i] + LinearGammaTable( color[i] * 1023.0f ); if( c > 1023.0f ) out[i] = 255; else - out[i] = gEngfuncs.ScreenGammaTable( c ) >> 2; + out[i] = ScreenGammaTable( c ) >> 2; } } else diff --git a/ref/soft/r_surf.c b/ref/soft/r_surf.c index a64e8273..8b2245b5 100644 --- a/ref/soft/r_surf.c +++ b/ref/soft/r_surf.c @@ -137,7 +137,7 @@ static void R_AddDynamicLights( const msurface_t *surf ) sl = DotProduct( impact, info->lmvecs[0] ) + info->lmvecs[0][3] - info->lightmapmins[0]; tl = DotProduct( impact, info->lmvecs[1] ) + info->lmvecs[1][3] - info->lightmapmins[1]; - monolight = gEngfuncs.LightToTexGamma(( dl->color.r + dl->color.g + dl->color.b ) / 3 ) * 3; + monolight = LightToTexGamma(( dl->color.r + dl->color.g + dl->color.b ) / 3 * 4 ) * 3; for( t = 0; t < tmax; t++ ) { @@ -222,7 +222,7 @@ static void R_BuildLightMap( void ) for( i = 0; i < size; i++ ) { if( blocklights[i] < 65280 ) - t = gEngfuncs.LightToTexGammaEx( blocklights[i] >> 6 ) << 6; + t = LightToTexGamma( blocklights[i] >> 6 ) << 6; else t = (int)blocklights[i]; t = bound( 0, t, 65535 * 3 );