2010-02-15 23:26:55 +00:00
/*
Copyright ( C ) 1996 - 2001 Id Software , Inc .
Copyright ( C ) 2002 - 2009 John Fitzgibbons and others
2014-09-22 08:55:46 +00:00
Copyright ( C ) 2010 - 2014 QuakeSpasm developers
2010-02-15 23:26:55 +00:00
This program is free software ; you can redistribute it and / or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation ; either version 2
of the License , or ( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE .
See the GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 59 Temple Place - Suite 330 , Boston , MA 02111 - 1307 , USA .
*/
// r_light.c
# include "quakedef.h"
int r_dlightframecount ;
extern cvar_t r_flatlightstyles ; //johnfitz
2019-09-10 14:41:11 +00:00
//Spike - made this a general function
void CL_UpdateLightstyle ( unsigned int idx , const char * str )
{
int total ;
int j ;
if ( idx < MAX_LIGHTSTYLES )
{
q_strlcpy ( cl_lightstyle [ idx ] . map , str , MAX_STYLESTRING ) ;
cl_lightstyle [ idx ] . length = Q_strlen ( cl_lightstyle [ idx ] . map ) ;
//johnfitz -- save extra info
if ( cl_lightstyle [ idx ] . length )
{
total = 0 ;
cl_lightstyle [ idx ] . peak = ' a ' ;
for ( j = 0 ; j < cl_lightstyle [ idx ] . length ; j + + )
{
total + = cl_lightstyle [ idx ] . map [ j ] - ' a ' ;
cl_lightstyle [ idx ] . peak = q_max ( cl_lightstyle [ idx ] . peak , cl_lightstyle [ idx ] . map [ j ] ) ;
}
cl_lightstyle [ idx ] . average = total / cl_lightstyle [ idx ] . length + ' a ' ;
}
else
cl_lightstyle [ idx ] . average = cl_lightstyle [ idx ] . peak = ' m ' ;
//johnfitz
}
}
2010-02-15 23:26:55 +00:00
/*
= = = = = = = = = = = = = = = = = =
R_AnimateLight
= = = = = = = = = = = = = = = = = =
*/
void R_AnimateLight ( void )
{
int i , j , k ;
//
// light animations
// 'm' is normal light, 'a' is no light, 'z' is double bright
i = ( int ) ( cl . time * 10 ) ;
for ( j = 0 ; j < MAX_LIGHTSTYLES ; j + + )
{
if ( ! cl_lightstyle [ j ] . length )
{
d_lightstylevalue [ j ] = 256 ;
continue ;
}
//johnfitz -- r_flatlightstyles
if ( r_flatlightstyles . value = = 2 )
k = cl_lightstyle [ j ] . peak - ' a ' ;
else if ( r_flatlightstyles . value = = 1 )
k = cl_lightstyle [ j ] . average - ' a ' ;
else
{
k = i % cl_lightstyle [ j ] . length ;
k = cl_lightstyle [ j ] . map [ k ] - ' a ' ;
}
d_lightstylevalue [ j ] = k * 22 ;
//johnfitz
}
}
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
DYNAMIC LIGHTS BLEND RENDERING ( gl_flashblend 1 )
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
void AddLightBlend ( float r , float g , float b , float a2 )
{
float a ;
v_blend [ 3 ] = a = v_blend [ 3 ] + a2 * ( 1 - v_blend [ 3 ] ) ;
a2 = a2 / a ;
v_blend [ 0 ] = v_blend [ 1 ] * ( 1 - a2 ) + r * a2 ;
v_blend [ 1 ] = v_blend [ 1 ] * ( 1 - a2 ) + g * a2 ;
v_blend [ 2 ] = v_blend [ 2 ] * ( 1 - a2 ) + b * a2 ;
}
void R_RenderDlight ( dlight_t * light )
{
int i , j ;
float a ;
vec3_t v ;
float rad ;
rad = light - > radius * 0.35 ;
VectorSubtract ( light - > origin , r_origin , v ) ;
2010-08-01 19:22:46 +00:00
if ( VectorLength ( v ) < rad )
2010-02-15 23:26:55 +00:00
{ // view is inside the dlight
2023-07-20 23:22:25 +00:00
if ( light - > color [ 0 ] = = 1 & & light - > color [ 1 ] = = 1 & & light - > color [ 2 ] = = 1 )
AddLightBlend ( 1.0 , 0.5 , 0.0 , light - > radius * 0.0003 ) ;
else
AddLightBlend ( light - > color [ 0 ] , light - > color [ 1 ] , light - > color [ 2 ] , light - > radius * 0.0003 ) ;
2010-02-15 23:26:55 +00:00
return ;
}
glBegin ( GL_TRIANGLE_FAN ) ;
2023-07-20 23:22:25 +00:00
if ( light - > color [ 0 ] = = 1 & & light - > color [ 1 ] = = 1 & & light - > color [ 2 ] = = 1 ) //if its default full-white, show it with an orange tint instead to replicate expected QS behaviour without breaking coloured dlights.
glColor3f ( 0.2f , 0.1f , 0.0 ) ;
else
glColor3f ( light - > color [ 0 ] * .2f , light - > color [ 1 ] * .2f , light - > color [ 2 ] * .2f ) ;
2010-02-15 23:26:55 +00:00
for ( i = 0 ; i < 3 ; i + + )
v [ i ] = light - > origin [ i ] - vpn [ i ] * rad ;
glVertex3fv ( v ) ;
glColor3f ( 0 , 0 , 0 ) ;
for ( i = 16 ; i > = 0 ; i - - )
{
a = i / 16.0 * M_PI * 2 ;
for ( j = 0 ; j < 3 ; j + + )
v [ j ] = light - > origin [ j ] + vright [ j ] * cos ( a ) * rad
+ vup [ j ] * sin ( a ) * rad ;
glVertex3fv ( v ) ;
}
glEnd ( ) ;
}
/*
= = = = = = = = = = = = =
R_RenderDlights
= = = = = = = = = = = = =
*/
void R_RenderDlights ( void )
{
int i ;
dlight_t * l ;
if ( ! gl_flashblend . value )
return ;
r_dlightframecount = r_framecount + 1 ; // because the count hasn't
// advanced yet for this frame
glDepthMask ( 0 ) ;
glDisable ( GL_TEXTURE_2D ) ;
glShadeModel ( GL_SMOOTH ) ;
glEnable ( GL_BLEND ) ;
glBlendFunc ( GL_ONE , GL_ONE ) ;
l = cl_dlights ;
for ( i = 0 ; i < MAX_DLIGHTS ; i + + , l + + )
{
if ( l - > die < cl . time | | ! l - > radius )
continue ;
R_RenderDlight ( l ) ;
}
glColor3f ( 1 , 1 , 1 ) ;
glDisable ( GL_BLEND ) ;
glEnable ( GL_TEXTURE_2D ) ;
glBlendFunc ( GL_SRC_ALPHA , GL_ONE_MINUS_SRC_ALPHA ) ;
glDepthMask ( 1 ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
DYNAMIC LIGHTS
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
/*
= = = = = = = = = = = = =
R_MarkLights - - johnfitz - - rewritten to use LordHavoc ' s lighting speedup
= = = = = = = = = = = = =
*/
2018-05-25 10:54:33 +00:00
void R_MarkLights ( dlight_t * light , vec3_t lightorg , int num , mnode_t * node )
2010-02-15 23:26:55 +00:00
{
mplane_t * splitplane ;
msurface_t * surf ;
vec3_t impact ;
float dist , l , maxdist ;
2017-09-17 02:12:53 +00:00
unsigned int i ;
int j , s , t ;
2010-02-15 23:26:55 +00:00
start :
if ( node - > contents < 0 )
return ;
splitplane = node - > plane ;
if ( splitplane - > type < 3 )
2018-05-25 10:54:33 +00:00
dist = lightorg [ splitplane - > type ] - splitplane - > dist ;
2010-02-15 23:26:55 +00:00
else
2018-05-25 10:54:33 +00:00
dist = DotProduct ( lightorg , splitplane - > normal ) - splitplane - > dist ;
2010-02-15 23:26:55 +00:00
if ( dist > light - > radius )
{
node = node - > children [ 0 ] ;
goto start ;
}
if ( dist < - light - > radius )
{
node = node - > children [ 1 ] ;
goto start ;
}
maxdist = light - > radius * light - > radius ;
// mark the polygons
surf = cl . worldmodel - > surfaces + node - > firstsurface ;
for ( i = 0 ; i < node - > numsurfaces ; i + + , surf + + )
{
for ( j = 0 ; j < 3 ; j + + )
2018-05-25 10:54:33 +00:00
impact [ j ] = lightorg [ j ] - surf - > plane - > normal [ j ] * dist ;
2010-02-15 23:26:55 +00:00
// clamp center of light to corner and check brightness
l = DotProduct ( impact , surf - > texinfo - > vecs [ 0 ] ) + surf - > texinfo - > vecs [ 0 ] [ 3 ] - surf - > texturemins [ 0 ] ;
s = l + 0.5 ; if ( s < 0 ) s = 0 ; else if ( s > surf - > extents [ 0 ] ) s = surf - > extents [ 0 ] ;
s = l - s ;
l = DotProduct ( impact , surf - > texinfo - > vecs [ 1 ] ) + surf - > texinfo - > vecs [ 1 ] [ 3 ] - surf - > texturemins [ 1 ] ;
t = l + 0.5 ; if ( t < 0 ) t = 0 ; else if ( t > surf - > extents [ 1 ] ) t = surf - > extents [ 1 ] ;
t = l - t ;
// compare to minimum light
if ( ( s * s + t * t + dist * dist ) < maxdist )
{
if ( surf - > dlightframe ! = r_dlightframecount ) // not dynamic until now
{
2012-07-10 11:21:17 +00:00
surf - > dlightbits [ num > > 5 ] = 1U < < ( num & 31 ) ;
2010-02-15 23:26:55 +00:00
surf - > dlightframe = r_dlightframecount ;
}
else // already dynamic
2012-07-10 11:21:17 +00:00
surf - > dlightbits [ num > > 5 ] | = 1U < < ( num & 31 ) ;
2010-02-15 23:26:55 +00:00
}
}
if ( node - > children [ 0 ] - > contents > = 0 )
2018-05-25 10:54:33 +00:00
R_MarkLights ( light , lightorg , num , node - > children [ 0 ] ) ;
2010-02-15 23:26:55 +00:00
if ( node - > children [ 1 ] - > contents > = 0 )
2018-05-25 10:54:33 +00:00
R_MarkLights ( light , lightorg , num , node - > children [ 1 ] ) ;
2010-02-15 23:26:55 +00:00
}
/*
= = = = = = = = = = = = =
R_PushDlights
= = = = = = = = = = = = =
*/
void R_PushDlights ( void )
{
int i ;
dlight_t * l ;
if ( gl_flashblend . value )
return ;
r_dlightframecount = r_framecount + 1 ; // because the count hasn't
// advanced yet for this frame
2020-07-02 19:05:51 +00:00
if ( ! r_refdef . drawworld )
return ;
2010-02-15 23:26:55 +00:00
l = cl_dlights ;
for ( i = 0 ; i < MAX_DLIGHTS ; i + + , l + + )
{
if ( l - > die < cl . time | | ! l - > radius )
continue ;
2018-05-25 10:54:33 +00:00
R_MarkLights ( l , l - > origin , i , cl . worldmodel - > nodes ) ;
2010-02-15 23:26:55 +00:00
}
}
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
LIGHT SAMPLING
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
mplane_t * lightplane ;
vec3_t lightspot ;
vec3_t lightcolor ; //johnfitz -- lit support via lordhavoc
/*
= = = = = = = = = = = = =
RecursiveLightPoint - - johnfitz - - replaced entire function for lit support via lordhavoc
= = = = = = = = = = = = =
*/
2021-09-20 08:55:10 +00:00
int RecursiveLightPoint ( vec3_t color , mnode_t * node , vec3_t rayorg , vec3_t start , vec3_t end , float * maxdist )
2010-02-15 23:26:55 +00:00
{
float front , back , frac ;
vec3_t mid ;
loc0 :
if ( node - > contents < 0 )
return false ; // didn't hit anything
// calculate mid point
if ( node - > plane - > type < 3 )
{
front = start [ node - > plane - > type ] - node - > plane - > dist ;
back = end [ node - > plane - > type ] - node - > plane - > dist ;
}
else
{
front = DotProduct ( start , node - > plane - > normal ) - node - > plane - > dist ;
back = DotProduct ( end , node - > plane - > normal ) - node - > plane - > dist ;
}
// LordHavoc: optimized recursion
if ( ( back < 0 ) = = ( front < 0 ) )
2021-09-20 08:55:10 +00:00
// return RecursiveLightPoint (color, node->children[front < 0], rayorg, start, end, maxdist);
2010-02-15 23:26:55 +00:00
{
node = node - > children [ front < 0 ] ;
goto loc0 ;
}
frac = front / ( front - back ) ;
mid [ 0 ] = start [ 0 ] + ( end [ 0 ] - start [ 0 ] ) * frac ;
mid [ 1 ] = start [ 1 ] + ( end [ 1 ] - start [ 1 ] ) * frac ;
mid [ 2 ] = start [ 2 ] + ( end [ 2 ] - start [ 2 ] ) * frac ;
// go down front side
2021-09-20 08:55:10 +00:00
if ( RecursiveLightPoint ( color , node - > children [ front < 0 ] , rayorg , start , mid , maxdist ) )
2010-02-15 23:26:55 +00:00
return true ; // hit something
else
{
2017-09-17 02:12:53 +00:00
unsigned int i ;
int ds , dt ;
2010-02-15 23:26:55 +00:00
msurface_t * surf ;
// check for impact on this node
VectorCopy ( mid , lightspot ) ;
lightplane = node - > plane ;
surf = cl . worldmodel - > surfaces + node - > firstsurface ;
for ( i = 0 ; i < node - > numsurfaces ; i + + , surf + + )
{
2021-09-20 08:55:10 +00:00
float sfront , sback , dist ;
vec3_t raydelta ;
2010-02-15 23:26:55 +00:00
if ( surf - > flags & SURF_DRAWTILED )
continue ; // no lightmaps
2015-01-26 06:46:53 +00:00
// ericw -- added double casts to force 64-bit precision.
// Without them the zombie at the start of jam3_ericw.bsp was
// incorrectly being lit up in SSE builds.
ds = ( int ) ( ( double ) DoublePrecisionDotProduct ( mid , surf - > texinfo - > vecs [ 0 ] ) + surf - > texinfo - > vecs [ 0 ] [ 3 ] ) ;
dt = ( int ) ( ( double ) DoublePrecisionDotProduct ( mid , surf - > texinfo - > vecs [ 1 ] ) + surf - > texinfo - > vecs [ 1 ] [ 3 ] ) ;
2010-02-15 23:26:55 +00:00
if ( ds < surf - > texturemins [ 0 ] | | dt < surf - > texturemins [ 1 ] )
continue ;
ds - = surf - > texturemins [ 0 ] ;
dt - = surf - > texturemins [ 1 ] ;
if ( ds > surf - > extents [ 0 ] | | dt > surf - > extents [ 1 ] )
continue ;
2021-09-20 08:55:10 +00:00
if ( surf - > plane - > type < 3 )
{
sfront = rayorg [ surf - > plane - > type ] - surf - > plane - > dist ;
sback = end [ surf - > plane - > type ] - surf - > plane - > dist ;
}
else
{
sfront = DotProduct ( rayorg , surf - > plane - > normal ) - surf - > plane - > dist ;
sback = DotProduct ( end , surf - > plane - > normal ) - surf - > plane - > dist ;
}
VectorSubtract ( end , rayorg , raydelta ) ;
dist = sfront / ( sfront - sback ) * VectorLength ( raydelta ) ;
if ( ! surf - > samples )
{
// We hit a surface that is flagged as lightmapped, but doesn't have actual lightmap info.
// Instead of just returning black, we'll keep looking for nearby surfaces that do have valid samples.
// This fixes occasional pitch-black models in otherwise well-lit areas in DOTM (e.g. mge1m1, mge4m1)
// caused by overlapping surfaces with mixed lighting data.
const float nearby = 8.f ;
dist + = nearby ;
* maxdist = q_min ( * maxdist , dist ) ;
continue ;
}
if ( dist < * maxdist )
2010-02-15 23:26:55 +00:00
{
// LordHavoc: enhanced to interpolate lighting
int maps , line3 , dsfrac = ds & 15 , dtfrac = dt & 15 , r00 = 0 , g00 = 0 , b00 = 0 , r01 = 0 , g01 = 0 , b01 = 0 , r10 = 0 , g10 = 0 , b10 = 0 , r11 = 0 , g11 = 0 , b11 = 0 ;
2023-06-29 15:40:18 +00:00
float scale , e ;
2010-02-15 23:26:55 +00:00
2023-06-29 15:40:18 +00:00
if ( cl . worldmodel - > flags & MOD_HDRLIGHTING )
{
static const float rgb9e5tab [ 32 ] = { //multipliers for the 9-bit mantissa, according to the biased mantissa
//aka: pow(2, biasedexponent - bias-bits) where bias is 15 and bits is 9
1.0 / ( 1 < < 24 ) , 1.0 / ( 1 < < 23 ) , 1.0 / ( 1 < < 22 ) , 1.0 / ( 1 < < 21 ) , 1.0 / ( 1 < < 20 ) , 1.0 / ( 1 < < 19 ) , 1.0 / ( 1 < < 18 ) , 1.0 / ( 1 < < 17 ) ,
1.0 / ( 1 < < 16 ) , 1.0 / ( 1 < < 15 ) , 1.0 / ( 1 < < 14 ) , 1.0 / ( 1 < < 13 ) , 1.0 / ( 1 < < 12 ) , 1.0 / ( 1 < < 11 ) , 1.0 / ( 1 < < 10 ) , 1.0 / ( 1 < < 9 ) ,
1.0 / ( 1 < < 8 ) , 1.0 / ( 1 < < 7 ) , 1.0 / ( 1 < < 6 ) , 1.0 / ( 1 < < 5 ) , 1.0 / ( 1 < < 4 ) , 1.0 / ( 1 < < 3 ) , 1.0 / ( 1 < < 2 ) , 1.0 / ( 1 < < 1 ) ,
1.0 , 1.0 * ( 1 < < 1 ) , 1.0 * ( 1 < < 2 ) , 1.0 * ( 1 < < 3 ) , 1.0 * ( 1 < < 4 ) , 1.0 * ( 1 < < 5 ) , 1.0 * ( 1 < < 6 ) , 1.0 * ( 1 < < 7 ) ,
} ;
uint32_t * lightmap = ( uint32_t * ) surf - > samples + ( ( dt > > surf - > lmshift ) * ( ( surf - > extents [ 0 ] > > surf - > lmshift ) + 1 ) + ( ds > > surf - > lmshift ) ) ;
line3 = ( ( surf - > extents [ 0 ] > > surf - > lmshift ) + 1 ) ;
for ( maps = 0 ; maps < MAXLIGHTMAPS & & surf - > styles [ maps ] ! = INVALID_LIGHTSTYLE ; maps + + )
{
2023-07-10 02:02:16 +00:00
scale = ( 1 < < 7 ) * ( float ) d_lightstylevalue [ surf - > styles [ maps ] ] * 1.0f / 256.0f ;
e = rgb9e5tab [ lightmap [ 0 ] > > 27 ] * scale ; r00 + = ( ( lightmap [ 0 ] > > 0 ) & 0x1ff ) * e ; g00 + = ( ( lightmap [ 0 ] > > 9 ) & 0x1ff ) * e ; b00 + = ( ( lightmap [ 0 ] > > 9 ) & 0x1ff ) * e ;
e = rgb9e5tab [ lightmap [ 1 ] > > 27 ] * scale ; r01 + = ( ( lightmap [ 1 ] > > 0 ) & 0x1ff ) * e ; g01 + = ( ( lightmap [ 1 ] > > 9 ) & 0x1ff ) * e ; b01 + = ( ( lightmap [ 1 ] > > 9 ) & 0x1ff ) * e ;
e = rgb9e5tab [ lightmap [ line3 + 0 ] > > 27 ] * scale ; r10 + = ( ( lightmap [ line3 + 0 ] > > 0 ) & 0x1ff ) * e ; g10 + = ( ( lightmap [ line3 + 0 ] > > 9 ) & 0x1ff ) * e ; b10 + = ( ( lightmap [ line3 + 0 ] > > 9 ) & 0x1ff ) * e ;
e = rgb9e5tab [ lightmap [ line3 + 1 ] > > 27 ] * scale ; r11 + = ( ( lightmap [ line3 + 1 ] > > 0 ) & 0x1ff ) * e ; g11 + = ( ( lightmap [ line3 + 1 ] > > 9 ) & 0x1ff ) * e ; b11 + = ( ( lightmap [ line3 + 1 ] > > 9 ) & 0x1ff ) * e ;
2023-06-29 15:40:18 +00:00
lightmap + = ( ( surf - > extents [ 0 ] > > surf - > lmshift ) + 1 ) * ( ( surf - > extents [ 1 ] > > surf - > lmshift ) + 1 ) ;
}
}
else
2010-02-15 23:26:55 +00:00
{
2023-07-10 02:02:16 +00:00
byte * lightmap = ( byte * ) surf - > samples + ( ( dt > > surf - > lmshift ) * ( ( surf - > extents [ 0 ] > > surf - > lmshift ) + 1 ) + ( ds > > surf - > lmshift ) ) * 3 ; // LordHavoc: *3 for color
2023-06-29 15:40:18 +00:00
line3 = ( ( surf - > extents [ 0 ] > > surf - > lmshift ) + 1 ) * 3 ;
for ( maps = 0 ; maps < MAXLIGHTMAPS & & surf - > styles [ maps ] ! = INVALID_LIGHTSTYLE ; maps + + )
{
2023-07-10 02:02:16 +00:00
scale = ( float ) d_lightstylevalue [ surf - > styles [ maps ] ] * 1.0f / 256.0f ;
2023-06-29 15:40:18 +00:00
r00 + = ( float ) lightmap [ 0 ] * scale ; g00 + = ( float ) lightmap [ 1 ] * scale ; b00 + = ( float ) lightmap [ 2 ] * scale ;
r01 + = ( float ) lightmap [ 3 ] * scale ; g01 + = ( float ) lightmap [ 4 ] * scale ; b01 + = ( float ) lightmap [ 5 ] * scale ;
r10 + = ( float ) lightmap [ line3 + 0 ] * scale ; g10 + = ( float ) lightmap [ line3 + 1 ] * scale ; b10 + = ( float ) lightmap [ line3 + 2 ] * scale ;
r11 + = ( float ) lightmap [ line3 + 3 ] * scale ; g11 + = ( float ) lightmap [ line3 + 4 ] * scale ; b11 + = ( float ) lightmap [ line3 + 5 ] * scale ;
lightmap + = ( ( surf - > extents [ 0 ] > > surf - > lmshift ) + 1 ) * ( ( surf - > extents [ 1 ] > > surf - > lmshift ) + 1 ) * 3 ; // LordHavoc: *3 for colored lighting
}
2010-02-15 23:26:55 +00:00
}
color [ 0 ] + = ( float ) ( ( int ) ( ( ( ( ( ( ( ( r11 - r10 ) * dsfrac ) > > 4 ) + r10 ) - ( ( ( ( r01 - r00 ) * dsfrac ) > > 4 ) + r00 ) ) * dtfrac ) > > 4 ) + ( ( ( ( r01 - r00 ) * dsfrac ) > > 4 ) + r00 ) ) ) ;
color [ 1 ] + = ( float ) ( ( int ) ( ( ( ( ( ( ( ( g11 - g10 ) * dsfrac ) > > 4 ) + g10 ) - ( ( ( ( g01 - g00 ) * dsfrac ) > > 4 ) + g00 ) ) * dtfrac ) > > 4 ) + ( ( ( ( g01 - g00 ) * dsfrac ) > > 4 ) + g00 ) ) ) ;
color [ 2 ] + = ( float ) ( ( int ) ( ( ( ( ( ( ( ( b11 - b10 ) * dsfrac ) > > 4 ) + b10 ) - ( ( ( ( b01 - b00 ) * dsfrac ) > > 4 ) + b00 ) ) * dtfrac ) > > 4 ) + ( ( ( ( b01 - b00 ) * dsfrac ) > > 4 ) + b00 ) ) ) ;
}
return true ; // success
}
// go down back side
2021-09-20 08:55:10 +00:00
return RecursiveLightPoint ( color , node - > children [ front > = 0 ] , rayorg , mid , end , maxdist ) ;
2010-02-15 23:26:55 +00:00
}
}
/*
= = = = = = = = = = = = =
R_LightPoint - - johnfitz - - replaced entire function for lit support via lordhavoc
= = = = = = = = = = = = =
*/
int R_LightPoint ( vec3_t p )
{
vec3_t end ;
2021-09-20 08:55:10 +00:00
float maxdist = 8192.f ; //johnfitz -- was 2048
2010-02-15 23:26:55 +00:00
if ( ! cl . worldmodel - > lightdata )
{
lightcolor [ 0 ] = lightcolor [ 1 ] = lightcolor [ 2 ] = 255 ;
return 255 ;
}
end [ 0 ] = p [ 0 ] ;
end [ 1 ] = p [ 1 ] ;
2021-09-20 08:55:10 +00:00
end [ 2 ] = p [ 2 ] - maxdist ;
2010-02-15 23:26:55 +00:00
lightcolor [ 0 ] = lightcolor [ 1 ] = lightcolor [ 2 ] = 0 ;
2021-09-20 08:55:10 +00:00
RecursiveLightPoint ( lightcolor , cl . worldmodel - > nodes , p , p , end , & maxdist ) ;
2010-02-15 23:26:55 +00:00
return ( ( lightcolor [ 0 ] + lightcolor [ 1 ] + lightcolor [ 2 ] ) * ( 1.0f / 3.0f ) ) ;
}