From 247deff5bb1f1e05f7b794c7df71e09202e70ae8 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Sun, 3 Oct 2021 03:47:40 +0200 Subject: [PATCH] Fix using wrong lightmap UV coordinates after all the wall clipping did its thing --- .../hwrenderer/scene/hw_drawlist.cpp | 5 ++ .../hwrenderer/scene/hw_drawstructs.h | 10 ++- src/rendering/hwrenderer/scene/hw_walls.cpp | 82 +++++++++++++++++-- .../hwrenderer/scene/hw_walls_vertex.cpp | 26 ++---- 4 files changed, 92 insertions(+), 31 deletions(-) diff --git a/src/rendering/hwrenderer/scene/hw_drawlist.cpp b/src/rendering/hwrenderer/scene/hw_drawlist.cpp index 872d5d4199..1d729e1108 100644 --- a/src/rendering/hwrenderer/scene/hw_drawlist.cpp +++ b/src/rendering/hwrenderer/scene/hw_drawlist.cpp @@ -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); diff --git a/src/rendering/hwrenderer/scene/hw_drawstructs.h b/src/rendering/hwrenderer/scene/hw_drawstructs.h index 3c08493c95..eac6b8424b 100644 --- a/src/rendering/hwrenderer/scene/hw_drawstructs.h +++ b/src/rendering/hwrenderer/scene/hw_drawstructs.h @@ -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); diff --git a/src/rendering/hwrenderer/scene/hw_walls.cpp b/src/rendering/hwrenderer/scene/hw_walls.cpp index 12a5fbfc35..bf62a77563 100644 --- a/src/rendering/hwrenderer/scene/hw_walls.cpp +++ b/src/rendering/hwrenderer/scene/hw_walls.cpp @@ -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); diff --git a/src/rendering/hwrenderer/scene/hw_walls_vertex.cpp b/src/rendering/hwrenderer/scene/hw_walls_vertex.cpp index 092d8dce68..e6cd1896f0 100644 --- a/src/rendering/hwrenderer/scene/hw_walls_vertex.cpp +++ b/src/rendering/hwrenderer/scene/hw_walls_vertex.cpp @@ -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); }