From 7c1acb5075cb7b42665ab35fdef9a87a0dcfe1dd Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Mon, 16 Oct 2023 16:46:35 +0200 Subject: [PATCH] Save lightmap lump --- src/level/level_udmf.cpp | 3 +- src/lightmapper/doom_levelmesh.cpp | 90 ++++++++++++----------------- src/lightmapper/doom_levelmesh.h | 3 +- src/lightmapper/gpuraytracer.cpp | 14 ++--- src/lightmapper/vk_renderdevice.cpp | 7 +-- src/lightmapper/vk_renderdevice.h | 2 +- 6 files changed, 50 insertions(+), 69 deletions(-) diff --git a/src/level/level_udmf.cpp b/src/level/level_udmf.cpp index 3e799d3..3efc27b 100644 --- a/src/level/level_udmf.cpp +++ b/src/level/level_udmf.cpp @@ -941,8 +941,7 @@ void FProcessor::WriteUDMF(FWadWriter &out) if (LightmapMesh) { - LightmapMesh->AddLightmapLump(out); - //LightmapMesh->Export("level.obj"); + LightmapMesh->AddLightmapLump(Level, out); } out.CreateLabel("ENDMAP"); diff --git a/src/lightmapper/doom_levelmesh.cpp b/src/lightmapper/doom_levelmesh.cpp index 5261775..af37dc6 100644 --- a/src/lightmapper/doom_levelmesh.cpp +++ b/src/lightmapper/doom_levelmesh.cpp @@ -2,6 +2,7 @@ #include "doom_levelmesh.h" #include "level/level.h" #include "framework/halffloat.h" +#include "framework/binfile.h" #include #include @@ -27,7 +28,7 @@ void DoomLevelMesh::DumpMesh(const FString& objFilename, const FString& mtlFilen static_cast(StaticMesh.get())->DumpMesh(objFilename, mtlFilename); } -void DoomLevelMesh::AddLightmapLump(FWadWriter& wadFile) +void DoomLevelMesh::AddLightmapLump(FLevel& doomMap, FWadWriter& wadFile) { /* // LIGHTMAP V2 pseudo-C specification: @@ -62,20 +63,15 @@ void DoomLevelMesh::AddLightmapLump(FWadWriter& wadFile) for (unsigned int i = 0; i < submesh->Surfaces.Size(); i++) { DoomLevelMeshSurface* surface = &submesh->Surfaces[i]; - if (surface->atlasPageIndex != -1) + if (surface->AtlasTile.ArrayIndex != -1) { surfaceCount++; pixelCount += surface->Area(); - uvCount += surface->verts.size(); - - if (surface->Area() != surf.texPixels.size()) - { - printf("Error: Surface area does not match the pixel count.\n"); - } + uvCount += surface->numVerts; } } - printf(" Writing %u surfaces out of %llu\n", surfaceCount, surfaces.size()); + printf(" Writing %u surfaces out of %llu\n", surfaceCount, (size_t)submesh->Surfaces.Size()); const int version = 2; @@ -118,23 +114,23 @@ void DoomLevelMesh::AddLightmapLump(FWadWriter& wadFile) { DoomLevelMeshSurface* surface = &submesh->Surfaces[i]; - if (surface->atlasPageIndex == -1) + if (surface->AtlasTile.ArrayIndex == -1) continue; lumpFile.Write32(surface->Type); lumpFile.Write32(surface->TypeIndex); - lumpFile.Write32(surface->ControlSector ? uint32_t(surface->ControlSector - &map->Sectors[0]) : 0xffffffff); + lumpFile.Write32(surface->ControlSector ? uint32_t(surface->ControlSector->Index(doomMap)) : 0xffffffff); - lumpFile.Write16(uint16_t(surface->texWidth)); - lumpFile.Write16(uint16_t(surface->texHeight)); + lumpFile.Write16(uint16_t(surface->AtlasTile.Width)); + lumpFile.Write16(uint16_t(surface->AtlasTile.Height)); lumpFile.Write32(pixelsOffset * 3); - lumpFile.Write32(surface->lightUV.size()); + lumpFile.Write32(surface->numVerts); lumpFile.Write32(uvOffset); pixelsOffset += surface->Area(); - uvOffset += surface->lightUV.size(); + uvOffset += (uint32_t)surface->numVerts; } if (debug) @@ -147,19 +143,22 @@ void DoomLevelMesh::AddLightmapLump(FWadWriter& wadFile) { DoomLevelMeshSurface* surface = &submesh->Surfaces[i]; - if (surface->atlasPageIndex == -1) + if (surface->AtlasTile.ArrayIndex == -1) continue; - if (debug) + const uint16_t* pixels = submesh->LMTextureData.Data() + surface->AtlasTile.ArrayIndex * submesh->LMTextureSize * submesh->LMTextureSize * 4; + int width = surface->AtlasTile.Width; + int height = surface->AtlasTile.Height; + for (int y = 0; y < height; y++) { - printf("Surface %llu contains %llu pixels\n", i, surface->texPixels.size()); - } - - for (const auto& pixel : surface->texPixels) - { - lumpFile.Write16(floatToHalf(clamp(pixel.r, 0.0f, 65000.0f))); - lumpFile.Write16(floatToHalf(clamp(pixel.g, 0.0f, 65000.0f))); - lumpFile.Write16(floatToHalf(clamp(pixel.b, 0.0f, 65000.0f))); + const uint16_t* srcline = pixels + (surface->AtlasTile.X + (surface->AtlasTile.Y + y) * submesh->LMTextureSize) * 4; + for (int x = 0; x < width; x++) + { + lumpFile.Write16(*(srcline++)); + lumpFile.Write16(*(srcline++)); + lumpFile.Write16(*(srcline++)); + srcline++; + } } } @@ -173,45 +172,32 @@ void DoomLevelMesh::AddLightmapLump(FWadWriter& wadFile) { DoomLevelMeshSurface* surface = &submesh->Surfaces[i]; - if (surface->atlasPageIndex == -1) + if (surface->AtlasTile.ArrayIndex == -1) continue; if (debug) { - printf("Surface %llu contains %llu UVs\n", i, surface->verts.size()); + printf("Surface %u contains %u UVs\n", i, surface->numVerts); } // as of V2 LIGHTMAP version: internal lightmapper uses ZDRay order triangle strips in its internal representation. It will convert from triangle strips to triangle fan on its own. - int count = surface->verts.size(); - if (surface->type == ST_FLOOR || surface->type == ST_CEILING) + float offsetU = surface->AtlasTile.X / (float)submesh->LMTextureSize; + float offsetV = surface->AtlasTile.Y / (float)submesh->LMTextureSize; + float scaleU = surface->AtlasTile.Width / (float)submesh->LMTextureSize; + float scaleV = surface->AtlasTile.Height / (float)submesh->LMTextureSize; + FVector2* texcoords = (FVector2*)surface->TexCoords; + for (int j = 0, count = surface->numVerts; j < count; j++) { - for (int j = 0; j < count; j++) - { - lumpFile.WriteFloat(surface->lightUV[j].x); - lumpFile.WriteFloat(surface->lightUV[j].y); - } - } - else - { - lumpFile.WriteFloat(surface->lightUV[0].x); - lumpFile.WriteFloat(surface->lightUV[0].y); - - lumpFile.WriteFloat(surface->lightUV[1].x); - lumpFile.WriteFloat(surface->lightUV[1].y); - - lumpFile.WriteFloat(surface->lightUV[2].x); - lumpFile.WriteFloat(surface->lightUV[2].y); - - lumpFile.WriteFloat(surface->lightUV[3].x); - lumpFile.WriteFloat(surface->lightUV[3].y); + lumpFile.WriteFloat((texcoords[j].X - offsetU) * scaleU); + lumpFile.WriteFloat((texcoords[j].Y - offsetV) * scaleV); } } // Compress and store in lump ZLibOut zout(wadFile); wadFile.StartWritingLump("LIGHTMAP"); - zout.Write(buffer.data(), lumpFile.BufferAt() - lumpFile.Buffer()); + zout.Write(buffer.data(), (int)(ptrdiff_t)(lumpFile.BufferAt() - lumpFile.Buffer())); } ///////////////////////////////////////////////////////////////////////////// @@ -1150,11 +1136,9 @@ void DoomLevelSubmesh::DumpMesh(const FString& objFilename, const FString& mtlFi fprintf(f, "v %f %f %f\n", v.X * scale, v.Z * scale, -v.Y * scale); } + for (const auto& uv : LightmapUvs) { - for (const auto& uv : LightmapUvs) - { - fprintf(f, "vt %f %f\n", uv.X, uv.Y); - } + fprintf(f, "vt %f %f\n", uv.X, uv.Y); } auto name = [](DoomLevelMeshSurfaceType type) -> const char* { diff --git a/src/lightmapper/doom_levelmesh.h b/src/lightmapper/doom_levelmesh.h index efba80e..15db55e 100644 --- a/src/lightmapper/doom_levelmesh.h +++ b/src/lightmapper/doom_levelmesh.h @@ -15,7 +15,7 @@ public: int AddSurfaceLights(const LevelMeshSurface* surface, LevelMeshLight* list, int listMaxSize) override; void DumpMesh(const FString& objFilename, const FString& mtlFilename) const; - void AddLightmapLump(FWadWriter& out); + void AddLightmapLump(FLevel& doomMap, FWadWriter& out); }; enum DoomLevelMeshSurfaceType @@ -55,7 +55,6 @@ public: void BindLightmapSurfacesToGeometry(FLevel& doomMap); void PackLightmapAtlas(int lightmapStartIndex); void CreatePortals(FLevel& doomMap); - void DisableLightmaps() { Surfaces.Clear(); } // Temp hack that disables lightmapping TArray Surfaces; TArray LightmapUvs; diff --git a/src/lightmapper/gpuraytracer.cpp b/src/lightmapper/gpuraytracer.cpp index e3a1043..57d4c35 100644 --- a/src/lightmapper/gpuraytracer.cpp +++ b/src/lightmapper/gpuraytracer.cpp @@ -39,8 +39,9 @@ void GPURaytracer::Raytrace(DoomLevelMesh* mesh) { auto raytrace = mDevice->GetRaytrace(); auto lightmap = mDevice->GetLightmap(); + auto submesh = mesh->StaticMesh.get(); - // mDevice->GetTextureManager()->CreateLightmap(mesh->LMTextureSize, mesh->LMTextureCount); + mDevice->GetTextureManager()->CreateLightmap(submesh->LMTextureSize, submesh->LMTextureCount); printf("."); raytrace->SetLevelMesh(mesh); @@ -49,16 +50,15 @@ void GPURaytracer::Raytrace(DoomLevelMesh* mesh) lightmap->BeginFrame(); printf("."); - // lightmap->Raytrace(surfaces); + //lightmap->Raytrace(surfaces); printf("."); - /* - TArray buffer; - for (int arrayIndex = 0; arrayIndex < mesh->LMTextureCount; arrayIndex++) + + submesh->LMTextureData.Resize(submesh->LMTextureSize * submesh->LMTextureSize * submesh->LMTextureCount * 4); + for (int arrayIndex = 0; arrayIndex < submesh->LMTextureCount; arrayIndex++) { - mDevice->GetTextureManager()->DownloadLightmap(arrayIndex, buffer); + mDevice->GetTextureManager()->DownloadLightmap(arrayIndex, submesh->LMTextureData.Data() + arrayIndex * submesh->LMTextureSize * submesh->LMTextureSize * 4); } - */ } catch (...) { diff --git a/src/lightmapper/vk_renderdevice.cpp b/src/lightmapper/vk_renderdevice.cpp index ed79f69..75cf3ee 100644 --- a/src/lightmapper/vk_renderdevice.cpp +++ b/src/lightmapper/vk_renderdevice.cpp @@ -116,10 +116,9 @@ void VkTextureManager::CreateLightmap(int newLMTextureSize, int newLMTextureCoun .Execute(fb->GetCommands()->GetTransferCommands(), 0, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); } -void VkTextureManager::DownloadLightmap(int arrayIndex, TArray& buffer) +void VkTextureManager::DownloadLightmap(int arrayIndex, uint16_t* buffer) { - unsigned int totalSize = LMTextureSize * LMTextureSize; - buffer.Resize(totalSize); + unsigned int totalSize = LMTextureSize * LMTextureSize * 4; auto stagingBuffer = BufferBuilder() .Size(totalSize * sizeof(uint16_t)) @@ -150,7 +149,7 @@ void VkTextureManager::DownloadLightmap(int arrayIndex, TArray& buffer fb->GetCommands()->SubmitAndWait(); uint16_t* srcdata = (uint16_t*)stagingBuffer->Map(0, totalSize * sizeof(uint16_t)); - memcpy(buffer.Data(), srcdata, totalSize * sizeof(uint16_t)); + memcpy(buffer, srcdata, totalSize * sizeof(uint16_t)); stagingBuffer->Unmap(); } diff --git a/src/lightmapper/vk_renderdevice.h b/src/lightmapper/vk_renderdevice.h index 10abf44..afdf4a4 100644 --- a/src/lightmapper/vk_renderdevice.h +++ b/src/lightmapper/vk_renderdevice.h @@ -113,7 +113,7 @@ public: VkTextureManager(VulkanRenderDevice* fb); void CreateLightmap(int newLMTextureSize, int newLMTextureCount); - void DownloadLightmap(int arrayIndex, TArray& buffer); + void DownloadLightmap(int arrayIndex, uint16_t* buffer); VkTextureImage Lightmap; int LMTextureSize = 0;