Merge pull request #47 from 0lvin/rerelease

Support lightmap from Q2 ReRelease
This commit is contained in:
Denis Pauk 2023-08-22 17:08:18 +03:00 committed by GitHub
commit 5ba12c08b4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 239 additions and 65 deletions

View file

@ -333,6 +333,7 @@ typedef struct m32tex_s
/* .BSP file format */ /* .BSP file format */
#define IDBSPHEADER (('P' << 24) + ('S' << 16) + ('B' << 8) + 'I') /* little-endian "IBSP" */ #define IDBSPHEADER (('P' << 24) + ('S' << 16) + ('B' << 8) + 'I') /* little-endian "IBSP" */
#define BSPXHEADER (('X' << 24) + ('P' << 16) + ('S' << 8) + 'B') /* little-endian "BSPX" */
#define BSPVERSION 38 #define BSPVERSION 38
/* upper design bounds: leaffaces, leafbrushes, planes, and /* upper design bounds: leaffaces, leafbrushes, planes, and
@ -399,6 +400,17 @@ typedef struct
lump_t lumps[HEADER_LUMPS]; lump_t lumps[HEADER_LUMPS];
} dheader_t; } dheader_t;
typedef struct bspx_header_s {
int ident; // 'BSPX'
int numlumps;
} bspx_header_t;
typedef struct {
char lumpname[24];
int fileofs;
int filelen;
} bspx_lump_t;
typedef struct typedef struct
{ {
float mins[3], maxs[3]; float mins[3], maxs[3];
@ -521,6 +533,13 @@ typedef struct
int lightofs; /* start of [numstyles*surfsize] samples */ int lightofs; /* start of [numstyles*surfsize] samples */
} dface_t; } dface_t;
typedef struct {
unsigned short lmwidth;
unsigned short lmheight;
int lightofs;
float vecs[2][4];
} dlminfo_t;
typedef struct typedef struct
{ {
int contents; /* OR of all brushes (not needed?) */ int contents; /* OR of all brushes (not needed?) */

View file

@ -43,6 +43,7 @@ BRUSH MODELS
// //
#define VERTEXSIZE 7 #define VERTEXSIZE 7
#define DEFAULT_LMSHIFT 4
typedef struct vkpoly_s typedef struct vkpoly_s
{ {
@ -66,6 +67,8 @@ typedef struct msurface_s
short texturemins[2]; short texturemins[2];
short extents[2]; short extents[2];
short lmshift;
int light_s, light_t; // gl lightmap coordinates int light_s, light_t; // gl lightmap coordinates
int dlight_s, dlight_t; // gl lightmap coordinates for dynamic lightmaps int dlight_s, dlight_t; // gl lightmap coordinates for dynamic lightmaps
@ -75,7 +78,11 @@ typedef struct msurface_s
mtexinfo_t *texinfo; mtexinfo_t *texinfo;
// lighting info /* decoupled lm */
float lmvecs[2][4];
float lmvlen[2];
/* lighting info */
int dlightframe; int dlightframe;
int dlightbits; int dlightbits;

View file

@ -215,9 +215,9 @@ RecursiveLightPoint(mnode_t *node, vec3_t start, vec3_t end, vec3_t pointcolor)
} }
frac = front / (front-back); frac = front / (front-back);
mid[0] = start[0] + (end[0] - start[0])*frac; mid[0] = start[0] + (end[0] - start[0]) * frac;
mid[1] = start[1] + (end[1] - start[1])*frac; mid[1] = start[1] + (end[1] - start[1]) * frac;
mid[2] = start[2] + (end[2] - start[2])*frac; mid[2] = start[2] + (end[2] - start[2]) * frac;
/* go down front side */ /* go down front side */
r = RecursiveLightPoint(node->children[side], start, mid, pointcolor); r = RecursiveLightPoint(node->children[side], start, mid, pointcolor);
@ -262,13 +262,13 @@ RecursiveLightPoint(mnode_t *node, vec3_t start, vec3_t end, vec3_t pointcolor)
return 0; return 0;
} }
ds >>= 4; ds >>= surf->lmshift;
dt >>= 4; dt >>= surf->lmshift;
lightmap = surf->samples; lightmap = surf->samples;
VectorCopy(vec3_origin, pointcolor); VectorCopy(vec3_origin, pointcolor);
lightmap += 3 * (dt * ((surf->extents[0] >> 4) + 1) + ds); lightmap += 3 * (dt * ((surf->extents[0] >> surf->lmshift) + 1) + ds);
for (maps = 0; maps < MAXLIGHTMAPS && surf->styles[maps] != 255; maps++) for (maps = 0; maps < MAXLIGHTMAPS && surf->styles[maps] != 255; maps++)
{ {
@ -276,14 +276,14 @@ RecursiveLightPoint(mnode_t *node, vec3_t start, vec3_t end, vec3_t pointcolor)
for (j = 0; j < 3; j++) for (j = 0; j < 3; j++)
{ {
scale[j] = r_modulate->value*r_newrefdef.lightstyles[surf->styles[maps]].rgb[j]; scale[j] = r_modulate->value * r_newrefdef.lightstyles[surf->styles[maps]].rgb[j];
} }
pointcolor[0] += lightmap[0] * scale[0] * (1.0/255); pointcolor[0] += lightmap[0] * scale[0] * (1.0/255);
pointcolor[1] += lightmap[1] * scale[1] * (1.0/255); pointcolor[1] += lightmap[1] * scale[1] * (1.0/255);
pointcolor[2] += lightmap[2] * scale[2] * (1.0/255); pointcolor[2] += lightmap[2] * scale[2] * (1.0/255);
lightmap += 3 * ((surf->extents[0] >> 4) + 1) * lightmap += 3 * ((surf->extents[0] >> surf->lmshift) + 1) *
((surf->extents[1] >> 4) + 1); ((surf->extents[1] >> surf->lmshift) + 1);
} }
return 1; return 1;
@ -367,14 +367,12 @@ R_AddDynamicLights(msurface_t *surf)
int s, t; int s, t;
int i; int i;
int smax, tmax; int smax, tmax;
mtexinfo_t *tex;
dlight_t *dl; dlight_t *dl;
float *plightdest; float *plightdest;
float fsacc, ftacc; float fsacc, ftacc;
smax = (surf->extents[0] >> 4) + 1; smax = (surf->extents[0] >> surf->lmshift) + 1;
tmax = (surf->extents[1] >> 4) + 1; tmax = (surf->extents[1] >> surf->lmshift) + 1;
tex = surf->texinfo;
for (lnum=0 ; lnum<r_newrefdef.num_dlights ; lnum++) for (lnum=0 ; lnum<r_newrefdef.num_dlights ; lnum++)
{ {
@ -404,23 +402,27 @@ R_AddDynamicLights(msurface_t *surf)
surf->plane->normal[i]*fdist; surf->plane->normal[i]*fdist;
} }
local[0] = DotProduct(impact, tex->vecs[0]) + tex->vecs[0][3] - surf->texturemins[0]; local[0] = DotProduct (impact, surf->lmvecs[0]) + surf->lmvecs[0][3] - surf->texturemins[0];
local[1] = DotProduct(impact, tex->vecs[1]) + tex->vecs[1][3] - surf->texturemins[1]; local[1] = DotProduct (impact, surf->lmvecs[1]) + surf->lmvecs[1][3] - surf->texturemins[1];
plightdest = s_blocklights; plightdest = s_blocklights;
for (t = 0, ftacc = 0 ; t<tmax ; t++, ftacc += 16) for (t = 0, ftacc = 0; t < tmax; t++, ftacc += (1 << surf->lmshift))
{ {
td = local[1] - ftacc; td = local[1] - ftacc;
if ( td < 0 ) if (td < 0)
td = -td; td = -td;
for ( s=0, fsacc = 0 ; s<smax ; s++, fsacc += 16, plightdest += 3) td *= surf->lmvlen[1];
for ( s=0, fsacc = 0 ; s<smax ; s++, fsacc += (1 << surf->lmshift), plightdest += 3)
{ {
sd = Q_ftol( local[0] - fsacc ); sd = Q_ftol( local[0] - fsacc );
if ( sd < 0 ) if ( sd < 0 )
sd = -sd; sd = -sd;
sd *= surf->lmvlen[0];
if (sd > td) if (sd > td)
fdist = sd + (td>>1); fdist = sd + (td>>1);
else else
@ -479,8 +481,8 @@ R_BuildLightMap(msurface_t *surf, byte *dest, int stride)
ri.Sys_Error (ERR_DROP, "R_BuildLightMap called for non-lit surface"); ri.Sys_Error (ERR_DROP, "R_BuildLightMap called for non-lit surface");
} }
smax = (surf->extents[0] >> 4) + 1; smax = (surf->extents[0] >> surf->lmshift) + 1;
tmax = (surf->extents[1] >> 4) + 1; tmax = (surf->extents[1] >> surf->lmshift) + 1;
size = smax * tmax; size = smax * tmax;
if (!s_blocklights || (s_blocklights + (size * 3) >= s_blocklights_max)) if (!s_blocklights || (s_blocklights + (size * 3) >= s_blocklights_max))

View file

@ -356,7 +356,8 @@ Vk_DrawAliasFrameLerpCommands (entity_t *currententity, int *order, int *order_e
} }
else else
{ {
meshUbo.textured = 1; /* Do not apply texture for lighmap debug case */
meshUbo.textured = r_lightmap->value ? 0 : 1;
do do
{ {
int vertIdx = vertCounts[pipelineIdx]; int vertIdx = vertCounts[pipelineIdx];

View file

@ -375,17 +375,154 @@ calcTexinfoAndFacesSize(const lump_t *fl, const byte *mod_base, const lump_t *tl
return ret; return ret;
} }
// Extension to support lightmaps that aren't tied to texture scale.
static int
Mod_LoadDecoupledLM(const dlminfo_t* lminfos, int surfnum, msurface_t *out)
{
const dlminfo_t *lminfo;
unsigned short lmwidth, lmheight;
if (lminfos == NULL) {
return -1;
}
lminfo = lminfos + surfnum;
lmwidth = LittleShort(lminfo->lmwidth);
lmheight = LittleShort(lminfo->lmheight);
if (lmwidth <= 0 || lmheight <= 0) {
return -1;
}
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 4; j++) {
out->lmvecs[i][j] = LittleFloat(lminfo->vecs[i][j]);
}
}
out->extents[0] = (short)(lmwidth - 1);
out->extents[1] = (short)(lmheight - 1);
out->lmshift = 0;
out->texturemins[0] = 0;
out->texturemins[1] = 0;
float v0 = VectorLength(out->lmvecs[0]);
out->lmvlen[0] = v0 > 0.0f ? 1.0f / v0 : 0.0f;
float v1 = VectorLength(out->lmvecs[1]);
out->lmvlen[1] = v1 > 0.0f ? 1.0f / v1 : 0.0f;
return LittleLong(lminfo->lightofs);
}
const void *
Mod_BSPX_FindLump(bspx_header_t* bspx_header, char* lumpname, int* plumpsize, const byte* mod_base)
{
int i;
bspx_lump_t* lump;
if (!bspx_header) {
return NULL;
}
lump = (bspx_lump_t*)(bspx_header + 1);
for (i = 0; i < bspx_header->numlumps; i++, lump++) {
if (!strcmp(lump->lumpname, lumpname)) {
if (plumpsize) {
*plumpsize = lump->filelen;
}
return mod_base + lump->fileofs;
}
}
return NULL;
}
bspx_header_t *
Mod_LoadBSPX(int filesize, byte* mod_base)
{
dheader_t* header;
bspx_header_t* xheader;
bspx_lump_t* lump;
int i;
int xofs;
// find end of last lump
header = (dheader_t*)mod_base;
xofs = 0;
for (i = 0; i < HEADER_LUMPS; i++) {
xofs = max(xofs,
ROUNDUP(header->lumps[i].fileofs + header->lumps[i].filelen, sizeof(int)));
}
if (xofs + sizeof(bspx_header_t) > filesize) {
return NULL;
}
xheader = (bspx_header_t*)(mod_base + xofs);
if (LittleLong(xheader->ident) != BSPXHEADER)
{
R_Printf(PRINT_ALL, "%s: Incorrect header ident.\n",
__func__, xheader->ident, BSPXHEADER);
return NULL;
}
xheader->numlumps = LittleLong(xheader->numlumps);
if (xheader->numlumps < 0 || xofs + sizeof(bspx_header_t) + xheader->numlumps * sizeof(bspx_lump_t) > filesize) {
return NULL;
}
// byte-swap and check sanity
lump = (bspx_lump_t*)(xheader + 1); // lumps immediately follow the header
for (i = 0; i < xheader->numlumps; i++, lump++) {
lump->lumpname[sizeof(lump->lumpname) - 1] = '\0'; // make sure it ends with zero
lump->fileofs = LittleLong(lump->fileofs);
lump->filelen = LittleLong(lump->filelen);
if (lump->fileofs < 0 || lump->filelen < 0 || (unsigned)(lump->fileofs + lump->filelen) >(unsigned)filesize) {
return NULL;
}
}
// success
return xheader;
}
static void
SetSurfaceLighting(model_t* loadmodel, msurface_t* out, byte* styles, int lightofs)
{
int i;
/* lighting info */
for (i = 0; i < MAXLIGHTMAPS; i++)
{
out->styles[i] = styles[i];
}
i = LittleLong(lightofs);
if (i == -1 || loadmodel->lightdata == NULL)
{
out->samples = NULL;
}
else
{
out->samples = loadmodel->lightdata + i;
}
}
/* /*
================= =================
Mod_LoadFaces Mod_LoadFaces
================= =================
*/ */
static void static void
Mod_LoadFaces (model_t *loadmodel, const byte *mod_base, const lump_t *l) Mod_LoadFaces(model_t *loadmodel, const byte *mod_base, const lump_t *l, bspx_header_t *bspx_header)
{ {
dface_t *in; int i, count, surfnum, lminfosize, lightofs;
const dlminfo_t *lminfos;
msurface_t *out; msurface_t *out;
int i, count, surfnum; dface_t *in;
in = (void *)(mod_base + l->fileofs); in = (void *)(mod_base + l->fileofs);
@ -401,6 +538,13 @@ Mod_LoadFaces (model_t *loadmodel, const byte *mod_base, const lump_t *l)
loadmodel->surfaces = out; loadmodel->surfaces = out;
loadmodel->numsurfaces = count; loadmodel->numsurfaces = count;
lminfos = Mod_BSPX_FindLump(bspx_header, "DECOUPLED_LM", &lminfosize, mod_base);
if (lminfos != NULL && lminfosize / sizeof(dlminfo_t) != loadmodel->numsurfaces) {
R_Printf(PRINT_ALL, "%s: [%s] decoupled_lm size %ld does not match surface count %d\n",
__func__, loadmodel->name, lminfosize / sizeof(dlminfo_t), loadmodel->numsurfaces);
lminfos = NULL;
}
Vk_BeginBuildingLightmaps(loadmodel); Vk_BeginBuildingLightmaps(loadmodel);
for (surfnum = 0; surfnum < count; surfnum++, in++, out++) for (surfnum = 0; surfnum < count; surfnum++, in++, out++)
@ -444,24 +588,19 @@ Mod_LoadFaces (model_t *loadmodel, const byte *mod_base, const lump_t *l)
out->texinfo = loadmodel->texinfo + ti; out->texinfo = loadmodel->texinfo + ti;
lightofs = Mod_LoadDecoupledLM(lminfos, surfnum, out);
if (lightofs < 0) {
memcpy(out->lmvecs, out->texinfo->vecs, sizeof(out->lmvecs));
out->lmshift = DEFAULT_LMSHIFT;
out->lmvlen[0] = 1.0f;
out->lmvlen[1] = 1.0f;
CalcSurfaceExtents(loadmodel, out); CalcSurfaceExtents(loadmodel, out);
/* lighting info */ lightofs = in->lightofs;
for (i = 0; i < MAXLIGHTMAPS; i++)
{
out->styles[i] = in->styles[i];
} }
i = LittleLong(in->lightofs); SetSurfaceLighting(loadmodel, out, in->styles, lightofs);
if (i == -1)
{
out->samples = NULL;
}
else
{
out->samples = loadmodel->lightdata + i;
}
/* set the drawing flags */ /* set the drawing flags */
if (out->texinfo->flags & SURF_WARP) if (out->texinfo->flags & SURF_WARP)
@ -635,9 +774,10 @@ Mod_LoadBrushModel
static void static void
Mod_LoadBrushModel (model_t *mod, const void *buffer, int modfilelen) Mod_LoadBrushModel (model_t *mod, const void *buffer, int modfilelen)
{ {
int i; bspx_header_t* bspx_header;
dheader_t *header;
byte *mod_base; byte *mod_base;
dheader_t *header;
int i;
header = (dheader_t *)buffer; header = (dheader_t *)buffer;
@ -677,6 +817,10 @@ Mod_LoadBrushModel (model_t *mod, const void *buffer, int modfilelen)
mod->extradata = Hunk_Begin(hunkSize); mod->extradata = Hunk_Begin(hunkSize);
mod->type = mod_brush; mod->type = mod_brush;
/* check for BSPX extensions */
bspx_header = Mod_LoadBSPX(modfilelen, (byte*)header);
/* load into heap */ /* load into heap */
Mod_LoadVertexes(mod->name, &mod->vertexes, &mod->numvertexes, mod_base, Mod_LoadVertexes(mod->name, &mod->vertexes, &mod->numvertexes, mod_base,
&header->lumps[LUMP_VERTEXES], 0); &header->lumps[LUMP_VERTEXES], 0);
@ -685,14 +829,14 @@ Mod_LoadBrushModel (model_t *mod, const void *buffer, int modfilelen)
Mod_LoadSurfedges(mod->name, &mod->surfedges, &mod->numsurfedges, Mod_LoadSurfedges(mod->name, &mod->surfedges, &mod->numsurfedges,
mod_base, &header->lumps[LUMP_SURFEDGES], 0); mod_base, &header->lumps[LUMP_SURFEDGES], 0);
Mod_LoadLighting(&mod->lightdata, mod_base, &header->lumps[LUMP_LIGHTING]); Mod_LoadLighting(&mod->lightdata, mod_base, &header->lumps[LUMP_LIGHTING]);
Mod_LoadPlanes (mod->name, &mod->planes, &mod->numplanes, Mod_LoadPlanes(mod->name, &mod->planes, &mod->numplanes,
mod_base, &header->lumps[LUMP_PLANES], 0); mod_base, &header->lumps[LUMP_PLANES], 0);
Mod_LoadTexinfo(mod->name, &mod->texinfo, &mod->numtexinfo, Mod_LoadTexinfo(mod->name, &mod->texinfo, &mod->numtexinfo,
mod_base, &header->lumps[LUMP_TEXINFO], (findimage_t)Vk_FindImage, mod_base, &header->lumps[LUMP_TEXINFO], (findimage_t)Vk_FindImage,
r_notexture, 0); r_notexture, 0);
Mod_LoadFaces(mod, mod_base, &header->lumps[LUMP_FACES]); Mod_LoadFaces(mod, mod_base, &header->lumps[LUMP_FACES], bspx_header);
Mod_LoadMarksurfaces(mod, mod_base, &header->lumps[LUMP_LEAFFACES]); Mod_LoadMarksurfaces(mod, mod_base, &header->lumps[LUMP_LEAFFACES]);
Mod_LoadVisibility (&mod->vis, mod_base, &header->lumps[LUMP_VISIBILITY]); Mod_LoadVisibility(&mod->vis, mod_base, &header->lumps[LUMP_VISIBILITY]);
Mod_LoadLeafs(mod, mod_base, &header->lumps[LUMP_LEAFS]); Mod_LoadLeafs(mod, mod_base, &header->lumps[LUMP_LEAFS]);
Mod_LoadNodes(mod->name, mod->planes, mod->numplanes, mod->leafs, Mod_LoadNodes(mod->name, mod->planes, mod->numplanes, mod->leafs,
mod->numleafs, &mod->nodes, &mod->numnodes, mod_base, mod->numleafs, &mod->nodes, &mod->numnodes, mod_base,

View file

@ -303,8 +303,8 @@ static void R_RenderBrushPoly (msurface_t *fa, float *modelMatrix, float alpha,
unsigned temp[34 * 34]; unsigned temp[34 * 34];
int smax, tmax; int smax, tmax;
smax = (fa->extents[0] >> 4) + 1; smax = (fa->extents[0] >> fa->lmshift) + 1;
tmax = (fa->extents[1] >> 4) + 1; tmax = (fa->extents[1] >> fa->lmshift) + 1;
R_BuildLightMap(fa, (void *)temp, smax * 4); R_BuildLightMap(fa, (void *)temp, smax * 4);
R_SetCacheState(fa); R_SetCacheState(fa);
@ -477,8 +477,8 @@ static void Vk_RenderLightmappedPoly( msurface_t *surf, float *modelMatrix, floa
unsigned temp[128 * 128]; unsigned temp[128 * 128];
int smax, tmax; int smax, tmax;
smax = (surf->extents[0] >> 4) + 1; smax = (surf->extents[0] >> surf->lmshift) + 1;
tmax = (surf->extents[1] >> 4) + 1; tmax = (surf->extents[1] >> surf->lmshift) + 1;
R_BuildLightMap(surf, (void *)temp, smax * 4); R_BuildLightMap(surf, (void *)temp, smax * 4);
@ -1131,10 +1131,11 @@ void Vk_BuildPolygonFromSurface(msurface_t *fa, model_t *currentmodel)
lnumverts = fa->numedges; lnumverts = fa->numedges;
VectorClear (total); VectorClear (total);
// //
// draw texture // draw texture
// //
poly = Hunk_Alloc (sizeof(vkpoly_t) + (lnumverts-4) * VERTEXSIZE*sizeof(float)); poly = Hunk_Alloc (sizeof(vkpoly_t) + (lnumverts-4) * VERTEXSIZE * sizeof(float));
poly->next = fa->polys; poly->next = fa->polys;
poly->flags = fa->flags; poly->flags = fa->flags;
fa->polys = poly; fa->polys = poly;
@ -1172,17 +1173,17 @@ void Vk_BuildPolygonFromSurface(msurface_t *fa, model_t *currentmodel)
// //
// lightmap texture coordinates // lightmap texture coordinates
// //
s = DotProduct(vec, fa->texinfo->vecs[0]) + fa->texinfo->vecs[0][3]; s = DotProduct(vec, fa->lmvecs[0]) + fa->lmvecs[0][3];
s -= fa->texturemins[0]; s -= fa->texturemins[0];
s += fa->light_s*16; s += fa->light_s * (1 << fa->lmshift);
s += 8; s += (1 << fa->lmshift) * 0.5;
s /= BLOCK_WIDTH*16; //fa->texinfo->texture->width; s /= BLOCK_WIDTH * (1 << fa->lmshift);
t = DotProduct(vec, fa->texinfo->vecs[1]) + fa->texinfo->vecs[1][3]; t = DotProduct(vec, fa->lmvecs[1]) + fa->lmvecs[1][3];
t -= fa->texturemins[1]; t -= fa->texturemins[1];
t += fa->light_t*16; t += fa->light_t * (1 << fa->lmshift);
t += 8; t += (1 << fa->lmshift) * 0.5;
t /= BLOCK_HEIGHT*16; //fa->texinfo->texture->height; t /= BLOCK_HEIGHT * (1 << fa->lmshift);
poly->verts[i][5] = s; poly->verts[i][5] = s;
poly->verts[i][6] = t; poly->verts[i][6] = t;
@ -1205,8 +1206,8 @@ void Vk_CreateSurfaceLightmap (msurface_t *surf)
if (surf->flags & (SURF_DRAWSKY|SURF_DRAWTURB)) if (surf->flags & (SURF_DRAWSKY|SURF_DRAWTURB))
return; return;
smax = (surf->extents[0] >> 4) + 1; smax = (surf->extents[0] >> surf->lmshift) + 1;
tmax = (surf->extents[1] >> 4) + 1; tmax = (surf->extents[1] >> surf->lmshift) + 1;
if ( !LM_AllocBlock( smax, tmax, &surf->light_s, &surf->light_t ) ) if ( !LM_AllocBlock( smax, tmax, &surf->light_s, &surf->light_t ) )
{ {