mirror of
https://github.com/yquake2/yquake2remaster.git
synced 2024-11-10 07:12:07 +00:00
soft: reuse R_BuildLightMap code
This commit is contained in:
parent
8d8034f244
commit
4778c6bd7c
5 changed files with 76 additions and 244 deletions
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in a new issue