Add more dynamic update code to level mesh

This commit is contained in:
Magnus Norddahl 2024-08-11 01:15:44 +02:00
commit f1b9e68305
15 changed files with 147 additions and 101 deletions

View file

@ -77,6 +77,7 @@ public:
info.Vertices = &Mesh.Vertices[info.VertexStart];
info.UniformIndexes = &Mesh.UniformIndexes[info.VertexStart];
info.Indexes = &Mesh.Indexes[info.IndexStart];
// To do: mark range as dirty
return info;
}
@ -89,6 +90,7 @@ public:
Mesh.Materials.Resize(info.Start + count);
info.Uniforms = &Mesh.Uniforms[info.Start];
info.Materials = &Mesh.Materials[info.Start];
// To do: mark range as dirty
return info;
}
@ -96,10 +98,19 @@ public:
{
for (int i = 0; i < indexCount; i++)
Mesh.Indexes[indexStart + i] = 0;
// To do: add to a free list
// To do: mark range as dirty
}
void FreeUniforms(int start, int count)
{
// To do: add to a free list
}
void FreeSurface(unsigned int surfaceIndex)
{
// To do: remove the surface from the surface tile, if attached
// To do: add to a free list
}
struct
@ -121,7 +132,7 @@ public:
TArray<int> SurfaceIndexes;
int DynamicIndexStart = 0;
// Above data must not be resized beyond these limits as that's the size of the GPU buffers)
// Above data must not be resized beyond these limits as that's the size of the GPU buffers
int MaxVertices = 0;
int MaxIndexes = 0;
int MaxSurfaces = 0;

View file

@ -24,8 +24,6 @@ struct LevelMeshSurface
FVector4 Plane = FVector4(0.0f, 0.0f, 1.0f, 0.0f);
int LightmapTileIndex = -1;
bool AlwaysUpdate = false;
FGameTexture* Texture = nullptr;
float Alpha = 1.0;

View file

@ -54,6 +54,8 @@ struct LightmapTile
// True if the tile needs to be rendered into the lightmap texture before it can be used
bool NeedsUpdate = true;
bool AlwaysUpdate = false;
FVector2 ToUV(const FVector3& vert) const
{
FVector3 localPos = vert - Transform.TranslateWorldToLocal;

View file

@ -467,7 +467,7 @@ public:
// Lightmaps
bool lightmaps = false;
TArray<DoomLevelMeshSurface*> Surfaces;
TArray<int> LightmapTiles;
FVector3 SunDirection;
FVector3 SunColor;
uint16_t LightmapSampleDistance;

View file

@ -1257,7 +1257,7 @@ struct side_t
uint16_t Flags;
int UDMFIndex; // needed to access custom UDMF fields which are stored in loading order.
FLightNode * lighthead; // all dynamic lights that may affect this wall
TArrayView<DoomLevelMeshSurface*> surface; // all mesh surfaces belonging to this sidedef
TArrayView<int> LightmapTiles; // all lightmap tiles belonging to this sidedef
seg_t **segs; // all segs belonging to this sidedef in ascending order. Used for precise rendering
int numsegs;
int sidenum;
@ -1674,7 +1674,7 @@ struct subsector_t
// 2: has one-sided walls
FPortalCoverage portalcoverage[2];
TArray<DVisualThinker *> sprites;
TArrayView<DoomLevelMeshSurface*> surface[2]; // all mesh surfaces belonging to this subsector
TArrayView<int> LightmapTiles[2]; // all lightmap tiles belonging to this subsector
};

View file

@ -2989,23 +2989,24 @@ void MapLoader::InitLevelMesh(MapData* map)
for (unsigned int i = 0; i < Level->subsectors.Size(); i++)
allSurfaces += 2 + Level->subsectors[i].sector->e->XFloor.ffloors.Size() * 2;
Level->Surfaces.Resize(allSurfaces);
memset(Level->Surfaces.Data(), 0, sizeof(DoomLevelMeshSurface*) * allSurfaces);
Level->LightmapTiles.Resize(allSurfaces);
for (int& value : Level->LightmapTiles)
value = -1;
unsigned int offset = 0;
for (unsigned int i = 0; i < Level->sides.Size(); i++)
{
auto& side = Level->sides[i];
int count = 4 + side.sector->e->XFloor.ffloors.Size();
side.surface = TArrayView<DoomLevelMeshSurface*>(&Level->Surfaces[offset], count);
side.LightmapTiles = TArrayView<int>(&Level->LightmapTiles[offset], count);
offset += count;
}
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.surface[0] = TArrayView<DoomLevelMeshSurface*>(&Level->Surfaces[offset], count);
subsector.surface[1] = TArrayView<DoomLevelMeshSurface*>(&Level->Surfaces[offset + count], count);
subsector.LightmapTiles[0] = TArrayView<int>(&Level->LightmapTiles[offset], count);
subsector.LightmapTiles[1] = TArrayView<int>(&Level->LightmapTiles[offset + count], count);
offset += count * 2;
}

View file

@ -95,8 +95,8 @@ void PrintSurfaceInfo(const DoomLevelMeshSurface* surface)
Printf(" Pixels: %dx%d (area: %d)\n", tile->AtlasLocation.Width, tile->AtlasLocation.Height, tile->AtlasLocation.Area());
Printf(" Sample dimension: %d\n", tile->SampleDimension);
Printf(" Needs update?: %d\n", tile->NeedsUpdate);
Printf(" Always update?: %d\n", tile->AlwaysUpdate);
}
Printf(" Always update?: %d\n", surface->AlwaysUpdate);
Printf(" Sector group: %d\n", surface->SectorGroup);
Printf(" Texture: '%s'\n", gameTexture ? gameTexture->GetName().GetChars() : "<nullptr>");
Printf(" Alpha: %f\n", surface->Alpha);
@ -345,8 +345,44 @@ void DoomLevelMesh::CreateSurfaces(FLevelLocals& doomMap)
}
}
void DoomLevelMesh::FreeSide(FLevelLocals& doomMap, unsigned int sideIndex)
{
if (sideIndex < 0 || sideIndex >= Sides.Size())
return;
int surf = Sides[sideIndex].FirstSurface;
while (surf != -1)
{
unsigned int next = Surfaces[surf].NextSurface;
FreeSurface(surf);
surf = next;
}
Sides[sideIndex].FirstSurface = -1;
// To do: call FreeGeometry and FreeUniforms
}
void DoomLevelMesh::FreeFlat(FLevelLocals& doomMap, unsigned int sectorIndex)
{
if (sectorIndex < 0 || sectorIndex >= Flats.Size())
return;
int surf = Flats[sectorIndex].FirstSurface;
while (surf != -1)
{
unsigned int next = Surfaces[surf].NextSurface;
FreeSurface(surf - 1);
surf = next;
}
Flats[sectorIndex].FirstSurface = -1;
// To do: call FreeGeometry and FreeUniforms
}
void DoomLevelMesh::UpdateSide(FLevelLocals& doomMap, unsigned int sideIndex)
{
FreeSide(doomMap, sideIndex);
side_t* side = &doomMap.sides[sideIndex];
seg_t* seg = side->segs[0];
if (!seg)
@ -369,20 +405,20 @@ void DoomLevelMesh::UpdateSide(FLevelLocals& doomMap, unsigned int sideIndex)
state.EnableTexture(true);
state.EnableBrightmap(true);
state.AlphaFunc(Alpha_GEqual, 0.f);
CreateWallSurface(side, disp, state, result.list, false, true);
CreateWallSurface(side, disp, state, result.list, false, true, sideIndex);
for (HWWall& portal : result.portals)
{
WallPortals.Push(portal);
}
CreateWallSurface(side, disp, state, result.portals, true, false);
CreateWallSurface(side, disp, state, result.portals, true, false, sideIndex);
/*
// final pass: translucent stuff
state.AlphaFunc(Alpha_GEqual, gl_mask_sprite_threshold);
state.SetRenderStyle(STYLE_Translucent);
CreateWallSurface(side, disp, state, result.translucent, false, true);
CreateWallSurface(side, disp, state, result.translucent, false, true, sideIndex);
state.AlphaFunc(Alpha_GEqual, 0.f);
state.SetRenderStyle(STYLE_Normal);
*/
@ -390,6 +426,8 @@ void DoomLevelMesh::UpdateSide(FLevelLocals& doomMap, unsigned int sideIndex)
void DoomLevelMesh::UpdateFlat(FLevelLocals& doomMap, unsigned int sectorIndex)
{
FreeSide(doomMap, sectorIndex);
sector_t* sector = &doomMap.sectors[sectorIndex];
for (FSection& section : doomMap.sections.SectionsForSector(sectorIndex))
{
@ -405,23 +443,23 @@ void DoomLevelMesh::UpdateFlat(FLevelLocals& doomMap, unsigned int sectorIndex)
state.ClearDepthBias();
state.EnableTexture(true);
state.EnableBrightmap(true);
CreateFlatSurface(disp, state, result.list, false, false);
CreateFlatSurface(disp, state, result.list, false, false, sectorIndex);
CreateFlatSurface(disp, state, result.portals, true, false);
CreateFlatSurface(disp, state, result.portals, true, false, sectorIndex);
// final pass: translucent stuff
state.AlphaFunc(Alpha_GEqual, gl_mask_sprite_threshold);
state.SetRenderStyle(STYLE_Translucent);
CreateFlatSurface(disp, state, result.translucentborder, false, true);
CreateFlatSurface(disp, state, result.translucentborder, false, true, sectorIndex);
state.SetDepthMask(false);
CreateFlatSurface(disp, state, result.translucent, false, true);
CreateFlatSurface(disp, state, result.translucent, false, true, sectorIndex);
state.AlphaFunc(Alpha_GEqual, 0.f);
state.SetDepthMask(true);
state.SetRenderStyle(STYLE_Normal);
}
}
void DoomLevelMesh::CreateWallSurface(side_t* side, HWWallDispatcher& disp, MeshBuilder& state, TArray<HWWall>& list, bool isPortal, bool translucent)
void DoomLevelMesh::CreateWallSurface(side_t* side, HWWallDispatcher& disp, MeshBuilder& state, TArray<HWWall>& list, bool isPortal, bool translucent, unsigned int sideIndex)
{
for (HWWall& wallpart : list)
{
@ -534,7 +572,6 @@ void DoomLevelMesh::CreateWallSurface(side_t* side, HWWallDispatcher& disp, Mesh
surf.ControlSector = wallpart.LevelMeshInfo.ControlSector;
surf.TypeIndex = side->Index();
surf.Side = side;
surf.AlwaysUpdate = !!(side->sector->Flags & SECF_LM_DYNAMIC);
surf.SectorGroup = sectorGroup[side->sector->Index()];
surf.Alpha = float(side->linedef->alpha);
surf.MeshLocation.StartVertIndex = ginfo.VertexStart;
@ -547,12 +584,19 @@ void DoomLevelMesh::CreateWallSurface(side_t* side, HWWallDispatcher& disp, Mesh
surf.PortalIndex = isPortal ? linePortals[side->linedef->Index()] : 0;
surf.IsSky = isPortal ? (wallpart.portaltype == PORTALTYPE_SKY || wallpart.portaltype == PORTALTYPE_SKYBOX || wallpart.portaltype == PORTALTYPE_HORIZON) : false;
surf.Bounds = GetBoundsFromSurface(surf);
surf.LightmapTileIndex = disp.Level->lightmaps ? AddSurfaceToTile(surf, sampleDimension) : -1;
surf.LightmapTileIndex = disp.Level->lightmaps ? AddSurfaceToTile(surf, sampleDimension, !!(side->sector->Flags & SECF_LM_DYNAMIC)) : -1;
if (sideIndex < Sides.Size())
{
surf.NextSurface = Sides[sideIndex].FirstSurface;
Sides[sideIndex].FirstSurface = Surfaces.Size();
}
Surfaces.Push(surf);
}
}
int DoomLevelMesh::AddSurfaceToTile(const DoomLevelMeshSurface& surf, uint16_t sampleDimension)
int DoomLevelMesh::AddSurfaceToTile(const DoomLevelMeshSurface& surf, uint16_t sampleDimension, bool alwaysUpdate)
{
if (surf.IsSky)
return -1;
@ -574,6 +618,7 @@ int DoomLevelMesh::AddSurfaceToTile(const DoomLevelMeshSurface& surf, uint16_t s
tile.Bounds.max.X = std::max(tile.Bounds.max.X, surf.Bounds.max.X);
tile.Bounds.max.Y = std::max(tile.Bounds.max.Y, surf.Bounds.max.Y);
tile.Bounds.max.Z = std::max(tile.Bounds.max.Z, surf.Bounds.max.Z);
tile.AlwaysUpdate = tile.AlwaysUpdate || alwaysUpdate;
return index;
}
@ -586,6 +631,7 @@ int DoomLevelMesh::AddSurfaceToTile(const DoomLevelMeshSurface& surf, uint16_t s
tile.Bounds = surf.Bounds;
tile.Plane = surf.Plane;
tile.SampleDimension = GetSampleDimension(surf, sampleDimension);
tile.AlwaysUpdate = alwaysUpdate;
LightmapTiles.Push(tile);
bindings[binding] = index;
@ -614,7 +660,7 @@ int DoomLevelMesh::GetSampleDimension(const DoomLevelMeshSurface& surf, uint16_t
return sampleDimension;
}
void DoomLevelMesh::CreateFlatSurface(HWFlatDispatcher& disp, MeshBuilder& state, TArray<HWFlat>& list, bool isSky, bool translucent)
void DoomLevelMesh::CreateFlatSurface(HWFlatDispatcher& disp, MeshBuilder& state, TArray<HWFlat>& list, bool isSky, bool translucent, unsigned int sectorIndex)
{
for (HWFlat& flatpart : list)
{
@ -702,7 +748,6 @@ void DoomLevelMesh::CreateFlatSurface(HWFlatDispatcher& disp, MeshBuilder& state
DoomLevelMeshSurface surf;
surf.Type = flatpart.ceiling ? ST_CEILING : ST_FLOOR;
surf.ControlSector = flatpart.controlsector ? flatpart.controlsector->model : nullptr;
surf.AlwaysUpdate = !!(flatpart.sector->Flags & SECF_LM_DYNAMIC);
surf.SectorGroup = sectorGroup[flatpart.sector->Index()];
surf.Alpha = flatpart.alpha;
surf.Texture = flatpart.texture;
@ -775,37 +820,19 @@ void DoomLevelMesh::CreateFlatSurface(HWFlatDispatcher& disp, MeshBuilder& state
surf.MeshLocation.NumVerts = sub->numlines;
surf.MeshLocation.NumElements = (sub->numlines - 2) * 3;
surf.Bounds = GetBoundsFromSurface(surf);
surf.LightmapTileIndex = disp.Level->lightmaps ? AddSurfaceToTile(surf, sampleDimension) : -1;
surf.LightmapTileIndex = disp.Level->lightmaps ? AddSurfaceToTile(surf, sampleDimension, !!(flatpart.sector->Flags & SECF_LM_DYNAMIC)) : -1;
if (sectorIndex < Flats.Size())
{
surf.NextSurface = Flats[sectorIndex].FirstSurface;
Flats[sectorIndex].FirstSurface = Surfaces.Size();
}
Surfaces.Push(surf);
}
}
}
#if 0
void DoomLevelMesh::CreateDynamicSurfaces(FLevelLocals& doomMap)
{
// 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)
continue;
// Make sure we have a surface array on the polyobj sidedef
if (!side->surface)
{
auto array = std::make_unique<DoomLevelMeshSurface * []>(4);
memset(array.get(), 0, sizeof(DoomLevelMeshSurface*));
side->surface = array.get();
PolyLMSurfaces.Push(std::move(array));
}
CreateSideSurfaces(doomMap, side);
}
}
#endif
void DoomLevelMesh::SortIndexes()
{
// Order surfaces by pipeline
@ -879,7 +906,7 @@ void DoomLevelMesh::SetSubsectorLightmap(DoomLevelMeshSurface* surface)
if (!surface->ControlSector)
{
int index = surface->Type == ST_CEILING ? 1 : 0;
surface->Subsector->surface[index][0] = surface;
surface->Subsector->LightmapTiles[index][0] = surface->LightmapTileIndex;
}
else
{
@ -889,7 +916,7 @@ void DoomLevelMesh::SetSubsectorLightmap(DoomLevelMeshSurface* surface)
{
if (ffloors[i]->model == surface->ControlSector)
{
surface->Subsector->surface[index][i + 1] = surface;
surface->Subsector->LightmapTiles[index][i + 1] = surface->LightmapTileIndex;
}
}
}
@ -901,16 +928,16 @@ void DoomLevelMesh::SetSideLightmap(DoomLevelMeshSurface* surface)
{
if (surface->Type == ST_UPPERSIDE)
{
surface->Side->surface[0] = surface;
surface->Side->LightmapTiles[0] = surface->LightmapTileIndex;
}
else if (surface->Type == ST_MIDDLESIDE)
{
surface->Side->surface[1] = surface;
surface->Side->surface[2] = surface;
surface->Side->LightmapTiles[1] = surface->LightmapTileIndex;
surface->Side->LightmapTiles[2] = surface->LightmapTileIndex;
}
else if (surface->Type == ST_LOWERSIDE)
{
surface->Side->surface[3] = surface;
surface->Side->LightmapTiles[3] = surface->LightmapTileIndex;
}
}
else
@ -921,7 +948,7 @@ void DoomLevelMesh::SetSideLightmap(DoomLevelMeshSurface* surface)
{
if (ffloors[i]->model == surface->ControlSector)
{
backside->surface[4 + i] = surface;
backside->LightmapTiles[4 + i] = surface->LightmapTileIndex;
}
}
}

View file

@ -27,18 +27,18 @@ struct DoomLevelMeshSurface : public LevelMeshSurface
sector_t* ControlSector = nullptr;
int PipelineID = 0;
int NextSurface = -1;
};
struct SideSurfaceRange
struct SideSurfaceBlock
{
int StartSurface = 0;
int SurfaceCount = 0;
int FirstSurface = -1;
};
struct FlatSurfaceRange
struct FlatSurfaceBlock
{
int StartSurface = 0;
int SurfaceCount = 0;
int FirstSurface = -1;
};
class DoomLevelMesh : public LevelMesh
@ -72,19 +72,22 @@ private:
void UpdateSide(FLevelLocals& doomMap, unsigned int sideIndex);
void UpdateFlat(FLevelLocals& doomMap, unsigned int sectorIndex);
void FreeSide(FLevelLocals& doomMap, unsigned int sideIndex);
void FreeFlat(FLevelLocals& doomMap, unsigned int sectorIndex);
void SetSubsectorLightmap(DoomLevelMeshSurface* surface);
void SetSideLightmap(DoomLevelMeshSurface* surface);
void SortIndexes();
void CreateWallSurface(side_t* side, HWWallDispatcher& disp, MeshBuilder& state, TArray<HWWall>& list, bool isPortal, bool translucent);
void CreateFlatSurface(HWFlatDispatcher& disp, MeshBuilder& state, TArray<HWFlat>& list, bool isSky, bool translucent);
void CreateWallSurface(side_t* side, HWWallDispatcher& disp, MeshBuilder& state, TArray<HWWall>& list, bool isPortal, bool translucent, unsigned int sectorIndex);
void CreateFlatSurface(HWFlatDispatcher& disp, MeshBuilder& state, TArray<HWFlat>& list, bool isSky, bool translucent, unsigned int sectorIndex);
void LinkSurfaces(FLevelLocals& doomMap);
BBox GetBoundsFromSurface(const LevelMeshSurface& surface) const;
int AddSurfaceToTile(const DoomLevelMeshSurface& surf, uint16_t sampleDimension);
int AddSurfaceToTile(const DoomLevelMeshSurface& surf, uint16_t sampleDimension, bool alwaysUpdate);
int GetSampleDimension(const DoomLevelMeshSurface& surf, uint16_t sampleDimension);
void CreatePortals(FLevelLocals& doomMap);
@ -92,8 +95,8 @@ private:
int GetLightIndex(FDynamicLight* light, int portalgroup);
TArray<SideSurfaceRange> Sides;
TArray<FlatSurfaceRange> Flats;
TArray<SideSurfaceBlock> Sides;
TArray<FlatSurfaceBlock> Flats;
std::map<LightmapTileBinding, int> bindings;
MeshBuilder state;
};

View file

@ -243,13 +243,17 @@ static int CreateIndexedSectorVerticesLM(sector_t* sec, const secplane_t& plane,
for(auto& sub : section.subsectors)
{
// vertices
DoomLevelMeshSurface* lightmap = sub->surface[h].Size() > lightmapIndex ? sub->surface[h][lightmapIndex] : nullptr;
if (lightmap && lightmap->Type != ST_NONE) // surface may be missing if the subsector is degenerate triangle
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
{
FFlatVertex* luvs = &level.levelMesh->Mesh.Vertices[lightmap->MeshLocation.StartVertIndex];
const auto& tile = level.levelMesh->LightmapTiles[lightmap];
float textureSize = (float)level.levelMesh->LMTextureSize;
float lindex = (float)tile.AtlasLocation.ArrayIndex;
for (unsigned int j = 0, end = sub->numlines; j < end; j++)
{
SetFlatVertex(vbo_shadowdata[vi + pos], sub->firstline[j].v1, plane, luvs[end - 1 - j].lu, luvs[end - 1 - j].lv, luvs[end - 1 - j].lindex);
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;
pos++;
}

View file

@ -422,9 +422,9 @@ void HWWall::ProcessDecal(HWDrawInfo *di, FRenderState& state, DBaseDecal *decal
auto verts = state.AllocVertices(4);
gldecal->vertindex = verts.second;
if (surface && surface->LightmapTileIndex >= 0)
if (lightmaptile >= 0)
{
LightmapTile* tile = &di->Level->levelMesh->LightmapTiles[surface->LightmapTileIndex];
LightmapTile* tile = &di->Level->levelMesh->LightmapTiles[lightmaptile];
float lightmapindex = (float)tile->AtlasLocation.ArrayIndex;
for (i = 0; i < 4; i++)

View file

@ -225,19 +225,19 @@ public:
VPUniforms.mClipHeight = 0;
}
void PushVisibleSurface(LevelMeshSurface* surface)
void PushVisibleTile(int tileIndex)
{
if (outer)
{
outer->PushVisibleSurface(surface);
outer->PushVisibleTile(tileIndex);
return;
}
if (surface->LightmapTileIndex < 0)
if (tileIndex < 0)
return;
LightmapTile* tile = &Level->levelMesh->LightmapTiles[surface->LightmapTileIndex];
if (lm_always_update || surface->AlwaysUpdate)
LightmapTile* tile = &Level->levelMesh->LightmapTiles[tileIndex];
if (lm_always_update || tile->AlwaysUpdate)
{
tile->NeedsUpdate = true;
}

View file

@ -174,7 +174,7 @@ public:
vertex_t* vertexes[2]; // required for polygon splitting
FGameTexture* texture;
TArray<lightlist_t>* lightlist;
DoomLevelMeshSurface* surface;
int lightmaptile;
HWSeg glseg;
float ztop[2], zbottom[2];

View file

@ -535,9 +535,9 @@ void HWFlat::ProcessSector(HWFlatDispatcher *di, FRenderState& state, sector_t *
unsigned int count = sector->e->XFloor.ffloors.Size() + 1;
for (unsigned int j = 0; j < count; j++)
{
if (auto surface = sector->subsectors[i]->surface[plane].Size() > j ? sector->subsectors[i]->surface[plane][j] : nullptr)
if (int tile = sector->subsectors[i]->LightmapTiles[plane].Size() > j ? sector->subsectors[i]->LightmapTiles[plane][j] : -1)
{
di->di->PushVisibleSurface(surface);
di->di->PushVisibleTile(tile);
}
}
}

View file

@ -1125,17 +1125,17 @@ void HWWall::DoTexture(HWWallDispatcher *di, FRenderState& state, int _type,seg_
if (di->di)
{
if (seg->sidedef->surface.Size() >= 4 && type >= RENDERWALL_TOP && type <= RENDERWALL_BOTTOM)
if (seg->sidedef->LightmapTiles.Size() >= 4 && type >= RENDERWALL_TOP && type <= RENDERWALL_BOTTOM)
{
surface = seg->sidedef->surface[type - RENDERWALL_TOP];
if (surface && di->di)
lightmaptile = seg->sidedef->LightmapTiles[type - RENDERWALL_TOP];
if (lightmaptile && di->di)
{
di->di->PushVisibleSurface(surface);
di->di->PushVisibleTile(lightmaptile);
}
}
else
{
surface = nullptr;
lightmaptile = -1;
}
}
else
@ -1150,7 +1150,7 @@ void HWWall::DoTexture(HWWallDispatcher *di, FRenderState& state, int _type,seg_
LevelMeshInfo.Type = ST_NONE;
}
LevelMeshInfo.ControlSector = nullptr;
surface = nullptr;
lightmaptile = -1;
}
float floatceilingref = ceilingrefheight + tci.RowOffset(seg->sidedef->GetTextureYOffset(texpos));
@ -1209,12 +1209,12 @@ void HWWall::DoMidTexture(HWWallDispatcher *di, FRenderState& state, seg_t * seg
{
if (di->di)
{
if (seg->sidedef->surface.Size() >= 4)
if (seg->sidedef->LightmapTiles.Size() >= 4)
{
surface = seg->sidedef->surface[side_t::mid];
if (surface && di->di)
lightmaptile = seg->sidedef->LightmapTiles[side_t::mid];
if (lightmaptile >= 0 && di->di)
{
di->di->PushVisibleSurface(surface);
di->di->PushVisibleTile(lightmaptile);
}
}
}
@ -1222,7 +1222,7 @@ void HWWall::DoMidTexture(HWWallDispatcher *di, FRenderState& state, seg_t * seg
{
LevelMeshInfo.Type = ST_MIDDLESIDE;
LevelMeshInfo.ControlSector = nullptr;
surface = nullptr;
lightmaptile = -1;
}
// Align the texture to the ORIGINAL sector's height!!
@ -1557,20 +1557,20 @@ void HWWall::BuildFFBlock(HWWallDispatcher *di, FRenderState& state, seg_t * seg
if (di->di)
{
if (seg->sidedef == seg->linedef->sidedef[0])
surface = seg->linedef->sidedef[1]->surface.Size() > 4 + roverIndex ? seg->linedef->sidedef[1]->surface[4 + roverIndex] : nullptr;
lightmaptile = seg->linedef->sidedef[1]->LightmapTiles.Size() > 4 + roverIndex ? seg->linedef->sidedef[1]->LightmapTiles[4 + roverIndex] : -1;
else
surface = seg->linedef->sidedef[0]->surface.Size() > 4 + roverIndex ? seg->linedef->sidedef[0]->surface[4 + roverIndex] : nullptr;
lightmaptile = seg->linedef->sidedef[0]->LightmapTiles.Size() > 4 + roverIndex ? seg->linedef->sidedef[0]->LightmapTiles[4 + roverIndex] : -1;
if (surface)
if (lightmaptile > 0)
{
di->di->PushVisibleSurface(surface);
di->di->PushVisibleTile(lightmaptile);
}
}
else
{
LevelMeshInfo.Type = ST_MIDDLESIDE;
LevelMeshInfo.ControlSector = rover->model;
surface = nullptr;
lightmaptile = -1;
}
if (rover->flags&FF_FOG)
@ -1936,7 +1936,7 @@ void HWWall::Process(HWWallDispatcher *di, FRenderState& state, seg_t *seg, sect
}
#endif
surface = nullptr;
lightmaptile = -1;
LevelMeshInfo.Type = ST_NONE;
LevelMeshInfo.ControlSector = nullptr;

View file

@ -195,9 +195,9 @@ void HWWall::SplitRightEdge(FFlatVertex *&ptr)
int HWWall::CreateVertices(FFlatVertex *&ptr, bool split)
{
if (surface && surface->LightmapTileIndex >= 0)
if (lightmaptile >= 0)
{
LightmapTile* tile = &level.levelMesh->LightmapTiles[surface->LightmapTileIndex];
LightmapTile* tile = &level.levelMesh->LightmapTiles[lightmaptile];
FVector2 lolft = tile->ToUV(FVector3(glseg.x1, glseg.y1, zbottom[0]), level.levelMesh->LMTextureSize);
FVector2 uplft = tile->ToUV(FVector3(glseg.x1, glseg.y1, ztop[0]), level.levelMesh->LMTextureSize);
FVector2 uprgt = tile->ToUV(FVector3(glseg.x2, glseg.y2, ztop[1]), level.levelMesh->LMTextureSize);