mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-28 15:02:01 +00:00
- added some checks to exclude dynamic lights from being subjected to shadowmapping if they do not touch any one-sided lines from the back side. This condition is a requirement for a 1D shadowmap to even have an effect.
This commit is contained in:
parent
0721aef218
commit
1031481167
4 changed files with 50 additions and 21 deletions
|
@ -568,6 +568,7 @@ void ADynamicLight::CollectWithinRadius(const DVector3 &opos, subsector_t *subSe
|
||||||
collected_ss.Push({ subSec, opos });
|
collected_ss.Push({ subSec, opos });
|
||||||
subSec->validcount = ::validcount;
|
subSec->validcount = ::validcount;
|
||||||
|
|
||||||
|
bool hitonesidedback = false;
|
||||||
for (unsigned i = 0; i < collected_ss.Size(); i++)
|
for (unsigned i = 0; i < collected_ss.Size(); i++)
|
||||||
{
|
{
|
||||||
subSec = collected_ss[i].sub;
|
subSec = collected_ss[i].sub;
|
||||||
|
@ -596,6 +597,10 @@ void ADynamicLight::CollectWithinRadius(const DVector3 &opos, subsector_t *subSe
|
||||||
seg->linedef->validcount = validcount;
|
seg->linedef->validcount = validcount;
|
||||||
touching_sides = AddLightNode(&seg->sidedef->lighthead, seg->sidedef, this, touching_sides);
|
touching_sides = AddLightNode(&seg->sidedef->lighthead, seg->sidedef, this, touching_sides);
|
||||||
}
|
}
|
||||||
|
else if (seg->linedef->sidedef[0] == seg->sidedef && seg->linedef->sidedef[1] == nullptr)
|
||||||
|
{
|
||||||
|
hitonesidedback = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (seg->linedef)
|
if (seg->linedef)
|
||||||
{
|
{
|
||||||
|
@ -657,6 +662,7 @@ void ADynamicLight::CollectWithinRadius(const DVector3 &opos, subsector_t *subSe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
shadowmapped = hitonesidedback && !(flags4 & MF4_NOSHADOWMAP);
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -758,6 +764,7 @@ void ADynamicLight::UnlinkLight ()
|
||||||
while (touching_sides) touching_sides = DeleteLightNode(touching_sides);
|
while (touching_sides) touching_sides = DeleteLightNode(touching_sides);
|
||||||
while (touching_subsectors) touching_subsectors = DeleteLightNode(touching_subsectors);
|
while (touching_subsectors) touching_subsectors = DeleteLightNode(touching_subsectors);
|
||||||
while (touching_sector) touching_sector = DeleteLightNode(touching_sector);
|
while (touching_sector) touching_sector = DeleteLightNode(touching_sector);
|
||||||
|
shadowmapped = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ADynamicLight::OnDestroy()
|
void ADynamicLight::OnDestroy()
|
||||||
|
@ -771,7 +778,7 @@ CCMD(listlights)
|
||||||
{
|
{
|
||||||
int walls, sectors, subsecs;
|
int walls, sectors, subsecs;
|
||||||
int allwalls=0, allsectors=0, allsubsecs = 0;
|
int allwalls=0, allsectors=0, allsubsecs = 0;
|
||||||
int i=0;
|
int i=0, shadowcount = 0;
|
||||||
ADynamicLight * dl;
|
ADynamicLight * dl;
|
||||||
TThinkerIterator<ADynamicLight> it;
|
TThinkerIterator<ADynamicLight> it;
|
||||||
|
|
||||||
|
@ -780,11 +787,12 @@ CCMD(listlights)
|
||||||
walls=0;
|
walls=0;
|
||||||
sectors=0;
|
sectors=0;
|
||||||
subsecs = 0;
|
subsecs = 0;
|
||||||
Printf("%s at (%f, %f, %f), color = 0x%02x%02x%02x, radius = %f %s",
|
Printf("%s at (%f, %f, %f), color = 0x%02x%02x%02x, radius = %f %s %s",
|
||||||
dl->target? dl->target->GetClass()->TypeName.GetChars() : dl->GetClass()->TypeName.GetChars(),
|
dl->target? dl->target->GetClass()->TypeName.GetChars() : dl->GetClass()->TypeName.GetChars(),
|
||||||
dl->X(), dl->Y(), dl->Z(), dl->args[LIGHT_RED],
|
dl->X(), dl->Y(), dl->Z(), dl->args[LIGHT_RED],
|
||||||
dl->args[LIGHT_GREEN], dl->args[LIGHT_BLUE], dl->radius, (dl->flags4 & MF4_ATTENUATE)? "attenuated" : "");
|
dl->args[LIGHT_GREEN], dl->args[LIGHT_BLUE], dl->radius, (dl->flags4 & MF4_ATTENUATE)? "attenuated" : "", dl->shadowmapped? "shadowmapped" : "");
|
||||||
i++;
|
i++;
|
||||||
|
shadowcount += dl->shadowmapped;
|
||||||
|
|
||||||
if (dl->target)
|
if (dl->target)
|
||||||
{
|
{
|
||||||
|
@ -824,7 +832,7 @@ CCMD(listlights)
|
||||||
Printf("- %d walls, %d subsectors, %d sectors\n", walls, subsecs, sectors);
|
Printf("- %d walls, %d subsectors, %d sectors\n", walls, subsecs, sectors);
|
||||||
|
|
||||||
}
|
}
|
||||||
Printf("%i dynamic lights, %d walls, %d subsectors, %d sectors\n\n\n", i, allwalls, allsubsecs, allsectors);
|
Printf("%i dynamic lights, %d shadowmapped, %d walls, %d subsectors, %d sectors\n\n\n", i, shadowcount, allwalls, allsubsecs, allsectors);
|
||||||
}
|
}
|
||||||
|
|
||||||
CCMD(listsublights)
|
CCMD(listsublights)
|
||||||
|
|
|
@ -21,11 +21,12 @@ enum
|
||||||
LIGHT_SCALE = 3,
|
LIGHT_SCALE = 3,
|
||||||
};
|
};
|
||||||
|
|
||||||
// This is as good as something new - and it can be set directly in the ActorInfo!
|
// This is as good as something new
|
||||||
#define MF4_SUBTRACTIVE MF4_MISSILEEVENMORE
|
#define MF4_SUBTRACTIVE MF4_MISSILEEVENMORE
|
||||||
#define MF4_ADDITIVE MF4_MISSILEMORE
|
#define MF4_ADDITIVE MF4_MISSILEMORE
|
||||||
#define MF4_DONTLIGHTSELF MF4_SEESDAGGERS
|
#define MF4_DONTLIGHTSELF MF4_SEESDAGGERS
|
||||||
#define MF4_ATTENUATE MF4_INCOMBAT
|
#define MF4_ATTENUATE MF4_INCOMBAT
|
||||||
|
#define MF4_NOSHADOWMAP MF4_STANDSTILL
|
||||||
|
|
||||||
enum ELightType
|
enum ELightType
|
||||||
{
|
{
|
||||||
|
@ -117,6 +118,7 @@ public:
|
||||||
uint8_t color2[3];
|
uint8_t color2[3];
|
||||||
bool visibletoplayer;
|
bool visibletoplayer;
|
||||||
bool swapped;
|
bool swapped;
|
||||||
|
bool shadowmapped;
|
||||||
int bufferindex;
|
int bufferindex;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -116,35 +116,43 @@ bool FShadowMap::IsEnabled() const
|
||||||
int FShadowMap::ShadowMapIndex(ADynamicLight *light)
|
int FShadowMap::ShadowMapIndex(ADynamicLight *light)
|
||||||
{
|
{
|
||||||
if (IsEnabled())
|
if (IsEnabled())
|
||||||
return mLightToShadowmap[light];
|
{
|
||||||
else
|
auto val = mLightToShadowmap.CheckKey(light);
|
||||||
return 1024;
|
if (val != nullptr) return *val;
|
||||||
|
}
|
||||||
|
return 1024;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FShadowMap::UploadLights()
|
void FShadowMap::UploadLights()
|
||||||
{
|
{
|
||||||
mLights.Clear();
|
if (mLights.Size() != 1024 * 4) mLights.Resize(1024 * 4);
|
||||||
|
int lightindex = 0;
|
||||||
mLightToShadowmap.Clear(mLightToShadowmap.CountUsed() * 2); // To do: allow clearing a TMap while building up a reserve
|
mLightToShadowmap.Clear(mLightToShadowmap.CountUsed() * 2); // To do: allow clearing a TMap while building up a reserve
|
||||||
|
|
||||||
|
// Todo: this should go through the blockmap in a spiral pattern around the player so that closer lights are preferred.
|
||||||
TThinkerIterator<ADynamicLight> it(STAT_DLIGHT);
|
TThinkerIterator<ADynamicLight> it(STAT_DLIGHT);
|
||||||
while (true)
|
while (auto light = it.Next())
|
||||||
{
|
{
|
||||||
ADynamicLight *light = it.Next();
|
if (light->shadowmapped)
|
||||||
if (!light) break;
|
{
|
||||||
|
mLightToShadowmap[light] = lightindex >> 2;
|
||||||
|
|
||||||
mLightToShadowmap[light] = mLights.Size() / 4;
|
mLights[lightindex] = light->X();
|
||||||
|
mLights[lightindex+1] = light->Y();
|
||||||
|
mLights[lightindex+2] = light->Z();
|
||||||
|
mLights[lightindex+3] = light->GetRadius();
|
||||||
|
lightindex += 4;
|
||||||
|
|
||||||
mLights.Push(light->X());
|
if (lightindex == 1024*4) // Only 1024 lights for now
|
||||||
mLights.Push(light->Y());
|
break;
|
||||||
mLights.Push(light->Z());
|
}
|
||||||
mLights.Push(light->GetRadius());
|
|
||||||
|
|
||||||
if (mLights.Size() == 1024) // Only 1024 lights for now
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while (mLights.Size() < 1024 * 4)
|
for (; lightindex < 1024 * 4; lightindex++)
|
||||||
mLights.Push(0.0f);
|
{
|
||||||
|
mLights[lightindex] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (mLightList == 0)
|
if (mLightList == 0)
|
||||||
glGenBuffers(1, (GLuint*)&mLightList);
|
glGenBuffers(1, (GLuint*)&mLightList);
|
||||||
|
|
|
@ -60,6 +60,7 @@
|
||||||
#include "r_data/sprites.h"
|
#include "r_data/sprites.h"
|
||||||
#include "serializer.h"
|
#include "serializer.h"
|
||||||
#include "wi_stuff.h"
|
#include "wi_stuff.h"
|
||||||
|
#include "a_dynlight.h"
|
||||||
|
|
||||||
static TArray<FPropertyInfo*> properties;
|
static TArray<FPropertyInfo*> properties;
|
||||||
static TArray<AFuncDesc> AFTable;
|
static TArray<AFuncDesc> AFTable;
|
||||||
|
@ -479,6 +480,16 @@ static FFlagDef PlayerPawnFlagDefs[] =
|
||||||
DEFINE_FLAG(PPF, CROUCHABLEMORPH, APlayerPawn, PlayerFlags),
|
DEFINE_FLAG(PPF, CROUCHABLEMORPH, APlayerPawn, PlayerFlags),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static FFlagDef DynLightFlagDefs[] =
|
||||||
|
{
|
||||||
|
// PlayerPawn flags
|
||||||
|
DEFINE_FLAG(MF4, SUBTRACTIVE, ADynamicLight, flags4),
|
||||||
|
DEFINE_FLAG(MF4, ADDITIVE, ADynamicLight, flags4),
|
||||||
|
DEFINE_FLAG(MF4, DONTLIGHTSELF, ADynamicLight, flags4),
|
||||||
|
DEFINE_FLAG(MF4, ATTENUATE, ADynamicLight, flags4),
|
||||||
|
DEFINE_FLAG(MF4, NOSHADOWMAP, ADynamicLight, flags4),
|
||||||
|
};
|
||||||
|
|
||||||
static FFlagDef PowerSpeedFlagDefs[] =
|
static FFlagDef PowerSpeedFlagDefs[] =
|
||||||
{
|
{
|
||||||
// PowerSpeed flags
|
// PowerSpeed flags
|
||||||
|
|
Loading…
Reference in a new issue