soft: reuse R_BuildLightMap code

This commit is contained in:
Denis Pauk 2024-09-03 00:35:53 +03:00
parent 8d8034f244
commit 4778c6bd7c
5 changed files with 76 additions and 244 deletions

View file

@ -370,6 +370,7 @@ extern vec3_t vright, base_vright;
extern surf_t *surfaces, *surface_p, *surf_max;
// allow some very large lightmaps
extern light_t *blocklights, *blocklight_max;
extern byte *bblocklights, *bblocklight_max;
// surfaces are generated in back to front order by the bsp, so if a surf
// pointer is greater than another one, it should be drawn in front

View file

@ -23,6 +23,7 @@
vec3_t lightspot;
light_t *blocklights = NULL, *blocklight_max = NULL;
byte *bblocklights = NULL, *bblocklight_max = NULL;
/*
=============================================================================
@ -49,279 +50,97 @@ RI_PushDlights(const model_t *model)
r_framecount, model->surfaces);
}
static void
RI_AddDynamicLights(const msurface_t *surf)
{
/* TODO: Covert to reuse with shared files/light */
int lnum;
int smax, tmax;
smax = (surf->extents[0] >> surf->lmshift) + 1;
tmax = (surf->extents[1] >> surf->lmshift) + 1;
if (blocklight_max <= blocklights + smax*tmax*3)
{
r_outoflights = true;
return;
}
for (lnum=0; lnum < r_newrefdef.num_dlights; lnum++)
{
vec3_t impact, local, color;
float dist, rad, minlight;
int t;
int i;
dlight_t *dl;
int negativeLight;
light_t *plightdest = blocklights;
if (!(surf->dlightbits & (1<<lnum)))
continue; // not lit by this light
dl = &r_newrefdef.dlights[lnum];
rad = dl->intensity;
if(r_colorlight->value == 0)
{
for(i=0; i<3; i++)
color[i] = 256;
}
else
{
for(i=0; i<3; i++)
color[i] = 256 * dl->color[i];
}
//=====
negativeLight = 0;
if(rad < 0)
{
negativeLight = 1;
rad = -rad;
}
//=====
dist = DotProduct (dl->origin, surf->plane->normal) -
surf->plane->dist;
rad -= fabs(dist);
minlight = DLIGHT_CUTOFF; // dl->minlight;
if (rad < minlight)
{
continue;
}
minlight = rad - minlight;
for (i = 0; i < 3; i++)
{
impact[i] = dl->origin[i] -
surf->plane->normal[i] * dist;
}
local[0] = DotProduct(impact, surf->lmvecs[0]) +
surf->lmvecs[0][3] - surf->texturemins[0];
local[1] = DotProduct(impact, surf->lmvecs[1]) +
surf->lmvecs[1][3] - surf->texturemins[1];
for (t = 0; t < tmax; t++)
{
int s, td;
td = local[1] - t * (1 << surf->lmshift);
if (td < 0)
{
td = -td;
}
td *= surf->lmvlen[1];
for (s = 0; s < smax; s++)
{
int sd;
sd = local[0] - s * (1 << surf->lmshift);
if (sd < 0)
{
sd = -sd;
}
sd *= surf->lmvlen[0];
if (sd > td)
{
dist = sd + (td >> 1);
}
else
{
dist = td + (sd >> 1);
}
for (i=0; i<3; i++)
{
//====
if(!negativeLight)
{
if (dist < minlight)
*plightdest += (rad - dist) * color[i];
}
else
{
if (dist < minlight)
*plightdest -= (rad - dist) * color[i];
if(*plightdest < minlight)
*plightdest = minlight;
}
//====
plightdest ++;
}
}
}
}
}
/*
* Combine and scale multiple lightmaps into the 8.8 format in blocklights
*/
void
RI_BuildLightMap(drawsurf_t* drawsurf)
RI_BuildLightMap(drawsurf_t* drawsurf, const refdef_t *r_newrefdef,
float modulate, int r_framecount)
{
int smax, tmax;
int size;
byte *lightmap;
const light_t *max_light;
msurface_t *surf;
surf = drawsurf->surf;
smax = (surf->extents[0] >> surf->lmshift) + 1;
tmax = (surf->extents[1] >> surf->lmshift) + 1;
size = smax * tmax * 3;
size = smax * tmax;
if (blocklight_max <= blocklights + size)
if ((blocklight_max <= blocklights + (size * 3)) ||
(bblocklight_max <= bblocklights + (size * LIGHTMAP_BYTES)))
{
r_outoflights = true;
return;
}
/* clear to no light */
memset(blocklights, 0, size * sizeof(light_t));
if (r_fullbright->value || !r_worldmodel->lightdata)
if (r_fullbright->value || !r_worldmodel->lightdata ||
(surf->texinfo->flags & (SURF_SKY | SURF_TRANSPARENT | SURF_WARP)))
{
/* clear to no light */
memset(blocklights, 0, size * sizeof(light_t) * 3);
return;
}
/* add all the lightmaps */
lightmap = surf->samples;
if (lightmap)
{
int maps;
max_light = blocklights + size * 3;
for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ;
maps++)
{
const light_t *max_light;
light_t *curr_light;
unsigned scale;
curr_light = blocklights;
max_light = blocklights + size;
scale = drawsurf->lightadj[maps]; // 8.8 fraction
R_BuildLightMap(surf, bblocklights, smax * 4,
r_newrefdef, modulate, r_framecount);
/* bound, invert, and shift */
if(r_colorlight->value == 0)
{
do
{
light_t light;
light = lightmap[0];
if (light < lightmap[1])
light = lightmap[1];
if (light < lightmap[2])
light = lightmap[2];
light *= scale;
*curr_light += light;
curr_light++;
*curr_light += light;
curr_light++;
*curr_light += light;
curr_light++;
lightmap += 3; /* skip to next lightmap */
}
while(curr_light < max_light);
}
else
{
do
{
*curr_light += *lightmap * scale;
curr_light++;
lightmap ++; /* skip to next lightmap */
}
while(curr_light < max_light);
}
}
}
else
{
int maps;
for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ;
maps++)
{
const light_t *max_light;
light_t *curr_light;
unsigned scale;
byte* curr;
curr = bblocklights;
curr_light = blocklights;
max_light = blocklights + size;
scale = drawsurf->lightadj[maps]; // 8.8 fraction
do
{
*curr_light += 255 * scale;
curr_light++;
}
while(curr_light < max_light);
}
}
// add all the dynamic lights
if (surf->dlightframe == r_framecount)
{
RI_AddDynamicLights(drawsurf->surf);
}
// bound, invert, and shift
{
const light_t *max_light;
light_t *curr_light;
curr_light = blocklights;
max_light = blocklights + size;
do
{
int t;
t = (int)*curr_light;
t = (255 - curr[3]) << VID_CBITS;
if (t < 0)
t = 0;
t = (255*256 - t) >> (8 - VID_CBITS);
if (t < VID_GRADES)
{
t = VID_GRADES;
}
if (t < (1 << 6))
t = (1 << 6);
curr_light[0] = curr_light[1] = curr_light[2] = t;
curr_light += 3;
curr += LIGHTMAP_BYTES;
}
while(curr_light < max_light);
}
else
{
light_t *curr_light;
byte* curr;
curr = bblocklights;
curr_light = blocklights;
do
{
int i;
for (i = 0; i < 3; i++)
{
int t;
t = (255 - curr[i]) << VID_CBITS;
if (t < VID_GRADES)
{
t = VID_GRADES;
}
*curr_light = t;
curr_light++;
curr_light ++;
}
curr += LIGHTMAP_BYTES;
}
while(curr_light < max_light);
}

View file

@ -591,6 +591,7 @@ R_ReallocateMapBuffers (void)
if (!r_numallocatedlights || r_outoflights)
{
free(blocklights);
free(bblocklights);
if (r_outoflights)
{
@ -602,6 +603,7 @@ R_ReallocateMapBuffers (void)
r_numallocatedlights = MAXLIGHTS;
blocklights = malloc (r_numallocatedlights * sizeof(light_t));
bblocklights = malloc (r_numallocatedlights);
if (!blocklights)
{
R_Printf(PRINT_ALL, "%s: Couldn't malloc %d bytes\n",
@ -611,6 +613,7 @@ R_ReallocateMapBuffers (void)
// set limits
blocklight_max = &blocklights[r_numallocatedlights];
bblocklight_max = &bblocklights[r_numallocatedlights];
R_Printf(PRINT_ALL, "Allocated %d lights.\n", r_numallocatedlights);
}
@ -2064,6 +2067,12 @@ RE_ShutdownContext(void)
}
blocklights = NULL;
if(bblocklights)
{
free(bblocklights);
}
bblocklights = NULL;
if(r_edges)
{
free(r_edges);

View file

@ -30,9 +30,10 @@ static int r_stepback;
static int r_lightwidth;
static int r_numvblocks;
static unsigned char *r_source, *r_sourcemax;
static unsigned *r_lightptr;
static light_t *r_lightptr;
void RI_BuildLightMap(drawsurf_t *drawsurf);
void RI_BuildLightMap(drawsurf_t* drawsurf, const refdef_t *r_newrefdef,
float modulate, int r_framecount);
static int sc_size;
static surfcache_t *sc_rover;
@ -140,6 +141,7 @@ R_DrawSurfaceBlock8_anymip (int level, int surfrowbytes)
// FIXME: use delta rather than both right and left, like ASM?
memcpy(lightleft, r_lightptr, sizeof(light3_t));
memcpy(lightright, r_lightptr + 3, sizeof(light3_t));
r_lightptr += r_lightwidth * 3;
for(i=0; i<3; i++)
{
@ -176,7 +178,7 @@ R_DrawSurface
===============
*/
static void
R_DrawSurface (drawsurf_t *drawsurf)
R_DrawSurface (drawsurf_t *drawsurf, light_t *blocklights, light_t *blocklight_max)
{
unsigned char *basetptr;
int smax, tmax, twidth;
@ -497,10 +499,10 @@ D_CacheSurface(const entity_t *currententity, msurface_t *surface, int miplevel)
c_surf++;
// calculate the lightings
RI_BuildLightMap(&r_drawsurf);
RI_BuildLightMap(&r_drawsurf, &r_newrefdef, r_modulate->value, r_framecount);
// rasterize the surface into the cache
R_DrawSurface(&r_drawsurf);
R_DrawSurface(&r_drawsurf, blocklights, blocklight_max);
return cache;
}

View file

@ -399,7 +399,8 @@ Vk_RenderLightmappedPoly(msurface_t *surf, float alpha,
R_BuildLightMap(surf, temp, smax * 4,
&r_newrefdef, r_modulate->value, r_framecount);
if ((surf->styles[map] >= 32 || surf->styles[map] == 0) && (surf->dlightframe != r_framecount))
if ((surf->styles[map] >= 32 || surf->styles[map] == 0) &&
(surf->dlightframe != r_framecount))
{
R_SetCacheState(surf, &r_newrefdef);