diff --git a/src/common/rendering/hwrenderer/data/hw_levelmesh.h b/src/common/rendering/hwrenderer/data/hw_levelmesh.h index c09fb84a3..eeaaf16db 100644 --- a/src/common/rendering/hwrenderer/data/hw_levelmesh.h +++ b/src/common/rendering/hwrenderer/data/hw_levelmesh.h @@ -12,9 +12,10 @@ #include - typedef dp::rect_pack::RectPacker RectPacker; +class LevelSubmesh; + class LevelMeshLight { public: @@ -31,6 +32,8 @@ public: struct LevelMeshSurface { + LevelSubmesh* Submesh = nullptr; + int numVerts = 0; unsigned int startVertIndex = 0; unsigned int startUvIndex = 0; diff --git a/src/common/rendering/vulkan/accelstructs/vk_lightmap.cpp b/src/common/rendering/vulkan/accelstructs/vk_lightmap.cpp index e93b61391..edfa978d3 100644 --- a/src/common/rendering/vulkan/accelstructs/vk_lightmap.cpp +++ b/src/common/rendering/vulkan/accelstructs/vk_lightmap.cpp @@ -167,10 +167,18 @@ void VkLightmap::Render() auto& selectedSurface = selectedSurfaces[i]; LevelMeshSurface* targetSurface = selectedSurface.Surface; + int surfaceIndexOffset = 0; + int firstIndexOffset = 0; + if (targetSurface->Submesh != mesh->StaticMesh.get()) + { + surfaceIndexOffset = mesh->StaticMesh->GetSurfaceCount(); + firstIndexOffset = mesh->StaticMesh->MeshElements.Size(); + } + LightmapRaytracePC pc; pc.TileX = (float)selectedSurface.X; pc.TileY = (float)selectedSurface.Y; - pc.SurfaceIndex = mesh->StaticMesh->GetSurfaceIndex(targetSurface); + pc.SurfaceIndex = surfaceIndexOffset + targetSurface->Submesh->GetSurfaceIndex(targetSurface); pc.TextureSize = (float)bakeImageSize; pc.TileWidth = (float)targetSurface->AtlasTile.Width; pc.TileHeight = (float)targetSurface->AtlasTile.Height; @@ -223,7 +231,7 @@ void VkLightmap::Render() VkDrawIndexedIndirectCommand cmd; cmd.indexCount = surface->numElements; cmd.instanceCount = 1; - cmd.firstIndex = surface->startElementIndex; + cmd.firstIndex = firstIndexOffset + surface->startElementIndex; cmd.vertexOffset = 0; cmd.firstInstance = drawindexed.Pos; drawindexed.Constants[drawindexed.Pos] = pc; diff --git a/src/common/rendering/vulkan/accelstructs/vk_raytrace.cpp b/src/common/rendering/vulkan/accelstructs/vk_raytrace.cpp index 94a0b8956..0eb633485 100644 --- a/src/common/rendering/vulkan/accelstructs/vk_raytrace.cpp +++ b/src/common/rendering/vulkan/accelstructs/vk_raytrace.cpp @@ -205,7 +205,8 @@ void VkRaytrace::UploadMeshes(bool dynamicOnly) *(vertices++) = { { submesh->MeshVertices[j], 1.0f }, submesh->MeshVertexUVs[j], float(j), j + 10000.0f }; size_t copysize = submesh->MeshVertices.Size() * sizeof(SurfaceVertex); - cmdbuffer->copyBuffer(transferBuffer.get(), VertexBuffer.get(), datapos, cur.VertexOffset * sizeof(SurfaceVertex), copysize); + if (copysize > 0) + cmdbuffer->copyBuffer(transferBuffer.get(), VertexBuffer.get(), datapos, cur.VertexOffset * sizeof(SurfaceVertex), copysize); datapos += copysize; } @@ -220,7 +221,8 @@ void VkRaytrace::UploadMeshes(bool dynamicOnly) *(indexes++) = cur.VertexOffset + submesh->MeshElements[j]; size_t copysize = submesh->MeshElements.Size() * sizeof(uint32_t); - cmdbuffer->copyBuffer(transferBuffer.get(), IndexBuffer.get(), datapos, cur.IndexOffset * sizeof(uint32_t), copysize); + if (copysize > 0) + cmdbuffer->copyBuffer(transferBuffer.get(), IndexBuffer.get(), datapos, cur.IndexOffset * sizeof(uint32_t), copysize); datapos += copysize; } @@ -243,7 +245,8 @@ void VkRaytrace::UploadMeshes(bool dynamicOnly) } size_t copysize = submesh->Collision->get_nodes().size() * sizeof(CollisionNode); - cmdbuffer->copyBuffer(transferBuffer.get(), NodeBuffer.get(), datapos, +sizeof(CollisionNodeBufferHeader) + cur.NodeOffset * sizeof(CollisionNode), copysize); + if (copysize > 0) + cmdbuffer->copyBuffer(transferBuffer.get(), NodeBuffer.get(), datapos, +sizeof(CollisionNodeBufferHeader) + cur.NodeOffset * sizeof(CollisionNode), copysize); datapos += copysize; } @@ -258,7 +261,8 @@ void VkRaytrace::UploadMeshes(bool dynamicOnly) *(indexes++) = cur.SurfaceIndexOffset + submesh->MeshSurfaceIndexes[j]; size_t copysize = submesh->MeshSurfaceIndexes.Size() * sizeof(int); - cmdbuffer->copyBuffer(transferBuffer.get(), SurfaceIndexBuffer.get(), datapos, cur.SurfaceIndexOffset * sizeof(int), copysize); + if (copysize > 0) + cmdbuffer->copyBuffer(transferBuffer.get(), SurfaceIndexBuffer.get(), datapos, cur.SurfaceIndexOffset * sizeof(int), copysize); datapos += copysize; } @@ -293,7 +297,8 @@ void VkRaytrace::UploadMeshes(bool dynamicOnly) } size_t copysize = submesh->GetSurfaceCount() * sizeof(SurfaceInfo); - cmdbuffer->copyBuffer(transferBuffer.get(), SurfaceBuffer.get(), datapos, cur.SurfaceOffset * sizeof(SurfaceInfo), copysize); + if (copysize > 0) + cmdbuffer->copyBuffer(transferBuffer.get(), SurfaceBuffer.get(), datapos, cur.SurfaceOffset * sizeof(SurfaceInfo), copysize); datapos += copysize; } @@ -309,7 +314,8 @@ void VkRaytrace::UploadMeshes(bool dynamicOnly) } size_t copysize = Mesh->StaticMesh->Portals.Size() * sizeof(PortalInfo); - cmdbuffer->copyBuffer(transferBuffer.get(), PortalBuffer.get(), datapos, 0, copysize); + if (copysize > 0) + cmdbuffer->copyBuffer(transferBuffer.get(), PortalBuffer.get(), datapos, 0, copysize); datapos += copysize; } diff --git a/src/common/rendering/vulkan/textures/vk_texture.cpp b/src/common/rendering/vulkan/textures/vk_texture.cpp index abffeddf3..a817bb486 100644 --- a/src/common/rendering/vulkan/textures/vk_texture.cpp +++ b/src/common/rendering/vulkan/textures/vk_texture.cpp @@ -190,11 +190,11 @@ void VkTextureManager::CreateLightmap() void VkTextureManager::CreateLightmap(int newLMTextureSize, int newLMTextureCount, TArray&& newPixelData) { - if (LMTextureSize == newLMTextureSize && LMTextureCount == newLMTextureCount && newPixelData.Size() == 0) + if (LMTextureSize == newLMTextureSize && LMTextureCount == newLMTextureCount + 1 && newPixelData.Size() == 0) return; LMTextureSize = newLMTextureSize; - LMTextureCount = newLMTextureCount; + LMTextureCount = newLMTextureCount + 1; // the extra texture is for the dynamic lightmap int w = newLMTextureSize; int h = newLMTextureSize; @@ -204,7 +204,7 @@ void VkTextureManager::CreateLightmap(int newLMTextureSize, int newLMTextureCoun Lightmap.Reset(fb); Lightmap.Image = ImageBuilder() - .Size(w, h, 1, count) + .Size(w, h, 1, LMTextureCount) .Format(VK_FORMAT_R16G16B16A16_SFLOAT) .Usage(VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) .DebugName("VkRenderBuffers.Lightmap") @@ -243,7 +243,7 @@ void VkTextureManager::CreateLightmap(int newLMTextureSize, int newLMTextureCoun stagingBuffer->Unmap(); VkImageTransition() - .AddImage(&Lightmap, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, true, 0, 1, 0, count) + .AddImage(&Lightmap, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, true, 0, 1, 0, LMTextureCount) .Execute(cmdbuffer); VkBufferImageCopy region = {}; @@ -260,6 +260,6 @@ void VkTextureManager::CreateLightmap(int newLMTextureSize, int newLMTextureCoun } VkImageTransition() - .AddImage(&Lightmap, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, false, 0, 1, 0, count) + .AddImage(&Lightmap, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, false, 0, 1, 0, LMTextureCount) .Execute(cmdbuffer); } diff --git a/src/maploader/maploader.cpp b/src/maploader/maploader.cpp index d2c3d3a7f..e5cde7384 100644 --- a/src/maploader/maploader.cpp +++ b/src/maploader/maploader.cpp @@ -2994,6 +2994,35 @@ void MapLoader::InitLevelMesh(MapData* map) Level->levelMesh->PackLightmapAtlas(); } + // Allocate room for lightmap arrays on sectors, sides and their 3D floors + + unsigned int allSurfaces = 0; + + for (unsigned int i = 0; i < Level->sides.Size(); i++) + allSurfaces += 4 + Level->sides[i].sector->e->XFloor.ffloors.Size(); + + for (unsigned int i = 0; i < Level->subsectors.Size(); i++) + allSurfaces += 2 + Level->subsectors[i].sector->e->XFloor.ffloors.Size() * 2; + + Level->LMSurfaces.Resize(allSurfaces); + memset(Level->LMSurfaces.Data(), 0, sizeof(DoomLevelMeshSurface*) * allSurfaces); + + unsigned int offset = 0; + for (unsigned int i = 0; i < Level->sides.Size(); i++) + { + auto& side = Level->sides[i]; + side.lightmap = &Level->LMSurfaces[offset]; + offset += 4 + side.sector->e->XFloor.ffloors.Size(); + } + for (unsigned int i = 0; i < Level->subsectors.Size(); i++) + { + auto& subsector = Level->subsectors[i]; + unsigned int count = 1 + subsector.sector->e->XFloor.ffloors.Size(); + subsector.lightmap[0] = &Level->LMSurfaces[offset]; + subsector.lightmap[1] = &Level->LMSurfaces[offset + count]; + offset += count * 2; + } + Level->levelMesh->BindLightmapSurfacesToGeometry(*Level); } else diff --git a/src/rendering/hwrenderer/doom_levelmesh.cpp b/src/rendering/hwrenderer/doom_levelmesh.cpp index ba6dbefe1..45fad74a7 100644 --- a/src/rendering/hwrenderer/doom_levelmesh.cpp +++ b/src/rendering/hwrenderer/doom_levelmesh.cpp @@ -85,7 +85,7 @@ void PrintSurfaceInfo(const DoomLevelMeshSurface* surface) auto gameTexture = TexMan.GameByIndex(surface->texture.GetIndex()); - Printf("Surface %d (%p)\n Type: %d, TypeIndex: %d, ControlSector: %d\n", level.levelMesh->StaticMesh->GetSurfaceIndex(surface), surface, surface->Type, surface->TypeIndex, surface->ControlSector ? surface->ControlSector->Index() : -1); + Printf("Surface %d (%p)\n Type: %d, TypeIndex: %d, ControlSector: %d\n", surface->Submesh->GetSurfaceIndex(surface), surface, surface->Type, surface->TypeIndex, surface->ControlSector ? surface->ControlSector->Index() : -1); Printf(" Atlas page: %d, x:%d, y:%d\n", surface->AtlasTile.ArrayIndex, surface->AtlasTile.X, surface->AtlasTile.Y); Printf(" Pixels: %dx%d (area: %d)\n", surface->AtlasTile.Width, surface->AtlasTile.Height, surface->Area()); Printf(" Sample dimension: %d\n", surface->sampleDimension); @@ -152,7 +152,7 @@ DoomLevelMesh::DoomLevelMesh(FLevelLocals& doomMap) void DoomLevelMesh::BeginFrame(FLevelLocals& doomMap) { - static_cast(DynamicMesh.get())->UpdateDynamic(doomMap); + static_cast(DynamicMesh.get())->UpdateDynamic(doomMap, static_cast(StaticMesh.get())->LMTextureCount); } bool DoomLevelMesh::TraceSky(const FVector3& start, FVector3 direction, float dist) @@ -164,7 +164,7 @@ bool DoomLevelMesh::TraceSky(const FVector3& start, FVector3 direction, float di void DoomLevelMesh::PackLightmapAtlas() { - static_cast(StaticMesh.get())->PackLightmapAtlas(); + static_cast(StaticMesh.get())->PackLightmapAtlas(0); } void DoomLevelMesh::BindLightmapSurfacesToGeometry(FLevelLocals& doomMap) @@ -193,7 +193,13 @@ int DoomLevelMesh::AddSurfaceLights(const LevelMeshSurface* surface, LevelMeshLi } else if (doomsurf->Type == ST_MIDDLESIDE || doomsurf->Type == ST_UPPERSIDE || doomsurf->Type == ST_LOWERSIDE) { - if (!doomsurf->ControlSector) + bool isPolyLine = !!(doomsurf->Side->Flags & WALLF_POLYOBJ); + if (isPolyLine) + { + subsector_t* subsector = level.PointInRenderSubsector((doomsurf->Side->V1()->fPos() + doomsurf->Side->V2()->fPos()) * 0.5); + node = subsector->section->lighthead; + } + else if (!doomsurf->ControlSector) { node = doomsurf->Side->lighthead; } @@ -282,6 +288,50 @@ void DoomLevelSubmesh::CreateStatic(FLevelLocals& doomMap) UpdateCollision(); } +void DoomLevelSubmesh::CreateDynamic(FLevelLocals& doomMap) +{ + LightmapSampleDistance = doomMap.LightmapSampleDistance; + BuildSectorGroups(doomMap); +} + +void DoomLevelSubmesh::UpdateDynamic(FLevelLocals& doomMap, int lightmapStartIndex) +{ + Surfaces.Clear(); + MeshVertices.Clear(); + MeshVertexUVs.Clear(); + MeshElements.Clear(); + MeshSurfaceIndexes.Clear(); + LightmapUvs.Clear(); + + // Look for polyobjects + for (unsigned int i = 0; i < doomMap.lines.Size(); i++) + { + side_t* side = doomMap.lines[i].sidedef[0]; + bool isPolyLine = !!(side->Flags & WALLF_POLYOBJ); + if (isPolyLine) + { + // Make sure we have a lightmap array on the polyobj sidedef + if (!side->lightmap) + { + auto array = std::make_unique(4); + memset(array.get(), 0, sizeof(DoomLevelMeshSurface*)); + side->lightmap = array.get(); + PolyLMSurfaces.Push(std::move(array)); + } + + CreateSideSurfaces(doomMap, side); + } + } + + CreateIndexes(); + SetupLightmapUvs(doomMap); + BuildTileSurfaceLists(); + UpdateCollision(); + + PackLightmapAtlas(lightmapStartIndex); + BindLightmapSurfacesToGeometry(doomMap); +} + void DoomLevelSubmesh::CreateIndexes() { for (size_t i = 0; i < Surfaces.Size(); i++) @@ -330,34 +380,6 @@ void DoomLevelSubmesh::CreateIndexes() } } -void DoomLevelSubmesh::CreateDynamic(FLevelLocals& doomMap) -{ - LightmapSampleDistance = doomMap.LightmapSampleDistance; - BuildSectorGroups(doomMap); -} - -void DoomLevelSubmesh::UpdateDynamic(FLevelLocals& doomMap) -{ - Surfaces.Clear(); - MeshVertices.Clear(); - MeshVertexUVs.Clear(); - MeshElements.Clear(); - MeshSurfaceIndexes.Clear(); - LightmapUvs.Clear(); - - for (unsigned int i = 0; i < doomMap.lines.Size(); i++) - { - bool isPolyLine = doomMap.lines[i].sidedef[0] && (doomMap.lines[i].sidedef[0]->Flags & WALLF_POLYOBJ); - if (isPolyLine) - CreateSideSurfaces(doomMap, doomMap.lines[i].sidedef[0]); - } - - CreateIndexes(); - SetupLightmapUvs(doomMap); - BuildTileSurfaceLists(); - UpdateCollision(); -} - void DoomLevelSubmesh::BuildSectorGroups(const FLevelLocals& doomMap) { int groupIndex = 0; @@ -539,44 +561,13 @@ void DoomLevelSubmesh::BindLightmapSurfacesToGeometry(FLevelLocals& doomMap) std::swap(LightmapUvs[surface.startUvIndex + 1], LightmapUvs[surface.startUvIndex + 2]); std::swap(LightmapUvs[surface.startUvIndex + 2], LightmapUvs[surface.startUvIndex + 3]); } + + surface.TexCoords = (float*)&LightmapUvs[surface.startUvIndex]; } - // Allocate room for all surfaces - - unsigned int allSurfaces = 0; - - for (unsigned int i = 0; i < doomMap.sides.Size(); i++) - allSurfaces += 4 + doomMap.sides[i].sector->e->XFloor.ffloors.Size(); - - for (unsigned int i = 0; i < doomMap.subsectors.Size(); i++) - allSurfaces += 2 + doomMap.subsectors[i].sector->e->XFloor.ffloors.Size() * 2; - - doomMap.LMSurfaces.Resize(allSurfaces); - memset(&doomMap.LMSurfaces[0], 0, sizeof(DoomLevelMeshSurface*) * allSurfaces); - - // Link the surfaces to sectors, sides and their 3D floors - - unsigned int offset = 0; - for (unsigned int i = 0; i < doomMap.sides.Size(); i++) - { - auto& side = doomMap.sides[i]; - side.lightmap = &doomMap.LMSurfaces[offset]; - offset += 4 + side.sector->e->XFloor.ffloors.Size(); - } - for (unsigned int i = 0; i < doomMap.subsectors.Size(); i++) - { - auto& subsector = doomMap.subsectors[i]; - unsigned int count = 1 + subsector.sector->e->XFloor.ffloors.Size(); - subsector.lightmap[0] = &doomMap.LMSurfaces[offset]; - subsector.lightmap[1] = &doomMap.LMSurfaces[offset + count]; - offset += count * 2; - } - - // Copy and build properties + // Link surfaces for (auto& surface : Surfaces) { - surface.TexCoords = (float*)&LightmapUvs[surface.startUvIndex]; - if (surface.Type == ST_FLOOR || surface.Type == ST_CEILING) { surface.Subsector = &doomMap.subsectors[surface.TypeIndex]; @@ -667,6 +658,7 @@ void DoomLevelSubmesh::CreateLinePortalSurface(FLevelLocals& doomMap, side_t* si verts[3].Z = v2Top; DoomLevelMeshSurface surf; + surf.Submesh = this; surf.Type = ST_MIDDLESIDE; surf.TypeIndex = side->Index(); surf.bSky = front->GetTexture(sector_t::floor) == skyflatnum || front->GetTexture(sector_t::ceiling) == skyflatnum; @@ -751,6 +743,7 @@ void DoomLevelSubmesh::CreateLineHorizonSurface(FLevelLocals& doomMap, side_t* s float v2Bottom = (float)front->floorplane.ZatPoint(v2); DoomLevelMeshSurface surf; + surf.Submesh = this; surf.Type = ST_MIDDLESIDE; surf.TypeIndex = side->Index(); surf.bSky = front->GetTexture(sector_t::floor) == skyflatnum || front->GetTexture(sector_t::ceiling) == skyflatnum; @@ -784,7 +777,14 @@ void DoomLevelSubmesh::CreateLineHorizonSurface(FLevelLocals& doomMap, side_t* s void DoomLevelSubmesh::CreateFrontWallSurface(FLevelLocals& doomMap, side_t* side) { sector_t* front = side->sector; - +/* + bool isPolyLine = !!(side->Flags & WALLF_POLYOBJ); + if (isPolyLine) + { + subsector_t* subsector = level.PointInRenderSubsector((side->V1()->fPos() + side->V2()->fPos()) * 0.5); + front = subsector->sector; + } +*/ FVector2 v1 = ToFVector2(side->V1()->fPos()); FVector2 v2 = ToFVector2(side->V2()->fPos()); @@ -804,6 +804,7 @@ void DoomLevelSubmesh::CreateFrontWallSurface(FLevelLocals& doomMap, side_t* sid verts[3].Z = v2Top; DoomLevelMeshSurface surf; + surf.Submesh = this; surf.bSky = false; surf.startVertIndex = MeshVertices.Size(); surf.numVerts = 4; @@ -883,6 +884,7 @@ void DoomLevelSubmesh::CreateMidWallSurface(FLevelLocals& doomMap, side_t* side) // mid texture DoomLevelMeshSurface surf; + surf.Submesh = this; surf.bSky = false; surf.startVertIndex = MeshVertices.Size(); surf.numVerts = 4; @@ -946,6 +948,7 @@ void DoomLevelSubmesh::Create3DFloorWallSurfaces(FLevelLocals& doomMap, side_t* continue; DoomLevelMeshSurface surf; + surf.Submesh = this; surf.Type = ST_MIDDLESIDE; surf.TypeIndex = side->Index(); surf.ControlSector = xfloor->model; @@ -1001,8 +1004,6 @@ void DoomLevelSubmesh::CreateTopWallSurface(FLevelLocals& doomMap, side_t* side) if (!bSky && !IsTopSideVisible(side)) return; - DoomLevelMeshSurface surf; - FVector3 verts[4]; verts[0].X = verts[2].X = v1.X; verts[0].Y = verts[2].Y = v1.Y; @@ -1013,6 +1014,8 @@ void DoomLevelSubmesh::CreateTopWallSurface(FLevelLocals& doomMap, side_t* side) verts[2].Z = v1Top; verts[3].Z = v2Top; + DoomLevelMeshSurface surf; + surf.Submesh = this; surf.startVertIndex = MeshVertices.Size(); surf.numVerts = 4; MeshVertices.Push(verts[0]); @@ -1050,8 +1053,6 @@ void DoomLevelSubmesh::CreateBottomWallSurface(FLevelLocals& doomMap, side_t* si float v1BottomBack = (float)back->floorplane.ZatPoint(v1); float v2BottomBack = (float)back->floorplane.ZatPoint(v2); - DoomLevelMeshSurface surf; - FVector3 verts[4]; verts[0].X = verts[2].X = v1.X; verts[0].Y = verts[2].Y = v1.Y; @@ -1062,6 +1063,8 @@ void DoomLevelSubmesh::CreateBottomWallSurface(FLevelLocals& doomMap, side_t* si verts[2].Z = v1BottomBack; verts[3].Z = v2BottomBack; + DoomLevelMeshSurface surf; + surf.Submesh = this; surf.startVertIndex = MeshVertices.Size(); surf.numVerts = 4; MeshVertices.Push(verts[0]); @@ -1124,6 +1127,7 @@ void DoomLevelSubmesh::SetSideTextureUVs(DoomLevelMeshSurface& surface, side_t* void DoomLevelSubmesh::CreateFloorSurface(FLevelLocals &doomMap, subsector_t *sub, sector_t *sector, sector_t *controlSector, int typeIndex) { DoomLevelMeshSurface surf; + surf.Submesh = this; secplane_t plane; if (!controlSector) @@ -1178,6 +1182,7 @@ void DoomLevelSubmesh::CreateFloorSurface(FLevelLocals &doomMap, subsector_t *su void DoomLevelSubmesh::CreateCeilingSurface(FLevelLocals& doomMap, subsector_t* sub, sector_t* sector, sector_t* controlSector, int typeIndex) { DoomLevelMeshSurface surf; + surf.Submesh = this; secplane_t plane; if (!controlSector) @@ -1415,7 +1420,7 @@ void DoomLevelSubmesh::SetupLightmapUvs(FLevelLocals& doomMap) } } -void DoomLevelSubmesh::PackLightmapAtlas() +void DoomLevelSubmesh::PackLightmapAtlas(int lightmapStartIndex) { std::vector sortedSurfaces; sortedSurfaces.reserve(Surfaces.Size()); @@ -1439,7 +1444,7 @@ void DoomLevelSubmesh::PackLightmapAtlas() surf->AtlasTile.X = x; surf->AtlasTile.Y = y; - surf->AtlasTile.ArrayIndex = (int)result.pageIndex; + surf->AtlasTile.ArrayIndex = lightmapStartIndex + (int)result.pageIndex; // calculate final texture coordinates for (int i = 0; i < (int)surf->numVerts; i++) diff --git a/src/rendering/hwrenderer/doom_levelmesh.h b/src/rendering/hwrenderer/doom_levelmesh.h index 23d0976bd..6e70e1eaa 100644 --- a/src/rendering/hwrenderer/doom_levelmesh.h +++ b/src/rendering/hwrenderer/doom_levelmesh.h @@ -12,6 +12,7 @@ typedef dp::rect_pack::RectPacker RectPacker; struct FLevelLocals; +struct FPolyObj; enum DoomLevelMeshSurfaceType { @@ -31,6 +32,7 @@ struct DoomLevelMeshSurface : public LevelMeshSurface subsector_t* Subsector = nullptr; side_t* Side = nullptr; sector_t* ControlSector = nullptr; + float* TexCoords = nullptr; }; @@ -39,7 +41,7 @@ class DoomLevelSubmesh : public LevelSubmesh public: void CreateStatic(FLevelLocals& doomMap); void CreateDynamic(FLevelLocals& doomMap); - void UpdateDynamic(FLevelLocals& doomMap); + void UpdateDynamic(FLevelLocals& doomMap, int lightmapStartIndex); LevelMeshSurface* GetSurface(int index) override { return &Surfaces[index]; } unsigned int GetSurfaceIndex(const LevelMeshSurface* surface) const override { return (unsigned int)(ptrdiff_t)(static_cast(surface) - Surfaces.Data()); } @@ -49,7 +51,7 @@ public: // Used by Maploader void BindLightmapSurfacesToGeometry(FLevelLocals& doomMap); - void PackLightmapAtlas(); + void PackLightmapAtlas(int lightmapStartIndex); void CreatePortals(); void DisableLightmaps() { Surfaces.Clear(); } // Temp hack that disables lightmapping @@ -57,6 +59,8 @@ public: TArray LightmapUvs; TArray sectorGroup; // index is sector, value is sectorGroup + TArray> PolyLMSurfaces; + private: void BuildSectorGroups(const FLevelLocals& doomMap);