diff --git a/src/client/refresh/soft/header/local.h b/src/client/refresh/soft/header/local.h index a9585a95..81daac47 100644 --- a/src/client/refresh/soft/header/local.h +++ b/src/client/refresh/soft/header/local.h @@ -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 diff --git a/src/client/refresh/soft/sw_light.c b/src/client/refresh/soft/sw_light.c index 5082818c..990bbbfc 100644 --- a/src/client/refresh/soft/sw_light.c +++ b/src/client/refresh/soft/sw_light.c @@ -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<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) + max_light = blocklights + size * 3; + + R_BuildLightMap(surf, bblocklights, smax * 4, + r_newrefdef, modulate, r_framecount); + + /* bound, invert, and shift */ + if(r_colorlight->value == 0) { - int maps; - - 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 - - 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; - - 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; + byte* curr; + curr = bblocklights; 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_light = t; - curr_light++; + 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 += LIGHTMAP_BYTES; } while(curr_light < max_light); } diff --git a/src/client/refresh/soft/sw_main.c b/src/client/refresh/soft/sw_main.c index 5b0652a3..c7c6ca06 100644 --- a/src/client/refresh/soft/sw_main.c +++ b/src/client/refresh/soft/sw_main.c @@ -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); diff --git a/src/client/refresh/soft/sw_surf.c b/src/client/refresh/soft/sw_surf.c index d96605d2..a0023f2b 100644 --- a/src/client/refresh/soft/sw_surf.c +++ b/src/client/refresh/soft/sw_surf.c @@ -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; } diff --git a/src/client/refresh/vk/vk_surf.c b/src/client/refresh/vk/vk_surf.c index 5012c1c4..23332d1f 100644 --- a/src/client/refresh/vk/vk_surf.c +++ b/src/client/refresh/vk/vk_surf.c @@ -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);