Add support for the DECOUPLED_LM bspx lump.

This commit is contained in:
Shpoike 2023-08-01 12:08:51 +01:00
parent 6fc3d57c76
commit e48e9c67ad
8 changed files with 189 additions and 76 deletions

View file

@ -80,7 +80,7 @@ void QDECL Surf_RebuildLightmap_Callback (struct cvar_s *var, char *oldvalue)
} }
//radius, x y z, r g b //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; int sd, td;
float dist, rad, minlight; float dist, rad, minlight;
@ -91,7 +91,8 @@ void Surf_StainSurf (msurface_t *surf, float *parms)
int smax, tmax; int smax, tmax;
float amm; float amm;
int lim; int lim;
mtexinfo_t *tex; vec4_t *lmvecs;
float *lmvecscale;
stmap *stainbase; stmap *stainbase;
lightmapinfo_t *lm; lightmapinfo_t *lm;
@ -107,7 +108,10 @@ void Surf_StainSurf (msurface_t *surf, float *parms)
smax = (surf->extents[0]>>surf->lmshift)+1; smax = (surf->extents[0]>>surf->lmshift)+1;
tmax = (surf->extents[1]>>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 = lm->stainmaps;
stainbase += (surf->light_t[0] * lm->width + surf->light_s[0]) * 3; 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; impact[i] = (parms+1)[i] - surf->plane->normal[i]*dist;
} }
local[0] = DotProduct (impact, tex->vecs[0]) + tex->vecs[0][3]; local[0] = DotProduct (impact, lmvecs[0]) + lmvecs[0][3];
local[1] = DotProduct (impact, tex->vecs[1]) + tex->vecs[1][3]; local[1] = DotProduct (impact, lmvecs[1]) + lmvecs[1][3];
local[0] -= surf->texturemins[0]; local[0] -= surf->texturemins[0];
local[1] -= surf->texturemins[1]; local[1] -= surf->texturemins[1];
for (t = 0 ; t<tmax ; t++) for (t = 0 ; t<tmax ; t++)
{ {
td = local[1] - (t<<surf->lmshift); td = (local[1] - (t<<surf->lmshift))*lmvecscale[1];
if (td < 0) if (td < 0)
td = -td; td = -td;
for (s=0 ; s<smax ; s++) for (s=0 ; s<smax ; s++)
{ {
sd = local[0] - (s<<surf->lmshift); sd = (local[0] - (s<<surf->lmshift))*lmvecscale[0];
if (sd < 0) if (sd < 0)
sd = -sd; sd = -sd;
if (sd > td) if (sd > td)
@ -219,7 +223,7 @@ void Surf_AddStain(vec3_t org, float red, float green, float blue, float radius)
parms[6] = blue; 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. //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 s, t;
int i; int i;
int smax, tmax; int smax, tmax;
mtexinfo_t *tex; float l;
float a;
unsigned *bl; unsigned *bl;
vec4_t *lmvecs;
float *lmvecscale;
smax = (surf->extents[0]>>surf->lmshift)+1; smax = (surf->extents[0]>>surf->lmshift)+1;
tmax = (surf->extents[1]>>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; lnum<RTL_FIRST; lnum++) for (lnum=rtlights_first; lnum<RTL_FIRST; lnum++)
{ {
if ( !(surf->dlightbits & ((dlightbitmask_t)1u<<lnum) ) ) if ( !(surf->dlightbits & ((dlightbitmask_t)1u<<lnum) ) )
@ -371,23 +378,23 @@ static void Surf_AddDynamicLights_Lum (msurface_t *surf)
surf->plane->normal[i]*dist; surf->plane->normal[i]*dist;
} }
local[0] = DotProduct (impact, tex->vecs[0]) + tex->vecs[0][3]; local[0] = DotProduct (impact, lmvecs[0]) + lmvecs[0][3];
local[1] = DotProduct (impact, tex->vecs[1]) + tex->vecs[1][3]; local[1] = DotProduct (impact, lmvecs[1]) + lmvecs[1][3];
local[0] -= surf->texturemins[0]; local[0] -= surf->texturemins[0];
local[1] -= surf->texturemins[1]; 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; bl = blocklights;
for (t = 0 ; t<tmax ; t++) for (t = 0 ; t<tmax ; t++)
{ {
td = local[1] - (t<<surf->lmshift); td = (local[1] - (t<<surf->lmshift))*lmvecscale[1];
if (td < 0) if (td < 0)
td = -td; td = -td;
for (s=0 ; s<smax ; s++) for (s=0 ; s<smax ; s++)
{ {
sd = local[0] - (s<<surf->lmshift); sd = (local[0] - (s<<surf->lmshift))*lmvecscale[0];
if (sd < 0) if (sd < 0)
sd = -sd; sd = -sd;
if (sd > td) if (sd > td)
@ -395,7 +402,7 @@ static void Surf_AddDynamicLights_Lum (msurface_t *surf)
else else
dist = td + (sd>>1); dist = td + (sd>>1);
if (dist < minlight) if (dist < minlight)
bl[0] += (rad - dist)*a; bl[0] += (rad - dist)*l;
bl++; bl++;
} }
} }
@ -412,7 +419,8 @@ static void Surf_AddDynamicLightNorms (msurface_t *surf)
int s, t; int s, t;
int i; int i;
int smax, tmax; int smax, tmax;
mtexinfo_t *tex; vec4_t *lmvecs;
float *lmvecscale;
float a; float a;
smax = (surf->extents[0]>>4)+1; smax = (surf->extents[0]>>4)+1;
@ -442,8 +450,8 @@ static void Surf_AddDynamicLightNorms (msurface_t *surf)
surf->plane->normal[i]*dist; surf->plane->normal[i]*dist;
} }
local[0] = DotProduct (impact, tex->vecs[0]) + tex->vecs[0][3]; local[0] = DotProduct (impact, lmvecs[0]) + lmvecs[0][3];
local[1] = DotProduct (impact, tex->vecs[1]) + tex->vecs[1][3]; local[1] = DotProduct (impact, lmvecs[1]) + lmvecs[1][3];
local[0] -= surf->texturemins[0]; local[0] -= surf->texturemins[0];
local[1] -= surf->texturemins[1]; local[1] -= surf->texturemins[1];
@ -452,12 +460,12 @@ static void Surf_AddDynamicLightNorms (msurface_t *surf)
for (t = 0 ; t<tmax ; t++) for (t = 0 ; t<tmax ; t++)
{ {
td = local[1] - t*surf->lmscale; td = (local[1] - t*surf->lmscale)*lmvecscale[1];
if (td < 0) if (td < 0)
td = -td; td = -td;
for (s=0 ; s<smax ; s++) for (s=0 ; s<smax ; s++)
{ {
sd = local[0] - s*surf->lmscale; sd = (local[0] - s*surf->lmscale)*lmvecscale[0];
if (sd < 0) if (sd < 0)
sd = -sd; sd = -sd;
if (sd > td) if (sd > td)
@ -480,13 +488,15 @@ static void Surf_AddDynamicLightNorms (msurface_t *surf)
static void Surf_AddDynamicLights_RGB (msurface_t *surf) static void Surf_AddDynamicLights_RGB (msurface_t *surf)
{ {
int lnum; int lnum;
int sd, td; float sd, td;
float dist, rad, minlight; float dist, rad, minlight;
vec3_t impact, local; vec3_t impact;
vec2_t local;
int s, t; int s, t;
int i; int i;
int smax, tmax; int smax, tmax;
mtexinfo_t *tex; vec4_t *lmvecs;
float *lmvecscale;
// float temp; // float temp;
float r, g, b; float r, g, b;
unsigned *bl; unsigned *bl;
@ -494,7 +504,10 @@ static void Surf_AddDynamicLights_RGB (msurface_t *surf)
smax = (surf->extents[0]>>surf->lmshift)+1; smax = (surf->extents[0]>>surf->lmshift)+1;
tmax = (surf->extents[1]>>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; lnum<RTL_FIRST; lnum++) for (lnum=rtlights_first; lnum<RTL_FIRST; lnum++)
{ {
@ -503,7 +516,7 @@ static void Surf_AddDynamicLights_RGB (msurface_t *surf)
rad = cl_dlights[lnum].radius; rad = cl_dlights[lnum].radius;
VectorSubtract(cl_dlights[lnum].origin, currententity->origin, lightofs); VectorSubtract(cl_dlights[lnum].origin, currententity->origin, lightofs);
//FIXME: transform by forward/right/up //FIXME: transform by currententity->axis
dist = DotProduct (lightofs, surf->plane->normal) - surf->plane->dist; dist = DotProduct (lightofs, surf->plane->normal) - surf->plane->dist;
rad -= fabs(dist); rad -= fabs(dist);
minlight = cl_dlights[lnum].minlight; minlight = cl_dlights[lnum].minlight;
@ -517,12 +530,13 @@ static void Surf_AddDynamicLights_RGB (msurface_t *surf)
surf->plane->normal[i]*dist; surf->plane->normal[i]*dist;
} }
local[0] = DotProduct (impact, tex->vecs[0]) + tex->vecs[0][3]; local[0] = DotProduct (impact, lmvecs[0]) + lmvecs[0][3];
local[1] = DotProduct (impact, tex->vecs[1]) + tex->vecs[1][3]; local[1] = DotProduct (impact, lmvecs[1]) + lmvecs[1][3];
local[0] -= surf->texturemins[0]; local[0] -= surf->texturemins[0];
local[1] -= surf->texturemins[1]; local[1] -= surf->texturemins[1];
if (r_dynamic.ival == 2) if (r_dynamic.ival == 2)
r = g = b = 256; r = g = b = 256;
else else
@ -537,18 +551,18 @@ static void Surf_AddDynamicLights_RGB (msurface_t *surf)
{ {
for (t = 0 ; t<tmax ; t++) for (t = 0 ; t<tmax ; t++)
{ {
td = local[1] - (t<<surf->lmshift); td = (local[1] - (t<<surf->lmshift))*lmvecscale[1];
if (td < 0) if (td < 0)
td = -td; td = -td;
for (s=0 ; s<smax ; s++) for (s=0 ; s<smax ; s++)
{ {
sd = local[0] - (s<<surf->lmshift); sd = (local[0] - (s<<surf->lmshift))*lmvecscale[0];
if (sd < 0) if (sd < 0)
sd = -sd; sd = -sd;
if (sd > td) if (sd > td)
dist = sd + (td>>1); dist = sd + td*0.5;
else else
dist = td + (sd>>1); dist = td + sd*0.5;
if (dist < minlight) if (dist < minlight)
{ {
i = bl[0] + (rad - dist)*r; i = bl[0] + (rad - dist)*r;
@ -566,18 +580,18 @@ static void Surf_AddDynamicLights_RGB (msurface_t *surf)
{ {
for (t = 0 ; t<tmax ; t++) for (t = 0 ; t<tmax ; t++)
{ {
td = local[1] - (t<<surf->lmshift); td = (local[1] - (t<<surf->lmshift))*lmvecscale[1];
if (td < 0) if (td < 0)
td = -td; td = -td;
for (s=0 ; s<smax ; s++) for (s=0 ; s<smax ; s++)
{ {
sd = local[0] - (s<<surf->lmshift); sd = (local[0] - (s<<surf->lmshift))*lmvecscale[0];
if (sd < 0) if (sd < 0)
sd = -sd; sd = -sd;
if (sd > td) if (sd > td)
dist = sd + (td>>1); dist = sd + td*0.5;
else else
dist = td + (sd>>1); dist = td + sd*0.5;
if (dist < minlight) if (dist < minlight)
{ {
bl[0] += (rad - dist)*r; bl[0] += (rad - dist)*r;
@ -2303,7 +2317,10 @@ void Surf_GenBrushBatches(batch_t **batches, entity_t *ent)
continue; continue;
if (!(cl_dlights[k].flags & LFLAG_LIGHTMAP)) if (!(cl_dlights[k].flags & LFLAG_LIGHTMAP))
continue; 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<<k, model->rootnode); model->funcs.MarkLights (&cl_dlights[k], (dlightbitmask_t)1<<k, model->rootnode);
} }
} }

View file

@ -354,7 +354,7 @@ void Surf_PreNewMap(void);
void Surf_SetupFrame(void); //determine pvs+viewcontents void Surf_SetupFrame(void); //determine pvs+viewcontents
void Surf_DrawWorld(void); void Surf_DrawWorld(void);
void Surf_GenBrushBatches(struct batch_s **batches, entity_t *ent); 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_AddStain(vec3_t org, float red, float green, float blue, float radius);
void Surf_LessenStains(void); void Surf_LessenStains(void);
void Surf_WipeStains(void); void Surf_WipeStains(void);

View file

@ -4432,7 +4432,7 @@ static void Q2BSP_MarkLights (dlight_t *light, dlightbitmask_t bit, mnode_t *nod
} }
#ifndef SERVERONLY #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; mplane_t *splitplane;
float dist; float dist;
@ -4447,26 +4447,30 @@ static void GLR_Q2BSP_StainNode (mnode_t *node, float *parms)
if (dist > (*parms)) if (dist > (*parms))
{ {
GLR_Q2BSP_StainNode (node->children[0], parms); GLR_Q2BSP_StainNode_r (model, node->children[0], parms);
return; return;
} }
if (dist < (-*parms)) if (dist < (-*parms))
{ {
GLR_Q2BSP_StainNode (node->children[1], parms); GLR_Q2BSP_StainNode_r (model, node->children[1], parms);
return; return;
} }
// mark the polygons // mark the polygons
surf = cl.worldmodel->surfaces + node->firstsurface; surf = model->surfaces + node->firstsurface;
for (i=0 ; i<node->numsurfaces ; i++, surf++) for (i=0 ; i<node->numsurfaces ; i++, surf++)
{ {
if (surf->flags&~(SURF_DONTWARP|SURF_PLANEBACK)) if (surf->flags&~(SURF_DONTWARP|SURF_PLANEBACK))
continue; continue;
Surf_StainSurf(surf, parms); Surf_StainSurf(model, surf, parms);
} }
GLR_Q2BSP_StainNode (node->children[0], parms); GLR_Q2BSP_StainNode_r (model, node->children[0], parms);
GLR_Q2BSP_StainNode (node->children[1], 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 #endif

View file

@ -1658,6 +1658,8 @@ void Q1BSP_MarkLights (dlight_t *light, dlightbitmask_t bit, mnode_t *node)
float l, maxdist; float l, maxdist;
int j, s, t; int j, s, t;
vec3_t impact; vec3_t impact;
vec4_t *lmvecs;
float *lmvecscale;
if (node->contents < 0) if (node->contents < 0)
return; return;
@ -1689,13 +1691,18 @@ void Q1BSP_MarkLights (dlight_t *light, dlightbitmask_t bit, mnode_t *node)
for (j=0 ; j<3 ; j++) for (j=0 ; j<3 ; j++)
impact[j] = light->origin[j] - surf->plane->normal[j]*dist; 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 // 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+0.5;if (s < 0) s = 0;else if (s > surf->extents[0]) s = surf->extents[0];
s = (l - s)*surf->texinfo->vecscale[0]; s = (l - s)*lmvecscale[0]; //FIXME
l = DotProduct (impact, surf->texinfo->vecs[1]) + surf->texinfo->vecs[1][3] - surf->texturemins[1]; 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+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 // compare to minimum light
if ((s*s+t*t+dist*dist) < maxdist) 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 //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; mplane_t *splitplane;
float dist; float dist;
@ -1729,26 +1736,30 @@ static void Q1BSP_StainNode (mnode_t *node, float *parms)
if (dist > (*parms)) if (dist > (*parms))
{ {
Q1BSP_StainNode (node->children[0], parms); Q1BSP_StainNode_r (model, node->children[0], parms);
return; return;
} }
if (dist < (-*parms)) if (dist < (-*parms))
{ {
Q1BSP_StainNode (node->children[1], parms); Q1BSP_StainNode_r (model, node->children[1], parms);
return; return;
} }
// mark the polygons // mark the polygons
surf = cl.worldmodel->surfaces + node->firstsurface; surf = model->surfaces + node->firstsurface;
for (i=0 ; i<node->numsurfaces ; i++, surf++) for (i=0 ; i<node->numsurfaces ; i++, surf++)
{ {
if (surf->flags&~(SURF_DRAWALPHA|SURF_DONTWARP|SURF_PLANEBACK)) if (surf->flags&~(SURF_DRAWALPHA|SURF_DONTWARP|SURF_PLANEBACK))
continue; continue;
Surf_StainSurf(surf, parms); Surf_StainSurf(model, surf, parms);
} }
Q1BSP_StainNode (node->children[0], parms); Q1BSP_StainNode_r (model, node->children[0], parms);
Q1BSP_StainNode (node->children[1], 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);
} }

View file

@ -4452,7 +4452,7 @@ void Heightmap_LightPointValues (model_t *mod, const vec3_t point, vec3_t res_di
res_dir[2] = 0;//sin(time); res_dir[2] = 0;//sin(time);
VectorNormalize(res_dir); 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) void Heightmap_MarkLights (dlight_t *light, dlightbitmask_t bit, mnode_t *node)

View file

@ -2485,6 +2485,7 @@ void ModQ1_Batches_BuildQ1Q2Poly(model_t *mod, msurface_t *surf, builddata_t *co
float s, t, d; float s, t, d;
int sty; int sty;
// int w,h; // int w,h;
struct facelmvecs_s *flmv = mod->facelmvecs?mod->facelmvecs + (surf-mod->surfaces):NULL;
if (!mesh) if (!mesh)
{ {
@ -2543,6 +2544,23 @@ void ModQ1_Batches_BuildQ1Q2Poly(model_t *mod, msurface_t *surf, builddata_t *co
mesh->st_array[i][1] /= surf->texinfo->texture->vheight; mesh->st_array[i][1] /= surf->texinfo->texture->vheight;
} }
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->light_s[sty] + s) / mod->lightmaps.width;
mesh->lmst_array[sty][i][1] = (surf->light_t[sty] + t) / mod->lightmaps.height;
}
}
else
{
#ifndef SERVERONLY #ifndef SERVERONLY
if (r_lightmap_average.ival) if (r_lightmap_average.ival)
{ {
@ -2561,6 +2579,7 @@ void ModQ1_Batches_BuildQ1Q2Poly(model_t *mod, msurface_t *surf, builddata_t *co
mesh->lmst_array[sty][i][1] = (t - surf->texturemins[1] + (surf->light_t[sty]<<surf->lmshift) + (1<<surf->lmshift)*0.5) / (mod->lightmaps.height<<surf->lmshift); mesh->lmst_array[sty][i][1] = (t - surf->texturemins[1] + (surf->light_t[sty]<<surf->lmshift) + (1<<surf->lmshift)*0.5) / (mod->lightmaps.height<<surf->lmshift);
} }
} }
}
if (mod->surfedgenormals) if (mod->surfedgenormals)
{ {
@ -4228,6 +4247,10 @@ static qboolean Mod_LoadFaces (model_t *loadmodel, bspx_header_t *bspx, qbyte *m
lightmapoverrides_t overrides; lightmapoverrides_t overrides;
int lofsscale = 1; int lofsscale = 1;
qboolean lightmapusable = false;
struct decoupled_lm_info_s *decoupledlm;
unsigned int dcsize;
memset(&overrides, 0, sizeof(overrides)); 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_LoadVertexNormals(loadmodel, bspx, mod_base, NULL);
Mod_LoadLighting (loadmodel, bspx, mod_base, lightlump, false, &overrides, subbsp); 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) switch(loadmodel->lightmaps.fmt)
{ {
case LM_E5BGR9: 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]) if (loadmodel->lightmaps.maxstyle < out->styles[i])
loadmodel->lightmaps.maxstyle = out->styles[i]; loadmodel->lightmaps.maxstyle = out->styles[i];
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); CalcSurfaceExtents (loadmodel, out);
if (lofs != (unsigned int)-1) if (lofs != (unsigned int)-1)
lofs *= lofsscale; 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) if (lofs > loadmodel->lightdatasize || lend < lofs)
out->samples = NULL; //should includes -1 out->samples = NULL; //should includes -1
else else
{
out->samples = loadmodel->lightdata + lofs; out->samples = loadmodel->lightdata + lofs;
lightmapusable = true; //something has a valid offset.
}
if (!out->texinfo->texture) if (!out->texinfo->texture)
continue; continue;
@ -4405,6 +4457,15 @@ static qboolean Mod_LoadFaces (model_t *loadmodel, bspx_header_t *bspx, qbyte *m
out->flags &= ~SURF_DRAWALPHA; 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; return true;
} }

View file

@ -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 (*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 (*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); 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). 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 typedef struct mtexinfo_s
{ {
float vecs[2][4]; vec4_t vecs[2];
float vecscale[2]; float vecscale[2];
texture_t *texture; texture_t *texture;
int flags; int flags;
@ -942,6 +942,18 @@ typedef struct
vec4_t *points; vec4_t *points;
} portal_t; } 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 { struct surfedgenormals_s {
quint32_t n; quint32_t n;
quint32_t s; quint32_t s;
@ -1014,6 +1026,7 @@ typedef struct model_s
mvertex_t *vertexes; mvertex_t *vertexes;
vec3_t *normals; vec3_t *normals;
struct surfedgenormals_s *surfedgenormals; //for per-vertex normals struct surfedgenormals_s *surfedgenormals; //for per-vertex normals
struct facelmvecs_s *facelmvecs;
int numedges; int numedges;
medge_t *edges; medge_t *edges;

View file

@ -753,6 +753,10 @@ void R_PushDlights (void)
{ {
if (!l->radius || !(l->flags & LFLAG_LIGHTMAP)) if (!l->radius || !(l->flags & LFLAG_LIGHTMAP))
continue; 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<<i, currentmodel->nodes ); currentmodel->funcs.MarkLights( l, (dlightbitmask_t)1u<<i, currentmodel->nodes );
} }
} }
@ -2701,7 +2705,7 @@ static float *GLRecursiveLightPoint3C (model_t *mod, mnode_t *node, const vec3_t
msurface_t *surf; msurface_t *surf;
int s, t, ds, dt; int s, t, ds, dt;
int i; int i;
mtexinfo_t *tex; vec4_t *lmvecs;
qbyte *lightmap, *deluxmap; qbyte *lightmap, *deluxmap;
float scale, overbright; float scale, overbright;
int maps; int maps;
@ -2748,10 +2752,13 @@ static float *GLRecursiveLightPoint3C (model_t *mod, mnode_t *node, const vec3_t
if (surf->flags & SURF_DRAWTILED) if (surf->flags & SURF_DRAWTILED)
continue; // no lightmaps 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]; s = DotProduct (mid, lmvecs[0]) + lmvecs[0][3];
t = DotProduct (mid, tex->vecs[1]) + tex->vecs[1][3]; t = DotProduct (mid, lmvecs[1]) + lmvecs[1][3];
if (s < surf->texturemins[0] || if (s < surf->texturemins[0] ||
t < surf->texturemins[1]) t < surf->texturemins[1])