]> de.git.xonotic.org Git - xonotic/darkplaces.git/commitdiff
reworked lightstyle chains code to use a struct, and combine allocations
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Sun, 2 Dec 2007 09:49:30 +0000 (09:49 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Sun, 2 Dec 2007 09:49:30 +0000 (09:49 +0000)
for all submodels of world (to reduce memory overhead), this also
cleaned up the code somewhat

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@7743 d7cf8633-e32d-0410-b094-e92efae38249

gl_rmain.c
model_brush.c
model_shared.h

index fb27c63bb7d836d52a319ae74f2598a46562e1b5..eb18ac316efbe38606756dc8c0cf9a38171e46a7 100644 (file)
@@ -6256,7 +6256,7 @@ extern void R_BuildLightMap(const entity_render_t *ent, msurface_t *surface);
 void R_DrawWorldSurfaces(qboolean skysurfaces, qboolean writedepth, qboolean depthonly, qboolean addwaterplanes, qboolean debug)
 {
        int i, j, endj, f, flagsmask;
-       msurface_t *surface, **surfacechain;
+       msurface_t *surface;
        texture_t *t;
        model_t *model = r_refdef.worldmodel;
        const int maxsurfacelist = 1024;
@@ -6267,17 +6267,19 @@ void R_DrawWorldSurfaces(qboolean skysurfaces, qboolean writedepth, qboolean dep
 
        RSurf_ActiveWorldEntity();
 
-       // update light styles
-       if (!skysurfaces && !depthonly && !addwaterplanes && model->brushq1.light_styleupdatechains)
+       // update light styles on this submodel
+       if (!skysurfaces && !depthonly && !addwaterplanes && model->brushq1.num_lightstyles)
        {
-               for (i = 0;i < model->brushq1.light_styles;i++)
+               model_brush_lightstyleinfo_t *style;
+               for (i = 0, style = model->brushq1.data_lightstyleinfo;i < model->brushq1.num_lightstyles;i++, style++)
                {
-                       if (model->brushq1.light_stylevalue[i] != r_refdef.lightstylevalue[model->brushq1.light_style[i]])
+                       if (style->value != r_refdef.lightstylevalue[style->style])
                        {
-                               model->brushq1.light_stylevalue[i] = r_refdef.lightstylevalue[model->brushq1.light_style[i]];
-                               if ((surfacechain = model->brushq1.light_styleupdatechains[i]))
-                                       for (;(surface = *surfacechain);surfacechain++)
-                                               surface->cached_dlight = true;
+                               msurface_t *surfaces = model->data_surfaces;
+                               int *list = style->surfacelist;
+                               style->value = r_refdef.lightstylevalue[style->style];
+                               for (j = 0;j < style->numsurfaces;j++)
+                                       surfaces[list[j]].cached_dlight = true;
                        }
                }
        }
@@ -6334,8 +6336,8 @@ void R_DrawWorldSurfaces(qboolean skysurfaces, qboolean writedepth, qboolean dep
 
 void R_DrawModelSurfaces(entity_render_t *ent, qboolean skysurfaces, qboolean writedepth, qboolean depthonly, qboolean addwaterplanes, qboolean debug)
 {
-       int i, f, flagsmask;
-       msurface_t *surface, *endsurface, **surfacechain;
+       int i, j, f, flagsmask;
+       msurface_t *surface, *endsurface;
        texture_t *t;
        model_t *model = ent->model;
        const int maxsurfacelist = 1024;
@@ -6355,16 +6357,18 @@ void R_DrawModelSurfaces(entity_render_t *ent, qboolean skysurfaces, qboolean wr
                RSurf_ActiveModelEntity(ent, true, r_glsl.integer && gl_support_fragment_shader && !depthonly);
 
        // update light styles
-       if (!skysurfaces && !depthonly && !addwaterplanes && model->brushq1.light_styleupdatechains)
+       if (!skysurfaces && !depthonly && !addwaterplanes && model->brushq1.num_lightstyles)
        {
-               for (i = 0;i < model->brushq1.light_styles;i++)
+               model_brush_lightstyleinfo_t *style;
+               for (i = 0, style = model->brushq1.data_lightstyleinfo;i < model->brushq1.num_lightstyles;i++, style++)
                {
-                       if (model->brushq1.light_stylevalue[i] != r_refdef.lightstylevalue[model->brushq1.light_style[i]])
+                       if (style->value != r_refdef.lightstylevalue[style->style])
                        {
-                               model->brushq1.light_stylevalue[i] = r_refdef.lightstylevalue[model->brushq1.light_style[i]];
-                               if ((surfacechain = model->brushq1.light_styleupdatechains[i]))
-                                       for (;(surface = *surfacechain);surfacechain++)
-                                               surface->cached_dlight = true;
+                               msurface_t *surfaces = model->data_surfaces;
+                               int *list = style->surfacelist;
+                               style->value = r_refdef.lightstylevalue[style->style];
+                               for (j = 0;j < style->numsurfaces;j++)
+                                       surfaces[list[j]].cached_dlight = true;
                        }
                }
        }
index 23264b20020077025353282dda9a2d4170fc71a6..3a9c14c47a5f43e335fe433eeb02f77e1a53468e 100644 (file)
@@ -3228,59 +3228,6 @@ static void Mod_Q1BSP_MakePortals(void)
        Mod_Q1BSP_FinalizePortals();
 }
 
-static void Mod_Q1BSP_BuildLightmapUpdateChains(mempool_t *mempool, model_t *model)
-{
-       int i, j, stylecounts[256], totalcount, remapstyles[256];
-       msurface_t *surface;
-       memset(stylecounts, 0, sizeof(stylecounts));
-       for (i = 0;i < model->nummodelsurfaces;i++)
-       {
-               surface = model->data_surfaces + model->firstmodelsurface + i;
-               for (j = 0;j < MAXLIGHTMAPS;j++)
-                       stylecounts[surface->lightmapinfo->styles[j]]++;
-       }
-       totalcount = 0;
-       model->brushq1.light_styles = 0;
-       for (i = 0;i < 255;i++)
-       {
-               if (stylecounts[i])
-               {
-                       remapstyles[i] = model->brushq1.light_styles++;
-                       totalcount += stylecounts[i] + 1;
-               }
-       }
-       if (!totalcount)
-               return;
-       model->brushq1.light_style = (unsigned char *)Mem_Alloc(mempool, model->brushq1.light_styles * sizeof(unsigned char));
-       model->brushq1.light_stylevalue = (int *)Mem_Alloc(mempool, model->brushq1.light_styles * sizeof(int));
-       model->brushq1.light_styleupdatechains = (msurface_t ***)Mem_Alloc(mempool, model->brushq1.light_styles * sizeof(msurface_t **));
-       model->brushq1.light_styleupdatechainsbuffer = (msurface_t **)Mem_Alloc(mempool, totalcount * sizeof(msurface_t *));
-       model->brushq1.light_styles = 0;
-       for (i = 0;i < 255;i++)
-               if (stylecounts[i])
-                       model->brushq1.light_style[model->brushq1.light_styles++] = i;
-       j = 0;
-       for (i = 0;i < model->brushq1.light_styles;i++)
-       {
-               model->brushq1.light_styleupdatechains[i] = model->brushq1.light_styleupdatechainsbuffer + j;
-               j += stylecounts[model->brushq1.light_style[i]] + 1;
-       }
-       for (i = 0;i < model->nummodelsurfaces;i++)
-       {
-               surface = model->data_surfaces + model->firstmodelsurface + i;
-               for (j = 0;j < MAXLIGHTMAPS;j++)
-                       if (surface->lightmapinfo->styles[j] != 255)
-                               *model->brushq1.light_styleupdatechains[remapstyles[surface->lightmapinfo->styles[j]]]++ = surface;
-       }
-       j = 0;
-       for (i = 0;i < model->brushq1.light_styles;i++)
-       {
-               *model->brushq1.light_styleupdatechains[i] = NULL;
-               model->brushq1.light_styleupdatechains[i] = model->brushq1.light_styleupdatechainsbuffer + j;
-               j += stylecounts[model->brushq1.light_style[i]] + 1;
-       }
-}
-
 //Returns PVS data for a given point
 //(note: can return NULL)
 static unsigned char *Mod_Q1BSP_GetPVS(model_t *model, const vec3_t p)
@@ -3391,6 +3338,9 @@ void Mod_Q1BSP_Load(model_t *mod, void *buffer, void *bufferend)
        int numshadowmeshtriangles;
        dheader_t _header;
        hullinfo_t hullinfo;
+       int totalstylesurfaces, totalstyles, stylecounts[256], remapstyles[256];
+       model_brush_lightstyleinfo_t styleinfo[256];
+       unsigned char *datapointer;
 
        mod->modeldatatypestring = "Q1BSP";
 
@@ -3593,6 +3543,25 @@ void Mod_Q1BSP_Load(model_t *mod, void *buffer, void *bufferend)
        // LordHavoc: now the explanation of my sane way (which works identically):
        // set up the world model, then on each submodel copy from the world model
        // and set up the submodel with the respective model info.
+       totalstylesurfaces = 0;
+       totalstyles = 0;
+       for (i = 0;i < mod->brush.numsubmodels;i++)
+       {
+               memset(stylecounts, 0, sizeof(stylecounts));
+               for (k = 0;k < mod->brushq1.submodels[i].numfaces;k++)
+               {
+                       surface = mod->data_surfaces + mod->brushq1.submodels[i].firstface + k;
+                       for (j = 0;j < MAXLIGHTMAPS;j++)
+                               stylecounts[surface->lightmapinfo->styles[j]]++;
+               }
+               for (k = 0;k < 255;k++)
+               {
+                       totalstyles++;
+                       if (stylecounts[k])
+                               totalstylesurfaces += stylecounts[k];
+               }
+       }
+       datapointer = (unsigned char *)Mem_Alloc(mod->mempool, mod->num_surfaces * sizeof(int) + totalstyles * sizeof(model_brush_lightstyleinfo_t) + totalstylesurfaces * sizeof(int *));
        for (i = 0;i < mod->brush.numsubmodels;i++)
        {
                // LordHavoc: this code was originally at the end of this loop, but
@@ -3636,7 +3605,7 @@ void Mod_Q1BSP_Load(model_t *mod, void *buffer, void *bufferend)
                mod->nummodelsurfaces = bm->numfaces;
 
                // make the model surface list (used by shadowing/lighting)
-               mod->surfacelist = (int *)Mem_Alloc(loadmodel->mempool, mod->nummodelsurfaces * sizeof(*mod->surfacelist));
+               mod->surfacelist = (int *)datapointer;datapointer += mod->nummodelsurfaces * sizeof(int);
                for (j = 0;j < mod->nummodelsurfaces;j++)
                        mod->surfacelist[j] = mod->firstmodelsurface + j;
 
@@ -3662,7 +3631,6 @@ void Mod_Q1BSP_Load(model_t *mod, void *buffer, void *bufferend)
                        mod->brush.LightPoint = NULL;
                        mod->brush.AmbientSoundLevelsForPoint = NULL;
                }
-               Mod_Q1BSP_BuildLightmapUpdateChains(loadmodel->mempool, mod);
                if (mod->nummodelsurfaces)
                {
                        // LordHavoc: calculate bmodel bounding box rather than trusting what it says
@@ -3703,6 +3671,44 @@ void Mod_Q1BSP_Load(model_t *mod, void *buffer, void *bufferend)
                        mod->rotatedmaxs[0] = mod->rotatedmaxs[1] = mod->rotatedmaxs[2] = modelradius;
                        mod->radius = modelradius;
                        mod->radius2 = modelradius * modelradius;
+
+                       // build lightstyle update chains
+                       // (used to rapidly mark surface->cached_dlight on many surfaces
+                       // when d_lightstylevalue changes)
+                       memset(stylecounts, 0, sizeof(stylecounts));
+                       for (k = 0;k < mod->nummodelsurfaces;k++)
+                       {
+                               surface = mod->data_surfaces + mod->firstmodelsurface + k;
+                               for (j = 0;j < MAXLIGHTMAPS;j++)
+                                       stylecounts[surface->lightmapinfo->styles[j]]++;
+                       }
+                       mod->brushq1.num_lightstyles = 0;
+                       for (k = 0;k < 255;k++)
+                       {
+                               if (stylecounts[k])
+                               {
+                                       styleinfo[mod->brushq1.num_lightstyles].style = k;
+                                       styleinfo[mod->brushq1.num_lightstyles].value = 0;
+                                       styleinfo[mod->brushq1.num_lightstyles].numsurfaces = 0;
+                                       styleinfo[mod->brushq1.num_lightstyles].surfacelist = (int *)datapointer;datapointer += stylecounts[k] * sizeof(int);
+                                       remapstyles[k] = mod->brushq1.num_lightstyles;
+                                       mod->brushq1.num_lightstyles++;
+                               }
+                       }
+                       for (k = 0;k < mod->nummodelsurfaces;k++)
+                       {
+                               surface = mod->data_surfaces + mod->firstmodelsurface + k;
+                               for (j = 0;j < MAXLIGHTMAPS;j++)
+                               {
+                                       if (surface->lightmapinfo->styles[j] != 255)
+                                       {
+                                               int r = remapstyles[surface->lightmapinfo->styles[j]];
+                                               styleinfo[r].surfacelist[styleinfo[r].numsurfaces++] = mod->firstmodelsurface + k;
+                                       }
+                               }
+                       }
+                       mod->brushq1.data_lightstyleinfo = (model_brush_lightstyleinfo_t *)datapointer;datapointer += mod->brushq1.num_lightstyles * sizeof(model_brush_lightstyleinfo_t);
+                       memcpy(mod->brushq1.data_lightstyleinfo, styleinfo, mod->brushq1.num_lightstyles * sizeof(model_brush_lightstyleinfo_t));
                }
                else
                {
index 89d3b2b9a9a4c8b27dee5da8a6e54b03c9fa100b..fdf71ee182cd11a386015334ec53e94056207004 100644 (file)
@@ -580,6 +580,15 @@ model_sprite_t;
 
 struct trace_s;
 
+typedef struct model_brush_lightstyleinfo_s
+{
+       int style;
+       int value;
+       int numsurfaces;
+       int *surfacelist;
+}
+model_brush_lightstyleinfo_t;
+
 typedef struct model_brush_s
 {
        // true if this model is a HalfLife .bsp file
@@ -701,11 +710,8 @@ typedef struct model_brushq1_s
        unsigned char                   *nmaplightdata; // deluxemap file
 
        // lightmap update chains for light styles
-       int                             light_styles;
-       unsigned char                   *light_style;
-       int                             *light_stylevalue;
-       msurface_t              ***light_styleupdatechains;
-       msurface_t              **light_styleupdatechainsbuffer;
+       int                             num_lightstyles;
+       model_brush_lightstyleinfo_t *data_lightstyleinfo;
 }
 model_brushq1_t;