Create VBO vertex data before the level mesh since the mesh uses it to build geometry.

Draw all sectors as subsectors if lightmaps are enabled (even if a sector doesn't have a tile initially it could gain one)
This commit is contained in:
Magnus Norddahl 2025-05-15 23:53:34 +02:00
commit 51c6e8add6
6 changed files with 25 additions and 31 deletions

View file

@ -729,7 +729,6 @@ struct sector_t
int vbocount[2]; // Total count of vertices belonging to this sector's planes. This is used when a sector height changes and also contains all attached planes.
int ibocount; // number of indices per plane (identical for all planes.) If this is -1 the index buffer is not in use.
bool HasLightmaps = false; // Sector has lightmaps, each subsector vertex needs its own unique lightmap UV data
bool Sec3dControlUseMidTex = false;
// Below are all properties which are not used by the renderer.

View file

@ -2942,7 +2942,7 @@ void MapLoader::CalcIndices()
//
//==========================================================================
void MapLoader::InitLevelMesh(MapData* map)
void MapLoader::InitLightmapTiles(MapData* map)
{
// Propagate sample distance where it isn't yet set
for (auto& line : Level->lines)
@ -3017,7 +3017,10 @@ void MapLoader::InitLevelMesh(MapData* map)
subsector.LightmapTiles[1] = TArrayView<int>(&Level->LightmapTiles[offset + count], count);
offset += count * 2;
}
}
void MapLoader::InitLevelMesh(MapData* map)
{
// Create the levelmesh
Level->levelMesh = new DoomLevelMesh(*Level);
@ -3553,7 +3556,7 @@ void MapLoader::LoadLevel(MapData *map, const char *lumpname, int position)
if (!Level->IsReentering())
Level->FinalizePortals(); // finalize line portals after polyobjects have been initialized. This info is needed for properly flagging them.
InitLevelMesh(map);
InitLightmapTiles(map);
Level->ClearDynamic3DFloorData(); // CreateVBO must be run on the plain 3D floor data.
CreateVBO(*screen->RenderState(), Level->sectors);
@ -3562,6 +3565,10 @@ void MapLoader::LoadLevel(MapData *map, const char *lumpname, int position)
P_Recalculate3DFloors(&sec);
}
InitLevelMesh(map);
UpdateVBOLightmap(*screen->RenderState(), Level->sectors);
Level->aabbTree = new DoomLevelAABBTree(Level);
// [DVR] Populate subsector->bbox for alternative space culling in orthographic projection with no fog of war

View file

@ -308,6 +308,7 @@ public:
void SetSlopes();
void CopySlopes();
void InitLightmapTiles(MapData* map);
void InitLevelMesh(MapData* map);
bool LoadLightmap(MapData* map);

View file

@ -1716,9 +1716,6 @@ void DoomLevelMesh::SetSubsectorLightmap(int surfaceIndex)
int lightmapTileIndex = Mesh.Surfaces[surfaceIndex].LightmapTileIndex;
auto surface = &DoomSurfaceInfos[surfaceIndex];
if (surface->Subsector->firstline && surface->Subsector->firstline->sidedef)
surface->Subsector->firstline->sidedef->sector->HasLightmaps = true;
if (!surface->ControlSector)
{
int index = surface->Type == ST_CEILING ? 1 : 0;

View file

@ -255,31 +255,12 @@ static int CreateIndexedSectorVerticesLM(sector_t* sec, const secplane_t& plane,
for(auto& sub : section.subsectors)
{
// vertices
int lightmap = sub->LightmapTiles[h].Size() > lightmapIndex ? sub->LightmapTiles[h][lightmapIndex] : -1;
if (lightmap >= 0) // tile may be missing if the subsector is degenerate triangle
for (unsigned int j = 0; j < sub->numlines; j++)
{
const auto& tile = level.levelMesh->Lightmap.Tiles[lightmap];
float textureSize = (float)level.levelMesh->Lightmap.TextureSize;
float lindex = (float)tile.AtlasLocation.ArrayIndex;
for (unsigned int j = 0, end = sub->numlines; j < end; j++)
{
vertex_t* vt = sub->firstline[j].v1;
FVector2 luv = tile.ToUV(FVector3((float)vt->fX(), (float)vt->fY(), (float)plane.ZatPoint(vt)), textureSize);
SetFlatVertex(vbo_shadowdata[vi + pos], vt, plane, luv.X, luv.Y, lindex);
vbo_shadowdata[vi + pos].z += diff;
vbo_origins[vi + pos] = SectorVertexOrigin(sub, h, lightmapIndex);
pos++;
}
}
else
{
for (unsigned int j = 0; j < sub->numlines; j++)
{
SetFlatVertex(vbo_shadowdata[vi + pos], sub->firstline[j].v1, plane);
vbo_shadowdata[vi + pos].z += diff;
vbo_origins[vi + pos] = SectorVertexOrigin(sub, h, lightmapIndex);
pos++;
}
SetFlatVertex(vbo_shadowdata[vi + pos], sub->firstline[j].v1, plane);
vbo_shadowdata[vi + pos].z += diff;
vbo_origins[vi + pos] = SectorVertexOrigin(sub, h, lightmapIndex);
pos++;
}
}
}
@ -307,7 +288,7 @@ static int CreateIndexedSectorVerticesLM(sector_t* sec, const secplane_t& plane,
static int CreateIndexedSectorVertices(sector_t* sec, const secplane_t& plane, int floor, VertexContainer& verts, int h, int lightmapIndex)
{
if (sec->HasLightmaps && lightmapIndex != -1)
if (level.lightmaps && lightmapIndex != -1)
return CreateIndexedSectorVerticesLM(sec, plane, floor, h, lightmapIndex);
auto& vbo_shadowdata = sector_vertices;
@ -568,6 +549,14 @@ void UpdateVBOLightmap(FRenderState& renderstate, sector_t* sector)
}
}
void UpdateVBOLightmap(FRenderState& renderstate, TArray<sector_t>& sectors)
{
for (sector_t& sector : sectors)
{
UpdateVBOLightmap(renderstate, &sector);
}
}
//==========================================================================
//
//

View file

@ -72,6 +72,7 @@ VertexContainers BuildVertices(TArray<sector_t> &sectors);
class FRenderState;
void CheckUpdate(FRenderState& renderstate, sector_t* sector);
void UpdateVBOLightmap(FRenderState& renderstate, sector_t* sector);
void UpdateVBOLightmap(FRenderState& renderstate, TArray<sector_t>& sectors);
void CreateVBO(FRenderState& renderstate, TArray<sector_t>& sectors);
extern TArray<FFlatVertex> sector_vertices;