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; extern surf_t *surfaces, *surface_p, *surf_max;
// allow some very large lightmaps // allow some very large lightmaps
extern light_t *blocklights, *blocklight_max; 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 // 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 // pointer is greater than another one, it should be drawn in front

View File

@ -23,6 +23,7 @@
vec3_t lightspot; vec3_t lightspot;
light_t *blocklights = NULL, *blocklight_max = NULL; 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); 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 * Combine and scale multiple lightmaps into the 8.8 format in blocklights
*/ */
void 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 smax, tmax;
int size; int size;
byte *lightmap; const light_t *max_light;
msurface_t *surf; msurface_t *surf;
surf = drawsurf->surf; surf = drawsurf->surf;
smax = (surf->extents[0] >> surf->lmshift) + 1; smax = (surf->extents[0] >> surf->lmshift) + 1;
tmax = (surf->extents[1] >> 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; r_outoflights = true;
return; return;
} }
/* clear to no light */ if (r_fullbright->value || !r_worldmodel->lightdata ||
memset(blocklights, 0, size * sizeof(light_t)); (surf->texinfo->flags & (SURF_SKY | SURF_TRANSPARENT | SURF_WARP)))
if (r_fullbright->value || !r_worldmodel->lightdata)
{ {
/* clear to no light */
memset(blocklights, 0, size * sizeof(light_t) * 3);
return; return;
} }
/* add all the lightmaps */ max_light = blocklights + size * 3;
lightmap = surf->samples;
if (lightmap)
{
int maps;
for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ; R_BuildLightMap(surf, bblocklights, smax * 4,
maps++) r_newrefdef, modulate, r_framecount);
{
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
/* bound, invert, and shift */
if(r_colorlight->value == 0) 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; light_t *curr_light;
unsigned scale; byte* curr;
curr = bblocklights;
curr_light = blocklights; 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 do
{ {
int t; int t;
t = (int)*curr_light; t = (255 - curr[3]) << VID_CBITS;
if (t < 0) if (t < VID_GRADES)
t = 0; {
t = (255*256 - t) >> (8 - VID_CBITS); t = VID_GRADES;
}
if (t < (1 << 6)) curr_light[0] = curr_light[1] = curr_light[2] = t;
t = (1 << 6); 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 = t;
curr_light++; curr_light ++;
}
curr += LIGHTMAP_BYTES;
} }
while(curr_light < max_light); while(curr_light < max_light);
} }

View File

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

View File

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

View File

@ -399,7 +399,8 @@ Vk_RenderLightmappedPoly(msurface_t *surf, float alpha,
R_BuildLightMap(surf, temp, smax * 4, R_BuildLightMap(surf, temp, smax * 4,
&r_newrefdef, r_modulate->value, r_framecount); &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); R_SetCacheState(surf, &r_newrefdef);