More big beautiful porting
This commit is contained in:
parent
3fdd22ef91
commit
e3cde7a9e9
12 changed files with 241 additions and 336 deletions
2
.github/workflows/continuous_integration.yml
vendored
2
.github/workflows/continuous_integration.yml
vendored
|
|
@ -107,7 +107,7 @@ jobs:
|
|||
cp -r vkdoom.app package
|
||||
cp -r vktool package
|
||||
elif [[ "${{ runner.os }}" == 'Linux' ]]; then
|
||||
cp vkdoom vktool *.pk3 zmusic/lib/libzmusic.so package
|
||||
cp vkdoom vktool *.pk3 libzmusic.so package
|
||||
strip package/vkdoom
|
||||
strip package/vktool
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
#include "g_levellocals.h"
|
||||
#include "d_event.h"
|
||||
#include "v_video.h"
|
||||
#include "d_net.h"
|
||||
|
||||
void G_SetMap(const char* mapname, int mode);
|
||||
|
||||
|
|
@ -36,9 +37,8 @@ void LightmapBuildCmdlet::OnCommand(FArgs args)
|
|||
G_SetMap(mapname.GetChars(), 0);
|
||||
for (int i = 0; i < 100; i++)
|
||||
{
|
||||
#ifdef NEEDS_BIG_BEAUTIFUL_MERGE_PORTING
|
||||
D_SingleTick();
|
||||
#endif
|
||||
TryRunTics(1);
|
||||
|
||||
if (gameaction == ga_nothing)
|
||||
break;
|
||||
}
|
||||
|
|
@ -126,9 +126,7 @@ void LightmapDeleteCmdlet::OnCommand(FArgs args)
|
|||
G_SetMap(mapname.GetChars(), 0);
|
||||
for (int i = 0; i < 100; i++)
|
||||
{
|
||||
#ifdef NEEDS_BIG_BEAUTIFUL_MERGE_PORTING
|
||||
D_SingleTick();
|
||||
#endif
|
||||
TryRunTics(1);
|
||||
if (gameaction == ga_nothing)
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2145,7 +2145,7 @@ static void CalculateNetStabilityBuffer(int diff)
|
|||
//
|
||||
// TryRunTics
|
||||
//
|
||||
void TryRunTics()
|
||||
void TryRunTics(int forceRunTics)
|
||||
{
|
||||
GC::CheckGC();
|
||||
|
||||
|
|
@ -2154,23 +2154,28 @@ void TryRunTics()
|
|||
ToggleFullscreen = false;
|
||||
AddCommandString("toggle vid_fullscreen");
|
||||
}
|
||||
|
||||
bool doWait = (cl_capfps || pauseext || (!netgame && r_NoInterpolate && !M_IsAnimated()));
|
||||
if (vid_dontdowait && (vid_maxfps > 0 || vid_vsync))
|
||||
doWait = false;
|
||||
if (!netgame && !AppActive && vid_lowerinbackground)
|
||||
doWait = true;
|
||||
|
||||
// Get the full number of tics the client can run.
|
||||
if (doWait)
|
||||
EnterTic = I_WaitForTic(LastEnterTic);
|
||||
else
|
||||
EnterTic = I_GetTime();
|
||||
|
||||
const int startCommand = ClientTic;
|
||||
int totalTics = EnterTic - LastEnterTic;
|
||||
if (totalTics > 1 && singletics)
|
||||
totalTics = 1;
|
||||
int totalTics = forceRunTics;
|
||||
if (totalTics == 0)
|
||||
{
|
||||
bool doWait = (cl_capfps || pauseext || (!netgame && r_NoInterpolate && !M_IsAnimated()));
|
||||
if (vid_dontdowait && (vid_maxfps > 0 || vid_vsync))
|
||||
doWait = false;
|
||||
if (!netgame && !AppActive && vid_lowerinbackground)
|
||||
doWait = true;
|
||||
|
||||
// Get the full number of tics the client can run.
|
||||
if (doWait)
|
||||
EnterTic = I_WaitForTic(LastEnterTic);
|
||||
else
|
||||
EnterTic = I_GetTime();
|
||||
|
||||
totalTics = EnterTic - LastEnterTic;
|
||||
if (totalTics > 1 && singletics)
|
||||
totalTics = 1;
|
||||
}
|
||||
|
||||
|
||||
// Listen for other clients and send out data as needed. This is also
|
||||
// needed for singleplayer! But is instead handled entirely through local
|
||||
|
|
|
|||
|
|
@ -136,7 +136,7 @@ void NetUpdate(int tics);
|
|||
void D_QuitNetGame (void);
|
||||
|
||||
//? how many ticks to run?
|
||||
void TryRunTics (void);
|
||||
void TryRunTics(int forceRunTics = 0);
|
||||
|
||||
// [RH] Functions for making and using special "ticcmds"
|
||||
void Net_NewClientTic();
|
||||
|
|
|
|||
|
|
@ -647,12 +647,10 @@ void FDynamicLight::CollectWithinRadius(const DVector3 &opos, FSection *section,
|
|||
auto pos = collected_ss[i].pos;
|
||||
section = collected_ss[i].sect;
|
||||
|
||||
AddLightNode(section, NULL);
|
||||
|
||||
if(markTiles)
|
||||
{
|
||||
if (markTiles)
|
||||
LevelMeshUpdater->SectorLightListChanged(section->sector);
|
||||
}
|
||||
|
||||
AddLightNode(section, NULL);
|
||||
|
||||
auto processSide = [&](side_t *sidedef, const vertex_t *v1, const vertex_t *v2)
|
||||
{
|
||||
|
|
@ -664,12 +662,10 @@ void FDynamicLight::CollectWithinRadius(const DVector3 &opos, FSection *section,
|
|||
{
|
||||
linedef->validcount = ::validcount;
|
||||
|
||||
AddLightNode(NULL, sidedef);
|
||||
|
||||
if(markTiles)
|
||||
{
|
||||
if (markTiles)
|
||||
LevelMeshUpdater->SideLightListChanged(sidedef);
|
||||
}
|
||||
|
||||
AddLightNode(NULL, sidedef);
|
||||
}
|
||||
else if (linedef->sidedef[0] == sidedef && linedef->sidedef[1] == nullptr)
|
||||
{
|
||||
|
|
@ -771,6 +767,8 @@ void FDynamicLight::CollectWithinRadius(const DVector3 &opos, FSection *section,
|
|||
|
||||
void FDynamicLight::LinkLight()
|
||||
{
|
||||
UnlinkLight();
|
||||
|
||||
if (radius>0)
|
||||
{
|
||||
// passing in radius*radius allows us to do a distance check without any calls to sqrt
|
||||
|
|
@ -779,38 +777,7 @@ void FDynamicLight::LinkLight()
|
|||
dl_validcount++;
|
||||
::validcount++;
|
||||
CollectWithinRadius(Pos, sect, float(radius*radius));
|
||||
|
||||
}
|
||||
|
||||
#ifdef NEEDS_BIG_BEAUTIFUL_MERGE_PORTING
|
||||
bool markTiles = ((Trace() || lm_dynlights) && Level->levelMesh);
|
||||
if(markTiles)
|
||||
{
|
||||
node = touching_sides;
|
||||
while (node)
|
||||
{
|
||||
if (node->lightsource == nullptr)
|
||||
{
|
||||
LevelMeshUpdater->SideLightListChanged(node->targLine);
|
||||
node = DeleteLightNode(node);
|
||||
}
|
||||
else
|
||||
node = node->nextTarget;
|
||||
}
|
||||
|
||||
node = touching_sector;
|
||||
while (node)
|
||||
{
|
||||
if (node->lightsource == nullptr)
|
||||
{
|
||||
LevelMeshUpdater->SectorLightListChanged(node->targSection->sector);
|
||||
node = DeleteLightNode(node);
|
||||
}
|
||||
else
|
||||
node = node->nextTarget;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -821,25 +788,6 @@ void FDynamicLight::LinkLight()
|
|||
//==========================================================================
|
||||
void FDynamicLight::UnlinkLight ()
|
||||
{
|
||||
#ifdef NEEDS_BIG_BEAUTIFUL_MERGE_PORTING
|
||||
bool markTiles = ((Trace() || lm_dynlights) && Level->levelMesh);
|
||||
|
||||
if(markTiles)
|
||||
{
|
||||
while (touching_sides)
|
||||
{
|
||||
LevelMeshUpdater->SideLightListChanged(touching_sides->targLine);
|
||||
touching_sides = DeleteLightNode(touching_sides);
|
||||
}
|
||||
|
||||
while (touching_sector)
|
||||
{
|
||||
LevelMeshUpdater->SectorLightListChanged(touching_sector->targSection->sector);
|
||||
touching_sector = DeleteLightNode(touching_sector);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
TMap<side_t *, side_t *>::Iterator wit(touchlists.wall_tlist);
|
||||
TMap<side_t *, side_t *>::Pair *wpair;
|
||||
while (wit.NextPair(wpair))
|
||||
|
|
@ -850,6 +798,7 @@ void FDynamicLight::UnlinkLight ()
|
|||
auto wallLightList = Level->lightlists.wall_dlist.CheckKey(sidedef);
|
||||
if (wallLightList)
|
||||
{
|
||||
LevelMeshUpdater->SideLightListChanged(sidedef);
|
||||
wallLightList->Remove(this);
|
||||
}
|
||||
}
|
||||
|
|
@ -864,6 +813,7 @@ void FDynamicLight::UnlinkLight ()
|
|||
auto flatLightList = Level->lightlists.flat_dlist.CheckKey(sec);
|
||||
if (flatLightList)
|
||||
{
|
||||
LevelMeshUpdater->SectorLightListChanged(sec->sector);
|
||||
flatLightList->Remove(this);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -650,9 +650,7 @@ void DoomLevelMesh::AddSidesToDrawLists(const TArray<int>& sides, LevelMeshDrawL
|
|||
int dynlightindex = -1;
|
||||
if (di->Level->HasDynamicLights && !di->isFullbrightScene() && decals[0].texture != nullptr && !lm_dynlights)
|
||||
{
|
||||
#ifdef NEEDS_BIG_BEAUTIFUL_MERGE_PORTING
|
||||
dynlightindex = decals[0].SetupLights(di, state, lightdata, level.sides[sideIndex].lighthead);
|
||||
#endif
|
||||
dynlightindex = decals[0].SetupLights(di, state, lightdata, &level.sides[sideIndex]);
|
||||
}
|
||||
|
||||
for (const HWDecalCreateInfo& info : decals)
|
||||
|
|
@ -1048,18 +1046,21 @@ void DoomLevelMesh::UpdateLightShadows(sector_t* sector)
|
|||
{
|
||||
for (FSection& section : level.sections.SectionsForSector(sector))
|
||||
{
|
||||
#ifdef NEEDS_BIG_BEAUTIFUL_MERGE_PORTING
|
||||
FLightNode* cur = section.lighthead;
|
||||
while (cur)
|
||||
auto flatLightList = level.lightlists.flat_dlist.CheckKey(§ion);
|
||||
if (flatLightList)
|
||||
{
|
||||
FDynamicLight* light = cur->lightsource;
|
||||
if (light && light->IsActive() && (light->Trace() || lm_dynlights))
|
||||
TMap<FDynamicLight*, std::unique_ptr<FLightNode>>::Iterator it(*flatLightList);
|
||||
TMap<FDynamicLight*, std::unique_ptr<FLightNode>>::Pair* pair;
|
||||
while (it.NextPair(pair))
|
||||
{
|
||||
UpdateLightShadows(light);
|
||||
auto node = pair->Value.get();
|
||||
FDynamicLight* light = node->lightsource;
|
||||
if (light && light->IsActive() && (light->Trace() || lm_dynlights))
|
||||
{
|
||||
UpdateLightShadows(light);
|
||||
}
|
||||
}
|
||||
cur = cur->nextLight;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1185,16 +1186,12 @@ void DoomLevelMesh::UpdateSideLightList(FLevelLocals& doomMap, unsigned int side
|
|||
return;
|
||||
|
||||
FreeLightList(sideBlock.Lights.Start, sideBlock.Lights.Count);
|
||||
#ifdef NEEDS_BIG_BEAUTIFUL_MERGE_PORTING
|
||||
sideBlock.Lights = CreateLightList(sub->section->lighthead, sub->sector->PortalGroup);
|
||||
#endif
|
||||
sideBlock.Lights = CreateLightList(sub->section, nullptr, sub->sector->PortalGroup);
|
||||
}
|
||||
else
|
||||
{
|
||||
FreeLightList(sideBlock.Lights.Start, sideBlock.Lights.Count);
|
||||
#ifdef NEEDS_BIG_BEAUTIFUL_MERGE_PORTING
|
||||
sideBlock.Lights = CreateLightList(side->lighthead, side->sector->PortalGroup);
|
||||
#endif
|
||||
sideBlock.Lights = CreateLightList(nullptr, side, side->sector->PortalGroup);
|
||||
}
|
||||
|
||||
int surf = Sides[sideIndex].FirstSurface;
|
||||
|
|
@ -1222,9 +1219,7 @@ void DoomLevelMesh::UpdateFlatLightList(FLevelLocals& doomMap, unsigned int sect
|
|||
sector_t* sector = &doomMap.sectors[sectorIndex];
|
||||
for (FSection& section : doomMap.sections.SectionsForSector(sectorIndex))
|
||||
{
|
||||
#ifdef NEEDS_BIG_BEAUTIFUL_MERGE_PORTING
|
||||
Flats[sectorIndex].Lights.Push(CreateLightList(section.lighthead, section.sector->PortalGroup));
|
||||
#endif
|
||||
Flats[sectorIndex].Lights.Push(CreateLightList(§ion, nullptr, section.sector->PortalGroup));
|
||||
}
|
||||
|
||||
int surf = Flats[sectorIndex].FirstSurface;
|
||||
|
|
@ -1318,36 +1313,51 @@ void DoomLevelMesh::UpdateFlat(unsigned int sectorIndex, SurfaceUpdateType updat
|
|||
}
|
||||
}
|
||||
|
||||
LightListAllocInfo DoomLevelMesh::CreateLightList(FLightNode* node, int portalgroup)
|
||||
LightListAllocInfo DoomLevelMesh::CreateLightList(FSection* section, side_t* side, int portalgroup)
|
||||
{
|
||||
int lightcount = 0;
|
||||
FLightNode* cur = node;
|
||||
while (cur)
|
||||
|
||||
auto srcLightList = section ? level.lightlists.flat_dlist.CheckKey(section) : level.lightlists.wall_dlist.CheckKey(side);
|
||||
if (srcLightList)
|
||||
{
|
||||
FDynamicLight* light = cur->lightsource;
|
||||
if (light && light->IsActive() && (light->Trace() || lm_dynlights) && GetLightIndex(light, portalgroup) >= 0)
|
||||
TMap<FDynamicLight*, std::unique_ptr<FLightNode>>::Iterator it(*srcLightList);
|
||||
TMap<FDynamicLight*, std::unique_ptr<FLightNode>>::Pair* pair;
|
||||
while (it.NextPair(pair))
|
||||
{
|
||||
lightcount++;
|
||||
auto node = pair->Value.get();
|
||||
if (!node) continue;
|
||||
|
||||
FDynamicLight* light = node->lightsource;
|
||||
if (light && light->IsActive() && (light->Trace() || lm_dynlights) && GetLightIndex(light, portalgroup) >= 0)
|
||||
{
|
||||
lightcount++;
|
||||
}
|
||||
}
|
||||
cur = cur->nextLight;
|
||||
}
|
||||
|
||||
LightListAllocInfo info = AllocLightList(lightcount);
|
||||
int32_t* lightList = GetLightList(info);
|
||||
int i = 0;
|
||||
cur = node;
|
||||
while (cur)
|
||||
|
||||
if (srcLightList)
|
||||
{
|
||||
FDynamicLight* light = cur->lightsource;
|
||||
if (light && light->IsActive() && (light->Trace() || lm_dynlights))
|
||||
int32_t* lightList = GetLightList(info);
|
||||
int i = 0;
|
||||
TMap<FDynamicLight*, std::unique_ptr<FLightNode>>::Iterator it(*srcLightList);
|
||||
TMap<FDynamicLight*, std::unique_ptr<FLightNode>>::Pair* pair;
|
||||
while (it.NextPair(pair))
|
||||
{
|
||||
int lightindex = GetLightIndex(light, portalgroup);
|
||||
if (lightindex >= 0)
|
||||
auto node = pair->Value.get();
|
||||
if (!node) continue;
|
||||
|
||||
FDynamicLight* light = node->lightsource;
|
||||
if (light && light->IsActive() && (light->Trace() || lm_dynlights))
|
||||
{
|
||||
lightList[i++] = lightindex;
|
||||
int lightindex = GetLightIndex(light, portalgroup);
|
||||
if (lightindex >= 0)
|
||||
{
|
||||
lightList[i++] = lightindex;
|
||||
}
|
||||
}
|
||||
}
|
||||
cur = cur->nextLight;
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
|
@ -1382,9 +1392,7 @@ void DoomLevelMesh::CreateSide(FLevelLocals& doomMap, unsigned int sideIndex)
|
|||
{
|
||||
if (!lightlistCreated)
|
||||
{
|
||||
#ifdef NEEDS_BIG_BEAUTIFUL_MERGE_PORTING
|
||||
sideBlock.Lights = CreateLightList(sub->section->lighthead, sub->sector->PortalGroup);
|
||||
#endif
|
||||
sideBlock.Lights = CreateLightList(sub->section, nullptr, sub->sector->PortalGroup);
|
||||
lightlistCreated = true;
|
||||
}
|
||||
|
||||
|
|
@ -1399,9 +1407,7 @@ void DoomLevelMesh::CreateSide(FLevelLocals& doomMap, unsigned int sideIndex)
|
|||
}
|
||||
else
|
||||
{
|
||||
#ifdef NEEDS_BIG_BEAUTIFUL_MERGE_PORTING
|
||||
sideBlock.Lights = CreateLightList(side->lighthead, side->sector->PortalGroup);
|
||||
#endif
|
||||
sideBlock.Lights = CreateLightList(nullptr, side, side->sector->PortalGroup);
|
||||
|
||||
subsector_t* sub = seg->Subsector;
|
||||
sector_t* front = side->sector;
|
||||
|
|
@ -1493,11 +1499,7 @@ void DoomLevelMesh::CreateFlat(FLevelLocals& doomMap, unsigned int sectorIndex)
|
|||
int lightlistSection = 0;
|
||||
for (FSection& section : doomMap.sections.SectionsForSector(sectorIndex))
|
||||
{
|
||||
#ifdef NEEDS_BIG_BEAUTIFUL_MERGE_PORTING
|
||||
Flats[sectorIndex].Lights.Push(CreateLightList(section.lighthead, section.sector->PortalGroup));
|
||||
#else
|
||||
Flats[sectorIndex].Lights.Push({});
|
||||
#endif
|
||||
Flats[sectorIndex].Lights.Push(CreateLightList(§ion, nullptr, section.sector->PortalGroup));
|
||||
const auto& lightlist = Flats[sectorIndex].Lights.Last();
|
||||
|
||||
HWFlatMeshHelper result;
|
||||
|
|
|
|||
|
|
@ -244,7 +244,7 @@ private:
|
|||
|
||||
void CreatePortals(FLevelLocals& doomMap);
|
||||
|
||||
LightListAllocInfo CreateLightList(FLightNode* node, int portalgroup);
|
||||
LightListAllocInfo CreateLightList(FSection* section, side_t* side, int portalgroup);
|
||||
int GetLightIndex(FDynamicLight* light, int portalgroup);
|
||||
void UpdateLight(FDynamicLight* light);
|
||||
void CopyToMeshLight(FDynamicLight* light, LevelMeshLight& meshlight, int portalgroup);
|
||||
|
|
|
|||
|
|
@ -751,7 +751,7 @@ void HWWall::ProcessDecals(HWWallDispatcher* di, FRenderState& state)
|
|||
|
||||
//==========================================================================
|
||||
|
||||
int HWDecalCreateInfo::SetupLights(HWDrawInfo* di, FRenderState& state, FDynLightData& lightdata, FLightNode* node) const
|
||||
int HWDecalCreateInfo::SetupLights(HWDrawInfo* di, FRenderState& state, FDynLightData& lightdata, side_t* side) const
|
||||
{
|
||||
lightdata.Clear();
|
||||
|
||||
|
|
@ -762,58 +762,66 @@ int HWDecalCreateInfo::SetupLights(HWDrawInfo* di, FRenderState& state, FDynLigh
|
|||
p.Set(normal, -normal.X * glseg.x1 - normal.Z * glseg.y1);
|
||||
|
||||
// Iterate through all dynamic lights which touch this wall and render them
|
||||
while (node)
|
||||
auto wallLightList = di->Level->lightlists.wall_dlist.CheckKey(side);
|
||||
|
||||
if (wallLightList)
|
||||
{
|
||||
if (node->lightsource->IsActive() && !node->lightsource->DontLightMap())
|
||||
TMap<FDynamicLight*, std::unique_ptr<FLightNode>>::Iterator it(*wallLightList);
|
||||
TMap<FDynamicLight*, std::unique_ptr<FLightNode>>::Pair* pair;
|
||||
while (it.NextPair(pair))
|
||||
{
|
||||
iter_dlight++;
|
||||
|
||||
DVector3 posrel = node->lightsource->PosRelative(frontsector->PortalGroup);
|
||||
float x = posrel.X;
|
||||
float y = posrel.Y;
|
||||
float z = posrel.Z;
|
||||
float dist = fabsf(p.DistToPoint(x, z, y));
|
||||
float radius = node->lightsource->GetRadius();
|
||||
float scale = 1.0f / ((2.f * radius) - dist);
|
||||
FVector3 fn, pos;
|
||||
|
||||
if (radius > 0.f && dist < radius)
|
||||
auto node = pair->Value.get();
|
||||
if (!node) continue;
|
||||
if (node->lightsource->IsActive() && !node->lightsource->DontLightMap())
|
||||
{
|
||||
FVector3 nearPt, up, right;
|
||||
iter_dlight++;
|
||||
|
||||
pos = { x, z, y };
|
||||
fn = p.Normal();
|
||||
DVector3 posrel = node->lightsource->PosRelative(frontsector->PortalGroup);
|
||||
float x = posrel.X;
|
||||
float y = posrel.Y;
|
||||
float z = posrel.Z;
|
||||
float dist = fabsf(p.DistToPoint(x, z, y));
|
||||
float radius = node->lightsource->GetRadius();
|
||||
float scale = 1.0f / ((2.f * radius) - dist);
|
||||
FVector3 fn, pos;
|
||||
|
||||
fn.GetRightUp(right, up);
|
||||
|
||||
FVector3 tmpVec = fn * dist;
|
||||
nearPt = pos + tmpVec;
|
||||
|
||||
FVector3 t1;
|
||||
int outcnt[4] = { 0,0,0,0 };
|
||||
texcoord tcs[4];
|
||||
|
||||
// do a quick check whether the light touches this polygon
|
||||
for (int i = 0; i < 4; i++)
|
||||
if (radius > 0.f && dist < radius)
|
||||
{
|
||||
t1 = FVector3(&vtx[i * 3]);
|
||||
FVector3 nearToVert = t1 - nearPt;
|
||||
tcs[i].u = ((nearToVert | right) * scale) + 0.5f;
|
||||
tcs[i].v = ((nearToVert | up) * scale) + 0.5f;
|
||||
FVector3 nearPt, up, right;
|
||||
|
||||
if (tcs[i].u < 0) outcnt[0]++;
|
||||
if (tcs[i].u > 1) outcnt[1]++;
|
||||
if (tcs[i].v < 0) outcnt[2]++;
|
||||
if (tcs[i].v > 1) outcnt[3]++;
|
||||
pos = { x, z, y };
|
||||
fn = p.Normal();
|
||||
|
||||
}
|
||||
if (outcnt[0] != 4 && outcnt[1] != 4 && outcnt[2] != 4 && outcnt[3] != 4)
|
||||
{
|
||||
draw_dlight += GetLight(lightdata, frontsector->PortalGroup, p, node->lightsource, true);
|
||||
fn.GetRightUp(right, up);
|
||||
|
||||
FVector3 tmpVec = fn * dist;
|
||||
nearPt = pos + tmpVec;
|
||||
|
||||
FVector3 t1;
|
||||
int outcnt[4] = { 0,0,0,0 };
|
||||
texcoord tcs[4];
|
||||
|
||||
// do a quick check whether the light touches this polygon
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
t1 = FVector3(&vtx[i * 3]);
|
||||
FVector3 nearToVert = t1 - nearPt;
|
||||
tcs[i].u = ((nearToVert | right) * scale) + 0.5f;
|
||||
tcs[i].v = ((nearToVert | up) * scale) + 0.5f;
|
||||
|
||||
if (tcs[i].u < 0) outcnt[0]++;
|
||||
if (tcs[i].u > 1) outcnt[1]++;
|
||||
if (tcs[i].v < 0) outcnt[2]++;
|
||||
if (tcs[i].v > 1) outcnt[3]++;
|
||||
|
||||
}
|
||||
if (outcnt[0] != 4 && outcnt[1] != 4 && outcnt[2] != 4 && outcnt[3] != 4)
|
||||
{
|
||||
draw_dlight += GetLight(lightdata, frontsector->PortalGroup, p, node->lightsource, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
node = node->nextLight;
|
||||
}
|
||||
return state.UploadLights(lightdata);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -466,7 +466,7 @@ struct HWDecal
|
|||
struct HWDecalCreateInfo
|
||||
{
|
||||
void ProcessDecal(HWDrawInfo* di, FRenderState& state, int dynlightindex) const;
|
||||
int SetupLights(HWDrawInfo* di, FRenderState& state, FDynLightData& lightdata, FLightNode* node) const;
|
||||
int SetupLights(HWDrawInfo* di, FRenderState& state, FDynLightData& lightdata, side_t* side) const;
|
||||
|
||||
DBaseDecal* decal;
|
||||
FVector3 normal;
|
||||
|
|
|
|||
|
|
@ -131,25 +131,23 @@ float inverseSquareAttenuation(float dist, float radius, float strength, float l
|
|||
return mix(((b * b) / (dist * dist + 1.0f) * strength), clamp((radius - dist) / radius, 0.0f, 1.0f), linearity);
|
||||
}
|
||||
|
||||
void HWDrawInfo::GetDynSpriteLight(AActor *self, sun_trace_cache_t * traceCache, double x, double y, double z, FSection *sec, int portalgroup, float *out, bool fullbright)
|
||||
void HWDrawInfo::GetDynSpriteLight(AActor* self, sun_trace_cache_t* traceCache, double x, double y, double z, FSection* sec, int portalgroup, float* out, bool fullbright)
|
||||
{
|
||||
|
||||
FDynamicLight *light;
|
||||
FDynamicLight* light;
|
||||
float frac, lr, lg, lb;
|
||||
float radius;
|
||||
|
||||
|
||||
out[0] = out[1] = out[2] = 0.f;
|
||||
|
||||
if (fullbright || get_gl_spritelight() > 0)
|
||||
return;
|
||||
|
||||
#ifdef NEEDS_BIG_BEAUTIFUL_MERGE_PORTING
|
||||
|
||||
ActorTraceStaticLight staticLight(self);
|
||||
|
||||
if (ActorTraceStaticLight::TraceSunVisibility(x, y, z, traceCache, (self ? staticLight.ActorMoved : traceCache ? traceCache->Pos != DVector3(x, y, z) : false)))
|
||||
{
|
||||
if(!self && traceCache)
|
||||
if (!self && traceCache)
|
||||
{
|
||||
traceCache->Pos = DVector3(x, y, z);
|
||||
}
|
||||
|
|
@ -164,69 +162,19 @@ void HWDrawInfo::GetDynSpriteLight(AActor *self, sun_trace_cache_t * traceCache,
|
|||
|
||||
if (flatLightList)
|
||||
{
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Iterator it(*flatLightList);
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Pair *pair;
|
||||
TMap<FDynamicLight*, std::unique_ptr<FLightNode>>::Iterator it(*flatLightList);
|
||||
TMap<FDynamicLight*, std::unique_ptr<FLightNode>>::Pair* pair;
|
||||
while (it.NextPair(pair))
|
||||
{
|
||||
auto node = pair->Value.get();
|
||||
if (!node) continue;
|
||||
|
||||
light=node->lightsource;
|
||||
light = node->lightsource;
|
||||
if (light->ShouldLightActor(self))
|
||||
{
|
||||
float dist;
|
||||
FVector3 L;
|
||||
|
||||
<<<<<<< HEAD
|
||||
DVector2 offset = Level->Displacements.getOffset(fromgroup, togroup);
|
||||
L = FVector3(x - (float)(light->X() + offset.X), y - (float)(light->Y() + offset.Y), z - (float)light->Z());
|
||||
}
|
||||
else
|
||||
{
|
||||
direct:
|
||||
L = FVector3(x - (float)light->X(), y - (float)light->Y(), z - (float)light->Z());
|
||||
}
|
||||
|
||||
dist = (float)L.LengthSquared();
|
||||
radius = light->GetRadius();
|
||||
|
||||
if (radius > 0 && dist < radius * radius)
|
||||
{
|
||||
dist = sqrtf(dist); // only calculate the square root if we really need it.
|
||||
|
||||
if (light->IsSpot() || light->TraceActors())
|
||||
L *= -1.0f / dist;
|
||||
|
||||
if (staticLight.TraceLightVisbility(node, L, dist, light->updated))
|
||||
{
|
||||
if(level.info->lightattenuationmode == ELightAttenuationMode::INVERSE_SQUARE)
|
||||
{
|
||||
frac = (inverseSquareAttenuation(std::max(dist, sqrt(radius) * 2), radius, light->GetStrength(), light->GetLinearity()));
|
||||
}
|
||||
else
|
||||
{
|
||||
frac = 1.0f - (dist / radius);
|
||||
}
|
||||
|
||||
if (light->IsSpot())
|
||||
{
|
||||
DAngle negPitch = -*light->pPitch;
|
||||
DAngle Angle = light->target->Angles.Yaw;
|
||||
double xyLen = negPitch.Cos();
|
||||
double spotDirX = -Angle.Cos() * xyLen;
|
||||
double spotDirY = -Angle.Sin() * xyLen;
|
||||
double spotDirZ = -negPitch.Sin();
|
||||
double cosDir = L.X * spotDirX + L.Y * spotDirY + L.Z * spotDirZ;
|
||||
frac *= (float)smoothstep(light->pSpotOuterAngle->Cos(), light->pSpotInnerAngle->Cos(), cosDir);
|
||||
}
|
||||
|
||||
if (frac > 0 && (!light->shadowmapped || (self && light->TraceActors()) || screen->mShadowMap->ShadowTest(light->Pos, { x, y, z })))
|
||||
{
|
||||
lr = light->GetRed() / 255.0f;
|
||||
lg = light->GetGreen() / 255.0f;
|
||||
lb = light->GetBlue() / 255.0f;
|
||||
|
||||
=======
|
||||
// This is a performance critical section of code where we cannot afford to let the compiler decide whether to inline the function or not.
|
||||
// This will do the calculations explicitly rather than calling one of AActor's utility functions.
|
||||
if (Level->Displacements.size > 0)
|
||||
|
|
@ -247,63 +195,73 @@ void HWDrawInfo::GetDynSpriteLight(AActor *self, sun_trace_cache_t * traceCache,
|
|||
dist = (float)L.LengthSquared();
|
||||
radius = light->GetRadius();
|
||||
|
||||
if (dist < radius * radius)
|
||||
if (radius > 0 && dist < radius * radius)
|
||||
{
|
||||
dist = sqrtf(dist); // only calculate the square root if we really need it.
|
||||
|
||||
frac = 1.0f - (dist / radius);
|
||||
|
||||
if (light->IsSpot())
|
||||
{
|
||||
if (light->IsSpot() || light->TraceActors())
|
||||
L *= -1.0f / dist;
|
||||
DAngle negPitch = -*light->pPitch;
|
||||
DAngle Angle = light->target->Angles.Yaw;
|
||||
double xyLen = negPitch.Cos();
|
||||
double spotDirX = -Angle.Cos() * xyLen;
|
||||
double spotDirY = -Angle.Sin() * xyLen;
|
||||
double spotDirZ = -negPitch.Sin();
|
||||
double cosDir = L.X * spotDirX + L.Y * spotDirY + L.Z * spotDirZ;
|
||||
frac *= (float)smoothstep(light->pSpotOuterAngle->Cos(), light->pSpotInnerAngle->Cos(), cosDir);
|
||||
}
|
||||
|
||||
if (frac > 0 && (!light->shadowmapped || (light->GetRadius() > 0 && screen->mShadowMap.ShadowTest(light->Pos, { x, y, z }))))
|
||||
if (staticLight.TraceLightVisbility(node, L, dist, light->updated))
|
||||
{
|
||||
lr = light->GetRed() / 255.0f;
|
||||
lg = light->GetGreen() / 255.0f;
|
||||
lb = light->GetBlue() / 255.0f;
|
||||
|
||||
>>>>>>> gzdoom/master
|
||||
if (light->target && (light->target->renderflags2 & RF2_LIGHTMULTALPHA))
|
||||
if (level.info->lightattenuationmode == ELightAttenuationMode::INVERSE_SQUARE)
|
||||
{
|
||||
float alpha = (float)light->target->Alpha;
|
||||
lr *= alpha;
|
||||
lg *= alpha;
|
||||
lb *= alpha;
|
||||
frac = (inverseSquareAttenuation(std::max(dist, sqrt(radius) * 2), radius, light->GetStrength(), light->GetLinearity()));
|
||||
}
|
||||
else
|
||||
{
|
||||
frac = 1.0f - (dist / radius);
|
||||
}
|
||||
|
||||
// Get GLDEFS intensity
|
||||
lr *= light->GetLightDefIntensity();
|
||||
lg *= light->GetLightDefIntensity();
|
||||
lb *= light->GetLightDefIntensity();
|
||||
|
||||
if (light->IsSubtractive())
|
||||
if (light->IsSpot())
|
||||
{
|
||||
float bright = (float)FVector3(lr, lg, lb).Length();
|
||||
FVector3 lightColor(lr, lg, lb);
|
||||
lr = (bright - lr) * -1;
|
||||
lg = (bright - lg) * -1;
|
||||
lb = (bright - lb) * -1;
|
||||
DAngle negPitch = -*light->pPitch;
|
||||
DAngle Angle = light->target->Angles.Yaw;
|
||||
double xyLen = negPitch.Cos();
|
||||
double spotDirX = -Angle.Cos() * xyLen;
|
||||
double spotDirY = -Angle.Sin() * xyLen;
|
||||
double spotDirZ = -negPitch.Sin();
|
||||
double cosDir = L.X * spotDirX + L.Y * spotDirY + L.Z * spotDirZ;
|
||||
frac *= (float)smoothstep(light->pSpotOuterAngle->Cos(), light->pSpotInnerAngle->Cos(), cosDir);
|
||||
}
|
||||
|
||||
out[0] += lr * frac;
|
||||
out[1] += lg * frac;
|
||||
out[2] += lb * frac;
|
||||
if (frac > 0 && (!light->shadowmapped || (self && light->TraceActors()) || screen->mShadowMap->ShadowTest(light->Pos, { x, y, z })))
|
||||
{
|
||||
lr = light->GetRed() / 255.0f;
|
||||
lg = light->GetGreen() / 255.0f;
|
||||
lb = light->GetBlue() / 255.0f;
|
||||
|
||||
if (light->target && (light->target->renderflags2 & RF2_LIGHTMULTALPHA))
|
||||
{
|
||||
float alpha = (float)light->target->Alpha;
|
||||
lr *= alpha;
|
||||
lg *= alpha;
|
||||
lb *= alpha;
|
||||
}
|
||||
|
||||
// Get GLDEFS intensity
|
||||
lr *= light->GetLightDefIntensity();
|
||||
lg *= light->GetLightDefIntensity();
|
||||
lb *= light->GetLightDefIntensity();
|
||||
|
||||
if (light->IsSubtractive())
|
||||
{
|
||||
float bright = (float)FVector3(lr, lg, lb).Length();
|
||||
FVector3 lightColor(lr, lg, lb);
|
||||
lr = (bright - lr) * -1;
|
||||
lg = (bright - lg) * -1;
|
||||
lb = (bright - lb) * -1;
|
||||
}
|
||||
|
||||
out[0] += lr * frac;
|
||||
out[1] += lg * frac;
|
||||
out[2] += lb * frac;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void HWDrawInfo::GetDynSpriteLight(AActor *thing, particle_t *particle, sun_trace_cache_t * traceCache, float *out)
|
||||
|
|
@ -323,8 +281,6 @@ void HWDrawInfo::GetDynSpriteLightList(AActor *self, double x, double y, double
|
|||
{
|
||||
modellightdata.Clear();
|
||||
|
||||
#ifdef NEEDS_BIG_BEAUTIFUL_MERGE_PORTING
|
||||
|
||||
if (self && (self->flags5 & MF5_BRIGHT))
|
||||
return;
|
||||
|
||||
|
|
@ -355,73 +311,48 @@ void HWDrawInfo::GetDynSpriteLightList(AActor *self, double x, double y, double
|
|||
{
|
||||
auto section = subsector->section;
|
||||
if (section->validcount == dl_validcount) return; // already done from a previous subsector.
|
||||
FLightNode * node = section->lighthead;
|
||||
while (node) // check all lights touching a subsector
|
||||
|
||||
auto flatLightList = level.lightlists.flat_dlist.CheckKey(subsector->section);
|
||||
if (flatLightList)
|
||||
{
|
||||
<<<<<<< HEAD
|
||||
FDynamicLight *light = node->lightsource;
|
||||
if (light->ShouldLightActor(self))
|
||||
{
|
||||
int group = subsector->sector->PortalGroup;
|
||||
DVector3 pos = light->PosRelative(group);
|
||||
float radius = (float)(light->GetRadius() + actorradius);
|
||||
double dx = pos.X - x;
|
||||
double dy = pos.Y - y;
|
||||
double dz = pos.Z - z;
|
||||
double distSquared = dx * dx + dy * dy + dz * dz;
|
||||
if (distSquared < radius * radius) // Light and actor touches
|
||||
TMap<FDynamicLight*, std::unique_ptr<FLightNode>>::Iterator it(*flatLightList);
|
||||
TMap<FDynamicLight*, std::unique_ptr<FLightNode>>::Pair* pair;
|
||||
while (it.NextPair(pair))
|
||||
{ // check all lights touching a subsector
|
||||
auto node = pair->Value.get();
|
||||
if (!node) continue;
|
||||
FDynamicLight* light = node->lightsource;
|
||||
if (light->ShouldLightActor(self))
|
||||
{
|
||||
unsigned index = addedLights.SortedFind(light, false);
|
||||
if(index == addedLights.Size() || addedLights[index] != light) // Check if we already added this light from a different subsector (use binary search instead of linear search)
|
||||
int group = subsector->sector->PortalGroup;
|
||||
DVector3 pos = light->PosRelative(group);
|
||||
float radius = (float)(light->GetRadius() + actorradius);
|
||||
double dx = pos.X - x;
|
||||
double dy = pos.Y - y;
|
||||
double dz = pos.Z - z;
|
||||
double distSquared = dx * dx + dy * dy + dz * dz;
|
||||
if (distSquared < radius * radius) // Light and actor touches
|
||||
{
|
||||
FVector3 L(dx, dy, dz);
|
||||
float dist = sqrtf(distSquared);
|
||||
if (gl_spritelight == 0 && light->TraceActors())
|
||||
L *= 1.0f / dist;
|
||||
unsigned index = addedLights.SortedFind(light, false);
|
||||
if (index == addedLights.Size() || addedLights[index] != light) // Check if we already added this light from a different subsector (use binary search instead of linear search)
|
||||
{
|
||||
FVector3 L(dx, dy, dz);
|
||||
float dist = sqrtf(distSquared);
|
||||
if (gl_spritelight == 0 && light->TraceActors())
|
||||
L *= 1.0f / dist;
|
||||
|
||||
if (gl_spritelight > 0 || staticLight.TraceLightVisbility(node, L, dist, light->updated))
|
||||
{
|
||||
AddLightToList(modellightdata, group, light, true, gl_spritelight > 0);
|
||||
=======
|
||||
auto section = subsector->section;
|
||||
if (section->validcount == dl_validcount) return; // already done from a previous subsector.
|
||||
auto flatLightList = self->Level->lightlists.flat_dlist.CheckKey(subsector->section);
|
||||
if (flatLightList)
|
||||
{
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Iterator it(*flatLightList);
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Pair *pair;
|
||||
while (it.NextPair(pair))
|
||||
{ // check all lights touching a subsector
|
||||
auto node = pair->Value.get();
|
||||
if (!node) continue;
|
||||
FDynamicLight *light = node->lightsource;
|
||||
if (light->ShouldLightActor(self))
|
||||
{
|
||||
int group = subsector->sector->PortalGroup;
|
||||
DVector3 pos = light->PosRelative(group);
|
||||
float radius = (float)(light->GetRadius() + actorradius);
|
||||
double dx = pos.X - x;
|
||||
double dy = pos.Y - y;
|
||||
double dz = pos.Z - z;
|
||||
double distSquared = dx * dx + dy * dy + dz * dz;
|
||||
if (distSquared < radius * radius) // Light and actor touches
|
||||
{
|
||||
if (std::find(addedLights.begin(), addedLights.end(), light) == addedLights.end()) // Check if we already added this light from a different subsector
|
||||
if (gl_spritelight > 0 || staticLight.TraceLightVisbility(node, L, dist, light->updated))
|
||||
{
|
||||
AddLightToList(modellightdata, group, light, true);
|
||||
addedLights.Push(light);
|
||||
AddLightToList(modellightdata, group, light, true, gl_spritelight > 0);
|
||||
}
|
||||
>>>>>>> gzdoom/master
|
||||
}
|
||||
|
||||
addedLights.Insert(index, light);
|
||||
addedLights.Insert(index, light);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
node = node->nextLight;
|
||||
}
|
||||
});
|
||||
#endif
|
||||
}
|
||||
|
||||
void HWDrawInfo::GetDynSpriteLightList(AActor *thing, particle_t *particle, sun_trace_cache_t * traceCache, FDynLightData &modellightdata, bool isModel)
|
||||
|
|
|
|||
|
|
@ -25,6 +25,9 @@ layout(set = 1, binding = 0, std140) uniform readonly ViewpointUBO
|
|||
float SunIntensity;
|
||||
|
||||
vec3 uCameraNormal;
|
||||
|
||||
float uThickFogDistance;
|
||||
float uThickFogMultiplier;
|
||||
};
|
||||
|
||||
layout(set = 1, binding = 1, std140) uniform readonly MatricesUBO
|
||||
|
|
|
|||
|
|
@ -156,6 +156,10 @@ vec3 AmbientOcclusionColor()
|
|||
fogdist = max(16.0, distance(pixelpos.xyz, uCameraPos.xyz));
|
||||
else
|
||||
fogdist = max(16.0, pixelpos.w);
|
||||
|
||||
if (uThickFogDistance > 0.0 && fogdist > uThickFogDistance)
|
||||
fogdist = fogdist + uThickFogMultiplier * (fogdist - uThickFogDistance);
|
||||
|
||||
float fogfactor = exp2 (uFogDensity * fogdist);
|
||||
|
||||
vec4 color = vec4(mix(uFogColor.rgb, vec3(0.0), fogfactor), 0.0);
|
||||
|
|
@ -198,6 +202,10 @@ vec4 ProcessLightMode(Material material)
|
|||
fogdist = max(16.0, distance(pixelpos.xyz, uCameraPos.xyz));
|
||||
else
|
||||
fogdist = max(16.0, pixelpos.w);
|
||||
|
||||
if (uThickFogDistance > 0.0 && fogdist > uThickFogDistance)
|
||||
fogdist = fogdist + uThickFogMultiplier * (fogdist - uThickFogDistance);
|
||||
|
||||
float fogfactor = exp2 (uFogDensity * fogdist);
|
||||
|
||||
return vec4(uFogColor.rgb, (1.0 - fogfactor) * material.Base.a * 0.75 * vColor.a);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue