remove linked lists entirely from lights
This commit is contained in:
parent
04c29dcf4b
commit
773c534896
10 changed files with 53 additions and 119 deletions
|
|
@ -405,7 +405,7 @@ public:
|
|||
// exact = false returns the closest match, to be used for, ex., insertions, exact = true returns Size() when no match, like Find does
|
||||
unsigned int SortedFind(const T& item, bool exact = true) const
|
||||
{
|
||||
unsigned int index = (std::lower_bound(begin(), end(), item) - begin());
|
||||
unsigned int index = (unsigned int)(std::lower_bound(begin(), end(), item) - begin());
|
||||
if(exact)
|
||||
{
|
||||
return (index < Count && Array[index] == item) ? index : Count;
|
||||
|
|
|
|||
|
|
@ -76,31 +76,12 @@ CCMD(listlights)
|
|||
if (dl->target)
|
||||
{
|
||||
FTextureID spr = sprites[dl->target->sprite].GetSpriteFrame(dl->target->frame, 0, nullAngle, nullptr);
|
||||
Printf(", frame = %s ", TexMan.GetGameTexture(spr)->GetName().GetChars());
|
||||
Printf(", frame = %s\n", TexMan.GetGameTexture(spr)->GetName().GetChars());
|
||||
}
|
||||
|
||||
|
||||
FLightNode * node;
|
||||
|
||||
node=dl->touching_sides;
|
||||
|
||||
while (node)
|
||||
{
|
||||
walls++;
|
||||
allwalls++;
|
||||
node = node->nextTarget;
|
||||
}
|
||||
|
||||
|
||||
node = dl->touching_sector;
|
||||
|
||||
while (node)
|
||||
{
|
||||
allsectors++;
|
||||
sectors++;
|
||||
node = node->nextTarget;
|
||||
}
|
||||
/*
|
||||
Printf("- %d walls, %d sectors\n", walls, sectors);
|
||||
*/
|
||||
|
||||
}
|
||||
Printf("%i dynamic lights, %d shadowmapped, %d walls, %d sectors\n\n\n", i, shadowcount, allwalls, allsectors);
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@
|
|||
|
||||
struct FGlobalDLightLists
|
||||
{
|
||||
//TODO add TSet and switch from TMap to TSet
|
||||
TArray<TMap<FDynamicLight*, std::unique_ptr<FLightNode>>> flat_dlist;
|
||||
TArray<TMap<FDynamicLight*, std::unique_ptr<FLightNode>>> wall_dlist;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -447,7 +447,6 @@ void FDynamicLight::AddLightNode(FSection *section, side_t *sidedef)
|
|||
{
|
||||
FLightNode * node = new FLightNode;
|
||||
node->lightsource = this;
|
||||
node->targ = section;
|
||||
|
||||
flatLightList.TryEmplace(this, node);
|
||||
touchlists.flat_tlist.SortedAddUnique(section);
|
||||
|
|
@ -466,7 +465,6 @@ void FDynamicLight::AddLightNode(FSection *section, side_t *sidedef)
|
|||
{
|
||||
FLightNode * node = new FLightNode;
|
||||
node->lightsource = this;
|
||||
node->targ = sidedef;
|
||||
|
||||
wallLightList.TryEmplace(this, node);
|
||||
touchlists.wall_tlist.SortedAddUnique(sidedef);
|
||||
|
|
|
|||
|
|
@ -184,17 +184,7 @@ protected:
|
|||
|
||||
struct FLightNode
|
||||
{
|
||||
FLightNode ** prevTarget;
|
||||
FLightNode * nextTarget;
|
||||
FLightNode ** prevLight;
|
||||
FLightNode * nextLight;
|
||||
FDynamicLight * lightsource;
|
||||
union
|
||||
{
|
||||
side_t * targLine;
|
||||
subsector_t * targSubsector;
|
||||
void * targ;
|
||||
};
|
||||
};
|
||||
|
||||
struct FDynamicLightTouchLists
|
||||
|
|
@ -281,8 +271,7 @@ public:
|
|||
sector_t *Sector;
|
||||
FLevelLocals *Level;
|
||||
TObjPtr<AActor *> target;
|
||||
FLightNode * touching_sides;
|
||||
FLightNode * touching_sector;
|
||||
|
||||
float radius; // The maximum size the light can be with its current settings.
|
||||
float m_currentRadius; // The current light size.
|
||||
int m_tickCount;
|
||||
|
|
|
|||
|
|
@ -241,46 +241,48 @@ namespace swrenderer
|
|||
|
||||
drawerargs.dc_num_lights = 0;
|
||||
|
||||
// Setup lights for column
|
||||
FLightNode* cur_node = drawerargs.LightList();
|
||||
while (cur_node)
|
||||
if(drawerargs.LightList())
|
||||
{
|
||||
if (cur_node->lightsource->IsActive())
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Iterator it(*drawerargs.LightList());
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Pair *pair;
|
||||
while (it.NextPair(pair))
|
||||
{
|
||||
double lightX = cur_node->lightsource->X() - wallargs.ViewpointPos.X;
|
||||
double lightY = cur_node->lightsource->Y() - wallargs.ViewpointPos.Y;
|
||||
double lightZ = cur_node->lightsource->Z() - wallargs.ViewpointPos.Z;
|
||||
|
||||
float lx = (float)(lightX * wallargs.Sin - lightY * wallargs.Cos) - drawerargs.dc_viewpos.X;
|
||||
float ly = (float)(lightX * wallargs.TanCos + lightY * wallargs.TanSin) - drawerargs.dc_viewpos.Y;
|
||||
float lz = (float)lightZ;
|
||||
|
||||
// Precalculate the constant part of the dot here so the drawer doesn't have to.
|
||||
bool is_point_light = cur_node->lightsource->IsAttenuated();
|
||||
float lconstant = lx * lx + ly * ly;
|
||||
float nlconstant = is_point_light ? lx * drawerargs.dc_normal.X + ly * drawerargs.dc_normal.Y : 0.0f;
|
||||
|
||||
// Include light only if it touches this column
|
||||
float radius = cur_node->lightsource->GetRadius();
|
||||
if (radius * radius >= lconstant && nlconstant >= 0.0f)
|
||||
auto cur_node = pair->Value.get();
|
||||
if (cur_node->lightsource->IsActive())
|
||||
{
|
||||
uint32_t red = cur_node->lightsource->GetRed();
|
||||
uint32_t green = cur_node->lightsource->GetGreen();
|
||||
uint32_t blue = cur_node->lightsource->GetBlue();
|
||||
double lightX = cur_node->lightsource->X() - wallargs.ViewpointPos.X;
|
||||
double lightY = cur_node->lightsource->Y() - wallargs.ViewpointPos.Y;
|
||||
double lightZ = cur_node->lightsource->Z() - wallargs.ViewpointPos.Z;
|
||||
|
||||
auto& light = drawerargs.dc_lights[drawerargs.dc_num_lights++];
|
||||
light.x = lconstant;
|
||||
light.y = nlconstant;
|
||||
light.z = lz;
|
||||
light.radius = 256.0f / cur_node->lightsource->GetRadius();
|
||||
light.color = (red << 16) | (green << 8) | blue;
|
||||
float lx = (float)(lightX * wallargs.Sin - lightY * wallargs.Cos) - drawerargs.dc_viewpos.X;
|
||||
float ly = (float)(lightX * wallargs.TanCos + lightY * wallargs.TanSin) - drawerargs.dc_viewpos.Y;
|
||||
float lz = (float)lightZ;
|
||||
|
||||
if (drawerargs.dc_num_lights == WallColumnDrawerArgs::MAX_DRAWER_LIGHTS)
|
||||
break;
|
||||
// Precalculate the constant part of the dot here so the drawer doesn't have to.
|
||||
bool is_point_light = cur_node->lightsource->IsAttenuated();
|
||||
float lconstant = lx * lx + ly * ly;
|
||||
float nlconstant = is_point_light ? lx * drawerargs.dc_normal.X + ly * drawerargs.dc_normal.Y : 0.0f;
|
||||
|
||||
// Include light only if it touches this column
|
||||
float radius = cur_node->lightsource->GetRadius();
|
||||
if (radius * radius >= lconstant && nlconstant >= 0.0f)
|
||||
{
|
||||
uint32_t red = cur_node->lightsource->GetRed();
|
||||
uint32_t green = cur_node->lightsource->GetGreen();
|
||||
uint32_t blue = cur_node->lightsource->GetBlue();
|
||||
|
||||
auto& light = drawerargs.dc_lights[drawerargs.dc_num_lights++];
|
||||
light.x = lconstant;
|
||||
light.y = nlconstant;
|
||||
light.z = lz;
|
||||
light.radius = 256.0f / cur_node->lightsource->GetRadius();
|
||||
light.color = (red << 16) | (green << 8) | blue;
|
||||
|
||||
if (drawerargs.dc_num_lights == WallColumnDrawerArgs::MAX_DRAWER_LIGHTS)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cur_node = cur_node->nextLight;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ namespace swrenderer
|
|||
ShadeConstants ColormapConstants() const { return wallargs->ColormapConstants(); }
|
||||
fixed_t Light() const { return LIGHTSCALE(mLight, mShade); }
|
||||
|
||||
FLightNode* LightList() const { return wallargs->lightlist; }
|
||||
TMap<FDynamicLight*, std::unique_ptr<FLightNode>>* LightList() const { return wallargs->lightlist; }
|
||||
|
||||
const WallDrawerArgs* wallargs;
|
||||
|
||||
|
|
|
|||
|
|
@ -207,60 +207,23 @@ namespace swrenderer
|
|||
drawerargs.DrawWall(Thread);
|
||||
}
|
||||
|
||||
FLightNode* RenderWallPart::GetLightList()
|
||||
TMap<FDynamicLight*, std::unique_ptr<FLightNode>>* RenderWallPart::GetLightList()
|
||||
{
|
||||
while (light_list)
|
||||
{
|
||||
// Clear out the wall part light list
|
||||
FLightNode *next = nullptr;
|
||||
if (light_list->nextLight) next = light_list->nextLight;
|
||||
delete light_list;
|
||||
if (next) light_list = next;
|
||||
}
|
||||
|
||||
CameraLight* cameraLight = CameraLight::Instance();
|
||||
if ((cameraLight->FixedLightLevel() >= 0) || cameraLight->FixedColormap())
|
||||
{
|
||||
return nullptr; // [SP] Don't draw dynlights if invul/lightamp active
|
||||
}
|
||||
else if (curline && curline->sidedef)
|
||||
{
|
||||
auto Level = curline->Subsector->sector->Level;
|
||||
|
||||
if (Level->lightlists.wall_dlist.SSize() > curline->sidedef->Index())
|
||||
{
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Iterator it(Level->lightlists.wall_dlist[curline->sidedef->Index()]);
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Pair *pair;
|
||||
while (it.NextPair(pair))
|
||||
{
|
||||
auto node = pair->Value.get();
|
||||
if (!node) continue;
|
||||
|
||||
if (node->lightsource->IsActive())
|
||||
{
|
||||
bool found = false;
|
||||
FLightNode *light_node = light_list;
|
||||
while (light_node)
|
||||
{
|
||||
if (light_node->lightsource == node->lightsource)
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
light_node = light_node->nextLight;
|
||||
}
|
||||
if (!found)
|
||||
{
|
||||
FLightNode *newlight = new FLightNode;
|
||||
newlight->nextLight = light_list;
|
||||
newlight->lightsource = node->lightsource;
|
||||
light_list = newlight;
|
||||
}
|
||||
}
|
||||
}
|
||||
return &Level->lightlists.wall_dlist[curline->sidedef->Index()];
|
||||
}
|
||||
|
||||
return light_list;
|
||||
}
|
||||
else
|
||||
return nullptr;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ namespace swrenderer
|
|||
private:
|
||||
void ProcessStripedWall(const short *uwal, const short *dwal, const ProjectedWallTexcoords& texcoords);
|
||||
void ProcessNormalWall(const short *uwal, const short *dwal, const ProjectedWallTexcoords& texcoords);
|
||||
FLightNode* GetLightList();
|
||||
TMap<FDynamicLight*, std::unique_ptr<FLightNode>>* GetLightList();
|
||||
|
||||
RenderThread* Thread = nullptr;
|
||||
|
||||
|
|
@ -76,7 +76,7 @@ namespace swrenderer
|
|||
|
||||
ProjectedWallLight mLight;
|
||||
|
||||
FLightNode *light_list = nullptr;
|
||||
TMap<FDynamicLight*, std::unique_ptr<FLightNode>> *light_list = nullptr;
|
||||
bool mask = false;
|
||||
bool additive = false;
|
||||
fixed_t alpha = 0;
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ namespace swrenderer
|
|||
short* dwal;
|
||||
FWallCoords WallC;
|
||||
ProjectedWallTexcoords texcoords;
|
||||
FLightNode* lightlist = nullptr;
|
||||
TMap<FDynamicLight*, std::unique_ptr<FLightNode>>* lightlist = nullptr;
|
||||
|
||||
float lightpos;
|
||||
float lightstep;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue