From e48e9c67ad284fabe7d7f41ff105bf8cfe16f4e6 Mon Sep 17 00:00:00 2001 From: Shpoike Date: Tue, 1 Aug 2023 12:08:51 +0100 Subject: [PATCH] Add support for the DECOUPLED_LM bspx lump. --- engine/client/r_surf.c | 97 +++++++++++++++++++++++----------------- engine/client/render.h | 2 +- engine/common/gl_q2bsp.c | 18 +++++--- engine/common/q1bsp.c | 33 +++++++++----- engine/gl/gl_heightmap.c | 2 +- engine/gl/gl_model.c | 81 ++++++++++++++++++++++++++++----- engine/gl/gl_model.h | 17 ++++++- engine/gl/gl_rlight.c | 15 +++++-- 8 files changed, 189 insertions(+), 76 deletions(-) diff --git a/engine/client/r_surf.c b/engine/client/r_surf.c index 0ad032fcd..788017f00 100644 --- a/engine/client/r_surf.c +++ b/engine/client/r_surf.c @@ -80,7 +80,7 @@ void QDECL Surf_RebuildLightmap_Callback (struct cvar_s *var, char *oldvalue) } //radius, x y z, r g b -void Surf_StainSurf (msurface_t *surf, float *parms) +void Surf_StainSurf (model_t *mod, msurface_t *surf, float *parms) { int sd, td; float dist, rad, minlight; @@ -91,7 +91,8 @@ void Surf_StainSurf (msurface_t *surf, float *parms) int smax, tmax; float amm; int lim; - mtexinfo_t *tex; + vec4_t *lmvecs; + float *lmvecscale; stmap *stainbase; lightmapinfo_t *lm; @@ -107,7 +108,10 @@ void Surf_StainSurf (msurface_t *surf, float *parms) smax = (surf->extents[0]>>surf->lmshift)+1; tmax = (surf->extents[1]>>surf->lmshift)+1; - tex = surf->texinfo; + if (mod->facelmvecs) + lmvecs = mod->facelmvecs[surf-mod->surfaces].lmvecs, lmvecscale = mod->facelmvecs[surf-mod->surfaces].lmvecscale; + else + lmvecs = surf->texinfo->vecs, lmvecscale = surf->texinfo->vecscale; stainbase = lm->stainmaps; stainbase += (surf->light_t[0] * lm->width + surf->light_s[0]) * 3; @@ -125,20 +129,20 @@ void Surf_StainSurf (msurface_t *surf, float *parms) impact[i] = (parms+1)[i] - surf->plane->normal[i]*dist; } - local[0] = DotProduct (impact, tex->vecs[0]) + tex->vecs[0][3]; - local[1] = DotProduct (impact, tex->vecs[1]) + tex->vecs[1][3]; + local[0] = DotProduct (impact, lmvecs[0]) + lmvecs[0][3]; + local[1] = DotProduct (impact, lmvecs[1]) + lmvecs[1][3]; local[0] -= surf->texturemins[0]; local[1] -= surf->texturemins[1]; for (t = 0 ; tlmshift); + td = (local[1] - (t<lmshift))*lmvecscale[1]; if (td < 0) td = -td; for (s=0 ; slmshift); + sd = (local[0] - (s<lmshift))*lmvecscale[0]; if (sd < 0) sd = -sd; if (sd > td) @@ -219,7 +223,7 @@ void Surf_AddStain(vec3_t org, float red, float green, float blue, float radius) parms[6] = blue; - cl.worldmodel->funcs.StainNode(cl.worldmodel->rootnode, parms); + cl.worldmodel->funcs.StainNode(cl.worldmodel, parms); //now stain inline bsp models other than world. @@ -243,7 +247,7 @@ void Surf_AddStain(vec3_t org, float red, float green, float blue, float radius) } - pe->model->funcs.StainNode(pe->model->rootnode, parms); + pe->model->funcs.StainNode(pe->model, parms); } } } @@ -340,14 +344,17 @@ static void Surf_AddDynamicLights_Lum (msurface_t *surf) int s, t; int i; int smax, tmax; - mtexinfo_t *tex; - float a; + float l; unsigned *bl; + vec4_t *lmvecs; + float *lmvecscale; smax = (surf->extents[0]>>surf->lmshift)+1; tmax = (surf->extents[1]>>surf->lmshift)+1; - tex = surf->texinfo; - + if (currentmodel->facelmvecs) + lmvecs = currentmodel->facelmvecs[surf-currentmodel->surfaces].lmvecs, lmvecscale = currentmodel->facelmvecs[surf-currentmodel->surfaces].lmvecscale; + else + lmvecs = surf->texinfo->vecs, lmvecscale = surf->texinfo->vecscale; for (lnum=rtlights_first; lnumdlightbits & ((dlightbitmask_t)1u<plane->normal[i]*dist; } - local[0] = DotProduct (impact, tex->vecs[0]) + tex->vecs[0][3]; - local[1] = DotProduct (impact, tex->vecs[1]) + tex->vecs[1][3]; + local[0] = DotProduct (impact, lmvecs[0]) + lmvecs[0][3]; + local[1] = DotProduct (impact, lmvecs[1]) + lmvecs[1][3]; local[0] -= surf->texturemins[0]; local[1] -= surf->texturemins[1]; - a = 256*(cl_dlights[lnum].color[0]*NTSC_RED + cl_dlights[lnum].color[1]*NTSC_GREEN + cl_dlights[lnum].color[2]*NTSC_BLUE); + l = 256*(cl_dlights[lnum].color[0]*NTSC_RED + cl_dlights[lnum].color[1]*NTSC_GREEN + cl_dlights[lnum].color[2]*NTSC_BLUE); bl = blocklights; for (t = 0 ; tlmshift); + td = (local[1] - (t<lmshift))*lmvecscale[1]; if (td < 0) td = -td; for (s=0 ; slmshift); + sd = (local[0] - (s<lmshift))*lmvecscale[0]; if (sd < 0) sd = -sd; if (sd > td) @@ -395,7 +402,7 @@ static void Surf_AddDynamicLights_Lum (msurface_t *surf) else dist = td + (sd>>1); if (dist < minlight) - bl[0] += (rad - dist)*a; + bl[0] += (rad - dist)*l; bl++; } } @@ -412,7 +419,8 @@ static void Surf_AddDynamicLightNorms (msurface_t *surf) int s, t; int i; int smax, tmax; - mtexinfo_t *tex; + vec4_t *lmvecs; + float *lmvecscale; float a; smax = (surf->extents[0]>>4)+1; @@ -442,8 +450,8 @@ static void Surf_AddDynamicLightNorms (msurface_t *surf) surf->plane->normal[i]*dist; } - local[0] = DotProduct (impact, tex->vecs[0]) + tex->vecs[0][3]; - local[1] = DotProduct (impact, tex->vecs[1]) + tex->vecs[1][3]; + local[0] = DotProduct (impact, lmvecs[0]) + lmvecs[0][3]; + local[1] = DotProduct (impact, lmvecs[1]) + lmvecs[1][3]; local[0] -= surf->texturemins[0]; local[1] -= surf->texturemins[1]; @@ -452,12 +460,12 @@ static void Surf_AddDynamicLightNorms (msurface_t *surf) for (t = 0 ; tlmscale; + td = (local[1] - t*surf->lmscale)*lmvecscale[1]; if (td < 0) td = -td; for (s=0 ; slmscale; + sd = (local[0] - s*surf->lmscale)*lmvecscale[0]; if (sd < 0) sd = -sd; if (sd > td) @@ -480,13 +488,15 @@ static void Surf_AddDynamicLightNorms (msurface_t *surf) static void Surf_AddDynamicLights_RGB (msurface_t *surf) { int lnum; - int sd, td; + float sd, td; float dist, rad, minlight; - vec3_t impact, local; + vec3_t impact; + vec2_t local; int s, t; int i; int smax, tmax; - mtexinfo_t *tex; + vec4_t *lmvecs; + float *lmvecscale; // float temp; float r, g, b; unsigned *bl; @@ -494,7 +504,10 @@ static void Surf_AddDynamicLights_RGB (msurface_t *surf) smax = (surf->extents[0]>>surf->lmshift)+1; tmax = (surf->extents[1]>>surf->lmshift)+1; - tex = surf->texinfo; + if (currentmodel->facelmvecs) + lmvecs = currentmodel->facelmvecs[surf-currentmodel->surfaces].lmvecs, lmvecscale = currentmodel->facelmvecs[surf-currentmodel->surfaces].lmvecscale; + else + lmvecs = surf->texinfo->vecs, lmvecscale = surf->texinfo->vecscale; for (lnum=rtlights_first; lnumorigin, lightofs); - //FIXME: transform by forward/right/up + //FIXME: transform by currententity->axis dist = DotProduct (lightofs, surf->plane->normal) - surf->plane->dist; rad -= fabs(dist); minlight = cl_dlights[lnum].minlight; @@ -517,12 +530,13 @@ static void Surf_AddDynamicLights_RGB (msurface_t *surf) surf->plane->normal[i]*dist; } - local[0] = DotProduct (impact, tex->vecs[0]) + tex->vecs[0][3]; - local[1] = DotProduct (impact, tex->vecs[1]) + tex->vecs[1][3]; + local[0] = DotProduct (impact, lmvecs[0]) + lmvecs[0][3]; + local[1] = DotProduct (impact, lmvecs[1]) + lmvecs[1][3]; local[0] -= surf->texturemins[0]; local[1] -= surf->texturemins[1]; + if (r_dynamic.ival == 2) r = g = b = 256; else @@ -537,18 +551,18 @@ static void Surf_AddDynamicLights_RGB (msurface_t *surf) { for (t = 0 ; tlmshift); + td = (local[1] - (t<lmshift))*lmvecscale[1]; if (td < 0) td = -td; for (s=0 ; slmshift); + sd = (local[0] - (s<lmshift))*lmvecscale[0]; if (sd < 0) sd = -sd; if (sd > td) - dist = sd + (td>>1); + dist = sd + td*0.5; else - dist = td + (sd>>1); + dist = td + sd*0.5; if (dist < minlight) { i = bl[0] + (rad - dist)*r; @@ -566,18 +580,18 @@ static void Surf_AddDynamicLights_RGB (msurface_t *surf) { for (t = 0 ; tlmshift); + td = (local[1] - (t<lmshift))*lmvecscale[1]; if (td < 0) td = -td; for (s=0 ; slmshift); + sd = (local[0] - (s<lmshift))*lmvecscale[0]; if (sd < 0) sd = -sd; if (sd > td) - dist = sd + (td>>1); + dist = sd + td*0.5; else - dist = td + (sd>>1); + dist = td + sd*0.5; if (dist < minlight) { bl[0] += (rad - dist)*r; @@ -2303,7 +2317,10 @@ void Surf_GenBrushBatches(batch_t **batches, entity_t *ent) continue; if (!(cl_dlights[k].flags & LFLAG_LIGHTMAP)) continue; - + if ((cl_dlights[k].flags & LFLAG_NORMALMODE) && r_shadow_realtime_dlight.ival) + continue; + if ((cl_dlights[k].flags & LFLAG_REALTIMEMODE) && r_shadow_realtime_world.ival) + continue; model->funcs.MarkLights (&cl_dlights[k], (dlightbitmask_t)1<rootnode); } } diff --git a/engine/client/render.h b/engine/client/render.h index 64c58320f..0ad014001 100644 --- a/engine/client/render.h +++ b/engine/client/render.h @@ -354,7 +354,7 @@ void Surf_PreNewMap(void); void Surf_SetupFrame(void); //determine pvs+viewcontents void Surf_DrawWorld(void); void Surf_GenBrushBatches(struct batch_s **batches, entity_t *ent); -void Surf_StainSurf(struct msurface_s *surf, float *parms); +void Surf_StainSurf(struct model_s *mod, struct msurface_s *surf, float *parms); void Surf_AddStain(vec3_t org, float red, float green, float blue, float radius); void Surf_LessenStains(void); void Surf_WipeStains(void); diff --git a/engine/common/gl_q2bsp.c b/engine/common/gl_q2bsp.c index cade071e8..d93fd3c2c 100644 --- a/engine/common/gl_q2bsp.c +++ b/engine/common/gl_q2bsp.c @@ -4432,7 +4432,7 @@ static void Q2BSP_MarkLights (dlight_t *light, dlightbitmask_t bit, mnode_t *nod } #ifndef SERVERONLY -static void GLR_Q2BSP_StainNode (mnode_t *node, float *parms) +static void GLR_Q2BSP_StainNode_r (model_t *model, mnode_t *node, float *parms) { mplane_t *splitplane; float dist; @@ -4447,26 +4447,30 @@ static void GLR_Q2BSP_StainNode (mnode_t *node, float *parms) if (dist > (*parms)) { - GLR_Q2BSP_StainNode (node->children[0], parms); + GLR_Q2BSP_StainNode_r (model, node->children[0], parms); return; } if (dist < (-*parms)) { - GLR_Q2BSP_StainNode (node->children[1], parms); + GLR_Q2BSP_StainNode_r (model, node->children[1], parms); return; } // mark the polygons - surf = cl.worldmodel->surfaces + node->firstsurface; + surf = model->surfaces + node->firstsurface; for (i=0 ; inumsurfaces ; i++, surf++) { if (surf->flags&~(SURF_DONTWARP|SURF_PLANEBACK)) continue; - Surf_StainSurf(surf, parms); + Surf_StainSurf(model, surf, parms); } - GLR_Q2BSP_StainNode (node->children[0], parms); - GLR_Q2BSP_StainNode (node->children[1], parms); + GLR_Q2BSP_StainNode_r (model, node->children[0], parms); + GLR_Q2BSP_StainNode_r (model, node->children[1], parms); +} +static void GLR_Q2BSP_StainNode (model_t *model, float *parms) +{ + GLR_Q2BSP_StainNode_r(model, model->rootnode, parms); } #endif diff --git a/engine/common/q1bsp.c b/engine/common/q1bsp.c index 4e812aae8..dca0c6f8e 100644 --- a/engine/common/q1bsp.c +++ b/engine/common/q1bsp.c @@ -1658,6 +1658,8 @@ void Q1BSP_MarkLights (dlight_t *light, dlightbitmask_t bit, mnode_t *node) float l, maxdist; int j, s, t; vec3_t impact; + vec4_t *lmvecs; + float *lmvecscale; if (node->contents < 0) return; @@ -1689,13 +1691,18 @@ void Q1BSP_MarkLights (dlight_t *light, dlightbitmask_t bit, mnode_t *node) for (j=0 ; j<3 ; j++) impact[j] = light->origin[j] - surf->plane->normal[j]*dist; + if (currentmodel->facelmvecs) + lmvecs = currentmodel->facelmvecs[surf-currentmodel->surfaces].lmvecs, lmvecscale = currentmodel->facelmvecs[surf-currentmodel->surfaces].lmvecscale; + else + lmvecs = surf->texinfo->vecs, lmvecscale = surf->texinfo->vecscale; + // clamp center of light to corner and check brightness - l = DotProduct (impact, surf->texinfo->vecs[0]) + surf->texinfo->vecs[0][3] - surf->texturemins[0]; + l = DotProduct (impact, lmvecs[0]) + lmvecs[0][3] - surf->texturemins[0]; s = l+0.5;if (s < 0) s = 0;else if (s > surf->extents[0]) s = surf->extents[0]; - s = (l - s)*surf->texinfo->vecscale[0]; - l = DotProduct (impact, surf->texinfo->vecs[1]) + surf->texinfo->vecs[1][3] - surf->texturemins[1]; + s = (l - s)*lmvecscale[0]; //FIXME + l = DotProduct (impact, lmvecs[1]) + lmvecs[1][3] - surf->texturemins[1]; t = l+0.5;if (t < 0) t = 0;else if (t > surf->extents[1]) t = surf->extents[1]; - t = (l - t)*surf->texinfo->vecscale[1]; + t = (l - t)*lmvecscale[1]; // compare to minimum light if ((s*s+t*t+dist*dist) < maxdist) { @@ -1714,7 +1721,7 @@ void Q1BSP_MarkLights (dlight_t *light, dlightbitmask_t bit, mnode_t *node) } //combination of R_AddDynamicLights and R_MarkLights -static void Q1BSP_StainNode (mnode_t *node, float *parms) +static void Q1BSP_StainNode_r (model_t *model, mnode_t *node, float *parms) { mplane_t *splitplane; float dist; @@ -1729,26 +1736,30 @@ static void Q1BSP_StainNode (mnode_t *node, float *parms) if (dist > (*parms)) { - Q1BSP_StainNode (node->children[0], parms); + Q1BSP_StainNode_r (model, node->children[0], parms); return; } if (dist < (-*parms)) { - Q1BSP_StainNode (node->children[1], parms); + Q1BSP_StainNode_r (model, node->children[1], parms); return; } // mark the polygons - surf = cl.worldmodel->surfaces + node->firstsurface; + surf = model->surfaces + node->firstsurface; for (i=0 ; inumsurfaces ; i++, surf++) { if (surf->flags&~(SURF_DRAWALPHA|SURF_DONTWARP|SURF_PLANEBACK)) continue; - Surf_StainSurf(surf, parms); + Surf_StainSurf(model, surf, parms); } - Q1BSP_StainNode (node->children[0], parms); - Q1BSP_StainNode (node->children[1], parms); + Q1BSP_StainNode_r (model, node->children[0], parms); + Q1BSP_StainNode_r (model, node->children[1], parms); +} +static void Q1BSP_StainNode (model_t *model, float *parms) +{ + Q1BSP_StainNode_r(model, model->rootnode, parms); } diff --git a/engine/gl/gl_heightmap.c b/engine/gl/gl_heightmap.c index ea112a065..a8a41c270 100644 --- a/engine/gl/gl_heightmap.c +++ b/engine/gl/gl_heightmap.c @@ -4452,7 +4452,7 @@ void Heightmap_LightPointValues (model_t *mod, const vec3_t point, vec3_t res_di res_dir[2] = 0;//sin(time); VectorNormalize(res_dir); } -void Heightmap_StainNode (mnode_t *node, float *parms) +void Heightmap_StainNode (model_t *mod, float *parms) { } void Heightmap_MarkLights (dlight_t *light, dlightbitmask_t bit, mnode_t *node) diff --git a/engine/gl/gl_model.c b/engine/gl/gl_model.c index 88f6420a0..6a73da339 100644 --- a/engine/gl/gl_model.c +++ b/engine/gl/gl_model.c @@ -2485,6 +2485,7 @@ void ModQ1_Batches_BuildQ1Q2Poly(model_t *mod, msurface_t *surf, builddata_t *co float s, t, d; int sty; // int w,h; + struct facelmvecs_s *flmv = mod->facelmvecs?mod->facelmvecs + (surf-mod->surfaces):NULL; if (!mesh) { @@ -2543,22 +2544,40 @@ void ModQ1_Batches_BuildQ1Q2Poly(model_t *mod, msurface_t *surf, builddata_t *co mesh->st_array[i][1] /= surf->texinfo->texture->vheight; } -#ifndef SERVERONLY - if (r_lightmap_average.ival) + if (flmv) { + s = DotProduct (vec, flmv->lmvecs[0]) + flmv->lmvecs[0][3]; + t = DotProduct (vec, flmv->lmvecs[1]) + flmv->lmvecs[1][3]; +#ifndef SERVERONLY + if (r_lightmap_average.ival) + s = surf->extents[0]*0.5, t = surf->extents[1]*0.5; +#endif + //s+t are now in luxels... need to convert those to normalised texcoords though. for (sty = 0; sty < 1; sty++) { - mesh->lmst_array[sty][i][0] = (surf->extents[0]*0.5 + (surf->light_s[sty]<lmshift) + (1<lmshift)*0.5) / (mod->lightmaps.width<lmshift); - mesh->lmst_array[sty][i][1] = (surf->extents[1]*0.5 + (surf->light_t[sty]<lmshift) + (1<lmshift)*0.5) / (mod->lightmaps.height<lmshift); + mesh->lmst_array[sty][i][0] = (surf->light_s[sty] + s) / mod->lightmaps.width; + mesh->lmst_array[sty][i][1] = (surf->light_t[sty] + t) / mod->lightmaps.height; } } else -#endif { - for (sty = 0; sty < 1; sty++) +#ifndef SERVERONLY + if (r_lightmap_average.ival) { - mesh->lmst_array[sty][i][0] = (s - surf->texturemins[0] + (surf->light_s[sty]<lmshift) + (1<lmshift)*0.5) / (mod->lightmaps.width<lmshift); - mesh->lmst_array[sty][i][1] = (t - surf->texturemins[1] + (surf->light_t[sty]<lmshift) + (1<lmshift)*0.5) / (mod->lightmaps.height<lmshift); + for (sty = 0; sty < 1; sty++) + { + mesh->lmst_array[sty][i][0] = (surf->extents[0]*0.5 + (surf->light_s[sty]<lmshift) + (1<lmshift)*0.5) / (mod->lightmaps.width<lmshift); + mesh->lmst_array[sty][i][1] = (surf->extents[1]*0.5 + (surf->light_t[sty]<lmshift) + (1<lmshift)*0.5) / (mod->lightmaps.height<lmshift); + } + } + else +#endif + { + for (sty = 0; sty < 1; sty++) + { + mesh->lmst_array[sty][i][0] = (s - surf->texturemins[0] + (surf->light_s[sty]<lmshift) + (1<lmshift)*0.5) / (mod->lightmaps.width<lmshift); + mesh->lmst_array[sty][i][1] = (t - surf->texturemins[1] + (surf->light_t[sty]<lmshift) + (1<lmshift)*0.5) / (mod->lightmaps.height<lmshift); + } } } @@ -4228,6 +4247,10 @@ static qboolean Mod_LoadFaces (model_t *loadmodel, bspx_header_t *bspx, qbyte *m lightmapoverrides_t overrides; int lofsscale = 1; + qboolean lightmapusable = false; + + struct decoupled_lm_info_s *decoupledlm; + unsigned int dcsize; memset(&overrides, 0, sizeof(overrides)); @@ -4271,6 +4294,12 @@ static qboolean Mod_LoadFaces (model_t *loadmodel, bspx_header_t *bspx, qbyte *m Mod_LoadVertexNormals(loadmodel, bspx, mod_base, NULL); Mod_LoadLighting (loadmodel, bspx, mod_base, lightlump, false, &overrides, subbsp); + decoupledlm = BSPX_FindLump(bspx, mod_base, "DECOUPLED_LM", &dcsize); //RGB packed data + if (dcsize == count*sizeof(*decoupledlm)) + loadmodel->facelmvecs = ZG_Malloc(&loadmodel->memgroup, count * sizeof(*loadmodel->facelmvecs)); //seems good. + else + decoupledlm = NULL; //wrong size somehow... discard it. + switch(loadmodel->lightmaps.fmt) { case LM_E5BGR9: @@ -4353,14 +4382,37 @@ static qboolean Mod_LoadFaces (model_t *loadmodel, bspx_header_t *bspx, qbyte *m if (loadmodel->lightmaps.maxstyle < out->styles[i]) loadmodel->lightmaps.maxstyle = out->styles[i]; - CalcSurfaceExtents (loadmodel, out); + if (decoupledlm) + { + lofs = LittleLong(decoupledlm->lmoffset); + out->texturemins[0] = out->texturemins[1] = 0; // should be handled by the now-per-surface vecs[][3] value. + out->lmshift = 0; //redundant. + out->extents[0] = (unsigned short)LittleShort(decoupledlm->lmsize[0]) - 1; + out->extents[1] = (unsigned short)LittleShort(decoupledlm->lmsize[1]) - 1; + loadmodel->facelmvecs[surfnum].lmvecs[0][0] = LittleFloat(decoupledlm->lmvecs[0][0]); + loadmodel->facelmvecs[surfnum].lmvecs[0][1] = LittleFloat(decoupledlm->lmvecs[0][1]); + loadmodel->facelmvecs[surfnum].lmvecs[0][2] = LittleFloat(decoupledlm->lmvecs[0][2]); + loadmodel->facelmvecs[surfnum].lmvecs[0][3] = LittleFloat(decoupledlm->lmvecs[0][3]) + 0.5f; //sigh + loadmodel->facelmvecs[surfnum].lmvecs[1][0] = LittleFloat(decoupledlm->lmvecs[1][0]); + loadmodel->facelmvecs[surfnum].lmvecs[1][1] = LittleFloat(decoupledlm->lmvecs[1][1]); + loadmodel->facelmvecs[surfnum].lmvecs[1][2] = LittleFloat(decoupledlm->lmvecs[1][2]); + loadmodel->facelmvecs[surfnum].lmvecs[1][3] = LittleFloat(decoupledlm->lmvecs[1][3]) + 0.5f; //sigh + loadmodel->facelmvecs[surfnum].lmvecscale[0] = 1.0f/Length(loadmodel->facelmvecs[surfnum].lmvecs[0]); //luxels->qu + loadmodel->facelmvecs[surfnum].lmvecscale[1] = 1.0f/Length(loadmodel->facelmvecs[surfnum].lmvecs[1]); + decoupledlm++; + } + else + CalcSurfaceExtents (loadmodel, out); if (lofs != (unsigned int)-1) lofs *= lofsscale; - lend = lofs+(out->extents[0]+1)*(out->extents[1]+1); + lend = lofs+(out->extents[0]+1)*(out->extents[1]+1) /*FIXME: mul by numstyles */; if (lofs > loadmodel->lightdatasize || lend < lofs) out->samples = NULL; //should includes -1 else + { out->samples = loadmodel->lightdata + lofs; + lightmapusable = true; //something has a valid offset. + } if (!out->texinfo->texture) continue; @@ -4405,6 +4457,15 @@ static qboolean Mod_LoadFaces (model_t *loadmodel, bspx_header_t *bspx, qbyte *m out->flags &= ~SURF_DRAWALPHA; } + if (!lightmapusable) + { + Con_Printf("no valid lightmap offsets in map\n"); +#ifdef RUNTIMELIGHTING + RelightTerminate(loadmodel); //not gonna work... +#endif + loadmodel->lightdata = NULL; + loadmodel->deluxdata = NULL; + } return true; } diff --git a/engine/gl/gl_model.h b/engine/gl/gl_model.h index 534946dee..2c3db8984 100644 --- a/engine/gl/gl_model.h +++ b/engine/gl/gl_model.h @@ -281,7 +281,7 @@ typedef struct { void (*FindTouchedLeafs) (struct model_s *model, struct pvscache_s *ent, const vec3_t cullmins, const vec3_t cullmaxs); //edict system as opposed to q2 game dll system. void (*LightPointValues) (struct model_s *model, const vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir); - void (*StainNode) (struct mnode_s *node, float *parms); + void (*StainNode) (struct model_s *model, float *parms); void (*MarkLights) (struct dlight_s *light, dlightbitmask_t bit, struct mnode_s *node); int (*ClusterForPoint) (struct model_s *model, const vec3_t point, int *areaout); //pvs index (leaf-1 for q1bsp). may be negative (ie: no pvs). @@ -413,7 +413,7 @@ typedef struct typedef struct mtexinfo_s { - float vecs[2][4]; + vec4_t vecs[2]; float vecscale[2]; texture_t *texture; int flags; @@ -942,6 +942,18 @@ typedef struct vec4_t *points; } portal_t; +struct decoupled_lm_info_s +{ + quint16_t lmsize[2]; //made explicit. beware MAX_ + quint32_t lmoffset; //replacement offset for vanilla compat. + vec4_t lmvecs[2]; //lmcoord[] = dotproduct3(vertexcoord, lmvecs[])+lmvecs[][3] +}; +struct facelmvecs_s +{ + vec4_t lmvecs[2]; //lmcoord[] = dotproduct3(vertexcoord, lmvecs[])+lmvecs[][3] + float lmvecscale[2]; //just 1/Length(lmvecs). dlights work in luxels, but need to be able to work back to qu. +}; + struct surfedgenormals_s { quint32_t n; quint32_t s; @@ -1014,6 +1026,7 @@ typedef struct model_s mvertex_t *vertexes; vec3_t *normals; struct surfedgenormals_s *surfedgenormals; //for per-vertex normals + struct facelmvecs_s *facelmvecs; int numedges; medge_t *edges; diff --git a/engine/gl/gl_rlight.c b/engine/gl/gl_rlight.c index 2a10c4b74..d295dfa8f 100644 --- a/engine/gl/gl_rlight.c +++ b/engine/gl/gl_rlight.c @@ -753,6 +753,10 @@ void R_PushDlights (void) { if (!l->radius || !(l->flags & LFLAG_LIGHTMAP)) continue; + if ((l->flags & LFLAG_NORMALMODE) && r_shadow_realtime_dlight.ival) + continue; //don't draw both. its redundant and a waste of cpu. + if ((l->flags & LFLAG_REALTIMEMODE) && r_shadow_realtime_world.ival) + continue; //also don't draw both. currentmodel->funcs.MarkLights( l, (dlightbitmask_t)1u<nodes ); } } @@ -2701,7 +2705,7 @@ static float *GLRecursiveLightPoint3C (model_t *mod, mnode_t *node, const vec3_t msurface_t *surf; int s, t, ds, dt; int i; - mtexinfo_t *tex; + vec4_t *lmvecs; qbyte *lightmap, *deluxmap; float scale, overbright; int maps; @@ -2748,10 +2752,13 @@ static float *GLRecursiveLightPoint3C (model_t *mod, mnode_t *node, const vec3_t if (surf->flags & SURF_DRAWTILED) continue; // no lightmaps - tex = surf->texinfo; + if (mod->facelmvecs) + lmvecs = mod->facelmvecs[surf-mod->surfaces].lmvecs; + else + lmvecs = surf->texinfo->vecs; - s = DotProduct (mid, tex->vecs[0]) + tex->vecs[0][3]; - t = DotProduct (mid, tex->vecs[1]) + tex->vecs[1][3]; + s = DotProduct (mid, lmvecs[0]) + lmvecs[0][3]; + t = DotProduct (mid, lmvecs[1]) + lmvecs[1][3]; if (s < surf->texturemins[0] || t < surf->texturemins[1])