ref: move R_PushDlights and R_MarkLights to ref_common

This commit is contained in:
Alibek Omarov
2026-04-12 22:38:43 +05:00
parent 8cd40db261
commit 2e579d0dd3
16 changed files with 218 additions and 221 deletions

View File

@@ -52,6 +52,13 @@ void *_Mem_Realloc( poolhandle_t poolptr, void *memptr, size_t size, qboolean cl
#define Mem_FreePool( pool ) gEngfuncs._Mem_FreePool( pool, __FILE__, __LINE__ )
#define Mem_EmptyPool( pool ) gEngfuncs._Mem_EmptyPool( pool, __FILE__, __LINE__ )
extern dlight_t *gp_dlights;
//
// ref_common cvars
//
extern convar_t r_dlight_virtual_radius;
//
// ref_math.c
//
@@ -67,5 +74,7 @@ void Matrix4x4_ToArrayFloatGL( const matrix4x4 in, float out[16] );
// ref_light.c
//
void CL_RunLightStyles_( lightstyle_t *ls, int *lightstylevalue );
void R_MarkLights( const dlight_t *light, int bit, const mnode_t *node, model_t *model, int dlightframecount );
int R_PushDlights( model_t *model, int framecount );
#endif // REF_COMMON_H

View File

@@ -23,6 +23,7 @@ ref_globals_t *gpGlobals;
ref_client_t *gp_cl;
ref_host_t *gp_host;
uint16_t rtable[MOD_FRAMES][MOD_FRAMES];
dlight_t *gp_dlights;
void _Mem_Free( void *data, const char *filename, int fileline )
{
@@ -67,8 +68,11 @@ 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_host = (ref_host_t *)ENGINE_GET_PARM( PARM_GET_HOST_PTR );
gp_dlights = (dlight_t *)ENGINE_GET_PARM( PARM_GET_DLIGHTS_PTR );
RETRIEVE_ENGINE_SHARED_CVAR_LIST();
gEngfuncs.Cvar_RegisterVariable( &r_dlight_virtual_radius );
return REF_API_VERSION;
}

188
ref/common/ref_light.c Normal file
View File

@@ -0,0 +1,188 @@
/*
ref_light.c - shared light code
Copyright (C) 2010 Uncle Mike
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 3 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.
*/
#include "ref_common.h"
#include "xash3d_mathlib.h"
#include "pm_local.h"
CVAR_DEFINE_AUTO( r_dlight_virtual_radius, "3", FCVAR_GLCONFIG, "increase dlight radius virtually by this amount" );
/*
==================
CL_RunLightStyles_
==================
*/
void CL_RunLightStyles_( lightstyle_t *ls, int *lightstylevalue )
{
const model_t *world = gp_cl->models[1];
int i;
float frametime = gp_cl->time - gp_cl->oldtime;
if( !world )
return;
if( r_fullbright->value || !world->lightdata )
{
for( i = 0; i < MAX_LIGHTSTYLES; i++ )
lightstylevalue[i] = 256 * 256;
return;
}
// light animations
// 'm' is normal light, 'a' is no light, 'z' is double bright
for( i = 0; i < MAX_LIGHTSTYLES; i++ )
{
int k, flight, clight;
float l, lerpfrac, backlerp;
if( !gp_cl->paused && frametime <= 0.1f )
ls[i].time += frametime; // evaluate local time
if( !ls[i].length )
{
lightstylevalue[i] = 256;
continue;
}
else if( ls[i].length == 1 )
{
// single length style so don't bother interpolating
lightstylevalue[i] = ls[i].map[0] * 22;
continue;
}
flight = (int)Q_floor( ls[i].time * 10 );
if( !ls[i].interp || !cl_lightstyle_lerping->value )
{
lightstylevalue[i] = ls[i].map[flight % ls[i].length] * 22;
continue;
}
clight = (int)Q_ceil( ls[i].time * 10 );
lerpfrac = ( ls[i].time * 10 ) - flight;
backlerp = 1.0f - lerpfrac;
// interpolate animating light
// frame just gone
k = ls[i].map[flight % ls[i].length];
l = (float)( k * 22.0f ) * backlerp;
// upcoming frame
k = ls[i].map[clight % ls[i].length];
l += (float)( k * 22.0f ) * lerpfrac;
lightstylevalue[i] = (int)l;
}
}
/*
=============
R_MarkLights
=============
*/
void R_MarkLights( const dlight_t *light, int bit, const mnode_t *node, model_t *model, int dlightframecount )
{
const float virtual_radius = light->radius * Q_max( 1.0f, r_dlight_virtual_radius.value );
const float maxdist = light->radius * light->radius;
start:
if( !node || node->contents < 0 )
return;
float dist = PlaneDiff( light->origin, node->plane );
if( dist > virtual_radius )
{
node = node_child( node, 0, model );
goto start;
}
if( dist < -virtual_radius )
{
node = node_child( node, 1, model );
goto start;
}
const float dist_sq = dist * dist;
// mark the polygons
int firstsurface = node_firstsurface( node, model );
int numsurfaces = node_numsurfaces( node, model );
for( int i = 0; i < numsurfaces && dist_sq < maxdist; i++ )
{
vec3_t impact;
float s, t, l;
msurface_t *surf = &model->surfaces[firstsurface + i];
const mextrasurf_t *info = surf->info;
if( surf->plane->type < 3 )
{
VectorCopy( light->origin, impact );
impact[surf->plane->type] -= dist;
}
else VectorMA( light->origin, -dist, surf->plane->normal, impact );
// a1ba: the fix was taken from JoeQuake, which traces back to FitzQuake,
// which attributes it to LadyHavoc (Darkplaces author)
// clamp center of light to corner and check brightness
l = DotProduct( impact, info->lmvecs[0] ) + info->lmvecs[0][3] - info->lightmapmins[0];
s = l + 0.5;
s = bound( 0, s, info->lightextents[0] );
s = l - s;
l = DotProduct( impact, info->lmvecs[1] ) + info->lmvecs[1][3] - info->lightmapmins[1];
t = l + 0.5;
t = bound( 0, t, info->lightextents[1] );
t = l - t;
if( s * s + t * t + dist_sq >= maxdist )
continue;
if( surf->dlightframe != dlightframecount )
{
surf->dlightbits = bit;
surf->dlightframe = dlightframecount;
}
else surf->dlightbits |= bit;
}
R_MarkLights( light, bit, node_child( node, 0, model ), model, dlightframecount );
node = node_child( node, 1, model );
goto start;
}
/*
=============
R_PushDlights
=============
*/
int R_PushDlights( model_t *model, int framecount )
{
if( !model )
return framecount;
for( int i = 0; i < MAX_DLIGHTS; i++ )
{
const dlight_t *l = &gp_dlights[i];
if( l->die < gp_cl->time || !l->radius )
continue;
R_MarkLights( l, 1 << i, model->nodes, model, framecount );
}
return framecount;
}

View File

@@ -684,7 +684,7 @@ static void R_AliasDynamicLight( cl_entity_t *ent, alight_t *plight )
for( lnum = 0; lnum < MAX_DLIGHTS; lnum++ )
{
const dlight_t *dl = &tr.dlights[lnum];
const dlight_t *dl = &gp_dlights[lnum];
if( dl->die < g_alias.time || !r_dynamic->value )
continue;

View File

@@ -249,7 +249,6 @@ typedef struct
movevars_t *movevars;
color24 *palette;
cl_entity_t *viewent;
dlight_t *dlights;
dlight_t *elights;
byte *texgammatable;
uint *lightgammatable;
@@ -375,9 +374,7 @@ void R_ShowTextures( void );
// gl_rlight.c
//
void CL_RunLightStyles( lightstyle_t *ls );
void R_PushDlights( void );
void R_GetLightSpot( vec3_t lightspot );
void R_MarkLights( const dlight_t *light, int bit, const mnode_t *node );
colorVec R_LightVec( const vec3_t start, const vec3_t end, vec3_t lightspot, vec3_t lightvec );
colorVec R_LightPoint( const vec3_t p0 );
@@ -782,7 +779,6 @@ extern convar_t r_ripple;
extern convar_t r_ripple_updatetime;
extern convar_t r_ripple_spawntime;
extern convar_t r_large_lightmaps;
extern convar_t r_dlight_virtual_radius;
//
// engine shared convars

View File

@@ -39,7 +39,6 @@ CVAR_DEFINE_AUTO( r_ripple, "0", FCVAR_GLCONFIG, "enable software-like water tex
CVAR_DEFINE_AUTO( r_ripple_updatetime, "0.05", FCVAR_GLCONFIG, "how fast ripple simulation is" );
CVAR_DEFINE_AUTO( r_ripple_spawntime, "0.1", FCVAR_GLCONFIG, "how fast new ripples spawn" );
CVAR_DEFINE_AUTO( r_large_lightmaps, "0", FCVAR_GLCONFIG|FCVAR_LATCH, "enable larger lightmap atlas textures (might break custom renderer mods)" );
CVAR_DEFINE_AUTO( r_dlight_virtual_radius, "3", FCVAR_GLCONFIG, "increase dlight radius virtually by this amount, should help against ugly cut off dlights on highly scaled textures" );
poolhandle_t r_temppool;
@@ -1159,7 +1158,6 @@ static void GL_InitCommands( void )
gEngfuncs.Cvar_RegisterVariable( &r_vbo_overbrightmode );
gEngfuncs.Cvar_RegisterVariable( &r_vbo_detail );
gEngfuncs.Cvar_RegisterVariable( &r_large_lightmaps );
gEngfuncs.Cvar_RegisterVariable( &r_dlight_virtual_radius );
gEngfuncs.Cvar_RegisterVariable( &gl_extensions );
gEngfuncs.Cvar_RegisterVariable( &gl_texture_nearest );
@@ -1273,7 +1271,6 @@ qboolean R_Init( void )
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 );
tr.dlights = (dlight_t *)ENGINE_GET_PARM( PARM_GET_DLIGHTS_PTR );
tr.elights = (dlight_t *)ENGINE_GET_PARM( PARM_GET_ELIGHTS_PTR );
GL_SetDefaults();

View File

@@ -37,118 +37,6 @@ void CL_RunLightStyles( lightstyle_t *ls )
CL_RunLightStyles_( ls, tr.lightstylevalue );
}
/*
=============
R_MarkLights
=============
*/
void R_MarkLights( const dlight_t *light, int bit, const mnode_t *node )
{
const float virtual_radius = light->radius * Q_max( 1.0f, r_dlight_virtual_radius.value );
const float maxdist = light->radius * light->radius;
float dist;
int i;
int firstsurface, numsurfaces;
start:
if( !node || node->contents < 0 )
return;
dist = PlaneDiff( light->origin, node->plane );
if( dist > virtual_radius )
{
node = node_child( node, 0, RI.currentmodel );
goto start;
}
if( dist < -virtual_radius )
{
node = node_child( node, 1, RI.currentmodel );
goto start;
}
const float dist_sq = dist * dist;
// mark the polygons
firstsurface = node_firstsurface( node, RI.currentmodel );
numsurfaces = node_numsurfaces( node, RI.currentmodel );
for( i = 0; i < numsurfaces && dist_sq < maxdist; i++ )
{
vec3_t impact;
float s, t, l;
msurface_t *surf = &RI.currentmodel->surfaces[firstsurface + i];
const mextrasurf_t *info = surf->info;
if( surf->plane->type < 3 )
{
VectorCopy( light->origin, impact );
impact[surf->plane->type] -= dist;
}
else VectorMA( light->origin, -dist, surf->plane->normal, impact );
// a1ba: the fix was taken from JoeQuake, which traces back to FitzQuake,
// which attributes it to LadyHavoc (Darkplaces author)
// clamp center of light to corner and check brightness
l = DotProduct( impact, info->lmvecs[0] ) + info->lmvecs[0][3] - info->lightmapmins[0];
s = l + 0.5;
s = bound( 0, s, info->lightextents[0] );
s = l - s;
l = DotProduct( impact, info->lmvecs[1] ) + info->lmvecs[1][3] - info->lightmapmins[1];
t = l + 0.5;
t = bound( 0, t, info->lightextents[1] );
t = l - t;
if( s * s + t * t + dist_sq >= maxdist )
continue;
if( surf->dlightframe != tr.dlightframecount )
{
surf->dlightbits = bit;
surf->dlightframe = tr.dlightframecount;
}
else surf->dlightbits |= bit;
}
R_MarkLights( light, bit, node_child( node, 0, RI.currentmodel ));
R_MarkLights( light, bit, node_child( node, 1, RI.currentmodel ));
}
/*
=============
R_PushDlights
=============
*/
void R_PushDlights( void )
{
int i;
tr.dlightframecount = tr.framecount;
RI.currententity = CL_GetEntityByIndex( 0 );
// no world -- no dlights
if( !RI.currententity )
return;
RI.currentmodel = RI.currententity->model;
for( i = 0; i < MAX_DLIGHTS; i++ )
{
dlight_t *l = &tr.dlights[i];
if( l->die < gp_cl->time || !l->radius )
continue;
if( GL_FrustumCullSphere( &RI.frustum, l->origin, l->radius, 15 ))
continue;
R_MarkLights( l, 1<<i, RI.currentmodel->nodes );
}
}
/*
=======================================================================

View File

@@ -998,7 +998,7 @@ void R_RenderScene( void )
// begin a new frame
tr.framecount++;
R_PushDlights();
tr.dlightframecount = R_PushDlights( WORLDMODEL, tr.framecount );
R_SetupFrustum();
R_SetupFrame();

View File

@@ -575,7 +575,7 @@ static void R_AddDynamicLights( const msurface_t *surf )
if( !FBitSet( surf->dlightbits, BIT( lnum )))
continue; // not lit by this light
dl = &tr.dlights[lnum];
dl = &gp_dlights[lnum];
// transform light origin to local bmodel space
if( !tr.modelviewIdentity )
@@ -1859,7 +1859,7 @@ void R_DrawBrushModel( cl_entity_t *e )
// calculate dynamic lighting for bmodel
for( int k = 0; k < MAX_DLIGHTS; k++ )
{
dlight_t *l = &tr.dlights[k];
dlight_t *l = &gp_dlights[k];
vec3_t origin_l, oldorigin;
if( l->die < gp_cl->time || !l->radius )
@@ -1868,7 +1868,7 @@ void R_DrawBrushModel( cl_entity_t *e )
VectorCopy( l->origin, oldorigin ); // save lightorigin
Matrix4x4_VectorITransform( RI.objectMatrix, l->origin, origin_l );
VectorCopy( origin_l, l->origin ); // move light in bmodel space
R_MarkLights( l, 1<<k, clmodel->nodes + clmodel->hulls[0].firstclipnode );
R_MarkLights( l, 1<<k, clmodel->nodes + clmodel->hulls[0].firstclipnode, clmodel, tr.dlightframecount );
VectorCopy( oldorigin, l->origin ); // restore lightorigin
}

View File

@@ -1441,7 +1441,7 @@ static void R_StudioDynamicLight( cl_entity_t *ent, alight_t *plight )
for( lnum = 0; lnum < MAX_DLIGHTS; lnum++ )
{
dl = &tr.dlights[lnum];
dl = &gp_dlights[lnum];
if( dl->die < g_studio.time || !r_dynamic->value )
continue;

View File

@@ -40,86 +40,6 @@ void CL_RunLightStyles( lightstyle_t *ls )
CL_RunLightStyles_( ls, tr.lightstylevalue );
}
/*
=============
R_MarkLights
=============
*/
void R_MarkLights( dlight_t *light, int bit, mnode_t *node )
{
float dist;
msurface_t *surf;
int i;
int firstsurface, numsurfaces;
if( !node || node->contents < 0 )
return;
dist = PlaneDiff( light->origin, node->plane );
firstsurface = node_firstsurface( node, RI.currentmodel );
numsurfaces = node_numsurfaces( node, RI.currentmodel );
if( dist > light->radius )
{
R_MarkLights( light, bit, node_child( node, 0, RI.currentmodel ));
return;
}
if( dist < -light->radius )
{
R_MarkLights( light, bit, node_child( node, 1, RI.currentmodel ));
return;
}
// mark the polygons
surf = RI.currentmodel->surfaces + firstsurface;
for( i = 0; i < numsurfaces; i++, surf++ )
{
if( !BoundsAndSphereIntersect( surf->info->mins, surf->info->maxs, light->origin, light->radius ))
continue; // no intersection
if( surf->dlightframe != tr.dlightframecount )
{
surf->dlightbits = 0;
surf->dlightframe = tr.dlightframecount;
}
surf->dlightbits |= bit;
}
R_MarkLights( light, bit, node_child( node, 0, RI.currentmodel ));
R_MarkLights( light, bit, node_child( node, 1, RI.currentmodel ));
}
/*
=============
R_PushDlights
=============
*/
void R_PushDlights( void )
{
int i;
tr.dlightframecount = tr.framecount;
RI.currententity = CL_GetEntityByIndex( 0 );
// no world -- no dlights
if( !RI.currententity )
return;
RI.currentmodel = RI.currententity->model;
for( i = 0; i < MAX_DLIGHTS; i++ )
{
dlight_t *l = &tr.dlights[i];
if( l->die < gp_cl->time || !l->radius )
continue;
R_MarkLights( l, 1 << i, RI.currentmodel->nodes );
}
}
/*
=======================================================================

View File

@@ -272,7 +272,6 @@ typedef struct
color24 *palette;
cl_entity_t *viewent;
lightstyle_t *lightstyles;
dlight_t *dlights;
dlight_t *elights;
byte *texgammatable;
uint *lightgammatable;
@@ -388,9 +387,7 @@ int R_TexMemory( void );
// gl_rlight.c
//
void CL_RunLightStyles( lightstyle_t *ls );
void R_PushDlights( void );
void R_GetLightSpot( vec3_t lightspot );
void R_MarkLights( dlight_t *light, int bit, mnode_t *node );
colorVec R_LightVec( const vec3_t start, const vec3_t end, vec3_t lightspot, vec3_t lightvec );
colorVec R_LightPoint( const vec3_t p0 );
#endif

View File

@@ -842,7 +842,7 @@ static void R_DrawBEntitiesOnList( void )
// calculate dynamic lighting for bmodel
for( k = 0; k < MAX_DLIGHTS; k++ )
{
dlight_t *l = &tr.dlights[k];
dlight_t *l = &gp_dlights[k];
vec3_t origin_l, oldorigin;
if( l->die < gp_cl->time || !l->radius )
@@ -852,7 +852,7 @@ static void R_DrawBEntitiesOnList( void )
Matrix4x4_CreateFromEntity( RI.objectMatrix, RI.currententity->angles, RI.currententity->origin, 1 );
Matrix4x4_VectorITransform( RI.objectMatrix, l->origin, origin_l );
VectorCopy( origin_l, l->origin ); // move light in bmodel space
R_MarkLights( l, 1 << k, RI.currentmodel->nodes + RI.currentmodel->hulls[0].firstclipnode );
R_MarkLights( l, 1 << k, RI.currentmodel->nodes + RI.currentmodel->hulls[0].firstclipnode, RI.currentmodel, tr.dlightframecount );
VectorCopy( oldorigin, l->origin ); // restore lightorigin
}
@@ -967,7 +967,7 @@ void R_DrawBrushModel( cl_entity_t *pent )
// calculate dynamic lighting for bmodel
for( k = 0; k < MAX_DLIGHTS; k++ )
{
dlight_t *l = &tr.dlights[k];
dlight_t *l = &gp_dlights[k];
vec3_t origin_l, oldorigin;
if( l->die < gp_cl->time || !l->radius )
@@ -978,7 +978,7 @@ void R_DrawBrushModel( cl_entity_t *pent )
Matrix4x4_VectorITransform( RI.objectMatrix, l->origin, origin_l );
tr.modelviewIdentity = false;
VectorCopy( origin_l, l->origin ); // move light in bmodel space
R_MarkLights( l, 1 << k, RI.currentmodel->nodes + RI.currentmodel->hulls[0].firstclipnode );
R_MarkLights( l, 1 << k, RI.currentmodel->nodes + RI.currentmodel->hulls[0].firstclipnode, RI.currentmodel, tr.dlightframecount );
VectorCopy( oldorigin, l->origin ); // restore lightorigin*/
}
@@ -1130,7 +1130,7 @@ void GAME_EXPORT R_RenderScene( void )
R_SetupFrustum();
R_SetupFrame();
R_PushDlights();
tr.dlightframecount = R_PushDlights( WORLDMODEL, tr.framecount );
R_SetupModelviewMatrix( RI.worldviewMatrix );
R_SetupProjectionMatrix( RI.projectionMatrix );
@@ -1450,8 +1450,7 @@ qboolean GAME_EXPORT R_Init( void )
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 );
tr.dlights = (dlight_t *)ENGINE_GET_PARM( PARM_GET_DLIGHTS_PTR );
tr.elights = (dlight_t *)ENGINE_GET_PARM( PARM_GET_ELIGHTS_PTR );
tr.elights = (dlight_t *)ENGINE_GET_PARM( PARM_GET_ELIGHTS_PTR );
if( !R_InitBlit( glblit ))
{

View File

@@ -62,16 +62,15 @@ Set sprite brightness factor
*/
static float R_SpriteGlowBlend( vec3_t origin, int rendermode, int renderfx, float *pscale )
{
float dist, brightness;
vec3_t glowDist;
pmtrace_t *tr;
float dist, brightness;
vec3_t glowDist;
VectorSubtract( origin, RI.vieworg, glowDist );
dist = VectorLength( glowDist );
if( RP_NORMALPASS( ))
{
tr = gEngfuncs.EV_VisTraceLine( RI.vieworg, origin, r_traceglow.value ? PM_GLASS_IGNORE : ( PM_GLASS_IGNORE | PM_STUDIO_IGNORE ));
pmtrace_t *tr = gEngfuncs.EV_VisTraceLine( RI.vieworg, origin, r_traceglow.value ? PM_GLASS_IGNORE : ( PM_GLASS_IGNORE | PM_STUDIO_IGNORE ));
if(( 1.0f - tr->fraction ) * dist > 8.0f )
return 0.0f;

View File

@@ -1467,7 +1467,7 @@ static void R_StudioDynamicLight( cl_entity_t *ent, alight_t *plight )
for( lnum = 0; lnum < MAX_DLIGHTS; lnum++ )
{
dl = &tr.dlights[lnum];
dl = &gp_dlights[lnum];
if( dl->die < g_studio.time || !r_dynamic->value )
continue;

View File

@@ -107,7 +107,7 @@ static void R_AddDynamicLights( const msurface_t *surf )
if( !FBitSet( surf->dlightbits, BIT( lnum )))
continue; // not lit by this light
dl = &tr.dlights[lnum];
dl = &gp_dlights[lnum];
// transform light origin to local bmodel space
if( !tr.modelviewIdentity )