Use LIGHTMAP lump surface dimensions before packing the lightmap atlas

This commit is contained in:
RaveYard 2023-09-18 15:53:32 +02:00 committed by Christoph Oelckers
parent b40269e3fe
commit b400634db8
5 changed files with 37 additions and 16 deletions

View file

@ -2984,7 +2984,11 @@ void MapLoader::InitLevelMesh(MapData* map)
if (Level->lightmaps) if (Level->lightmaps)
{ {
LoadLightmap(map); if (!LoadLightmap(map))
{
Level->levelMesh->PackLightmapAtlas();
}
Level->levelMesh->BindLightmapSurfacesToGeometry(*Level); Level->levelMesh->BindLightmapSurfacesToGeometry(*Level);
} }
else else
@ -2993,30 +2997,30 @@ void MapLoader::InitLevelMesh(MapData* map)
} }
} }
void MapLoader::LoadLightmap(MapData* map) bool MapLoader::LoadLightmap(MapData* map)
{ {
if (!map->Size(ML_LIGHTMAP)) if (!map->Size(ML_LIGHTMAP))
return; return false;
FileReader fr; FileReader fr;
if (!fr.OpenDecompressor(map->Reader(ML_LIGHTMAP), -1, FileSys::METHOD_ZLIB, false, true)) if (!fr.OpenDecompressor(map->Reader(ML_LIGHTMAP), -1, FileSys::METHOD_ZLIB, false, true))
return; return false;
int version = fr.ReadInt32(); int version = fr.ReadInt32();
if (version == 0) if (version == 0)
{ {
Printf(PRINT_HIGH, "LoadLightmap: This is an old unsupported alpha version of the lightmap lump. Please rebuild the map with a newer version of zdray.\n"); Printf(PRINT_HIGH, "LoadLightmap: This is an old unsupported alpha version of the lightmap lump. Please rebuild the map with a newer version of zdray.\n");
return; return false;
} }
if (version == 1) if (version == 1)
{ {
Printf(PRINT_HIGH, "LoadLightmap: This is an old unsupported version of the lightmap lump. Please rebuild the map with a newer version of zdray.\n"); Printf(PRINT_HIGH, "LoadLightmap: This is an old unsupported version of the lightmap lump. Please rebuild the map with a newer version of zdray.\n");
return; return false;
} }
if (version != 2) if (version != 2)
{ {
Printf(PRINT_HIGH, "LoadLightmap: unsupported lightmap lump version\n"); Printf(PRINT_HIGH, "LoadLightmap: unsupported lightmap lump version\n");
return; return false;
} }
uint32_t numSurfaces = fr.ReadUInt32(); uint32_t numSurfaces = fr.ReadUInt32();
@ -3029,7 +3033,7 @@ void MapLoader::LoadLightmap(MapData* map)
} }
if (numSurfaces == 0 || numTexCoords == 0 || numTexPixels == 0) if (numSurfaces == 0 || numTexCoords == 0 || numTexPixels == 0)
return; return false;
bool errors = false; bool errors = false;
@ -3073,7 +3077,8 @@ void MapLoader::LoadLightmap(MapData* map)
}; };
TMap<DoomLevelMeshSurface*, int> detectedSurfaces; TMap<DoomLevelMeshSurface*, int> detectedSurfaces;
TArray<SurfaceEntry> zdraySurfaces; // TODO reserve ahead of time 'numSurfaces' TArray<SurfaceEntry> zdraySurfaces;
zdraySurfaces.Reserve(numSurfaces);
for (auto& surface : Level->levelMesh->Surfaces) for (auto& surface : Level->levelMesh->Surfaces)
{ {
@ -3092,6 +3097,7 @@ void MapLoader::LoadLightmap(MapData* map)
} }
} }
uint32_t usedSurfaceIndex = 0;
for (uint32_t i = 0; i < numSurfaces; i++) for (uint32_t i = 0; i < numSurfaces; i++)
{ {
SurfaceEntry surface; SurfaceEntry surface;
@ -3160,12 +3166,19 @@ void MapLoader::LoadLightmap(MapData* map)
} }
else else
{ {
levelSurface->texWidth = surface.width;
levelSurface->texHeight = surface.height;
surface.targetSurface = levelSurface; surface.targetSurface = levelSurface;
detectedSurfaces.Insert(levelSurface, 1); detectedSurfaces.Insert(levelSurface, 1);
zdraySurfaces.Push(surface); zdraySurfaces[usedSurfaceIndex++] = surface;
} }
} }
Level->levelMesh->PackLightmapAtlas();
zdraySurfaces.Resize(usedSurfaceIndex);
if (developer >= 1) if (developer >= 1)
{ {
Printf("Lightmap contains %d surfaces out of which %d were successfully matched.\n", numSurfaces, zdraySurfaces.Size()); Printf("Lightmap contains %d surfaces out of which %d were successfully matched.\n", numSurfaces, zdraySurfaces.Size());
@ -3310,7 +3323,7 @@ void MapLoader::LoadLightmap(MapData* map)
// Use UVs from the lightmap // Use UVs from the lightmap
for (auto& surface : zdraySurfaces) for (auto& surface : zdraySurfaces)
{ {
auto& realSurface = Level->levelMesh->Surfaces[findSurfaceIndex(surface.type, surface.typeIndex, getControlSector(surface.controlSector))]; auto& realSurface = *surface.targetSurface;
auto* UVs = &Level->levelMesh->LightmapUvs[realSurface.startUvIndex]; auto* UVs = &Level->levelMesh->LightmapUvs[realSurface.startUvIndex];
auto* newUVs = &zdrayUvs[surface.uvOffset]; auto* newUVs = &zdrayUvs[surface.uvOffset];

View file

@ -305,7 +305,7 @@ public:
void CopySlopes(); void CopySlopes();
void InitLevelMesh(MapData* map); void InitLevelMesh(MapData* map);
void LoadLightmap(MapData* map); bool LoadLightmap(MapData* map);
void LoadLevel(MapData *map, const char *lumpname, int position); void LoadLevel(MapData *map, const char *lumpname, int position);

View file

@ -1070,17 +1070,24 @@ void DoomLevelMesh::SetupLightmapUvs()
{ {
LMTextureSize = 1024; // TODO cvar LMTextureSize = 1024; // TODO cvar
for (auto& surface : Surfaces)
{
BuildSurfaceParams(LMTextureSize, LMTextureSize, surface);
}
BuildSmoothingGroups();
}
void DoomLevelMesh::PackLightmapAtlas()
{
std::vector<LevelMeshSurface*> sortedSurfaces; std::vector<LevelMeshSurface*> sortedSurfaces;
sortedSurfaces.reserve(Surfaces.Size()); sortedSurfaces.reserve(Surfaces.Size());
for (auto& surface : Surfaces) for (auto& surface : Surfaces)
{ {
BuildSurfaceParams(LMTextureSize, LMTextureSize, surface);
sortedSurfaces.push_back(&surface); sortedSurfaces.push_back(&surface);
} }
BuildSmoothingGroups();
std::sort(sortedSurfaces.begin(), sortedSurfaces.end(), [](LevelMeshSurface* a, LevelMeshSurface* b) { return a->texHeight != b->texHeight ? a->texHeight > b->texHeight : a->texWidth > b->texWidth; }); std::sort(sortedSurfaces.begin(), sortedSurfaces.end(), [](LevelMeshSurface* a, LevelMeshSurface* b) { return a->texHeight != b->texHeight ? a->texHeight > b->texHeight : a->texWidth > b->texWidth; });
RectPacker packer(LMTextureSize, LMTextureSize, RectPacker::Spacing(0)); RectPacker packer(LMTextureSize, LMTextureSize, RectPacker::Spacing(0));

View file

@ -30,6 +30,7 @@ public:
void CreatePortals(); void CreatePortals();
void DumpMesh(const FString& objFilename, const FString& mtlFilename) const; void DumpMesh(const FString& objFilename, const FString& mtlFilename) const;
void BindLightmapSurfacesToGeometry(FLevelLocals& doomMap); void BindLightmapSurfacesToGeometry(FLevelLocals& doomMap);
void PackLightmapAtlas();
bool TraceSky(const FVector3& start, FVector3 direction, float dist) bool TraceSky(const FVector3& start, FVector3 direction, float dist)
{ {

View file

@ -214,7 +214,7 @@ struct HWDrawInfo
{ {
surface->needsUpdate = true; surface->needsUpdate = true;
} }
else if (VisibleSurfaces.Size() >= lm_max_updates) else if (VisibleSurfaces.Size() >= unsigned(lm_max_updates))
{ {
return; return;
} }