From afb6583375658686ca5ddba8eb2d94e4494a1c12 Mon Sep 17 00:00:00 2001 From: Spike Date: Fri, 15 Dec 2017 04:01:14 +0000 Subject: [PATCH] Added lightmap scaling. --- Quake/bspfile.h | 2 + Quake/gl_model.c | 108 ++++++++++++++++++++++++++++++++++++++++------ Quake/gl_model.h | 1 + Quake/gl_rlight.c | 6 +-- Quake/pr_ext.c | 6 +-- Quake/r_brush.c | 35 ++++++++------- 6 files changed, 122 insertions(+), 36 deletions(-) diff --git a/Quake/bspfile.h b/Quake/bspfile.h index 7a88ac92..db7f1fa7 100644 --- a/Quake/bspfile.h +++ b/Quake/bspfile.h @@ -244,6 +244,8 @@ typedef struct } dledge_t; #define MAXLIGHTMAPS 4 +#define LMBLOCK_WIDTH 256 +#define LMBLOCK_HEIGHT 256 typedef struct { short planenum; diff --git a/Quake/gl_model.c b/Quake/gl_model.c index cad5e728..556804a6 100644 --- a/Quake/gl_model.c +++ b/Quake/gl_model.c @@ -37,6 +37,7 @@ qmodel_t *Mod_LoadModel (qmodel_t *mod, qboolean crash); cvar_t external_ents = {"external_ents", "1", CVAR_ARCHIVE}; cvar_t gl_load24bit = {"gl_load24bit", "1", CVAR_ARCHIVE}; +cvar_t mod_ignorelmscale = {"mod_ignorelmscale", "0"}; static byte *mod_novis; static int mod_novis_capacity; @@ -61,6 +62,7 @@ void Mod_Init (void) Cvar_RegisterVariable (&gl_subdivide_size); Cvar_RegisterVariable (&external_ents); Cvar_RegisterVariable (&gl_load24bit); + Cvar_RegisterVariable (&mod_ignorelmscale); //johnfitz -- create notexture miptex r_notexture_mip = (texture_t *) Hunk_AllocName (sizeof(texture_t), "r_notexture_mip"); @@ -469,12 +471,13 @@ static char *bspxbase; static bspx_header_t *bspxheader; //supported lumps: //RGBLIGHTING (.lit) +//LMSHIFT (.lit2) +//LMOFFSET (LMSHIFT helper) +//LMSTYLE (LMSHIFT helper) + //unsupported lumps ('documented' elsewhere): //BRUSHLIST (because hulls suck) //LIGHTINGDIR (.lux) -//LMSHIFT (.lit2) -//LMOFFSET (.lit2) -//LMSTYLE (.lit2) static void *Q1BSPX_FindLump(char *lumpname, int *lumpsize) { int i; @@ -999,6 +1002,46 @@ _load_embedded: } +/* +================= +Mod_ParseWorldspawnKey +================= +(Blame Spike) +This just quickly scans the worldspawn entity for a single key. Returning both _prefixed and non prefixed keys. +(wantkey argument should not have a _prefix.) +*/ +const char *Mod_ParseWorldspawnKey(qmodel_t *mod, const char *wantkey, char *buffer, size_t sizeofbuffer) +{ + char foundkey[128]; + const char *data = COM_Parse(mod->entities); + + if (data && com_token[0] == '{') + { + while (1) + { + data = COM_Parse(data); + if (!data) + break; // error + if (com_token[0] == '}') + break; // end of worldspawn + if (com_token[0] == '_') + strcpy(foundkey, com_token + 1); + else + strcpy(foundkey, com_token); + data = COM_Parse(data); + if (!data) + break; // error + if (!strcmp(wantkey, foundkey)) + { + q_strlcpy(buffer, com_token, sizeofbuffer); + return buffer; + } + } + } + return NULL; +} + + /* ================= Mod_LoadVertexes @@ -1164,6 +1207,7 @@ void CalcSurfaceExtents (msurface_t *s) mvertex_t *v; mtexinfo_t *tex; int bmins[2], bmaxs[2]; + int maxextent, lmscale; mins[0] = mins[1] = FLT_MAX; maxs[0] = maxs[1] = -FLT_MAX; @@ -1207,15 +1251,18 @@ void CalcSurfaceExtents (msurface_t *s) } } + lmscale = 1<lmshift; + maxextent = q_max(LMBLOCK_WIDTH,LMBLOCK_HEIGHT)*lmscale; + for (i=0 ; i<2 ; i++) { - bmins[i] = floor(mins[i]/16); - bmaxs[i] = ceil(maxs[i]/16); + bmins[i] = floor(mins[i]/lmscale); + bmaxs[i] = ceil(maxs[i]/lmscale); - s->texturemins[i] = bmins[i] * 16; - s->extents[i] = (bmaxs[i] - bmins[i]) * 16; + s->texturemins[i] = bmins[i] * lmscale; + s->extents[i] = (bmaxs[i] - bmins[i]) * lmscale; - if ( !(tex->flags & TEX_SPECIAL) && s->extents[i] > 2000) //johnfitz -- was 512 in glquake, 256 in winquake + if ( !(tex->flags & TEX_SPECIAL) && s->extents[i] > maxextent) //johnfitz -- was 512 in glquake, 256 in winquake Sys_Error ("Bad surface extents"); } } @@ -1314,9 +1361,15 @@ void Mod_LoadFaces (lump_t *l, qboolean bsp2) dsface_t *ins; dlface_t *inl; msurface_t *out; - int i, count, surfnum, lofs; + int i, count, surfnum, lofs, shift; int planenum, side, texinfon; + unsigned char *lmshift = NULL, defaultshift = 4; + unsigned int *lmoffset = NULL; + unsigned char *lmstyle = NULL; + int lumpsize; + char scalebuf[16]; + if (bsp2) { ins = NULL; @@ -1340,13 +1393,33 @@ void Mod_LoadFaces (lump_t *l, qboolean bsp2) Con_DWarning ("%i faces exceeds standard limit of 32767.\n", count); //johnfitz + if (!mod_ignorelmscale.value) + { + lmshift = Q1BSPX_FindLump("LMSHIFT", &lumpsize); + if (lumpsize != sizeof(*lmshift)*count) + lmshift = NULL; + lmoffset = Q1BSPX_FindLump("LMOFFSET", &lumpsize); + if (lumpsize != sizeof(*lmoffset)*count) + lmoffset = NULL; + lmstyle = Q1BSPX_FindLump("LMSTYLE", &lumpsize); + if (lumpsize != sizeof(*lmstyle)*MAXLIGHTMAPS*count) + lmstyle = NULL; + + if (Mod_ParseWorldspawnKey(loadmodel, "lightmap_scale", scalebuf, sizeof(scalebuf))) + { + i = atoi(scalebuf); + for (defaultshift = 0; (1<surfaces = out; loadmodel->numsurfaces = count; for (surfnum=0 ; surfnumfirstedge = LittleLong(inl->firstedge); out->numedges = LittleLong(inl->numedges); planenum = LittleLong(inl->planenum); @@ -1358,7 +1431,7 @@ void Mod_LoadFaces (lump_t *l, qboolean bsp2) inl++; } else - { + { //16bit datatypes out->firstedge = LittleLong(ins->firstedge); out->numedges = LittleShort(ins->numedges); planenum = LittleShort(ins->planenum); @@ -1369,6 +1442,15 @@ void Mod_LoadFaces (lump_t *l, qboolean bsp2) lofs = LittleLong(ins->lightofs); ins++; } + shift = defaultshift; + //bspx overrides (for lmscale) + if (lmstyle) + shift = lmshift[surfnum]; + if (lmoffset) + lofs = LittleLong(lmoffset[surfnum]); + if (lmstyle) + for (i=0 ; istyles[i] = lmstyle[surfnum*MAXLIGHTMAPS+i]; out->flags = 0; @@ -1376,8 +1458,8 @@ void Mod_LoadFaces (lump_t *l, qboolean bsp2) out->flags |= SURF_PLANEBACK; out->plane = loadmodel->planes + planenum; - out->texinfo = loadmodel->texinfo + texinfon; + out->lmshift = shift; CalcSurfaceExtents (out); @@ -2357,13 +2439,13 @@ void Mod_LoadBrushModel (qmodel_t *mod, void *buffer) Mod_LoadLighting (&header->lumps[LUMP_LIGHTING]); Mod_LoadPlanes (&header->lumps[LUMP_PLANES]); Mod_LoadTexinfo (&header->lumps[LUMP_TEXINFO]); + Mod_LoadEntities (&header->lumps[LUMP_ENTITIES]); //Spike: moved this earlier, so that we can parse worldspawn keys earlier. Mod_LoadFaces (&header->lumps[LUMP_FACES], bsp2); Mod_LoadMarksurfaces (&header->lumps[LUMP_MARKSURFACES], bsp2); Mod_LoadVisibility (&header->lumps[LUMP_VISIBILITY]); Mod_LoadLeafs (&header->lumps[LUMP_LEAFS], bsp2); Mod_LoadNodes (&header->lumps[LUMP_NODES], bsp2); Mod_LoadClipnodes (&header->lumps[LUMP_CLIPNODES], bsp2); - Mod_LoadEntities (&header->lumps[LUMP_ENTITIES]); Mod_LoadSubmodels (&header->lumps[LUMP_MODELS]); Mod_MakeHull0 (); diff --git a/Quake/gl_model.h b/Quake/gl_model.h index 5a1db951..43f075ba 100644 --- a/Quake/gl_model.h +++ b/Quake/gl_model.h @@ -147,6 +147,7 @@ typedef struct msurface_s short extents[2]; int light_s, light_t; // gl lightmap coordinates + unsigned char lmshift; glpoly_t *polys; // multiple if warped struct msurface_s *texturechain; diff --git a/Quake/gl_rlight.c b/Quake/gl_rlight.c index eee4e9fb..7036b139 100644 --- a/Quake/gl_rlight.c +++ b/Quake/gl_rlight.c @@ -346,9 +346,9 @@ loc0: byte *lightmap; int maps, line3, dsfrac = ds & 15, dtfrac = dt & 15, r00 = 0, g00 = 0, b00 = 0, r01 = 0, g01 = 0, b01 = 0, r10 = 0, g10 = 0, b10 = 0, r11 = 0, g11 = 0, b11 = 0; float scale; - line3 = ((surf->extents[0]>>4)+1)*3; + line3 = ((surf->extents[0]>>surf->lmshift)+1)*3; - lightmap = surf->samples + ((dt>>4) * ((surf->extents[0]>>4)+1) + (ds>>4))*3; // LordHavoc: *3 for color + lightmap = surf->samples + ((dt>>surf->lmshift) * ((surf->extents[0]>>surf->lmshift)+1) + (ds>>surf->lmshift))*3; // LordHavoc: *3 for color for (maps = 0;maps < MAXLIGHTMAPS && surf->styles[maps] != 255;maps++) { @@ -357,7 +357,7 @@ loc0: r01 += (float) lightmap[ 3] * scale;g01 += (float) lightmap[ 4] * scale;b01 += (float) lightmap[5] * scale; r10 += (float) lightmap[line3+0] * scale;g10 += (float) lightmap[line3+1] * scale;b10 += (float) lightmap[line3+2] * scale; r11 += (float) lightmap[line3+3] * scale;g11 += (float) lightmap[line3+4] * scale;b11 += (float) lightmap[line3+5] * scale; - lightmap += ((surf->extents[0]>>4)+1) * ((surf->extents[1]>>4)+1)*3; // LordHavoc: *3 for colored lighting + lightmap += ((surf->extents[0]>>surf->lmshift)+1) * ((surf->extents[1]>>surf->lmshift)+1)*3; // LordHavoc: *3 for colored lighting } color[0] += (float) ((int) ((((((((r11-r10) * dsfrac) >> 4) + r10)-((((r01-r00) * dsfrac) >> 4) + r00)) * dtfrac) >> 4) + ((((r01-r00) * dsfrac) >> 4) + r00))); diff --git a/Quake/pr_ext.c b/Quake/pr_ext.c index 213971af..916530db 100644 --- a/Quake/pr_ext.c +++ b/Quake/pr_ext.c @@ -1851,10 +1851,8 @@ static void PF_getsurfacepointattribute(void) G_FLOAT(OFS_RETURN+2) = 0; break; case 5: //lmst coord, not actually very useful -#define BLOCK_WIDTH 128 -#define BLOCK_HEIGHT 128 - G_FLOAT(OFS_RETURN+0) = (DotProduct(v->position, fa->texinfo->vecs[0]) + fa->texinfo->vecs[0][3] - fa->texturemins[0] + fa->light_s*16+8) / (BLOCK_WIDTH*16); - G_FLOAT(OFS_RETURN+1) = (DotProduct(v->position, fa->texinfo->vecs[1]) + fa->texinfo->vecs[1][3] - fa->texturemins[1] + fa->light_t*16+8) / (BLOCK_HEIGHT*16); + G_FLOAT(OFS_RETURN+0) = (DotProduct(v->position, fa->texinfo->vecs[0]) + fa->texinfo->vecs[0][3] - fa->texturemins[0] + (fa->light_s+.5)*(1<lmshift)) / (LMBLOCK_WIDTH*(1<lmshift)); + G_FLOAT(OFS_RETURN+1) = (DotProduct(v->position, fa->texinfo->vecs[1]) + fa->texinfo->vecs[1][3] - fa->texturemins[1] + (fa->light_t+.5)*(1<lmshift)) / (LMBLOCK_HEIGHT*(1<lmshift)); G_FLOAT(OFS_RETURN+2) = 0; break; case 6: //colour diff --git a/Quake/r_brush.c b/Quake/r_brush.c index 186d8f5d..967a919c 100644 --- a/Quake/r_brush.c +++ b/Quake/r_brush.c @@ -690,8 +690,8 @@ dynamic: theRect->w += theRect->l - fa->light_s; theRect->l = fa->light_s; } - smax = (fa->extents[0]>>4)+1; - tmax = (fa->extents[1]>>4)+1; + smax = (fa->extents[0]>>fa->lmshift)+1; + tmax = (fa->extents[1]>>fa->lmshift)+1; if ((theRect->w + theRect->l) < (fa->light_s + smax)) theRect->w = (fa->light_s-theRect->l)+smax; if ((theRect->h + theRect->t) < (fa->light_t + tmax)) @@ -782,8 +782,8 @@ void GL_CreateSurfaceLightmap (qmodel_t *model, msurface_t *surf) int smax, tmax; byte *base; - smax = (surf->extents[0]>>4)+1; - tmax = (surf->extents[1]>>4)+1; + smax = (surf->extents[0]>>surf->lmshift)+1; + tmax = (surf->extents[1]>>surf->lmshift)+1; surf->lightmaptexturenum = AllocBlock (smax, tmax, &surf->light_s, &surf->light_t); base = lightmap[surf->lightmaptexturenum].data; @@ -803,6 +803,7 @@ void BuildSurfaceDisplayList (msurface_t *fa) float *vec; float s, t; glpoly_t *poly; + int lmscale = (1<lmshift); // reconstruct the polygon pedges = currentmodel->edges; @@ -845,15 +846,15 @@ void BuildSurfaceDisplayList (msurface_t *fa) // s = DotProduct (vec, fa->texinfo->vecs[0]) + fa->texinfo->vecs[0][3]; s -= fa->texturemins[0]; - s += fa->light_s*16; - s += 8; - s /= LMBLOCK_WIDTH*16; //fa->texinfo->texture->width; + s += fa->light_s*lmscale; + s += lmscale/2.0; + s /= LMBLOCK_WIDTH*lmscale; //fa->texinfo->texture->width; t = DotProduct (vec, fa->texinfo->vecs[1]) + fa->texinfo->vecs[1][3]; t -= fa->texturemins[1]; - t += fa->light_t*16; - t += 8; - t /= LMBLOCK_HEIGHT*16; //fa->texinfo->texture->height; + t += fa->light_t*lmscale; + t += lmscale/2.0; + t /= LMBLOCK_HEIGHT*lmscale; //fa->texinfo->texture->height; poly->verts[i][5] = s; poly->verts[i][6] = t; @@ -1056,10 +1057,12 @@ void R_AddDynamicLights (msurface_t *surf) float cred, cgreen, cblue, brightness; unsigned *bl; //johnfitz + int lmscale; - smax = (surf->extents[0]>>4)+1; - tmax = (surf->extents[1]>>4)+1; + smax = (surf->extents[0]>>surf->lmshift)+1; + tmax = (surf->extents[1]>>surf->lmshift)+1; tex = surf->texinfo; + lmscale = 1<lmshift; for (lnum=0 ; lnum td) @@ -1142,8 +1145,8 @@ void R_BuildLightMap (qmodel_t *model, msurface_t *surf, byte *dest, int stride) surf->cached_dlight = (surf->dlightframe == r_framecount); - smax = (surf->extents[0]>>4)+1; - tmax = (surf->extents[1]>>4)+1; + smax = (surf->extents[0]>>surf->lmshift)+1; + tmax = (surf->extents[1]>>surf->lmshift)+1; size = smax*tmax; lightmap = surf->samples;