Fix using wrong lightmap UV coordinates after all the wall clipping did its thing

This commit is contained in:
Magnus Norddahl 2021-10-03 03:47:40 +02:00
parent 0ac1baac48
commit 247deff5bb
4 changed files with 92 additions and 31 deletions

View file

@ -287,6 +287,7 @@ void HWDrawList::SortWallIntoPlane(HWDrawInfo* di, SortNode * head, SortNode * s
{
ws->vertcount = 0; // invalidate current vertices.
float newtexv = ws->tcs[HWWall::UPLFT].v + ((ws->tcs[HWWall::LOLFT].v - ws->tcs[HWWall::UPLFT].v) / (ws->zbottom[0] - ws->ztop[0])) * (fh->z - ws->ztop[0]);
float newlmv = ws->lightuv[HWWall::UPLFT].v + ((ws->lightuv[HWWall::LOLFT].v - ws->lightuv[HWWall::UPLFT].v) / (ws->zbottom[0] - ws->ztop[0])) * (fh->z - ws->ztop[0]);
// I make the very big assumption here that translucent walls in sloped sectors
// and 3D-floors never coexist in the same level - If that were the case this
@ -295,11 +296,13 @@ void HWDrawList::SortWallIntoPlane(HWDrawInfo* di, SortNode * head, SortNode * s
{
ws->ztop[1] = w->zbottom[1] = ws->ztop[0] = w->zbottom[0] = fh->z;
ws->tcs[HWWall::UPRGT].v = w->tcs[HWWall::LORGT].v = ws->tcs[HWWall::UPLFT].v = w->tcs[HWWall::LOLFT].v = newtexv;
ws->lightuv[HWWall::UPRGT].v = w->lightuv[HWWall::LORGT].v = ws->lightuv[HWWall::UPLFT].v = w->lightuv[HWWall::LOLFT].v = newlmv;
}
else
{
w->ztop[1] = ws->zbottom[1] = w->ztop[0] = ws->zbottom[0] = fh->z;
w->tcs[HWWall::UPLFT].v = ws->tcs[HWWall::LOLFT].v = w->tcs[HWWall::UPRGT].v = ws->tcs[HWWall::LORGT].v = newtexv;
w->lightuv[HWWall::UPLFT].v = ws->lightuv[HWWall::LOLFT].v = w->lightuv[HWWall::UPRGT].v = ws->lightuv[HWWall::LORGT].v = newlmv;
}
w->MakeVertices(di, false);
ws->MakeVertices(di, false);
@ -433,6 +436,7 @@ void HWDrawList::SortWallIntoWall(HWDrawInfo *di, SortNode * head,SortNode * sor
float ix=(float)(ws->glseg.x1+r*(ws->glseg.x2-ws->glseg.x1));
float iy=(float)(ws->glseg.y1+r*(ws->glseg.y2-ws->glseg.y1));
float iu=(float)(ws->tcs[HWWall::UPLFT].u + r * (ws->tcs[HWWall::UPRGT].u - ws->tcs[HWWall::UPLFT].u));
float ilmu=(float)(ws->lightuv[HWWall::UPLFT].u + r * (ws->lightuv[HWWall::UPRGT].u - ws->lightuv[HWWall::UPLFT].u));
float izt=(float)(ws->ztop[0]+r*(ws->ztop[1]-ws->ztop[0]));
float izb=(float)(ws->zbottom[0]+r*(ws->zbottom[1]-ws->zbottom[0]));
@ -446,6 +450,7 @@ void HWDrawList::SortWallIntoWall(HWDrawInfo *di, SortNode * head,SortNode * sor
w->ztop[0]=ws->ztop[1]=izt;
w->zbottom[0]=ws->zbottom[1]=izb;
w->tcs[HWWall::LOLFT].u = w->tcs[HWWall::UPLFT].u = ws->tcs[HWWall::LORGT].u = ws->tcs[HWWall::UPRGT].u = iu;
w->lightuv[HWWall::LOLFT].u = w->lightuv[HWWall::UPLFT].u = ws->lightuv[HWWall::LORGT].u = ws->lightuv[HWWall::UPRGT].u = iu;
ws->MakeVertices(di, false);
w->MakeVertices(di, false);

View file

@ -159,6 +159,8 @@ public:
HWSeg glseg;
float ztop[2],zbottom[2];
texcoord tcs[4];
texcoord lightuv[4];
float lindex;
float alpha;
FColormap Colormap;
@ -256,10 +258,10 @@ public:
void ProcessDecals(HWDrawInfo *di);
int CreateVertices(FFlatVertex *&ptr, bool nosplit);
void SplitLeftEdge (FFlatVertex *&ptr, texcoord* lightuv, float lindex);
void SplitRightEdge(FFlatVertex *&ptr, texcoord* lightuv, float lindex);
void SplitUpperEdge(FFlatVertex *&ptr, texcoord* lightuv, float lindex);
void SplitLowerEdge(FFlatVertex *&ptr, texcoord* lightuv, float lindex);
void SplitLeftEdge (FFlatVertex *&ptr);
void SplitRightEdge(FFlatVertex *&ptr);
void SplitUpperEdge(FFlatVertex *&ptr);
void SplitLowerEdge(FFlatVertex *&ptr);
void CountLeftEdge (unsigned &ptr);
void CountRightEdge(unsigned &ptr);

View file

@ -734,6 +734,10 @@ bool HWWall::SplitWallComplex(HWDrawInfo *di, sector_t * frontsector, bool trans
copyWall1.tcs[UPRGT].v = copyWall2.tcs[UPLFT].v = tcs[UPLFT].v + coeff * (tcs[UPRGT].v - tcs[UPLFT].v);
copyWall1.tcs[LORGT].u = copyWall2.tcs[LOLFT].u = tcs[LOLFT].u + coeff * (tcs[LORGT].u - tcs[LOLFT].u);
copyWall1.tcs[LORGT].v = copyWall2.tcs[LOLFT].v = tcs[LOLFT].v + coeff * (tcs[LORGT].v - tcs[LOLFT].v);
copyWall1.lightuv[UPRGT].u = copyWall2.lightuv[UPLFT].u = lightuv[UPLFT].u + coeff * (lightuv[UPRGT].u - lightuv[UPLFT].u);
copyWall1.lightuv[UPRGT].v = copyWall2.lightuv[UPLFT].v = lightuv[UPLFT].v + coeff * (lightuv[UPRGT].v - lightuv[UPLFT].v);
copyWall1.lightuv[LORGT].u = copyWall2.lightuv[LOLFT].u = lightuv[LOLFT].u + coeff * (lightuv[LORGT].u - lightuv[LOLFT].u);
copyWall1.lightuv[LORGT].v = copyWall2.lightuv[LOLFT].v = lightuv[LOLFT].v + coeff * (lightuv[LORGT].v - lightuv[LOLFT].v);
copyWall1.SplitWall(di, frontsector, translucent);
copyWall2.SplitWall(di, frontsector, translucent);
@ -775,6 +779,10 @@ bool HWWall::SplitWallComplex(HWDrawInfo *di, sector_t * frontsector, bool trans
copyWall1.tcs[UPRGT].v = copyWall2.tcs[UPLFT].v = tcs[UPLFT].v + coeff * (tcs[UPRGT].v - tcs[UPLFT].v);
copyWall1.tcs[LORGT].u = copyWall2.tcs[LOLFT].u = tcs[LOLFT].u + coeff * (tcs[LORGT].u - tcs[LOLFT].u);
copyWall1.tcs[LORGT].v = copyWall2.tcs[LOLFT].v = tcs[LOLFT].v + coeff * (tcs[LORGT].v - tcs[LOLFT].v);
copyWall1.lightuv[UPRGT].u = copyWall2.lightuv[UPLFT].u = lightuv[UPLFT].u + coeff * (lightuv[UPRGT].u - lightuv[UPLFT].u);
copyWall1.lightuv[UPRGT].v = copyWall2.lightuv[UPLFT].v = lightuv[UPLFT].v + coeff * (lightuv[UPRGT].v - lightuv[UPLFT].v);
copyWall1.lightuv[LORGT].u = copyWall2.lightuv[LOLFT].u = lightuv[LOLFT].u + coeff * (lightuv[LORGT].u - lightuv[LOLFT].u);
copyWall1.lightuv[LORGT].v = copyWall2.lightuv[LOLFT].v = lightuv[LOLFT].v + coeff * (lightuv[LORGT].v - lightuv[LOLFT].v);
copyWall1.SplitWall(di, frontsector, translucent);
copyWall2.SplitWall(di, frontsector, translucent);
@ -870,6 +878,10 @@ void HWWall::SplitWall(HWDrawInfo *di, sector_t * frontsector, bool translucent)
(maplightbottomleft-copyWall1.ztop[0])*(copyWall1.tcs[LOLFT].v-copyWall1.tcs[UPLFT].v)/(zbottom[0]-copyWall1.ztop[0]);
tcs[UPRGT].v=copyWall1.tcs[LORGT].v=copyWall1.tcs[UPRGT].v+
(maplightbottomright-copyWall1.ztop[1])*(copyWall1.tcs[LORGT].v-copyWall1.tcs[UPRGT].v)/(zbottom[1]-copyWall1.ztop[1]);
lightuv[UPLFT].v=copyWall1.lightuv[LOLFT].v=copyWall1.lightuv[UPLFT].v+
(maplightbottomleft-copyWall1.ztop[0])*(copyWall1.lightuv[LOLFT].v-copyWall1.lightuv[UPLFT].v)/(zbottom[0]-copyWall1.ztop[0]);
lightuv[UPRGT].v=copyWall1.lightuv[LORGT].v=copyWall1.lightuv[UPRGT].v+
(maplightbottomright-copyWall1.ztop[1])*(copyWall1.lightuv[LORGT].v-copyWall1.lightuv[UPRGT].v)/(zbottom[1]-copyWall1.ztop[1]);
copyWall1.Put3DWall(di, &lightlist[i], translucent);
}
if (ztop[0]==zbottom[0] && ztop[1]==zbottom[1])
@ -967,6 +979,8 @@ bool HWWall::DoHorizon(HWDrawInfo *di, seg_t * seg,sector_t * fs, vertex_t * v1,
return true;
}
static float ZeroLightmapUVs[8] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f };
//==========================================================================
//
//
@ -997,6 +1011,17 @@ bool HWWall::SetWallCoordinates(seg_t * seg, FTexCoordInfo *tci, float textureto
texlength = 0;
}
texcoord* srclightuv;
if (lightmap && lightmap->Type != ST_NULL)
{
srclightuv = (texcoord*)lightmap->TexCoords;
lindex = (float)lightmap->LightmapNum;
}
else
{
srclightuv = (texcoord*)ZeroLightmapUVs;
lindex = -1.0f;
}
//
//
@ -1014,6 +1039,9 @@ bool HWWall::SetWallCoordinates(seg_t * seg, FTexCoordInfo *tci, float textureto
tcs[UPLFT].v = tci->FloatToTexV(-ztop[0] + texturetop);
tcs[LOLFT].v = tci->FloatToTexV(-zbottom[0] + texturetop);
}
lightuv[UPLFT].v = srclightuv[UPLFT].v;
lightuv[LOLFT].v = srclightuv[LOLFT].v;
}
else
{
@ -1034,6 +1062,9 @@ bool HWWall::SetWallCoordinates(seg_t * seg, FTexCoordInfo *tci, float textureto
{
tcs[LOLFT].v = tcs[UPLFT].v = tci->FloatToTexV(-ztop[0] + texturetop);
}
lightuv[UPLFT].v = srclightuv[UPLFT].v + inter_x * (srclightuv[UPRGT].v - srclightuv[UPLFT].v);
lightuv[LOLFT].v = srclightuv[LOLFT].v + inter_x * (srclightuv[LORGT].v - srclightuv[LOLFT].v);
}
//
@ -1052,6 +1083,9 @@ bool HWWall::SetWallCoordinates(seg_t * seg, FTexCoordInfo *tci, float textureto
tcs[UPRGT].v = tci->FloatToTexV(-ztop[1] + texturetop);
tcs[LORGT].v = tci->FloatToTexV(-zbottom[1] + texturetop);
}
lightuv[UPRGT].v = srclightuv[UPRGT].v;
lightuv[LORGT].v = srclightuv[LORGT].v;
}
else
{
@ -1071,11 +1105,19 @@ bool HWWall::SetWallCoordinates(seg_t * seg, FTexCoordInfo *tci, float textureto
{
tcs[LORGT].v = tcs[UPRGT].v = tci->FloatToTexV(-ztop[1] + texturetop);
}
lightuv[UPRGT].v = srclightuv[UPRGT].v + inter_x * (srclightuv[UPRGT].v - srclightuv[UPLFT].v);
lightuv[LORGT].v = srclightuv[LORGT].v + inter_x * (srclightuv[LORGT].v - srclightuv[LOLFT].v);
}
tcs[UPLFT].u = tcs[LOLFT].u = l_ul + texlength * glseg.fracleft;
tcs[UPRGT].u = tcs[LORGT].u = l_ul + texlength * glseg.fracright;
lightuv[UPLFT].u = srclightuv[UPLFT].u + (srclightuv[UPRGT].u - srclightuv[UPLFT].u) * glseg.fracleft;
lightuv[LOLFT].u = srclightuv[LOLFT].u + (srclightuv[LORGT].u - srclightuv[LOLFT].u) * glseg.fracleft;
lightuv[UPRGT].u = srclightuv[UPLFT].u + (srclightuv[UPRGT].u - srclightuv[UPLFT].u) * glseg.fracright;
lightuv[LORGT].u = srclightuv[LOLFT].u + (srclightuv[LORGT].u - srclightuv[LOLFT].u) * glseg.fracright;
if (texture != NULL)
{
bool normalize = false;
@ -1606,6 +1648,15 @@ void HWWall::BuildFFBlock(HWDrawInfo *di, seg_t * seg, F3DFloor * rover, int rov
float texlength;
FTexCoordInfo tci;
lightmap = nullptr;
if (seg->sidedef == seg->linedef->sidedef[0])
lightmap = seg->linedef->sidedef[1]->lightmap;
else
lightmap = seg->linedef->sidedef[0]->lightmap;
if (lightmap)
lightmap += 4 + roverIndex;
if (rover->flags&FF_FOG)
{
if (!di->isFullbrightScene())
@ -1664,6 +1715,28 @@ void HWWall::BuildFFBlock(HWDrawInfo *di, seg_t * seg, F3DFloor * rover, int rov
tcs[LORGT].v = tci.FloatToTexV(to - ff_bottomright);
type = RENDERWALL_FFBLOCK;
CheckTexturePosition(&tci);
texcoord* srclightuv;
if (lightmap && lightmap->Type != ST_NULL)
{
srclightuv = (texcoord*)lightmap->TexCoords;
lindex = (float)lightmap->LightmapNum;
}
else
{
srclightuv = (texcoord*)ZeroLightmapUVs;
lindex = -1.0f;
}
lightuv[UPLFT].u = srclightuv[UPLFT].u + (srclightuv[UPRGT].u - srclightuv[UPLFT].u) * glseg.fracleft;
lightuv[LOLFT].u = srclightuv[LOLFT].u + (srclightuv[LORGT].u - srclightuv[LOLFT].u) * glseg.fracleft;
lightuv[UPRGT].u = srclightuv[UPLFT].u + (srclightuv[UPRGT].u - srclightuv[UPLFT].u) * glseg.fracright;
lightuv[LORGT].u = srclightuv[LOLFT].u + (srclightuv[LORGT].u - srclightuv[LOLFT].u) * glseg.fracright;
lightuv[UPLFT].v = srclightuv[UPLFT].v;
lightuv[UPRGT].v = srclightuv[UPRGT].v;
lightuv[LOLFT].v = srclightuv[LOLFT].v;
lightuv[LORGT].v = srclightuv[LORGT].v;
}
ztop[0] = ff_topleft;
@ -1685,15 +1758,6 @@ void HWWall::BuildFFBlock(HWDrawInfo *di, seg_t * seg, F3DFloor * rover, int rov
translucent = false;
}
lightmap = nullptr;
if (seg->sidedef == seg->linedef->sidedef[0])
lightmap = seg->linedef->sidedef[1]->lightmap;
else
lightmap = seg->linedef->sidedef[0]->lightmap;
if (lightmap)
lightmap += 4 + roverIndex;
sector_t * sec = sub ? sub->sector : seg->frontsector;
if (sec->e->XFloor.lightlist.Size() == 0 || di->isFullbrightScene()) PutWall(di, translucent);

View file

@ -34,7 +34,7 @@ EXTERN_CVAR(Bool, gl_seamless)
//
//==========================================================================
void HWWall::SplitUpperEdge(FFlatVertex *&ptr, texcoord* lightuv, float lindex)
void HWWall::SplitUpperEdge(FFlatVertex *&ptr)
{
side_t *sidedef = seg->sidedef;
float polyw = glseg.fracright - glseg.fracleft;
@ -73,7 +73,7 @@ void HWWall::SplitUpperEdge(FFlatVertex *&ptr, texcoord* lightuv, float lindex)
//
//==========================================================================
void HWWall::SplitLowerEdge(FFlatVertex *&ptr, texcoord* lightuv, float lindex)
void HWWall::SplitLowerEdge(FFlatVertex *&ptr)
{
side_t *sidedef = seg->sidedef;
float polyw = glseg.fracright - glseg.fracleft;
@ -112,7 +112,7 @@ void HWWall::SplitLowerEdge(FFlatVertex *&ptr, texcoord* lightuv, float lindex)
//
//==========================================================================
void HWWall::SplitLeftEdge(FFlatVertex *&ptr, texcoord* lightuv, float lindex)
void HWWall::SplitLeftEdge(FFlatVertex *&ptr)
{
if (vertexes[0] == NULL) return;
@ -151,7 +151,7 @@ void HWWall::SplitLeftEdge(FFlatVertex *&ptr, texcoord* lightuv, float lindex)
//
//==========================================================================
void HWWall::SplitRightEdge(FFlatVertex *&ptr, texcoord* lightuv, float lindex)
void HWWall::SplitRightEdge(FFlatVertex *&ptr)
{
if (vertexes[1] == NULL) return;
@ -190,31 +190,21 @@ void HWWall::SplitRightEdge(FFlatVertex *&ptr, texcoord* lightuv, float lindex)
//
//==========================================================================
static float ZeroLightmapUVs[8] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f };
int HWWall::CreateVertices(FFlatVertex *&ptr, bool split)
{
texcoord* lightuv = (texcoord*)ZeroLightmapUVs;
float lindex = -1.0f;
if (lightmap && lightmap->Type != ST_NULL)
{
lightuv = (texcoord*)lightmap->TexCoords;
lindex = (float)lightmap->LightmapNum;
}
auto oo = ptr;
ptr->Set(glseg.x1, zbottom[0], glseg.y1, tcs[LOLFT].u, tcs[LOLFT].v, lightuv[LOLFT].u, lightuv[LOLFT].v, lindex);
ptr++;
if (split && glseg.fracleft == 0) SplitLeftEdge(ptr, lightuv, lindex);
if (split && glseg.fracleft == 0) SplitLeftEdge(ptr);
ptr->Set(glseg.x1, ztop[0], glseg.y1, tcs[UPLFT].u, tcs[UPLFT].v, lightuv[UPLFT].u, lightuv[UPLFT].v, lindex);
ptr++;
if (split && !(flags & HWF_NOSPLITUPPER && seg->sidedef->numsegs > 1)) SplitUpperEdge(ptr, lightuv, lindex);
if (split && !(flags & HWF_NOSPLITUPPER && seg->sidedef->numsegs > 1)) SplitUpperEdge(ptr);
ptr->Set(glseg.x2, ztop[1], glseg.y2, tcs[UPRGT].u, tcs[UPRGT].v, lightuv[UPRGT].u, lightuv[UPRGT].v, lindex);
ptr++;
if (split && glseg.fracright == 1) SplitRightEdge(ptr, lightuv, lindex);
if (split && glseg.fracright == 1) SplitRightEdge(ptr);
ptr->Set(glseg.x2, zbottom[1], glseg.y2, tcs[LORGT].u, tcs[LORGT].v, lightuv[LORGT].u, lightuv[LORGT].v, lindex);
ptr++;
if (split && !(flags & HWF_NOSPLITLOWER) && seg->sidedef->numsegs > 1) SplitLowerEdge(ptr, lightuv, lindex);
if (split && !(flags & HWF_NOSPLITLOWER) && seg->sidedef->numsegs > 1) SplitLowerEdge(ptr);
return int(ptr - oo);
}