Add more dynamic update code to level mesh
This commit is contained in:
parent
8b78a1569f
commit
f1b9e68305
15 changed files with 147 additions and 101 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -467,7 +467,7 @@ public:
|
|||
|
||||
// Lightmaps
|
||||
bool lightmaps = false;
|
||||
TArray<DoomLevelMeshSurface*> Surfaces;
|
||||
TArray<int> LightmapTiles;
|
||||
FVector3 SunDirection;
|
||||
FVector3 SunColor;
|
||||
uint16_t LightmapSampleDistance;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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++;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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++)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue