From 3f3769afdb629816857940f35eb0ca620f94522a Mon Sep 17 00:00:00 2001 From: nashmuhandes Date: Fri, 24 Sep 2021 17:27:23 +0800 Subject: [PATCH] - implement drawing sides with lightmaps - misc bug fixes in lump loading and format --- src/gamedata/r_defs.h | 5 +- src/maploader/maploader.cpp | 39 +++++++------ src/maploader/maploader.h | 2 +- src/rendering/hwrenderer/hw_vertexbuilder.cpp | 6 +- .../hwrenderer/scene/hw_drawstructs.h | 8 +-- .../hwrenderer/scene/hw_walls_vertex.cpp | 58 +++++++++++++++---- 6 files changed, 77 insertions(+), 41 deletions(-) diff --git a/src/gamedata/r_defs.h b/src/gamedata/r_defs.h index 8d2d7d910..3dc9497c0 100644 --- a/src/gamedata/r_defs.h +++ b/src/gamedata/r_defs.h @@ -1219,6 +1219,7 @@ struct side_t uint16_t Flags; int UDMFIndex; // needed to access custom UDMF fields which are stored in loading order. FLightNode * lighthead; // all dynamic lights that may affect this wall + LightmapSurface *lightmap[4]; seg_t **segs; // all segs belonging to this sidedef in ascending order. Used for precise rendering int numsegs; int sidenum; @@ -1461,8 +1462,6 @@ struct line_t int healthgroup; // [ZZ] this is the "destructible object" id int linenum; - LightmapSurface *lightmap[4]; - DVector2 Delta() const { return delta; @@ -1682,7 +1681,7 @@ struct LightmapSurface { SurfaceType Type; subsector_t *Subsector; - line_t *Line; + side_t *Side; sector_t *ControlSector; uint32_t LightmapNum; float *TexCoords; diff --git a/src/maploader/maploader.cpp b/src/maploader/maploader.cpp index d11c892d0..b2da76b9d 100644 --- a/src/maploader/maploader.cpp +++ b/src/maploader/maploader.cpp @@ -3292,7 +3292,7 @@ void MapLoader::SetSubsectorLightmap(const LightmapSurface &surface) } } -void MapLoader::SetLineLightmap(const LightmapSurface &surface) +void MapLoader::SetSideLightmap(const LightmapSurface &surface) { int index = 0; switch (surface.Type) @@ -3305,16 +3305,16 @@ void MapLoader::SetLineLightmap(const LightmapSurface &surface) if (!surface.ControlSector) { - surface.Line->lightmap[index][0] = surface; + surface.Side->lightmap[index][0] = surface; } else { - const auto& ffloors = surface.Line->frontsector->e->XFloor.ffloors; + const auto &ffloors = surface.Side->sector->e->XFloor.ffloors; for (unsigned int i = 0; i < ffloors.Size(); i++) { if (ffloors[i]->model == surface.ControlSector) { - surface.Line->lightmap[index][i + 1] = surface; + surface.Side->lightmap[index][i + 1] = surface; } } } @@ -3337,7 +3337,7 @@ void MapLoader::LoadLightmap(MapData *map) uint16_t numTextures = fr.ReadUInt16(); uint32_t numSurfaces = fr.ReadUInt32(); uint32_t numTexCoords = fr.ReadUInt32(); - uint32_t numTexBytes = numSurfaces * numTextures * textureSize * 2; + uint32_t numTexBytes = numTextures * textureSize * textureSize * 3 * 2; if (numSurfaces == 0 || numTexCoords == 0 || numTexBytes == 0) return; @@ -3348,8 +3348,8 @@ void MapLoader::LoadLightmap(MapData *map) unsigned int allSurfaces = 0; - for (unsigned int i = 0; i < Level->lines.Size(); i++) - allSurfaces += 3 + Level->lines[i].frontsector->e->XFloor.ffloors.Size() * 3; + for (unsigned int i = 0; i < Level->sides.Size(); i++) + allSurfaces += 3 + Level->sides[i].sector->e->XFloor.ffloors.Size() * 3; for (unsigned int i = 0; i < Level->subsectors.Size(); i++) allSurfaces += 2 + Level->subsectors[i].sector->e->XFloor.ffloors.Size() * 2; @@ -3357,17 +3357,17 @@ void MapLoader::LoadLightmap(MapData *map) Level->LMSurfaces.Resize(allSurfaces); memset(&Level->LMSurfaces[0], 0, sizeof(LightmapSurface) * allSurfaces); - // Link the surfaces to sectors, lines and their 3D floors + // Link the surfaces to sectors, sides and their 3D floors unsigned int offset = 0; - for (unsigned int i = 0; i < Level->lines.Size(); i++) + for (unsigned int i = 0; i < Level->sides.Size(); i++) { - auto& line = Level->lines[i]; - unsigned int count = 1 + line.frontsector->e->XFloor.ffloors.Size(); - line.lightmap[0] = &Level->LMSurfaces[offset]; - line.lightmap[1] = &Level->LMSurfaces[offset + count]; - line.lightmap[2] = line.lightmap[1]; - line.lightmap[3] = &Level->LMSurfaces[offset + count * 2]; + auto& side = Level->sides[i]; + unsigned int count = 1 + side.sector->e->XFloor.ffloors.Size(); + side.lightmap[0] = &Level->LMSurfaces[offset]; + side.lightmap[1] = &Level->LMSurfaces[offset + count]; + side.lightmap[2] = side.lightmap[1]; + side.lightmap[3] = &Level->LMSurfaces[offset + count * 2]; offset += count * 3; } for (unsigned int i = 0; i < Level->subsectors.Size(); i++) @@ -3397,7 +3397,7 @@ void MapLoader::LoadLightmap(MapData *map) surface.Type = type; surface.LightmapNum = lightmapNum; - surface.TexCoords = &Level->LMTexCoords[firstTexCoord]; + surface.TexCoords = &Level->LMTexCoords[firstTexCoord * 2]; if (type == ST_CEILING || type == ST_FLOOR) { @@ -3407,8 +3407,8 @@ void MapLoader::LoadLightmap(MapData *map) } else if (type != ST_NULL) { - surface.Line = &Level->lines[typeIndex]; - SetLineLightmap(surface); + surface.Side = &Level->sides[typeIndex]; + SetSideLightmap(surface); } } @@ -3423,6 +3423,9 @@ void MapLoader::LoadLightmap(MapData *map) Level->LMTextureData.Resize(numTexBytes); uint8_t* data = &Level->LMTextureData[0]; fr.Read(data, numTexBytes); +#if 0 + // Apply compression predictor for (uint32_t i = 1; i < numTexBytes; i++) data[i] += data[i - 1]; +#endif } diff --git a/src/maploader/maploader.h b/src/maploader/maploader.h index 37b0c4016..cc7e08187 100644 --- a/src/maploader/maploader.h +++ b/src/maploader/maploader.h @@ -305,7 +305,7 @@ public: void CopySlopes(); void SetSubsectorLightmap(const LightmapSurface &surface); - void SetLineLightmap(const LightmapSurface &surface); + void SetSideLightmap(const LightmapSurface &surface); void LoadLightmap(MapData *map); void LoadLevel(MapData *map, const char *lumpname, int position); diff --git a/src/rendering/hwrenderer/hw_vertexbuilder.cpp b/src/rendering/hwrenderer/hw_vertexbuilder.cpp index f95f3c356..d7aeb4cbb 100644 --- a/src/rendering/hwrenderer/hw_vertexbuilder.cpp +++ b/src/rendering/hwrenderer/hw_vertexbuilder.cpp @@ -242,7 +242,7 @@ static int CreateIndexedSectorVerticesLM(FFlatVertexBuffer* fvb, sector_t* sec, int lindex = lightmap->LightmapNum; for (unsigned int j = 0; j < sub->numlines; j++) { - SetFlatVertex(vbo_shadowdata[vi + pos], sub->firstline->v1, plane, luvs[j * 2], luvs[j * 2 + 1], lindex); + SetFlatVertex(vbo_shadowdata[vi + pos], sub->firstline[j].v1, plane, luvs[j * 2], luvs[j * 2 + 1], lindex); vbo_shadowdata[vi + pos].z += diff; pos++; } @@ -251,7 +251,7 @@ static int CreateIndexedSectorVerticesLM(FFlatVertexBuffer* fvb, sector_t* sec, { for (unsigned int j = 0; j < sub->numlines; j++) { - SetFlatVertex(vbo_shadowdata[vi + pos], sub->firstline->v1, plane); + SetFlatVertex(vbo_shadowdata[vi + pos], sub->firstline[j].v1, plane); vbo_shadowdata[vi + pos].z += diff; pos++; } @@ -259,7 +259,7 @@ static int CreateIndexedSectorVerticesLM(FFlatVertexBuffer* fvb, sector_t* sec, } // Create the indices for the subsectors - for (int i = 0; i < sec->subsectorcount; i++) + for (i = 0, pos = 0; i < sec->subsectorcount; i++) { subsector_t* sub = sec->subsectors[i]; int firstndx = vi + pos; diff --git a/src/rendering/hwrenderer/scene/hw_drawstructs.h b/src/rendering/hwrenderer/scene/hw_drawstructs.h index 205f225d3..239c35f24 100644 --- a/src/rendering/hwrenderer/scene/hw_drawstructs.h +++ b/src/rendering/hwrenderer/scene/hw_drawstructs.h @@ -255,10 +255,10 @@ public: void ProcessDecals(HWDrawInfo *di); int CreateVertices(FFlatVertex *&ptr, bool nosplit); - void SplitLeftEdge (FFlatVertex *&ptr); - void SplitRightEdge(FFlatVertex *&ptr); - void SplitUpperEdge(FFlatVertex *&ptr); - void SplitLowerEdge(FFlatVertex *&ptr); + void SplitLeftEdge (FFlatVertex *&ptr, float *lightuv, float lindex); + void SplitRightEdge(FFlatVertex *&ptr, float *lightuv, float lindex); + void SplitUpperEdge(FFlatVertex *&ptr, float *lightuv, float lindex); + void SplitLowerEdge(FFlatVertex *&ptr, float *lightuv, float lindex); void CountLeftEdge (unsigned &ptr); void CountRightEdge(unsigned &ptr); diff --git a/src/rendering/hwrenderer/scene/hw_walls_vertex.cpp b/src/rendering/hwrenderer/scene/hw_walls_vertex.cpp index 751dbde64..ec23dd186 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) +void HWWall::SplitUpperEdge(FFlatVertex *&ptr, float *lightuv, float lindex) { side_t *sidedef = seg->sidedef; float polyw = glseg.fracright - glseg.fracleft; @@ -43,6 +43,8 @@ void HWWall::SplitUpperEdge(FFlatVertex *&ptr) float fact = (ztop[1] - ztop[0]) / polyw; float facc = (zceil[1] - zceil[0]) / polyw; float facf = (zfloor[1] - zfloor[0]) / polyw; + float faclu = (lightuv[UPRGT * 2] - lightuv[UPLFT * 2]) / polyw; + float faclv = (lightuv[UPRGT * 2 + 1] - lightuv[UPLFT * 2 + 1]) / polyw; for (int i = 0; i < sidedef->numsegs - 1; i++) { @@ -58,6 +60,9 @@ void HWWall::SplitUpperEdge(FFlatVertex *&ptr) ptr->z = ztop[0] + fact * fracfac; ptr->u = tcs[UPLFT].u + facu * fracfac; ptr->v = tcs[UPLFT].v + facv * fracfac; + ptr->lu = lightuv[UPLFT * 2] + faclu * fracfac; + ptr->lv = lightuv[UPLFT * 2 + 1] + faclv * fracfac; + ptr->lindex = lindex; ptr++; } } @@ -68,7 +73,7 @@ void HWWall::SplitUpperEdge(FFlatVertex *&ptr) // //========================================================================== -void HWWall::SplitLowerEdge(FFlatVertex *&ptr) +void HWWall::SplitLowerEdge(FFlatVertex *&ptr, float *lightuv, float lindex) { side_t *sidedef = seg->sidedef; float polyw = glseg.fracright - glseg.fracleft; @@ -77,6 +82,8 @@ void HWWall::SplitLowerEdge(FFlatVertex *&ptr) float facb = (zbottom[1] - zbottom[0]) / polyw; float facc = (zceil[1] - zceil[0]) / polyw; float facf = (zfloor[1] - zfloor[0]) / polyw; + float faclu = (lightuv[LORGT * 2] - lightuv[LOLFT * 2]) / polyw; + float faclv = (lightuv[LORGT * 2 + 1] - lightuv[LOLFT * 2 + 1]) / polyw; for (int i = sidedef->numsegs - 2; i >= 0; i--) { @@ -92,6 +99,9 @@ void HWWall::SplitLowerEdge(FFlatVertex *&ptr) ptr->z = zbottom[0] + facb * fracfac; ptr->u = tcs[LOLFT].u + facu * fracfac; ptr->v = tcs[LOLFT].v + facv * fracfac; + ptr->lu = lightuv[LOLFT * 2] + faclu * fracfac; + ptr->lv = lightuv[LOLFT * 2 + 1] + faclv * fracfac; + ptr->lindex = lindex; ptr++; } } @@ -102,7 +112,7 @@ void HWWall::SplitLowerEdge(FFlatVertex *&ptr) // //========================================================================== -void HWWall::SplitLeftEdge(FFlatVertex *&ptr) +void HWWall::SplitLeftEdge(FFlatVertex *&ptr, float *lightuv, float lindex) { if (vertexes[0] == NULL) return; @@ -115,6 +125,8 @@ void HWWall::SplitLeftEdge(FFlatVertex *&ptr) float polyh1 = ztop[0] - zbottom[0]; float factv1 = polyh1 ? (tcs[UPLFT].v - tcs[LOLFT].v) / polyh1 : 0; float factu1 = polyh1 ? (tcs[UPLFT].u - tcs[LOLFT].u) / polyh1 : 0; + float factlv1 = polyh1 ? (lightuv[UPLFT * 2 + 1] - lightuv[LOLFT * 2 + 1]) / polyh1 : 0; + float factlu1 = polyh1 ? (lightuv[UPLFT * 2] - lightuv[LOLFT * 2]) / polyh1 : 0; while (inumheights && vi->heightlist[i] <= zbottom[0]) i++; while (inumheights && vi->heightlist[i] < ztop[0]) @@ -124,6 +136,9 @@ void HWWall::SplitLeftEdge(FFlatVertex *&ptr) ptr->z = vi->heightlist[i]; ptr->u = factu1*(vi->heightlist[i] - ztop[0]) + tcs[UPLFT].u; ptr->v = factv1*(vi->heightlist[i] - ztop[0]) + tcs[UPLFT].v; + ptr->lu = factlu1 * (vi->heightlist[i] - ztop[0]) + lightuv[UPLFT * 2]; + ptr->lv = factlv1 * (vi->heightlist[i] - ztop[0]) + lightuv[UPLFT * 2 + 1]; + ptr->lindex = lindex; ptr++; i++; } @@ -136,7 +151,7 @@ void HWWall::SplitLeftEdge(FFlatVertex *&ptr) // //========================================================================== -void HWWall::SplitRightEdge(FFlatVertex *&ptr) +void HWWall::SplitRightEdge(FFlatVertex *&ptr, float *lightuv, float lindex) { if (vertexes[1] == NULL) return; @@ -149,6 +164,8 @@ void HWWall::SplitRightEdge(FFlatVertex *&ptr) float polyh2 = ztop[1] - zbottom[1]; float factv2 = polyh2 ? (tcs[UPRGT].v - tcs[LORGT].v) / polyh2 : 0; float factu2 = polyh2 ? (tcs[UPRGT].u - tcs[LORGT].u) / polyh2 : 0; + float factlv2 = polyh2 ? (lightuv[UPRGT * 2 + 1] - lightuv[LORGT * 2 + 1]) / polyh2 : 0; + float factlu2 = polyh2 ? (lightuv[UPRGT * 2] - lightuv[LORGT * 2]) / polyh2 : 0; while (i>0 && vi->heightlist[i] >= ztop[1]) i--; while (i>0 && vi->heightlist[i] > zbottom[1]) @@ -158,6 +175,9 @@ void HWWall::SplitRightEdge(FFlatVertex *&ptr) ptr->z = vi->heightlist[i]; ptr->u = factu2*(vi->heightlist[i] - ztop[1]) + tcs[UPRGT].u; ptr->v = factv2*(vi->heightlist[i] - ztop[1]) + tcs[UPRGT].v; + ptr->lu = factlu2 * (vi->heightlist[i] - ztop[1]) + lightuv[UPRGT * 2]; + ptr->lv = factlv2 * (vi->heightlist[i] - ztop[1]) + lightuv[UPRGT * 2 + 1]; + ptr->lindex = lindex; ptr++; i--; } @@ -170,21 +190,35 @@ void HWWall::SplitRightEdge(FFlatVertex *&ptr) // //========================================================================== +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) { + float *lightuv = ZeroLightmapUVs; + float lindex = -1.0f; + if (seg && seg->sidedef && type >= RENDERWALL_TOP && type <= RENDERWALL_BOTTOM) + { + LightmapSurface *lightmap = seg->sidedef->lightmap[type - RENDERWALL_TOP]; + if (lightmap != nullptr && lightmap->Type != ST_NULL) + { + lightuv = lightmap->TexCoords; + lindex = (float)lightmap->LightmapNum; + } + } + auto oo = ptr; - ptr->Set(glseg.x1, zbottom[0], glseg.y1, tcs[LOLFT].u, tcs[LOLFT].v); + ptr->Set(glseg.x1, zbottom[0], glseg.y1, tcs[LOLFT].u, tcs[LOLFT].v, lightuv[LOLFT * 2], lightuv[LOLFT * 2 + 1], lindex); ptr++; - if (split && glseg.fracleft == 0) SplitLeftEdge(ptr); - ptr->Set(glseg.x1, ztop[0], glseg.y1, tcs[UPLFT].u, tcs[UPLFT].v); + if (split && glseg.fracleft == 0) SplitLeftEdge(ptr, lightuv, lindex); + ptr->Set(glseg.x1, ztop[0], glseg.y1, tcs[UPLFT].u, tcs[UPLFT].v, lightuv[UPLFT * 2], lightuv[UPLFT * 2 + 1], lindex); ptr++; - 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); + if (split && !(flags & HWF_NOSPLITUPPER && seg->sidedef->numsegs > 1)) SplitUpperEdge(ptr, lightuv, lindex); + ptr->Set(glseg.x2, ztop[1], glseg.y2, tcs[UPRGT].u, tcs[UPRGT].v, lightuv[UPRGT * 2], lightuv[UPRGT * 2 + 1], lindex); ptr++; - if (split && glseg.fracright == 1) SplitRightEdge(ptr); - ptr->Set(glseg.x2, zbottom[1], glseg.y2, tcs[LORGT].u, tcs[LORGT].v); + if (split && glseg.fracright == 1) SplitRightEdge(ptr, lightuv, lindex); + ptr->Set(glseg.x2, zbottom[1], glseg.y2, tcs[LORGT].u, tcs[LORGT].v, lightuv[LORGT * 2], lightuv[LORGT * 2 + 1], lindex); ptr++; - if (split && !(flags & HWF_NOSPLITLOWER) && seg->sidedef->numsegs > 1) SplitLowerEdge(ptr); + if (split && !(flags & HWF_NOSPLITLOWER) && seg->sidedef->numsegs > 1) SplitLowerEdge(ptr, lightuv, lindex); return int(ptr - oo); }