From 0c53fbe1742f946ba1403edf127a6328880cd2c3 Mon Sep 17 00:00:00 2001 From: RaveYard <29225776+MrRaveYard@users.noreply.github.com> Date: Sat, 15 Mar 2025 15:17:45 +0100 Subject: [PATCH] Minor refactor of lightmap loading code --- src/maploader/maploader.cpp | 37 ++++++++++-- src/rendering/hwrenderer/doom_levelmesh.cpp | 59 +++++++++---------- .../hwrenderer/scene/hw_drawstructs.h | 6 +- 3 files changed, 66 insertions(+), 36 deletions(-) diff --git a/src/maploader/maploader.cpp b/src/maploader/maploader.cpp index 38ae56856..e2bbbc8db 100644 --- a/src/maploader/maploader.cpp +++ b/src/maploader/maploader.cpp @@ -3038,7 +3038,10 @@ bool MapLoader::LoadLightmap(MapData* map) FileReader fr; if (!OpenDecompressor(fr, map->Reader(ML_LIGHTMAP), -1, FileSys::METHOD_ZLIB)) + { + Printf(PRINT_HIGH, "LoadLightmap: unable to open and decompress lightmap lump.\n"); return false; + } int version = fr.ReadInt32(); if (version < LIGHTMAPVER) @@ -3067,7 +3070,7 @@ bool MapLoader::LoadLightmap(MapData* map) // Load the tiles we have lightmap data for - struct TileEntry // V2 entries + struct TileEntry { uint32_t type, typeIndex; uint32_t controlSector; // 0xFFFFFFFF is none @@ -3076,6 +3079,27 @@ bool MapLoader::LoadLightmap(MapData* map) FVector3 translateWorldToLocal; FVector3 projLocalToU; FVector3 projLocalToV; + + inline bool IsValid(const FLevelLocals& level) const + { + if (width > 0 && height > 0 && type > ST_NONE && type < MAX_SURFACE_TYPES && (controlSector == 0xFFFFFFFF || controlSector < level.subsectors.Size())) + { + if (type < ST_CEILING) + { + return typeIndex < level.sides.Size(); + } + else + { + return typeIndex < level.subsectors.Size(); + } + } + return false; + } + + inline const char* GetTypeName() const + { + return GetDoomLevelMeshSurfaceTypeName(static_cast(type)); + } }; TArray tileEntries; @@ -3134,10 +3158,10 @@ bool MapLoader::LoadLightmap(MapData* map) continue; } - if (entry.width == 0 || entry.height == 0) + if (!entry.IsValid(*Level)) { if (errors < 100 && developer >= 1) - Printf("Invalid lightmap tile found (type = %d, index = %d, control sector = %d)\n", entry.type, entry.typeIndex, entry.controlSector); + Printf("LoadLightmap: Invalid lightmap tile found (type = %s = %d, index = %d, control sector = %d, width = %d, height = %d)\n", entry.GetTypeName(), entry.type, entry.typeIndex, entry.controlSector, entry.width, entry.height); errors++; continue; } @@ -3154,6 +3178,11 @@ bool MapLoader::LoadLightmap(MapData* map) foundBindings.Push({ &entry, tile }); } + if (errors > 0 && developer >= 1) + { + Printf("Note: Level contains %d sidedefs and %d subsectors.", Level->sides.Size(), Level->subsectors.Size()); + } + // Place all tiles in atlas textures Level->levelMesh->PackStaticLightmapAtlas(); @@ -3178,7 +3207,7 @@ bool MapLoader::LoadLightmap(MapData* map) { uint16_t* dstline = dst + (destx + (desty + yy) * textureSize) * 3; const uint16_t* srcline = src + yy * (width * 3); - memcpy(dstline, srcline, width * 6); + memcpy(dstline, srcline, width * 3 * sizeof(uint16_t)); } tile->NeedsUpdate = false; diff --git a/src/rendering/hwrenderer/doom_levelmesh.cpp b/src/rendering/hwrenderer/doom_levelmesh.cpp index 7b896c924..4d468cead 100644 --- a/src/rendering/hwrenderer/doom_levelmesh.cpp +++ b/src/rendering/hwrenderer/doom_levelmesh.cpp @@ -1548,6 +1548,28 @@ void DoomLevelMesh::GetVisibleSurfaces(LightmapTile* tile, TArray& outSurfa } } +const char* GetDoomLevelMeshSurfaceTypeName(DoomLevelMeshSurfaceType type) +{ + switch (type) + { + case ST_NONE: + return "none"; + case ST_MIDDLESIDE: + return "middleside"; + case ST_UPPERSIDE: + return "upperside"; + case ST_LOWERSIDE: + return "lowerside"; + case ST_CEILING: + return "ceiling"; + case ST_FLOOR: + return "floor"; + default: + break; + } + return "unknown"; +} + void DoomLevelMesh::DumpMesh(const FString& objFilename, const FString& mtlFilename) const { auto f = fopen(objFilename.GetChars(), "w"); @@ -1570,31 +1592,7 @@ void DoomLevelMesh::DumpMesh(const FString& objFilename, const FString& mtlFilen fprintf(f, "vt %f %f\n", v.lu, v.lv); } - auto name = [](DoomLevelMeshSurfaceType type) -> const char* { - switch (type) - { - case ST_CEILING: - return "ceiling"; - case ST_FLOOR: - return "floor"; - case ST_LOWERSIDE: - return "lowerside"; - case ST_UPPERSIDE: - return "upperside"; - case ST_MIDDLESIDE: - return "middleside"; - case ST_NONE: - return "none"; - default: - break; - } - return "error"; - }; - - uint32_t lastSurfaceIndex = -1; - - bool useErrorMaterial = false; int highestUsedAtlasPage = -1; @@ -1617,7 +1615,7 @@ void DoomLevelMesh::DumpMesh(const FString& objFilename, const FString& mtlFilen { const auto& info = DoomSurfaceInfos[index]; const auto& surface = Mesh.Surfaces[index]; - fprintf(f, "o Surface[%d] %s %d%s\n", index, name(info.Type), info.TypeIndex, surface.IsSky ? " sky" : ""); + fprintf(f, "o Surface[%d] %s %d%s\n", index, GetDoomLevelMeshSurfaceTypeName(info.Type), info.TypeIndex, surface.IsSky ? " sky" : ""); if (surface.LightmapTileIndex >= 0) { @@ -1710,7 +1708,7 @@ void DoomLevelMesh::BuildSectorGroups(const FLevelLocals& doomMap) if (developer >= 5) { - Printf("DoomLevelMesh::BuildSectorGroups created %d groups.", groupIndex); + Printf("DoomLevelMesh::BuildSectorGroups created %d groups.\n", groupIndex); } } @@ -1997,8 +1995,7 @@ void DoomLevelMesh::SaveLightmapLump(FLevelLocals& doomMap) int version; uint32_t tileCount; uint32_t pixelCount; - uint32_t uvCount; - SurfaceEntry surfaces[surfaceCount]; + TileEntry tiles[surfaceCount]; uint16_t pixels[pixelCount * 3]; }; @@ -2008,9 +2005,9 @@ void DoomLevelMesh::SaveLightmapLump(FLevelLocals& doomMap) uint32_t controlSector; // 0xFFFFFFFF is none uint16_t width, height; // in pixels uint32_t pixelsOffset; // offset in pixels array - vec3 translateWorldToLocal; - vec3 projLocalToU; - vec3 projLocalToV; + vec3f translateWorldToLocal; + vec3f projLocalToU; + vec3f projLocalToV; }; */ diff --git a/src/rendering/hwrenderer/scene/hw_drawstructs.h b/src/rendering/hwrenderer/scene/hw_drawstructs.h index f90fc6b4c..e0d4f21d5 100644 --- a/src/rendering/hwrenderer/scene/hw_drawstructs.h +++ b/src/rendering/hwrenderer/scene/hw_drawstructs.h @@ -74,9 +74,13 @@ enum DoomLevelMeshSurfaceType ST_UPPERSIDE, ST_LOWERSIDE, ST_CEILING, - ST_FLOOR + ST_FLOOR, + + MAX_SURFACE_TYPES, }; +const char* GetDoomLevelMeshSurfaceTypeName(DoomLevelMeshSurfaceType type); + //========================================================================== // // One sector plane, still in fixed point