Removed legacy switchable lightstyles limit (requires updated engines when exceeded). Added -facestyles argument that allows for >4 styles per face, as well as potentially increasing style indexes to 16bit for far far more switchable styles.
This commit is contained in:
parent
2ff31d012e
commit
96cd23761c
|
|
@ -400,6 +400,7 @@ extern uint8_t *filebase;
|
|||
extern uint8_t *lit_filebase;
|
||||
extern uint8_t *lux_filebase;
|
||||
|
||||
extern int facestyles;
|
||||
extern int oversample;
|
||||
extern int write_litfile;
|
||||
extern int write_luxfile;
|
||||
|
|
|
|||
|
|
@ -36,10 +36,13 @@ typedef struct litheader_s {
|
|||
} litheader_t;
|
||||
|
||||
/* internal representation for bspx/lit2 */
|
||||
#define MAXLIGHTMAPSSUP 16
|
||||
#define INVALID_LIGHTSTYLE 0xffffu
|
||||
#define INVALID_LIGHTSTYLE_OLD 0xffu
|
||||
typedef struct {
|
||||
float lmscale;
|
||||
uint8_t styles[MAXLIGHTMAPS]; /* scaled styles */
|
||||
int32_t lightofs; /* scaled lighting */
|
||||
uint16_t styles[MAXLIGHTMAPSSUP]; /* scaled styles */
|
||||
int32_t lightofs; /* scaled lighting */
|
||||
unsigned short extent[2];
|
||||
} facesup_t;
|
||||
|
||||
|
|
|
|||
|
|
@ -172,7 +172,8 @@ typedef struct {
|
|||
uint32_t v[2]; /* vertex numbers */
|
||||
} bsp2_dedge_t;
|
||||
|
||||
#define MAXLIGHTMAPS 4
|
||||
#define MAXLIGHTMAPS 4
|
||||
#define INVALID_LIGHTSTYLE_OLD 0xffu /*signifies 'no more lightstyles'*/
|
||||
typedef struct {
|
||||
int16_t planenum;
|
||||
int16_t side;
|
||||
|
|
|
|||
|
|
@ -61,7 +61,6 @@ const char * light_t::classname() const {
|
|||
|
||||
static std::vector<std::pair<std::string, int>> lightstyleForTargetname;
|
||||
|
||||
#define MAX_SWITCHABLE_STYLES 64
|
||||
|
||||
static entdict_t &WorldEnt()
|
||||
{
|
||||
|
|
@ -99,12 +98,13 @@ LightStyleForTargetname(const globalconfig_t& cfg, const std::string &targetname
|
|||
|
||||
// generate a new style number and return it
|
||||
const int newStylenum = cfg.compilerstyle_start.intValue() + lightstyleForTargetname.size();
|
||||
|
||||
// check if full
|
||||
if (newStylenum >= MAX_SWITCHABLE_STYLES) {
|
||||
Error("%s: Too many unique light targetnames (max=%d)\n", __func__, MAX_SWITCHABLE_STYLES);
|
||||
if (newStylenum >= (facestyles?INVALID_LIGHTSTYLE:INVALID_LIGHTSTYLE_OLD))
|
||||
{
|
||||
if (!facestyles)
|
||||
Error("%s: Too many unique light targetnames (reached max of %i)\nTip: Use '-facestyles N' for 16bit lightstyle limits in supporting engines.", __func__, newStylenum-cfg.compilerstyle_start.intValue());
|
||||
else
|
||||
Error("%s: Too many unique light targetnames (reached max of %i)\n", __func__, newStylenum-cfg.compilerstyle_start.intValue());
|
||||
}
|
||||
|
||||
lightstyleForTargetname.emplace_back(targetname, newStylenum); //mxd. https://clang.llvm.org/extra/clang-tidy/checks/modernize-use-emplace.html
|
||||
|
||||
if (verbose_log) {
|
||||
|
|
@ -375,8 +375,8 @@ CheckEntityFields(const globalconfig_t &cfg, light_t *entity)
|
|||
entity->light.setFloatValue(entity->light.floatValue() / entity->samples.intValue());
|
||||
}
|
||||
|
||||
if (entity->style.intValue() < 0 || entity->style.intValue() > 254) {
|
||||
Error("Bad light style %i (must be 0-254)", entity->style.intValue());
|
||||
if (entity->style.intValue() < 0 || entity->style.intValue() > INVALID_LIGHTSTYLE) {
|
||||
Error("Bad light style %i (must be 0-%i)", entity->style.intValue(), INVALID_LIGHTSTYLE-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1272,9 +1272,8 @@ WriteEntitiesToString(const globalconfig_t& cfg, mbsp_t *bsp)
|
|||
free(bsp->dentdata);
|
||||
|
||||
/* FIXME - why are we printing this here? */
|
||||
logprint("%i switchable light styles (%d max)\n",
|
||||
static_cast<int>(lightstyleForTargetname.size()),
|
||||
MAX_SWITCHABLE_STYLES - cfg.compilerstyle_start.intValue());
|
||||
logprint("%i switchable light styles\n",
|
||||
static_cast<int>(lightstyleForTargetname.size()));
|
||||
|
||||
bsp->entdatasize = entdata.size() + 1; // +1 for a null byte at the end
|
||||
bsp->dentdata = (char *) calloc(bsp->entdatasize, 1);
|
||||
|
|
|
|||
100
light/light.cc
100
light/light.cc
|
|
@ -94,6 +94,7 @@ std::vector<const modelinfo_t *> selfshadowlist;
|
|||
std::vector<const modelinfo_t *> shadowworldonlylist;
|
||||
std::vector<const modelinfo_t *> switchableshadowlist;
|
||||
|
||||
int facestyles = 0; //max styles per face - uses bspx stuff.
|
||||
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 */
|
||||
|
|
@ -281,15 +282,15 @@ LightThread(void *arg)
|
|||
else if (scaledonly)
|
||||
{
|
||||
f->lightofs = -1;
|
||||
f->styles[0] = 255;
|
||||
f->styles[0] = INVALID_LIGHTSTYLE_OLD;
|
||||
LightFace(bsp, f, faces_sup + facenum, cfg_static);
|
||||
}
|
||||
else if (faces_sup[facenum].lmscale == face_modelinfo->lightmapscale)
|
||||
{
|
||||
LightFace(bsp, f, nullptr, cfg_static);
|
||||
faces_sup[facenum].lightofs = f->lightofs;
|
||||
LightFace(bsp, f, faces_sup + facenum, cfg_static);
|
||||
f->lightofs = faces_sup[facenum].lightofs;
|
||||
for (int i = 0; i < MAXLIGHTMAPS; i++)
|
||||
faces_sup[facenum].styles[i] = f->styles[i];
|
||||
f->styles[i] = faces_sup[facenum].styles[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -418,10 +419,8 @@ LightWorld(bspdata_t *bspdata, qboolean forcedscale)
|
|||
BSPX_AddLump(bspdata, "LMSHIFT", NULL, 0);
|
||||
|
||||
const unsigned char *lmshift_lump = (const unsigned char *)BSPX_GetLump(bspdata, "LMSHIFT", NULL);
|
||||
if (!lmshift_lump && write_litfile != ~0)
|
||||
faces_sup = NULL; //no scales, no lit2
|
||||
else
|
||||
{ //we have scales or lit2 output. yay...
|
||||
if (lmshift_lump || (write_litfile&2) || (write_luxfile&2) || facestyles)
|
||||
{ //we have scales/bspx/lit2 output. yay...
|
||||
faces_sup = (facesup_t *)malloc(sizeof(*faces_sup) * bsp->numfaces);
|
||||
memset(faces_sup, 0, sizeof(*faces_sup) * bsp->numfaces);
|
||||
if (lmshift_lump)
|
||||
|
|
@ -435,6 +434,10 @@ LightWorld(bspdata_t *bspdata, qboolean forcedscale)
|
|||
faces_sup[i].lmscale = modelinfo.at(0)->lightmapscale;
|
||||
}
|
||||
}
|
||||
else
|
||||
faces_sup = NULL; //no scales, no lit2, no -bspx
|
||||
if (!facestyles)
|
||||
facestyles = 4;
|
||||
|
||||
CalcualateVertexNormals(bsp);
|
||||
|
||||
|
|
@ -484,20 +487,69 @@ LightWorld(bspdata_t *bspdata, qboolean forcedscale)
|
|||
}
|
||||
logprint("lightdatasize: %i\n", bsp->lightdatasize);
|
||||
|
||||
if (faces_sup) {
|
||||
uint8_t *styles = (uint8_t *)malloc(sizeof(*styles)*4*bsp->numfaces);
|
||||
int32_t *offsets = (int32_t *)malloc(sizeof(*offsets)*bsp->numfaces);
|
||||
//kill this stuff if it lingered from a previous light compile
|
||||
BSPX_AddLump(bspdata, "LMSTYLE16", NULL, 0);
|
||||
BSPX_AddLump(bspdata, "LMSTYLE", NULL, 0);
|
||||
BSPX_AddLump(bspdata, "LMOFFSET", NULL, 0);
|
||||
|
||||
//write out new stuff if we have it.
|
||||
if (faces_sup)
|
||||
{
|
||||
bool needoffsets = false;
|
||||
bool needstyles = false;
|
||||
int maxstyle = 0;
|
||||
int stylesperface = 0;
|
||||
|
||||
for (int i = 0; i < bsp->numfaces; i++) {
|
||||
offsets[i] = faces_sup[i].lightofs;
|
||||
for (int j = 0; j < MAXLIGHTMAPS; j++)
|
||||
styles[i*4+j] = faces_sup[i].styles[j];
|
||||
if (bsp->dfaces[i].lightofs != faces_sup[i].lightofs)
|
||||
needoffsets = true;
|
||||
int j = 0;
|
||||
for (; j < MAXLIGHTMAPSSUP; j++) {
|
||||
if (faces_sup[i].styles[j] == INVALID_LIGHTSTYLE)
|
||||
break;
|
||||
if (bsp->dfaces[i].styles[j] != faces_sup[i].styles[j])
|
||||
needstyles = true;
|
||||
if (maxstyle < faces_sup[i].styles[j])
|
||||
maxstyle = faces_sup[i].styles[j];
|
||||
}
|
||||
if (stylesperface < j)
|
||||
stylesperface = j;
|
||||
}
|
||||
needstyles |= (stylesperface>4);
|
||||
|
||||
logprint("max %i styles per face%s\n", stylesperface, maxstyle >= INVALID_LIGHTSTYLE_OLD?", 16bit lightstyles":"");
|
||||
|
||||
if (needstyles)
|
||||
{
|
||||
if (maxstyle >= INVALID_LIGHTSTYLE_OLD/*needs bigger datatype*/) {
|
||||
/*LMSTYLE16 lump provides for more than 4 styles per surface, as well as more than 255 styles*/
|
||||
uint16_t *styles = (uint16_t *)malloc(sizeof(*styles)*stylesperface*bsp->numfaces);
|
||||
for (int i = 0; i < bsp->numfaces; i++) {
|
||||
for (int j = 0; j < stylesperface; j++)
|
||||
styles[i*stylesperface+j] = faces_sup[i].styles[j];
|
||||
}
|
||||
BSPX_AddLump(bspdata, "LMSTYLE16", styles, sizeof(*styles)*stylesperface*bsp->numfaces);
|
||||
}
|
||||
else {
|
||||
/*original LMSTYLE lump was just for different lmshift info*/
|
||||
if (stylesperface < 4)
|
||||
stylesperface = 4; /*better compat*/
|
||||
uint8_t *styles = (uint8_t *)malloc(sizeof(*styles)*stylesperface*bsp->numfaces);
|
||||
for (int i = 0; i < bsp->numfaces; i++) {
|
||||
for (int j = 0; j < stylesperface; j++)
|
||||
styles[i*stylesperface+j] = faces_sup[i].styles[j];
|
||||
}
|
||||
BSPX_AddLump(bspdata, "LMSTYLE", styles, sizeof(*styles)*stylesperface*bsp->numfaces);
|
||||
}
|
||||
}
|
||||
if (needoffsets)
|
||||
{
|
||||
int32_t *offsets = (int32_t *)malloc(sizeof(*offsets)*bsp->numfaces);
|
||||
for (int i = 0; i < bsp->numfaces; i++) {
|
||||
offsets[i] = faces_sup[i].lightofs;
|
||||
}
|
||||
BSPX_AddLump(bspdata, "LMOFFSET", offsets, sizeof(*offsets)*bsp->numfaces);
|
||||
}
|
||||
BSPX_AddLump(bspdata, "LMSTYLE", styles, sizeof(*styles)*4*bsp->numfaces);
|
||||
BSPX_AddLump(bspdata, "LMOFFSET", offsets, sizeof(*offsets)*bsp->numfaces);
|
||||
} else {
|
||||
//kill this stuff if its somehow found.
|
||||
BSPX_AddLump(bspdata, "LMSTYLE", NULL, 0);
|
||||
BSPX_AddLump(bspdata, "LMOFFSET", NULL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -810,7 +862,8 @@ static void PrintUsage()
|
|||
" -bspxlit writes rgb data into the bsp itself\n"
|
||||
" -bspx writes both rgb and directions data into the bsp itself\n"
|
||||
" -novanilla implies -bspxlit. don't write vanilla lighting\n"
|
||||
" -radlights filename.rad loads a <surfacename> <r> <g> <b> <intensity> file\n");
|
||||
" -radlights filename.rad loads a <surfacename> <r> <g> <b> <intensity> file\n"
|
||||
" -facestyles n (bspx) overrides the max number of lightstyles per face\n");
|
||||
|
||||
printf("\n");
|
||||
printf("Overridable worldspawn keys:\n");
|
||||
|
|
@ -997,6 +1050,11 @@ light_main(int argc, const char **argv)
|
|||
} else if (!strcmp(argv[i], "-bspx")) {
|
||||
write_litfile |= 2;
|
||||
write_luxfile |= 2;
|
||||
} else if (!strcmp(argv[i], "-facestyles")) {
|
||||
if ((i + 1) < argc && isdigit(argv[i + 1][0]))
|
||||
facestyles = atoi(argv[++i]);
|
||||
else
|
||||
facestyles = 0;
|
||||
} else if (!strcmp(argv[i], "-novanilla")) {
|
||||
scaledonly = true;
|
||||
} else if ( !strcmp( argv[ i ], "-radlights" ) ) {
|
||||
|
|
|
|||
|
|
@ -900,7 +900,7 @@ Lightmap_ForStyle(lightmapdict_t *lightmaps, const int style, const lightsurf_t
|
|||
|
||||
// no exact match, check for an unsaved one
|
||||
for (auto &lm : *lightmaps) {
|
||||
if (lm.style == 255) {
|
||||
if (lm.style == INVALID_LIGHTSTYLE) {
|
||||
Lightmap_AllocOrClear(&lm, lightsurf);
|
||||
return &lm;
|
||||
}
|
||||
|
|
@ -908,7 +908,7 @@ Lightmap_ForStyle(lightmapdict_t *lightmaps, const int style, const lightsurf_t
|
|||
|
||||
// add a new one to the vector (invalidates existing lightmap_t pointers)
|
||||
lightmap_t newLightmap {};
|
||||
newLightmap.style = 255;
|
||||
newLightmap.style = INVALID_LIGHTSTYLE;
|
||||
Lightmap_AllocOrClear(&newLightmap, lightsurf);
|
||||
lightmaps->push_back(newLightmap);
|
||||
|
||||
|
|
@ -919,7 +919,7 @@ static void
|
|||
Lightmap_ClearAll(lightmapdict_t *lightmaps)
|
||||
{
|
||||
for (auto &lm : *lightmaps) {
|
||||
lm.style = 255;
|
||||
lm.style = INVALID_LIGHTSTYLE;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -933,7 +933,7 @@ static void
|
|||
Lightmap_Save(lightmapdict_t *lightmaps, const lightsurf_t *lightsurf,
|
||||
lightmap_t *lightmap, const int style)
|
||||
{
|
||||
if (lightmap->style == 255) {
|
||||
if (lightmap->style == INVALID_LIGHTSTYLE) {
|
||||
lightmap->style = style;
|
||||
}
|
||||
}
|
||||
|
|
@ -3072,13 +3072,25 @@ WriteLightmaps(const mbsp_t *bsp, bsp2_dface_t *face, facesup_t *facesup, const
|
|||
return;
|
||||
}
|
||||
|
||||
int maxfstyles = facesup?MAXLIGHTMAPSSUP:MAXLIGHTMAPS;
|
||||
if (maxfstyles > facestyles)
|
||||
maxfstyles = facestyles; //truncate it a little
|
||||
int maxstyle = facesup?INVALID_LIGHTSTYLE:INVALID_LIGHTSTYLE_OLD;
|
||||
|
||||
// intermediate collection for sorting lightmaps
|
||||
std::vector<std::pair<float, const lightmap_t *>> sortable;
|
||||
|
||||
for (const lightmap_t &lightmap : *lightmaps) {
|
||||
// skip un-saved lightmaps
|
||||
if (lightmap.style == 255)
|
||||
if (lightmap.style == INVALID_LIGHTSTYLE)
|
||||
continue;
|
||||
if (lightmap.style > maxstyle) {
|
||||
logprint("WARNING: Style %i too high\n"
|
||||
" lightmap point near (%s)\n",
|
||||
lightmap.style,
|
||||
VecStr(lightsurf->points[0]).c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
// skip lightmaps where all samples have brightness below 1
|
||||
if (bsp->loadversion != Q2_BSPVERSION) { // HACK: don't do this on Q2. seems if all styles are 0xff, the face is drawn fullbright instead of black (Q1)
|
||||
|
|
@ -3097,7 +3109,7 @@ WriteLightmaps(const mbsp_t *bsp, bsp2_dface_t *face, facesup_t *facesup, const
|
|||
|
||||
std::vector<const lightmap_t *> sorted;
|
||||
for (const auto &pair : sortable) {
|
||||
if (sorted.size() == MAXLIGHTMAPS) {
|
||||
if (sorted.size() == maxfstyles) {
|
||||
logprint("WARNING: Too many light styles on a face\n"
|
||||
" lightmap point near (%s)\n",
|
||||
VecStr(lightsurf->points[0]).c_str());
|
||||
|
|
@ -3109,7 +3121,7 @@ WriteLightmaps(const mbsp_t *bsp, bsp2_dface_t *face, facesup_t *facesup, const
|
|||
|
||||
/* final number of lightmaps */
|
||||
const int numstyles = static_cast<int>(sorted.size());
|
||||
Q_assert(numstyles <= MAXLIGHTMAPS);
|
||||
Q_assert(numstyles <= MAXLIGHTMAPSSUP);
|
||||
|
||||
/* update face info (either core data or supplementary stuff) */
|
||||
if (facesup)
|
||||
|
|
@ -3120,8 +3132,8 @@ WriteLightmaps(const mbsp_t *bsp, bsp2_dface_t *face, facesup_t *facesup, const
|
|||
for (mapnum = 0; mapnum < numstyles; mapnum++) {
|
||||
facesup->styles[mapnum] = sorted.at(mapnum)->style;
|
||||
}
|
||||
for (; mapnum < MAXLIGHTMAPS; mapnum++) {
|
||||
facesup->styles[mapnum] = 255;
|
||||
for (; mapnum < MAXLIGHTMAPSSUP; mapnum++) {
|
||||
facesup->styles[mapnum] = INVALID_LIGHTSTYLE;
|
||||
}
|
||||
facesup->lmscale = lightsurf->lightmapscale;
|
||||
}
|
||||
|
|
@ -3132,7 +3144,7 @@ WriteLightmaps(const mbsp_t *bsp, bsp2_dface_t *face, facesup_t *facesup, const
|
|||
face->styles[mapnum] = sorted.at(mapnum)->style;
|
||||
}
|
||||
for (; mapnum < MAXLIGHTMAPS; mapnum++) {
|
||||
face->styles[mapnum] = 255;
|
||||
face->styles[mapnum] = INVALID_LIGHTSTYLE_OLD;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3297,14 +3309,14 @@ LightFace(const mbsp_t *bsp, bsp2_dface_t *face, facesup_t *facesup, const globa
|
|||
if (facesup)
|
||||
{
|
||||
facesup->lightofs = -1;
|
||||
for (int i = 0; i < MAXLIGHTMAPS; i++)
|
||||
facesup->styles[i] = 255;
|
||||
for (int i = 0; i < MAXLIGHTMAPSSUP; i++)
|
||||
facesup->styles[i] = INVALID_LIGHTSTYLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
face->lightofs = -1;
|
||||
for (int i = 0; i < MAXLIGHTMAPS; i++)
|
||||
face->styles[i] = 255;
|
||||
face->styles[i] = INVALID_LIGHTSTYLE_OLD;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue