From 81dc2f3fa9ce39a370b04fd48677a3df2540f5cd Mon Sep 17 00:00:00 2001 From: Eric Wasylishen Date: Fri, 8 May 2015 03:27:55 -0600 Subject: [PATCH] per-brush lm scale support --- include/light/light.h | 4 +++- light/light.c | 39 +++++++++++++++++++++++++++++++++++++-- light/ltface.c | 5 ++++- qbsp/brush.c | 3 ++- qbsp/csg4.c | 2 ++ qbsp/globals.c | 1 + qbsp/map.c | 34 +++++++++++++++++++++++++++++++++- qbsp/merge.c | 3 ++- qbsp/qbsp.h | 3 +++ qbsp/surfaces.c | 4 ++++ qbsp/writebsp.c | 28 ++++++++++++++++++++++++++++ 11 files changed, 119 insertions(+), 7 deletions(-) diff --git a/include/light/light.h b/include/light/light.h index 8eff300c..0367ec77 100644 --- a/include/light/light.h +++ b/include/light/light.h @@ -82,7 +82,7 @@ typedef struct { const dmodel_t *model; qboolean shadowself; lightsample_t minlight; - float lightmapscale; + //float lightmapscale; vec3_t offset; qboolean nodirt; } modelinfo_t; @@ -148,6 +148,8 @@ extern int oversample; extern int write_litfile; extern int write_luxfile; +extern byte *lmshifts; + void SetupDirt(); /* Used by fence texture sampling */ diff --git a/light/light.c b/light/light.c index 11867593..9e8d04f6 100644 --- a/light/light.c +++ b/light/light.c @@ -73,6 +73,8 @@ int oversample = 1; int write_litfile = 0; /* 0 for none, 1 for .lit, 2 for bspx, 3 for both */ int write_luxfile = 0; /* 0 for none, 1 for .lux, 2 for bspx, 3 for both */ +byte *lmshifts; + void GetFileSpace(byte **lightdata, byte **colordata, byte **deluxdata, int size) { @@ -163,6 +165,7 @@ FindModelInfo(const bsp2_t *bsp, const char *lmscaleoverride) memset(modelinfo, 0, sizeof(*modelinfo) * bsp->nummodels); modelinfo[0].model = &bsp->dmodels[0]; +#if 0 if (lmscaleoverride) SetKeyValue(entities, "_lightmap_scale", lmscaleoverride); @@ -181,10 +184,11 @@ FindModelInfo(const bsp2_t *bsp, const char *lmscaleoverride) if (i != lightmapscale) logprint("WARNING: lightmap scale is not a power of 2\n"); modelinfo[0].lightmapscale = lightmapscale; +#endif for (i = 1, info = modelinfo + 1; i < bsp->nummodels; i++, info++) { info->model = &bsp->dmodels[i]; - info->lightmapscale = lightmapscale; + //info->lightmapscale = lightmapscale; /* Find the entity for the model */ snprintf(modelname, sizeof(modelname), "*%d", i); @@ -229,6 +233,35 @@ FindModelInfo(const bsp2_t *bsp, const char *lmscaleoverride) tracelist = shadowmodels; } +/* + ================== + FinishBSPFile + ================== + */ +void +LoadLMScaleFile(const bsp2_t *bsp, const char *name) +{ + char source[1024]; + FILE *LmscaleFile; + + strcpy(source, name); + StripExtension(source); + DefaultExtension(source, ".lmscale"); + + LmscaleFile = fopen(source, "rb"); + if (!LmscaleFile) + Error("Failed to open %s: %s", source, strerror(errno)); + + + lmshifts = calloc(bsp->numfaces, 1); + if (bsp->numfaces != fread(lmshifts, 1, bsp->numfaces, LmscaleFile)) { + Error("Corrupt .lmscale file"); + // FIXME: Not fatal + } + + fclose(LmscaleFile); +} + /* * ============= * LightWorld @@ -440,7 +473,9 @@ main(int argc, const char **argv) loadversion = bspdata.version; if (bspdata.version != BSP2VERSION) ConvertBSPFormat(BSP2VERSION, &bspdata); - + + LoadLMScaleFile(bsp, source); + LoadEntities(bsp); if (dirty) diff --git a/light/ltface.c b/light/ltface.c index 64aab75c..53eb5d86 100644 --- a/light/ltface.c +++ b/light/ltface.c @@ -531,12 +531,15 @@ Lightsurf_Init(const modelinfo_t *modelinfo, const bsp2_dface_t *face, const texinfo_t *tex; vec3_t planepoint; texorg_t texorg; + int facenum, lmshift; /*FIXME: memset can be slow on large datasets*/ // memset(lightsurf, 0, sizeof(*lightsurf)); lightsurf->modelinfo = modelinfo; - lightsurf->lightmapscale = modelinfo->lightmapscale; + facenum = face - bsp->dfaces; + lmshift = lmshifts[facenum]; + lightsurf->lightmapscale = 1 << lmshift; /* Set up the plane, including model offset */ plane = &lightsurf->plane; diff --git a/qbsp/brush.c b/qbsp/brush.c index afe839fb..dabf4297 100644 --- a/qbsp/brush.c +++ b/qbsp/brush.c @@ -452,6 +452,7 @@ CreateBrushFaces(hullbrush_t *hullbrush, const vec3_t rotate_offset, f->texinfo = hullnum ? 0 : mapface->texinfo; f->planenum = FindPlane(&plane, &f->planeside); + f->lmshift = mapface->lmshift; f->next = facelist; facelist = f; CheckFace(f); @@ -904,7 +905,7 @@ Brush_LoadEntity(mapentity_t *dst, const mapentity_t *src, const int hullnum) /* If the source entity is func_detail, set the content flag */ if (!strcasecmp(classname, "func_detail")) cflags |= CFLAGS_DETAIL; - + mapbrush = src->mapbrushes; for (i = 0; i < src->nummapbrushes; i++, mapbrush++) { contents = Brush_GetContents(mapbrush); diff --git a/qbsp/csg4.c b/qbsp/csg4.c index 6b2b2307..76551805 100644 --- a/qbsp/csg4.c +++ b/qbsp/csg4.c @@ -57,6 +57,7 @@ NewFaceFromFace(face_t *in) newf->contents[1] = in->contents[1]; newf->cflags[0] = in->cflags[0]; newf->cflags[1] = in->cflags[1]; + newf->lmshift = in->lmshift; VectorCopy(in->origin, newf->origin); newf->radius = in->radius; @@ -306,6 +307,7 @@ SaveFacesToPlaneList(face_t *facelist, bool mirror, face_t **planefaces) newface->contents[1] = face->contents[0]; newface->cflags[0] = face->cflags[1]; newface->cflags[1] = face->cflags[0]; + newface->lmshift = face->lmshift; for (i = 0; i < face->w.numpoints; i++) VectorCopy(face->w.points[face->w.numpoints - 1 - i], newface->w.points[i]); diff --git a/qbsp/globals.c b/qbsp/globals.c index 695d90a2..af16f170 100644 --- a/qbsp/globals.c +++ b/qbsp/globals.c @@ -114,6 +114,7 @@ mapdata_t map; // Useful shortcuts mapentity_t *pWorldEnt; +byte *lmshifts; // Mathlib.c const vec3_t vec3_origin = { 0, 0, 0 }; diff --git a/qbsp/map.c b/qbsp/map.c index f5d7d798..9c1a99c7 100644 --- a/qbsp/map.c +++ b/qbsp/map.c @@ -554,7 +554,7 @@ ParseBrushFace(parser_t *parser, mapface_t *face) } face->texinfo = FindTexinfo(&tx); - + return true; } @@ -601,10 +601,33 @@ ParseBrush(parser_t *parser, mapbrush_t *brush) brush->faces = NULL; } +static int GetLightmapShift(const mapentity_t *src) +{ + float floatscale; + int intscale; + int shift; + + floatscale = atof(ValueForKey(src, "_lightmapscale")); + intscale = 16 * floatscale; + + if (intscale == 0) + { + return 4; // 1<<4 == 16, default lightmap shift + } + + for (shift = 0; (1<nummapbrushes) entity->mapbrushes = NULL; + /* Record scale for lit2 */ + lmshift = GetLightmapShift(entity); + for (i=0, brush = entity->mapbrushes; inummapbrushes; i++, brush++) { + for (j=0, face = brush->faces; jnumfaces; j++, face++) { + face->lmshift = lmshift; + if (lmshift != 4) printf("face %p has %d\n", face, lmshift); + } + } return true; } @@ -683,6 +714,7 @@ PreParseFile(const char *buf) map.faces = AllocMem(MAPFACE, map.maxfaces, true); map.brushes = AllocMem(MAPBRUSH, map.maxbrushes, true); map.entities = AllocMem(MAPENTITY, map.maxentities, true); + lmshifts = AllocMem(OTHER, map.maxfaces *64, true); // While we're here... pWorldEnt = map.entities; diff --git a/qbsp/merge.c b/qbsp/merge.c index fc6c324a..072d4463 100644 --- a/qbsp/merge.c +++ b/qbsp/merge.c @@ -73,7 +73,8 @@ TryMerge(face_t *f1, face_t *f2) f1->planeside != f2->planeside || f1->texinfo != f2->texinfo || f1->contents[0] != f2->contents[0] || - f1->contents[1] != f2->contents[1]) + f1->contents[1] != f2->contents[1] || + f1->lmshift != f2->lmshift) return NULL; // find a common edge diff --git a/qbsp/qbsp.h b/qbsp/qbsp.h index 7e145550..738ffddc 100644 --- a/qbsp/qbsp.h +++ b/qbsp/qbsp.h @@ -266,6 +266,7 @@ typedef struct visfacet_s { int texinfo; short contents[2]; // 0 = front side short cflags[2]; // contents flags + int lmshift; struct visfacet_s *original; // face on node int outputnumber; // only valid for original faces after @@ -472,6 +473,7 @@ typedef struct mapface_s { plane_t plane; int texinfo; int linenum; + int lmshift; } mapface_t; typedef struct mapbrush_s { @@ -529,6 +531,7 @@ typedef struct mapdata_s { extern mapdata_t map; extern mapentity_t *pWorldEnt; +extern byte *lmshifts; void LoadMapFile(void); diff --git a/qbsp/surfaces.c b/qbsp/surfaces.c index 70562f59..39ebdac7 100644 --- a/qbsp/surfaces.c +++ b/qbsp/surfaces.c @@ -439,6 +439,8 @@ GrowNodeRegion_BSP29(mapentity_t *entity, node_t *node) // emit a region face->outputnumber = map.cTotal[LUMP_FACES]; + // ericw -- record lmshift + lmshifts[face->outputnumber] = face->lmshift; out = (bsp29_dface_t *)faces->data + faces->index; out->planenum = node->outputplanenum; out->side = face->planeside; @@ -488,6 +490,8 @@ GrowNodeRegion_BSP2(mapentity_t *entity, node_t *node) // emit a region face->outputnumber = map.cTotal[LUMP_FACES]; + // ericw -- record lmshift + lmshifts[face->outputnumber] = face->lmshift; out = (bsp2_dface_t *)faces->data + faces->index; out->planenum = node->outputplanenum; out->side = face->planeside; diff --git a/qbsp/writebsp.c b/qbsp/writebsp.c index 9640fa17..6f804e54 100644 --- a/qbsp/writebsp.c +++ b/qbsp/writebsp.c @@ -366,6 +366,7 @@ ExportLeaf_BSP29(mapentity_t *entity, node_t *node) /* emit a marksurface */ do { + printf ("face %p has lmscale %d!\n", face, face->lmshift); marksurfnums[marksurfs->index] = face->outputnumber; marksurfs->index++; map.cTotal[LUMP_MARKSURFACES]++; @@ -416,6 +417,7 @@ ExportLeaf_BSP2(mapentity_t *entity, node_t *node) /* emit a marksurface */ do { + printf ("face %p has lmscale %d!\n", face, face->lmshift); marksurfnums[marksurfs->index] = face->outputnumber; marksurfs->index++; map.cTotal[LUMP_MARKSURFACES]++; @@ -709,6 +711,30 @@ CleanBSPTexinfoFlags(void) texinfo->flags &= TEX_SPECIAL; } +/* + ================== + FinishBSPFile + ================== + */ +void +WriteLMScaleFile(void) +{ + FILE *LmscaleFile; + int numfaces; + + // write the file + StripExtension(options.szBSPName); + strcat(options.szBSPName, ".lmscale"); + + LmscaleFile = fopen(options.szBSPName, "wb"); + if (!LmscaleFile) + Error("Failed to open %s: %s", options.szBSPName, strerror(errno)); + + numfaces = map.cTotal[LUMP_FACES]; + fwrite(lmshifts, 1, numfaces, LmscaleFile); + fclose(LmscaleFile); +} + /* ================== FinishBSPFile @@ -746,6 +772,8 @@ FinishBSPFile(void) PrintBSPFileSizes(); CleanBSPTexinfoFlags(); WriteBSPFile(); + + WriteLMScaleFile(); options.fVerbose = options.fAllverbose; }