From 584163379eecddcd8d9de0e11f45a07b24507df5 Mon Sep 17 00:00:00 2001 From: havoc Date: Sat, 16 Nov 2002 12:49:34 +0000 Subject: [PATCH] lightmap update checking is now handled very differently; each brush model has a set of lightmap chains for each light style, and they are marked if the light style's value changes, similarly dlights mark surfaces they touch as well... both use surf->cached_dlight... this doesn't seem to be a speed gain (or loss) at present, but allows further restructuring which should be a speed gain git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@2630 d7cf8633-e32d-0410-b094-e92efae38249 --- gl_rsurf.c | 27 ++++++++++++++++++++++++- model_brush.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++ model_brush.h | 7 ++++--- model_shared.h | 8 ++++++++ r_light.c | 4 ++++ render.h | 1 + 6 files changed, 97 insertions(+), 4 deletions(-) diff --git a/gl_rsurf.c b/gl_rsurf.c index db6c3188..d6d0ccc3 100644 --- a/gl_rsurf.c +++ b/gl_rsurf.c @@ -1430,7 +1430,7 @@ void R_PrepareSurfaces(entity_render_t *ent) { int i, numsurfaces, *surfacevisframes; model_t *model; - msurface_t *surf, *surfaces; + msurface_t *surf, *surfaces, **surfchain; vec3_t modelorg; if (!ent->model) @@ -1447,6 +1447,26 @@ void R_PrepareSurfaces(entity_render_t *ent) if (r_dynamic.integer && r_shadow_lightingmode < 1) R_MarkLights(ent); + if (model->light_ambient != r_ambient.value || model->light_scalebit != r_lightmapscalebit) + { + model->light_ambient = r_ambient.value; + model->light_scalebit = r_lightmapscalebit; + for (i = 0;i < model->nummodelsurfaces;i++) + model->surfaces[i + model->firstmodelsurface].cached_dlight = true; + } + else + { + for (i = 0;i < model->light_styles;i++) + { + if (model->light_stylevalue[i] != d_lightstylevalue[model->light_style[i]]) + { + model->light_stylevalue[i] = d_lightstylevalue[model->light_style[i]]; + for (surfchain = model->light_styleupdatechains[i];*surfchain;surfchain++) + (**surfchain).cached_dlight = true; + } + } + } + for (i = 0, surf = surfaces;i < numsurfaces;i++, surf++) { if (surfacevisframes[i] == r_framecount) @@ -1468,6 +1488,10 @@ void R_PrepareSurfaces(entity_render_t *ent) { c_faces++; surf->visframe = r_framecount; +#if 1 + if (surf->cached_dlight && surf->lightmaptexture != NULL && !r_vertexsurfaces.integer) + R_BuildLightMap(ent, surf, false); // base lighting changed +#else if (!r_vertexsurfaces.integer && surf->lightmaptexture != NULL) { if (surf->cached_dlight @@ -1485,6 +1509,7 @@ void R_PrepareSurfaces(entity_render_t *ent) R_BuildLightMap(ent, surf, true); // only dlights } } +#endif } } } diff --git a/model_brush.c b/model_brush.c index d4b1314a..ea39f1cd 100644 --- a/model_brush.c +++ b/model_brush.c @@ -2739,6 +2739,59 @@ static void Mod_BuildSurfaceNeighbors (msurface_t *surfaces, int numsurfaces, me #endif } +void Mod_BuildLightmapUpdateChains(mempool_t *mempool, model_t *model) +{ + int i, j, stylecounts[256], totalcount, remapstyles[256]; + msurface_t *surf; + memset(stylecounts, 0, sizeof(stylecounts)); + for (i = 0;i < model->nummodelsurfaces;i++) + { + surf = model->surfaces + model->firstmodelsurface + i; + for (j = 0;j < MAXLIGHTMAPS;j++) + stylecounts[surf->styles[j]]++; + } + totalcount = 0; + model->light_styles = 0; + for (i = 0;i < 255;i++) + { + if (stylecounts[i]) + { + remapstyles[i] = model->light_styles++; + totalcount += stylecounts[i] + 1; + } + } + if (!totalcount) + return; + model->light_style = Mem_Alloc(mempool, model->light_styles * sizeof(qbyte)); + model->light_stylevalue = Mem_Alloc(mempool, model->light_styles * sizeof(int)); + model->light_styleupdatechains = Mem_Alloc(mempool, model->light_styles * sizeof(msurface_t **)); + model->light_styleupdatechainsbuffer = Mem_Alloc(mempool, totalcount * sizeof(msurface_t *)); + model->light_styles = 0; + for (i = 0;i < 255;i++) + if (stylecounts[i]) + model->light_style[model->light_styles++] = i; + j = 0; + for (i = 0;i < model->light_styles;i++) + { + model->light_styleupdatechains[i] = model->light_styleupdatechainsbuffer + j; + j += stylecounts[model->light_style[i]] + 1; + } + for (i = 0;i < model->nummodelsurfaces;i++) + { + surf = model->surfaces + model->firstmodelsurface + i; + for (j = 0;j < MAXLIGHTMAPS;j++) + if (surf->styles[j] != 255) + *model->light_styleupdatechains[remapstyles[surf->styles[j]]]++ = surf; + } + j = 0; + for (i = 0;i < model->light_styles;i++) + { + *model->light_styleupdatechains[i] = NULL; + model->light_styleupdatechains[i] = model->light_styleupdatechainsbuffer + j; + j += stylecounts[model->light_style[i]] + 1; + } +} + void Mod_BuildPVSTextureChains(model_t *model) { int i, j; @@ -2877,6 +2930,7 @@ void Mod_LoadBrushModel (model_t *mod, void *buffer) mod->pvstexturechainsbuffer = Mem_Alloc(originalloadmodel->mempool, (mod->nummodelsurfaces + mod->numtextures) * sizeof(msurface_t *)); mod->pvstexturechainslength = Mem_Alloc(originalloadmodel->mempool, mod->numtextures * sizeof(int)); Mod_BuildPVSTextureChains(mod); + Mod_BuildLightmapUpdateChains(originalloadmodel->mempool, mod); if (mod->nummodelsurfaces) { // LordHavoc: calculate bmodel bounding box rather than trusting what it says diff --git a/model_brush.h b/model_brush.h index 557c2ce5..8870e965 100644 --- a/model_brush.h +++ b/model_brush.h @@ -186,8 +186,6 @@ typedef struct msurface_s mplane_t *plane; // SURF_ flags int flags; - // rendering chain - struct msurface_s *texturechain; // look up in model->surfedges[], negative numbers are backwards edges int firstedge; @@ -221,13 +219,16 @@ typedef struct msurface_s vec3_t poly_mins, poly_maxs, poly_center; // neighboring surfaces (one per poly_numverts) - struct msurface_s **neighborsurfaces; + //struct msurface_s **neighborsurfaces; // currently used only for generating static shadow volumes int castshadow; // these are regenerated every frame // lighting info + // if this == r_framecount there are dynamic lights on the surface int dlightframe; + // which dynamic lights are touching this surface + // (only access this if dlightframe is current) int dlightbits[8]; // avoid redundent addition of dlights int lightframe; diff --git a/model_shared.h b/model_shared.h index 1bcd0a19..8f504282 100644 --- a/model_shared.h +++ b/model_shared.h @@ -214,6 +214,14 @@ typedef struct model_s msurface_t **pvstexturechainsbuffer; int *pvstexturechainslength; + // lightmap update chains for light styles + int light_styles; + qbyte *light_style; + int *light_stylevalue; + msurface_t ***light_styleupdatechains; + msurface_t **light_styleupdatechainsbuffer; + int light_scalebit; + float light_ambient; // skin animation info animscene_t *skinscenes; // [numskins] diff --git a/r_light.c b/r_light.c index 8e658787..86c2a0d4 100644 --- a/r_light.c +++ b/r_light.c @@ -285,6 +285,8 @@ loc0: { surf->dlightbits[0] = surf->dlightbits[1] = surf->dlightbits[2] = surf->dlightbits[3] = surf->dlightbits[4] = surf->dlightbits[5] = surf->dlightbits[6] = surf->dlightbits[7] = 0; surf->dlightframe = r_framecount; + if (r_dlightmap.integer) + surf->cached_dlight = true; } surf->dlightbits[bitindex] |= bit; } @@ -424,6 +426,8 @@ static void R_VisMarkLights (entity_render_t *ent, rdlight_t *rd, int bit, int b { surf->dlightbits[0] = surf->dlightbits[1] = surf->dlightbits[2] = surf->dlightbits[3] = surf->dlightbits[4] = surf->dlightbits[5] = surf->dlightbits[6] = surf->dlightbits[7] = 0; surf->dlightframe = r_framecount; + if (r_dlightmap.integer) + surf->cached_dlight = true; } surf->dlightbits[bitindex] |= bit; } diff --git a/render.h b/render.h index 5b951cb5..1c9a91ab 100644 --- a/render.h +++ b/render.h @@ -99,6 +99,7 @@ extern cvar_t r_speeds; extern cvar_t r_fullbright; extern cvar_t r_wateralpha; extern cvar_t r_dynamic; +extern cvar_t r_dlightmap; void R_Init (void); void R_RenderView (void); // must set r_refdef first -- 2.39.2