ref: add R_EntityDynamicLight that calculates lighting for studio and alias models, and also located in libref_common

This commit is contained in:
Alibek Omarov
2026-04-19 01:17:28 +05:00
parent da4c4bb76a
commit 044523434d
14 changed files with 229 additions and 574 deletions

View File

@@ -26,6 +26,7 @@ extern ref_api_t gEngfuncs;
extern ref_globals_t *gpGlobals; extern ref_globals_t *gpGlobals;
extern ref_client_t *gp_cl; extern ref_client_t *gp_cl;
extern ref_host_t *gp_host; extern ref_host_t *gp_host;
extern struct movevars_s *gp_movevars;
extern const ref_interface_t gReffuncs; extern const ref_interface_t gReffuncs;
DECLARE_ENGINE_SHARED_CVAR_LIST() DECLARE_ENGINE_SHARED_CVAR_LIST()
@@ -81,6 +82,7 @@ void R_PushDlightsForBmodel( model_t *model, int framecount, const matrix4x4 obj
int R_PushDlights( model_t *model, int framecount ); int R_PushDlights( model_t *model, int framecount );
colorVec R_LightVec( const vec3_t start, const vec3_t end, vec3_t lspot, vec3_t lvec ); colorVec R_LightVec( const vec3_t start, const vec3_t end, vec3_t lspot, vec3_t lvec );
colorVec R_LightPoint( const vec3_t p0 ); colorVec R_LightPoint( const vec3_t p0 );
void R_EntityDynamicLight( cl_entity_t *ent, alight_t *plight, qboolean draw_world, double time, vec3_t lightspot, vec3_t lightvec );
void R_GatherPlayerLight( cl_entity_t *view ); void R_GatherPlayerLight( cl_entity_t *view );
void R_UpdateSurfaceCachedLight( msurface_t *surf ); void R_UpdateSurfaceCachedLight( msurface_t *surf );

View File

@@ -22,6 +22,7 @@ ref_api_t gEngfuncs;
ref_globals_t *gpGlobals; ref_globals_t *gpGlobals;
ref_client_t *gp_cl; ref_client_t *gp_cl;
ref_host_t *gp_host; ref_host_t *gp_host;
struct movevars_s *gp_movevars;
uint16_t rtable[MOD_FRAMES][MOD_FRAMES]; uint16_t rtable[MOD_FRAMES][MOD_FRAMES];
dlight_t *gp_dlights; dlight_t *gp_dlights;
int g_lightstylevalue[MAX_LIGHTSTYLES]; int g_lightstylevalue[MAX_LIGHTSTYLES];
@@ -70,6 +71,7 @@ int EXPORT GetRefAPI( int version, ref_interface_t *funcs, ref_api_t *engfuncs,
gp_cl = (ref_client_t *)ENGINE_GET_PARM( PARM_GET_CLIENT_PTR ); gp_cl = (ref_client_t *)ENGINE_GET_PARM( PARM_GET_CLIENT_PTR );
gp_host = (ref_host_t *)ENGINE_GET_PARM( PARM_GET_HOST_PTR ); gp_host = (ref_host_t *)ENGINE_GET_PARM( PARM_GET_HOST_PTR );
gp_movevars = (struct movevars_s *)ENGINE_GET_PARM( PARM_GET_MOVEVARS_PTR );
gp_dlights = (dlight_t *)ENGINE_GET_PARM( PARM_GET_DLIGHTS_PTR ); gp_dlights = (dlight_t *)ENGINE_GET_PARM( PARM_GET_DLIGHTS_PTR );
RETRIEVE_ENGINE_SHARED_CVAR_LIST(); RETRIEVE_ENGINE_SHARED_CVAR_LIST();

View File

@@ -15,6 +15,7 @@ GNU General Public License for more details.
#include "ref_common.h" #include "ref_common.h"
#include "xash3d_mathlib.h" #include "xash3d_mathlib.h"
#include "enginefeatures.h"
#include "pm_local.h" #include "pm_local.h"
CVAR_DEFINE_AUTO( r_dlight_virtual_radius, "3", FCVAR_GLCONFIG, "increase dlight radius virtually by this amount" ); CVAR_DEFINE_AUTO( r_dlight_virtual_radius, "3", FCVAR_GLCONFIG, "increase dlight radius virtually by this amount" );
@@ -489,6 +490,202 @@ void R_GatherPlayerLight( cl_entity_t *view )
gEngfuncs.SetLocalLightLevel(( c.r + c.g + c.b ) / 3 ); gEngfuncs.SetLocalLightLevel(( c.r + c.g + c.b ) / 3 );
} }
/*
===============
R_EntityDynamicLight
===============
*/
void R_EntityDynamicLight( cl_entity_t *ent, alight_t *plight, qboolean draw_world, double time, vec3_t lightspot, vec3_t lightvec )
{
movevars_t *mv = gp_movevars;
vec3_t lightDir, vecSrc, vecEnd;
vec3_t origin, dist, finalLight;
float add, radius, total;
colorVec light;
uint lnum;
dlight_t *dl;
if( !plight || !ent )
return;
if( !draw_world || r_fullbright->value || FBitSet( ent->curstate.effects, EF_FULLBRIGHT ))
{
plight->shadelight = 0;
plight->ambientlight = 192;
VectorSet( plight->plightvec, 0.0f, 0.0f, -1.0f );
VectorSet( plight->color, 1.0f, 1.0f, 1.0f );
return;
}
// determine plane to get lightvalues from: ceil or floor
if( FBitSet( ent->curstate.effects, EF_INVLIGHT ))
VectorSet( lightDir, 0.0f, 0.0f, 1.0f );
else
VectorSet( lightDir, 0.0f, 0.0f, -1.0f );
VectorCopy( ent->origin, origin );
VectorSet( vecSrc, origin[0], origin[1], origin[2] - lightDir[2] * 8.0f );
light.r = light.g = light.b = light.a = 0;
if(( mv->skycolor[0] + mv->skycolor[1] + mv->skycolor[2] ) != 0 )
{
msurface_t *psurf = NULL;
pmtrace_t trace;
vec3_t skyvec;
if( FBitSet( gp_host->features, ENGINE_WRITE_LARGE_COORD ))
VectorScale( mv->skyvec, 65536.0f, skyvec );
else
VectorScale( mv->skyvec, 8192.0f, skyvec );
VectorSubtract( origin, skyvec, vecEnd );
trace = gEngfuncs.CL_TraceLine( vecSrc, vecEnd, PM_WORLD_ONLY );
if( trace.ent > 0 )
psurf = gEngfuncs.EV_TraceSurface( trace.ent, vecSrc, vecEnd );
else
psurf = gEngfuncs.EV_TraceSurface( 0, vecSrc, vecEnd );
if(( ent->model->type == mod_studio && FBitSet( ent->model->flags, STUDIO_FORCE_SKYLIGHT ))
|| ( psurf && FBitSet( psurf->flags, SURF_DRAWSKY )))
{
VectorCopy( mv->skyvec, lightDir );
light.r = mv->skycolor[0];
light.g = mv->skycolor[1];
light.b = mv->skycolor[2];
}
}
if(( light.r + light.g + light.b ) == 0 )
{
colorVec gcolor;
float grad[4];
VectorScale( lightDir, 2048.0f, vecEnd );
VectorAdd( vecEnd, vecSrc, vecEnd );
light = R_LightVec( vecSrc, vecEnd, lightspot, lightvec );
if( VectorIsNull( lightvec ))
{
vecSrc[0] -= 16.0f;
vecSrc[1] -= 16.0f;
vecEnd[0] -= 16.0f;
vecEnd[1] -= 16.0f;
gcolor = R_LightVec( vecSrc, vecEnd, NULL, NULL );
grad[0] = ( gcolor.r + gcolor.g + gcolor.b ) / 768.0f;
vecSrc[0] += 32.0f;
vecEnd[0] += 32.0f;
gcolor = R_LightVec( vecSrc, vecEnd, NULL, NULL );
grad[1] = ( gcolor.r + gcolor.g + gcolor.b ) / 768.0f;
vecSrc[1] += 32.0f;
vecEnd[1] += 32.0f;
gcolor = R_LightVec( vecSrc, vecEnd, NULL, NULL );
grad[2] = ( gcolor.r + gcolor.g + gcolor.b ) / 768.0f;
vecSrc[0] -= 32.0f;
vecEnd[0] -= 32.0f;
gcolor = R_LightVec( vecSrc, vecEnd, NULL, NULL );
grad[3] = ( gcolor.r + gcolor.g + gcolor.b ) / 768.0f;
lightDir[0] = grad[0] - grad[1] - grad[2] + grad[3];
lightDir[1] = grad[1] + grad[0] - grad[2] - grad[3];
VectorNormalize( lightDir );
}
else
{
VectorCopy( lightvec, lightDir );
}
}
if( ent->curstate.renderfx == kRenderFxLightMultiplier && ent->curstate.iuser4 != 10 )
{
light.r *= ent->curstate.iuser4 / 10.0f;
light.g *= ent->curstate.iuser4 / 10.0f;
light.b *= ent->curstate.iuser4 / 10.0f;
}
VectorSet( finalLight, light.r, light.g, light.b );
ent->cvFloorColor = light;
total = Q_max( Q_max( light.r, light.g ), light.b );
if( total == 0.0f )
total = 1.0f;
// scale lightdir by light intentsity
VectorScale( lightDir, total, lightDir );
for( lnum = 0; lnum < MAX_DLIGHTS; lnum++ )
{
dl = &gp_dlights[lnum];
if( dl->die < time || !r_dynamic->value )
continue;
VectorSubtract( ent->origin, dl->origin, dist );
radius = VectorLength( dist );
add = ( dl->radius - radius );
if( add > 0.0f )
{
total += add;
if( radius > 1.0f )
VectorScale( dist, ( add / radius ), dist );
else
VectorScale( dist, add, dist );
VectorAdd( lightDir, dist, lightDir );
finalLight[0] += dl->color.r * ( add / 256.0f );
finalLight[1] += dl->color.g * ( add / 256.0f );
finalLight[2] += dl->color.b * ( add / 256.0f );
}
}
if( ent->model->type == mod_alias )
add = 0.9f;
else if( ent->model->type == mod_studio && FBitSet( ent->model->flags, STUDIO_AMBIENT_LIGHT ))
add = 0.6f;
else
add = bound( 0.75f, v_direct->value, 1.0f );
VectorScale( lightDir, add, lightDir );
plight->shadelight = VectorLength( lightDir );
plight->ambientlight = total - plight->shadelight;
total = Q_max( Q_max( finalLight[0], finalLight[1] ), finalLight[2] );
if( total > 0.0f )
{
plight->color[0] = finalLight[0] * ( 1.0f / total );
plight->color[1] = finalLight[1] * ( 1.0f / total );
plight->color[2] = finalLight[2] * ( 1.0f / total );
}
else
VectorSet( plight->color, 1.0f, 1.0f, 1.0f );
if( plight->ambientlight > 128 )
plight->ambientlight = 128;
if( plight->ambientlight + plight->shadelight > 255 )
plight->shadelight = 255 - plight->ambientlight;
VectorNormalize2( lightDir, plight->plightvec );
}
/* /*
================ ================
R_SetCacheState R_SetCacheState

View File

@@ -559,181 +559,6 @@ void Mod_AliasUnloadTextures( void *data )
============================================================= =============================================================
*/ */
/*
===============
R_AliasDynamicLight
similar to R_StudioDynamicLight
===============
*/
static void R_AliasDynamicLight( cl_entity_t *ent, alight_t *plight )
{
movevars_t *mv = tr.movevars;
vec3_t lightDir, vecSrc, vecEnd;
vec3_t origin, dist, finalLight;
float add, radius, total;
colorVec light;
uint lnum;
if( !plight || !ent )
return;
if( !FBitSet( RI.rvp.flags, RF_DRAW_WORLD ) || r_fullbright->value || FBitSet( ent->curstate.effects, EF_FULLBRIGHT ))
{
plight->shadelight = 0;
plight->ambientlight = 192;
VectorSet( plight->plightvec, 0.0f, 0.0f, -1.0f );
VectorSet( plight->color, 1.0f, 1.0f, 1.0f );
return;
}
// determine plane to get lightvalues from: ceil or floor
if( FBitSet( ent->curstate.effects, EF_INVLIGHT ))
VectorSet( lightDir, 0.0f, 0.0f, 1.0f );
else VectorSet( lightDir, 0.0f, 0.0f, -1.0f );
VectorCopy( ent->origin, origin );
VectorSet( vecSrc, origin[0], origin[1], origin[2] - lightDir[2] * 8.0f );
light.r = light.g = light.b = light.a = 0;
if(( mv->skycolor[0] + mv->skycolor[1] + mv->skycolor[2] ) != 0 )
{
msurface_t *psurf = NULL;
pmtrace_t trace;
vec3_t skyvec;
if( FBitSet( gp_host->features, ENGINE_WRITE_LARGE_COORD ))
VectorScale( mv->skyvec, 65536.0f, skyvec );
else
VectorScale( mv->skyvec, 8192.0f, skyvec );
VectorSubtract( origin, skyvec, vecEnd );
trace = gEngfuncs.CL_TraceLine( vecSrc, vecEnd, PM_STUDIO_IGNORE );
if( trace.ent > 0 ) psurf = gEngfuncs.EV_TraceSurface( trace.ent, vecSrc, vecEnd );
else psurf = gEngfuncs.EV_TraceSurface( 0, vecSrc, vecEnd );
if( psurf && FBitSet( psurf->flags, SURF_DRAWSKY ))
{
VectorCopy( mv->skyvec, lightDir );
light.r = mv->skycolor[0];
light.g = mv->skycolor[1];
light.b = mv->skycolor[2];
}
}
if(( light.r + light.g + light.b ) == 0 )
{
colorVec gcolor;
float grad[4];
VectorScale( lightDir, 2048.0f, vecEnd );
VectorAdd( vecEnd, vecSrc, vecEnd );
light = R_LightVec( vecSrc, vecEnd, g_alias.lightspot, g_alias.lightvec );
if( VectorIsNull( g_alias.lightvec ))
{
vecSrc[0] -= 16.0f;
vecSrc[1] -= 16.0f;
vecEnd[0] -= 16.0f;
vecEnd[1] -= 16.0f;
gcolor = R_LightVec( vecSrc, vecEnd, NULL, NULL );
grad[0] = ( gcolor.r + gcolor.g + gcolor.b ) / 768.0f;
vecSrc[0] += 32.0f;
vecEnd[0] += 32.0f;
gcolor = R_LightVec( vecSrc, vecEnd, NULL, NULL );
grad[1] = ( gcolor.r + gcolor.g + gcolor.b ) / 768.0f;
vecSrc[1] += 32.0f;
vecEnd[1] += 32.0f;
gcolor = R_LightVec( vecSrc, vecEnd, NULL, NULL );
grad[2] = ( gcolor.r + gcolor.g + gcolor.b ) / 768.0f;
vecSrc[0] -= 32.0f;
vecEnd[0] -= 32.0f;
gcolor = R_LightVec( vecSrc, vecEnd, NULL, NULL );
grad[3] = ( gcolor.r + gcolor.g + gcolor.b ) / 768.0f;
lightDir[0] = grad[0] - grad[1] - grad[2] + grad[3];
lightDir[1] = grad[1] + grad[0] - grad[2] - grad[3];
VectorNormalize( lightDir );
}
else
{
VectorCopy( g_alias.lightvec, lightDir );
}
}
VectorSet( finalLight, light.r, light.g, light.b );
ent->cvFloorColor = light;
total = Q_max( Q_max( light.r, light.g ), light.b );
if( total == 0.0f ) total = 1.0f;
// scale lightdir by light intentsity
VectorScale( lightDir, total, lightDir );
for( lnum = 0; lnum < MAX_DLIGHTS; lnum++ )
{
const dlight_t *dl = &gp_dlights[lnum];
if( dl->die < g_alias.time || !r_dynamic->value )
continue;
VectorSubtract( origin, dl->origin, dist );
radius = VectorLength( dist );
add = dl->radius - radius;
if( add > 0.0f )
{
total += add;
if( radius > 1.0f )
VectorScale( dist, ( add / radius ), dist );
else VectorScale( dist, add, dist );
VectorAdd( lightDir, dist, lightDir );
finalLight[0] += dl->color.r * ( add / 256.0f );
finalLight[1] += dl->color.g * ( add / 256.0f );
finalLight[2] += dl->color.b * ( add / 256.0f );
}
}
VectorScale( lightDir, 0.9f, lightDir );
plight->shadelight = VectorLength( lightDir );
plight->ambientlight = total - plight->shadelight;
total = Q_max( Q_max( finalLight[0], finalLight[1] ), finalLight[2] );
if( total > 0.0f )
{
plight->color[0] = finalLight[0] * ( 1.0f / total );
plight->color[1] = finalLight[1] * ( 1.0f / total );
plight->color[2] = finalLight[2] * ( 1.0f / total );
}
else VectorSet( plight->color, 1.0f, 1.0f, 1.0f );
if( plight->ambientlight > 128 )
plight->ambientlight = 128;
if( plight->ambientlight + plight->shadelight > 255 )
plight->shadelight = 255 - plight->ambientlight;
VectorNormalize2( lightDir, plight->plightvec );
}
/* /*
=============== ===============
R_AliasSetupLighting R_AliasSetupLighting
@@ -1188,7 +1013,7 @@ void R_DrawAliasModel( cl_entity_t *e )
// get lighting information // get lighting information
// //
lighting.plightvec = dir; lighting.plightvec = dir;
R_AliasDynamicLight( e, &lighting ); R_EntityDynamicLight( e, &lighting, FBitSet( RI.rvp.flags, RF_DRAW_WORLD ), g_alias.time, g_alias.lightspot, g_alias.lightvec );
r_stats.c_alias_polys += m_pAliasHeader->numtris; r_stats.c_alias_polys += m_pAliasHeader->numtris;
r_stats.c_alias_models_drawn++; r_stats.c_alias_models_drawn++;

View File

@@ -223,7 +223,6 @@ typedef struct
model_t *worldmodel; model_t *worldmodel;
world_static_t *world; world_static_t *world;
cl_entity_t *entities; cl_entity_t *entities;
movevars_t *movevars;
color24 *palette; color24 *palette;
cl_entity_t *viewent; cl_entity_t *viewent;
dlight_t *elights; dlight_t *elights;

View File

@@ -1260,7 +1260,6 @@ qboolean R_Init( void )
// see R_ProcessEntData for tr.entities initialization // see R_ProcessEntData for tr.entities initialization
tr.world = (struct world_static_s *)ENGINE_GET_PARM( PARM_GET_WORLD_PTR ); tr.world = (struct world_static_s *)ENGINE_GET_PARM( PARM_GET_WORLD_PTR );
tr.movevars = (movevars_t *)ENGINE_GET_PARM( PARM_GET_MOVEVARS_PTR );
tr.palette = (color24 *)ENGINE_GET_PARM( PARM_GET_PALETTE_PTR ); tr.palette = (color24 *)ENGINE_GET_PARM( PARM_GET_PALETTE_PTR );
tr.viewent = (cl_entity_t *)ENGINE_GET_PARM( PARM_GET_VIEWENT_PTR ); tr.viewent = (cl_entity_t *)ENGINE_GET_PARM( PARM_GET_VIEWENT_PTR );
tr.texgammatable = (byte *)ENGINE_GET_PARM( PARM_GET_TEXGAMMATABLE_PTR ); tr.texgammatable = (byte *)ENGINE_GET_PARM( PARM_GET_TEXGAMMATABLE_PTR );

View File

@@ -341,7 +341,7 @@ R_GetFarClip
static float R_GetFarClip( void ) static float R_GetFarClip( void )
{ {
if( WORLDMODEL && FBitSet( RI.rvp.flags, RF_DRAW_WORLD )) if( WORLDMODEL && FBitSet( RI.rvp.flags, RF_DRAW_WORLD ))
return tr.movevars->zmax * 1.73f; return gp_movevars->zmax * 1.73f;
return 2048.0f; return 2048.0f;
} }
@@ -678,7 +678,7 @@ static void R_CheckFog( void )
// quake global fog // quake global fog
if( FBitSet( gp_host->features, ENGINE_QUAKE_COMPATIBLE )) if( FBitSet( gp_host->features, ENGINE_QUAKE_COMPATIBLE ))
{ {
if( !tr.movevars->fog_settings ) if( !gp_movevars->fog_settings )
{ {
if( pglIsEnabled( GL_FOG )) if( pglIsEnabled( GL_FOG ))
pglDisable( GL_FOG ); pglDisable( GL_FOG );
@@ -687,10 +687,10 @@ static void R_CheckFog( void )
} }
// quake-style global fog // quake-style global fog
RI.fogColor[0] = ((tr.movevars->fog_settings & 0xFF000000) >> 24) / 255.0f; RI.fogColor[0] = ((gp_movevars->fog_settings & 0xFF000000) >> 24) / 255.0f;
RI.fogColor[1] = ((tr.movevars->fog_settings & 0xFF0000) >> 16) / 255.0f; RI.fogColor[1] = ((gp_movevars->fog_settings & 0xFF0000) >> 16) / 255.0f;
RI.fogColor[2] = ((tr.movevars->fog_settings & 0xFF00) >> 8) / 255.0f; RI.fogColor[2] = ((gp_movevars->fog_settings & 0xFF00) >> 8) / 255.0f;
RI.fogDensity = ((tr.movevars->fog_settings & 0xFF) / 255.0f) * 0.01f; RI.fogDensity = ((gp_movevars->fog_settings & 0xFF) / 255.0f) * 0.01f;
RI.fogStart = RI.fogEnd = 0.0f; RI.fogStart = RI.fogEnd = 0.0f;
RI.fogColor[3] = 1.0f; RI.fogColor[3] = 1.0f;
RI.fogCustom = false; RI.fogCustom = false;

View File

@@ -187,7 +187,7 @@ void CL_DrawTracers( double frametime, particle_t *cl_active_tracers )
pglDisable( GL_ALPHA_TEST ); pglDisable( GL_ALPHA_TEST );
pglDepthMask( GL_FALSE ); pglDepthMask( GL_FALSE );
gravity = frametime * tr.movevars->gravity; gravity = frametime * gp_movevars->gravity;
scale = 1.0 - (frametime * 0.9); scale = 1.0 - (frametime * 0.9);
if( scale < 0.0f ) scale = 0.0f; if( scale < 0.0f ) scale = 0.0f;

View File

@@ -1525,7 +1525,7 @@ static void R_DrawTextureChains( void )
if( !s || ( i == tr.skytexturenum )) if( !s || ( i == tr.skytexturenum ))
continue; continue;
if(( s->flags & SURF_DRAWTURB ) && tr.movevars->wateralpha < 1.0f ) if(( s->flags & SURF_DRAWTURB ) && gp_movevars->wateralpha < 1.0f )
{ {
R_AddToSeparatePass( &draw_wateralpha, i ); R_AddToSeparatePass( &draw_wateralpha, i );
continue; // draw translucent water later continue; // draw translucent water later
@@ -1629,7 +1629,7 @@ void R_DrawWaterSurfaces( void )
pglDisable( GL_ALPHA_TEST ); pglDisable( GL_ALPHA_TEST );
pglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); pglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
pglColor4f( 1.0f, 1.0f, 1.0f, tr.movevars->wateralpha ); pglColor4f( 1.0f, 1.0f, 1.0f, gp_movevars->wateralpha );
for( i = draw_wateralpha.first; i <= draw_wateralpha.last; i++ ) for( i = draw_wateralpha.first; i <= draw_wateralpha.last; i++ )
{ {

View File

@@ -1253,192 +1253,6 @@ static int R_StudioCheckBBox( void )
return R_StudioComputeBBox( NULL ); return R_StudioComputeBBox( NULL );
} }
/*
===============
R_StudioDynamicLight
===============
*/
static void R_StudioDynamicLight( cl_entity_t *ent, alight_t *plight )
{
movevars_t *mv = tr.movevars;
vec3_t lightDir, vecSrc, vecEnd;
vec3_t origin, dist, finalLight;
float add, radius, total;
colorVec light;
uint lnum;
dlight_t *dl;
if( !plight || !ent || !ent->model )
return;
if( !FBitSet( RI.rvp.flags, RF_DRAW_WORLD ) || r_fullbright->value || FBitSet( ent->curstate.effects, EF_FULLBRIGHT ))
{
plight->shadelight = 0;
plight->ambientlight = 192;
VectorSet( plight->plightvec, 0.0f, 0.0f, -1.0f );
VectorSet( plight->color, 1.0f, 1.0f, 1.0f );
return;
}
// determine plane to get lightvalues from: ceil or floor
if( FBitSet( ent->curstate.effects, EF_INVLIGHT ))
VectorSet( lightDir, 0.0f, 0.0f, 1.0f );
else VectorSet( lightDir, 0.0f, 0.0f, -1.0f );
VectorCopy( ent->origin, origin );
VectorSet( vecSrc, origin[0], origin[1], origin[2] - lightDir[2] * 8.0f );
light.r = light.g = light.b = light.a = 0;
if(( mv->skycolor[0] + mv->skycolor[1] + mv->skycolor[2] ) != 0 )
{
msurface_t *psurf = NULL;
pmtrace_t trace;
vec3_t skyvec;
if( FBitSet( gp_host->features, ENGINE_WRITE_LARGE_COORD ))
VectorScale( mv->skyvec, 65536.0f, skyvec );
else
VectorScale( mv->skyvec, 8192.0f, skyvec );
VectorSubtract( origin, skyvec, vecEnd );
trace = gEngfuncs.CL_TraceLine( vecSrc, vecEnd, PM_WORLD_ONLY );
if( trace.ent > 0 ) psurf = gEngfuncs.EV_TraceSurface( trace.ent, vecSrc, vecEnd );
else psurf = gEngfuncs.EV_TraceSurface( 0, vecSrc, vecEnd );
if( FBitSet( ent->model->flags, STUDIO_FORCE_SKYLIGHT ) || ( psurf && FBitSet( psurf->flags, SURF_DRAWSKY )))
{
VectorCopy( mv->skyvec, lightDir );
light.r = mv->skycolor[0];
light.g = mv->skycolor[1];
light.b = mv->skycolor[2];
}
}
if(( light.r + light.g + light.b ) == 0 )
{
colorVec gcolor;
float grad[4];
VectorScale( lightDir, 2048.0f, vecEnd );
VectorAdd( vecEnd, vecSrc, vecEnd );
light = R_LightVec( vecSrc, vecEnd, g_studio.lightspot, g_studio.lightvec );
if( VectorIsNull( g_studio.lightvec ))
{
vecSrc[0] -= 16.0f;
vecSrc[1] -= 16.0f;
vecEnd[0] -= 16.0f;
vecEnd[1] -= 16.0f;
gcolor = R_LightVec( vecSrc, vecEnd, NULL, NULL );
grad[0] = ( gcolor.r + gcolor.g + gcolor.b ) / 768.0f;
vecSrc[0] += 32.0f;
vecEnd[0] += 32.0f;
gcolor = R_LightVec( vecSrc, vecEnd, NULL, NULL );
grad[1] = ( gcolor.r + gcolor.g + gcolor.b ) / 768.0f;
vecSrc[1] += 32.0f;
vecEnd[1] += 32.0f;
gcolor = R_LightVec( vecSrc, vecEnd, NULL, NULL );
grad[2] = ( gcolor.r + gcolor.g + gcolor.b ) / 768.0f;
vecSrc[0] -= 32.0f;
vecEnd[0] -= 32.0f;
gcolor = R_LightVec( vecSrc, vecEnd, NULL, NULL );
grad[3] = ( gcolor.r + gcolor.g + gcolor.b ) / 768.0f;
lightDir[0] = grad[0] - grad[1] - grad[2] + grad[3];
lightDir[1] = grad[1] + grad[0] - grad[2] - grad[3];
VectorNormalize( lightDir );
}
else
{
VectorCopy( g_studio.lightvec, lightDir );
}
}
if( ent->curstate.renderfx == kRenderFxLightMultiplier && ent->curstate.iuser4 != 10 )
{
light.r *= ent->curstate.iuser4 / 10.0f;
light.g *= ent->curstate.iuser4 / 10.0f;
light.b *= ent->curstate.iuser4 / 10.0f;
}
VectorSet( finalLight, light.r, light.g, light.b );
ent->cvFloorColor = light;
total = Q_max( Q_max( light.r, light.g ), light.b );
if( total == 0.0f ) total = 1.0f;
// scale lightdir by light intentsity
VectorScale( lightDir, total, lightDir );
for( lnum = 0; lnum < MAX_DLIGHTS; lnum++ )
{
dl = &gp_dlights[lnum];
if( dl->die < g_studio.time || !r_dynamic->value )
continue;
VectorSubtract( ent->origin, dl->origin, dist );
radius = VectorLength( dist );
add = (dl->radius - radius);
if( add > 0.0f )
{
total += add;
if( radius > 1.0f )
VectorScale( dist, ( add / radius ), dist );
else VectorScale( dist, add, dist );
VectorAdd( lightDir, dist, lightDir );
finalLight[0] += dl->color.r * ( add / 256.0f );
finalLight[1] += dl->color.g * ( add / 256.0f );
finalLight[2] += dl->color.b * ( add / 256.0f );
}
}
if( FBitSet( ent->model->flags, STUDIO_AMBIENT_LIGHT ))
add = 0.6f;
else add = bound( 0.75f, v_direct->value, 1.0f );
VectorScale( lightDir, add, lightDir );
plight->shadelight = VectorLength( lightDir );
plight->ambientlight = total - plight->shadelight;
total = Q_max( Q_max( finalLight[0], finalLight[1] ), finalLight[2] );
if( total > 0.0f )
{
plight->color[0] = finalLight[0] * ( 1.0f / total );
plight->color[1] = finalLight[1] * ( 1.0f / total );
plight->color[2] = finalLight[2] * ( 1.0f / total );
}
else VectorSet( plight->color, 1.0f, 1.0f, 1.0f );
if( plight->ambientlight > 128 )
plight->ambientlight = 128;
if( plight->ambientlight + plight->shadelight > 255 )
plight->shadelight = 255 - plight->ambientlight;
VectorNormalize2( lightDir, plight->plightvec );
}
/* /*
=============== ===============
pfnStudioEntityLight pfnStudioEntityLight
@@ -3340,7 +3154,7 @@ static int R_StudioDrawPlayer( int flags, entity_state_t *pplayer )
RI.currententity->curstate.body = 1; // force helmet RI.currententity->curstate.body = 1; // force helmet
lighting.plightvec = dir; lighting.plightvec = dir;
R_StudioDynamicLight( RI.currententity, &lighting ); R_EntityDynamicLight( RI.currententity, &lighting, FBitSet( RI.rvp.flags, RF_DRAW_WORLD ), g_studio.time, g_studio.lightspot, g_studio.lightvec );
R_StudioEntityLight( &lighting ); R_StudioEntityLight( &lighting );
@@ -3460,7 +3274,7 @@ static int R_StudioDrawModel( int flags )
if( flags & STUDIO_RENDER ) if( flags & STUDIO_RENDER )
{ {
lighting.plightvec = dir; lighting.plightvec = dir;
R_StudioDynamicLight( RI.currententity, &lighting ); R_EntityDynamicLight( RI.currententity, &lighting, FBitSet( RI.rvp.flags, RF_DRAW_WORLD ), g_studio.time, g_studio.lightspot, g_studio.lightvec );
R_StudioEntityLight( &lighting ); R_StudioEntityLight( &lighting );
@@ -3799,6 +3613,11 @@ void Mod_StudioUnloadTextures( void *data )
} }
} }
static void pfnStudioDynamicLight( cl_entity_t *ent, alight_t *plight )
{
R_EntityDynamicLight( ent, plight, FBitSet( RI.rvp.flags, RF_DRAW_WORLD ), g_studio.time, g_studio.lightspot, g_studio.lightvec );
}
qboolean R_StudioFillAPI( engine_studio_api_t *api, r_studio_interface_t *pDefaultDraw ) qboolean R_StudioFillAPI( engine_studio_api_t *api, r_studio_interface_t *pDefaultDraw )
{ {
cl_righthand = gEngfuncs.pfnGetCvarPointer( "cl_righthand" ); cl_righthand = gEngfuncs.pfnGetCvarPointer( "cl_righthand" );
@@ -3814,7 +3633,7 @@ qboolean R_StudioFillAPI( engine_studio_api_t *api, r_studio_interface_t *pDefau
api->StudioGetRotationMatrix = pfnStudioGetRotationMatrix; api->StudioGetRotationMatrix = pfnStudioGetRotationMatrix;
api->StudioSetupModel = R_StudioSetupModel; api->StudioSetupModel = R_StudioSetupModel;
api->StudioCheckBBox = R_StudioCheckBBox; api->StudioCheckBBox = R_StudioCheckBBox;
api->StudioDynamicLight = R_StudioDynamicLight; api->StudioDynamicLight = pfnStudioDynamicLight;
api->StudioEntityLight = R_StudioEntityLight; api->StudioEntityLight = R_StudioEntityLight;
api->StudioSetupLighting = R_StudioSetupLighting; api->StudioSetupLighting = R_StudioSetupLighting;
api->StudioDrawPoints = R_StudioDrawPoints; api->StudioDrawPoints = R_StudioDrawPoints;

View File

@@ -245,7 +245,6 @@ typedef struct
// get from engine // get from engine
cl_entity_t *entities; cl_entity_t *entities;
movevars_t *movevars;
color24 *palette; color24 *palette;
cl_entity_t *viewent; cl_entity_t *viewent;
lightstyle_t *lightstyles; lightstyle_t *lightstyles;

View File

@@ -380,7 +380,7 @@ R_GetFarClip
static float R_GetFarClip( void ) static float R_GetFarClip( void )
{ {
if( WORLDMODEL && FBitSet( RI.rvp.flags, RF_DRAW_WORLD )) if( WORLDMODEL && FBitSet( RI.rvp.flags, RF_DRAW_WORLD ))
return tr.movevars->zmax * 1.73f; return gp_movevars->zmax * 1.73f;
return 2048.0f; return 2048.0f;
} }
@@ -1381,7 +1381,6 @@ qboolean GAME_EXPORT R_Init( void )
} }
// see R_ProcessEntData for tr.entities initialization // see R_ProcessEntData for tr.entities initialization
tr.movevars = (movevars_t *)ENGINE_GET_PARM( PARM_GET_MOVEVARS_PTR );
tr.palette = (color24 *)ENGINE_GET_PARM( PARM_GET_PALETTE_PTR ); tr.palette = (color24 *)ENGINE_GET_PARM( PARM_GET_PALETTE_PTR );
tr.viewent = (cl_entity_t *)ENGINE_GET_PARM( PARM_GET_VIEWENT_PTR ); tr.viewent = (cl_entity_t *)ENGINE_GET_PARM( PARM_GET_VIEWENT_PTR );
tr.texgammatable = (byte *)ENGINE_GET_PARM( PARM_GET_TEXGAMMATABLE_PTR ); tr.texgammatable = (byte *)ENGINE_GET_PARM( PARM_GET_TEXGAMMATABLE_PTR );

View File

@@ -171,7 +171,7 @@ void GAME_EXPORT CL_DrawTracers( double frametime, particle_t *cl_active_tracers
// pglDisable( GL_ALPHA_TEST ); // pglDisable( GL_ALPHA_TEST );
// pglDepthMask( GL_FALSE ); // pglDepthMask( GL_FALSE );
gravity = frametime * tr.movevars->gravity; gravity = frametime * gp_movevars->gravity;
scale = 1.0 - ( frametime * 0.9 ); scale = 1.0 - ( frametime * 0.9 );
if( scale < 0.0f ) if( scale < 0.0f )
scale = 0.0f; scale = 0.0f;

View File

@@ -1275,197 +1275,6 @@ static int R_StudioCheckBBox( void )
return R_StudioComputeBBox( NULL ); return R_StudioComputeBBox( NULL );
} }
/*
===============
R_StudioDynamicLight
===============
*/
static void R_StudioDynamicLight( cl_entity_t *ent, alight_t *plight )
{
movevars_t *mv = tr.movevars;
vec3_t lightDir, vecSrc, vecEnd;
vec3_t origin, dist, finalLight;
float add, radius, total;
colorVec light;
uint lnum;
dlight_t *dl;
if( !plight || !ent || !ent->model )
return;
if( !FBitSet( RI.rvp.flags, RF_DRAW_WORLD ) || r_fullbright->value || FBitSet( ent->curstate.effects, EF_FULLBRIGHT ))
{
plight->shadelight = 0;
plight->ambientlight = 192;
VectorSet( plight->plightvec, 0.0f, 0.0f, -1.0f );
VectorSet( plight->color, 1.0f, 1.0f, 1.0f );
return;
}
// determine plane to get lightvalues from: ceil or floor
if( FBitSet( ent->curstate.effects, EF_INVLIGHT ))
VectorSet( lightDir, 0.0f, 0.0f, 1.0f );
else
VectorSet( lightDir, 0.0f, 0.0f, -1.0f );
VectorCopy( ent->origin, origin );
VectorSet( vecSrc, origin[0], origin[1], origin[2] - lightDir[2] * 8.0f );
light.r = light.g = light.b = light.a = 0;
if(( mv->skycolor[0] + mv->skycolor[1] + mv->skycolor[2] ) != 0 )
{
msurface_t *psurf = NULL;
pmtrace_t trace;
vec3_t skyvec;
if( FBitSet( gp_host->features, ENGINE_WRITE_LARGE_COORD ))
VectorScale( mv->skyvec, 65536.0f, skyvec );
else
VectorScale( mv->skyvec, 8192.0f, skyvec );
VectorSubtract( origin, skyvec, vecEnd );
trace = gEngfuncs.CL_TraceLine( vecSrc, vecEnd, PM_WORLD_ONLY );
if( trace.ent > 0 ) psurf = gEngfuncs.EV_TraceSurface( trace.ent, vecSrc, vecEnd );
else psurf = gEngfuncs.EV_TraceSurface( 0, vecSrc, vecEnd );
if( FBitSet( ent->model->flags, STUDIO_FORCE_SKYLIGHT ) || ( psurf && FBitSet( psurf->flags, SURF_DRAWSKY )))
{
VectorCopy( mv->skyvec, lightDir );
light.r = mv->skycolor[0];
light.g = mv->skycolor[1];
light.b = mv->skycolor[2];
}
}
if(( light.r + light.g + light.b ) == 0 )
{
colorVec gcolor;
float grad[4];
VectorScale( lightDir, 2048.0f, vecEnd );
VectorAdd( vecEnd, vecSrc, vecEnd );
light = R_LightVec( vecSrc, vecEnd, g_studio.lightspot, g_studio.lightvec );
if( VectorIsNull( g_studio.lightvec ))
{
vecSrc[0] -= 16.0f;
vecSrc[1] -= 16.0f;
vecEnd[0] -= 16.0f;
vecEnd[1] -= 16.0f;
gcolor = R_LightVec( vecSrc, vecEnd, NULL, NULL );
grad[0] = ( gcolor.r + gcolor.g + gcolor.b ) / 768.0f;
vecSrc[0] += 32.0f;
vecEnd[0] += 32.0f;
gcolor = R_LightVec( vecSrc, vecEnd, NULL, NULL );
grad[1] = ( gcolor.r + gcolor.g + gcolor.b ) / 768.0f;
vecSrc[1] += 32.0f;
vecEnd[1] += 32.0f;
gcolor = R_LightVec( vecSrc, vecEnd, NULL, NULL );
grad[2] = ( gcolor.r + gcolor.g + gcolor.b ) / 768.0f;
vecSrc[0] -= 32.0f;
vecEnd[0] -= 32.0f;
gcolor = R_LightVec( vecSrc, vecEnd, NULL, NULL );
grad[3] = ( gcolor.r + gcolor.g + gcolor.b ) / 768.0f;
lightDir[0] = grad[0] - grad[1] - grad[2] + grad[3];
lightDir[1] = grad[1] + grad[0] - grad[2] - grad[3];
VectorNormalize( lightDir );
}
else
{
VectorCopy( g_studio.lightvec, lightDir );
}
}
if( ent->curstate.renderfx == kRenderFxLightMultiplier && ent->curstate.iuser4 != 10 )
{
light.r *= ent->curstate.iuser4 / 10.0f;
light.g *= ent->curstate.iuser4 / 10.0f;
light.b *= ent->curstate.iuser4 / 10.0f;
}
VectorSet( finalLight, light.r, light.g, light.b );
ent->cvFloorColor = light;
total = Q_max( Q_max( light.r, light.g ), light.b );
if( total == 0.0f )
total = 1.0f;
// scale lightdir by light intentsity
VectorScale( lightDir, total, lightDir );
for( lnum = 0; lnum < MAX_DLIGHTS; lnum++ )
{
dl = &gp_dlights[lnum];
if( dl->die < g_studio.time || !r_dynamic->value )
continue;
VectorSubtract( ent->origin, dl->origin, dist );
radius = VectorLength( dist );
add = ( dl->radius - radius );
if( add > 0.0f )
{
total += add;
if( radius > 1.0f )
VectorScale( dist, ( add / radius ), dist );
else
VectorScale( dist, add, dist );
VectorAdd( lightDir, dist, lightDir );
finalLight[0] += dl->color.r * ( add / 256.0f );
finalLight[1] += dl->color.g * ( add / 256.0f );
finalLight[2] += dl->color.b * ( add / 256.0f );
}
}
if( FBitSet( ent->model->flags, STUDIO_AMBIENT_LIGHT ))
add = 0.6f;
else
add = bound( 0.75f, v_direct->value, 1.0f );
VectorScale( lightDir, add, lightDir );
plight->shadelight = VectorLength( lightDir );
plight->ambientlight = total - plight->shadelight;
total = Q_max( Q_max( finalLight[0], finalLight[1] ), finalLight[2] );
if( total > 0.0f )
{
plight->color[0] = finalLight[0] * ( 1.0f / total );
plight->color[1] = finalLight[1] * ( 1.0f / total );
plight->color[2] = finalLight[2] * ( 1.0f / total );
}
else
VectorSet( plight->color, 1.0f, 1.0f, 1.0f );
if( plight->ambientlight > 128 )
plight->ambientlight = 128;
if( plight->ambientlight + plight->shadelight > 255 )
plight->shadelight = 255 - plight->ambientlight;
VectorNormalize2( lightDir, plight->plightvec );
}
/* /*
=============== ===============
pfnStudioEntityLight pfnStudioEntityLight
@@ -2866,7 +2675,7 @@ static int R_StudioDrawPlayer( int flags, entity_state_t *pplayer )
RI.currententity->curstate.body = 1; // force helmet RI.currententity->curstate.body = 1; // force helmet
lighting.plightvec = dir; lighting.plightvec = dir;
R_StudioDynamicLight( RI.currententity, &lighting ); R_EntityDynamicLight( RI.currententity, &lighting, FBitSet( RI.rvp.flags, RF_DRAW_WORLD ), g_studio.time, g_studio.lightspot, g_studio.lightvec );
R_StudioEntityLight( &lighting ); R_StudioEntityLight( &lighting );
@@ -2991,7 +2800,7 @@ static int R_StudioDrawModel( int flags )
if( flags & STUDIO_RENDER ) if( flags & STUDIO_RENDER )
{ {
lighting.plightvec = dir; lighting.plightvec = dir;
R_StudioDynamicLight( RI.currententity, &lighting ); R_EntityDynamicLight( RI.currententity, &lighting, FBitSet( RI.rvp.flags, RF_DRAW_WORLD ), g_studio.time, g_studio.lightspot, g_studio.lightvec );
R_StudioEntityLight( &lighting ); R_StudioEntityLight( &lighting );
@@ -3331,6 +3140,11 @@ void Mod_StudioUnloadTextures( void *data )
} }
} }
static void pfnStudioDynamicLight( cl_entity_t *ent, alight_t *plight )
{
R_EntityDynamicLight( ent, plight, FBitSet( RI.rvp.flags, RF_DRAW_WORLD ), g_studio.time, g_studio.lightspot, g_studio.lightvec );
}
qboolean R_StudioFillAPI( engine_studio_api_t *api, r_studio_interface_t *pDefaultDraw ) qboolean R_StudioFillAPI( engine_studio_api_t *api, r_studio_interface_t *pDefaultDraw )
{ {
cl_righthand = gEngfuncs.pfnGetCvarPointer( "cl_righthand" ); cl_righthand = gEngfuncs.pfnGetCvarPointer( "cl_righthand" );
@@ -3346,7 +3160,7 @@ qboolean R_StudioFillAPI( engine_studio_api_t *api, r_studio_interface_t *pDefau
api->StudioGetRotationMatrix = pfnStudioGetRotationMatrix; api->StudioGetRotationMatrix = pfnStudioGetRotationMatrix;
api->StudioSetupModel = R_StudioSetupModel; api->StudioSetupModel = R_StudioSetupModel;
api->StudioCheckBBox = R_StudioCheckBBox; api->StudioCheckBBox = R_StudioCheckBBox;
api->StudioDynamicLight = R_StudioDynamicLight; api->StudioDynamicLight = pfnStudioDynamicLight;
api->StudioEntityLight = R_StudioEntityLight; api->StudioEntityLight = R_StudioEntityLight;
api->StudioSetupLighting = R_StudioSetupLighting; api->StudioSetupLighting = R_StudioSetupLighting;
api->StudioDrawPoints = R_StudioDrawPoints; api->StudioDrawPoints = R_StudioDrawPoints;