Merge remote-tracking branch 'gzdoom/master' into big_beautiful_merge
This commit is contained in:
commit
3fdd22ef91
1433 changed files with 484787 additions and 9566 deletions
|
|
@ -296,7 +296,7 @@ DoomLevelMesh::DoomLevelMesh(FLevelLocals& doomMap)
|
|||
// Collect all the models we want to bake into the level mesh
|
||||
if (lm_models)
|
||||
{
|
||||
TThinkerIterator<AActor> it(&doomMap, PClass::FindClass("Actor"), STAT_STATIC, true);
|
||||
TThinkerIterator<AActor> it(&doomMap, PClass::FindClass("Actor"), STAT_STATIC, FThinkerIteratorMode::forceSearch);
|
||||
AActor* thing;
|
||||
while ((thing = it.Next()) != nullptr)
|
||||
{
|
||||
|
|
@ -650,7 +650,9 @@ 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
|
||||
}
|
||||
|
||||
for (const HWDecalCreateInfo& info : decals)
|
||||
|
|
@ -1046,7 +1048,7 @@ void DoomLevelMesh::UpdateLightShadows(sector_t* sector)
|
|||
{
|
||||
for (FSection& section : level.sections.SectionsForSector(sector))
|
||||
{
|
||||
int lightcount = 0;
|
||||
#ifdef NEEDS_BIG_BEAUTIFUL_MERGE_PORTING
|
||||
FLightNode* cur = section.lighthead;
|
||||
while (cur)
|
||||
{
|
||||
|
|
@ -1057,6 +1059,7 @@ void DoomLevelMesh::UpdateLightShadows(sector_t* sector)
|
|||
}
|
||||
cur = cur->nextLight;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1182,12 +1185,16 @@ 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
|
||||
}
|
||||
else
|
||||
{
|
||||
FreeLightList(sideBlock.Lights.Start, sideBlock.Lights.Count);
|
||||
#ifdef NEEDS_BIG_BEAUTIFUL_MERGE_PORTING
|
||||
sideBlock.Lights = CreateLightList(side->lighthead, side->sector->PortalGroup);
|
||||
#endif
|
||||
}
|
||||
|
||||
int surf = Sides[sideIndex].FirstSurface;
|
||||
|
|
@ -1215,7 +1222,9 @@ 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
|
||||
}
|
||||
|
||||
int surf = Flats[sectorIndex].FirstSurface;
|
||||
|
|
@ -1373,7 +1382,9 @@ 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
|
||||
lightlistCreated = true;
|
||||
}
|
||||
|
||||
|
|
@ -1388,7 +1399,9 @@ void DoomLevelMesh::CreateSide(FLevelLocals& doomMap, unsigned int sideIndex)
|
|||
}
|
||||
else
|
||||
{
|
||||
#ifdef NEEDS_BIG_BEAUTIFUL_MERGE_PORTING
|
||||
sideBlock.Lights = CreateLightList(side->lighthead, side->sector->PortalGroup);
|
||||
#endif
|
||||
|
||||
subsector_t* sub = seg->Subsector;
|
||||
sector_t* front = side->sector;
|
||||
|
|
@ -1480,7 +1493,11 @@ 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
|
||||
const auto& lightlist = Flats[sectorIndex].Lights.Last();
|
||||
|
||||
HWFlatMeshHelper result;
|
||||
|
|
|
|||
|
|
@ -321,7 +321,7 @@ void HWDrawInfo::AddLine (seg_t *seg, bool portalclip, FRenderState& state)
|
|||
{
|
||||
if (!(currentsubsector->flags & SSECMF_DRAWN))
|
||||
{
|
||||
if (clipper.SafeCheckRange(startAngle, endAngle) && (!r_radarclipper || (Level->flags3 & LEVEL3_NOFOGOFWAR)))
|
||||
if (clipper.SafeCheckRange(startAngle, endAngle) && !Viewpoint.IsAllowedOoB())
|
||||
{
|
||||
currentsubsector->flags |= SSECMF_DRAWN;
|
||||
}
|
||||
|
|
@ -338,7 +338,7 @@ void HWDrawInfo::AddLine (seg_t *seg, bool portalclip, FRenderState& state)
|
|||
return;
|
||||
}
|
||||
|
||||
if (Viewpoint.IsAllowedOoB() && (!r_radarclipper || (Level->flags3 & LEVEL3_NOFOGOFWAR) || clipperr.SafeCheckRange(startAngleR, endAngleR)))
|
||||
if (!Viewpoint.IsAllowedOoB() || (!r_radarclipper || (Level->flags3 & LEVEL3_NOFOGOFWAR) || clipperr.SafeCheckRange(startAngleR, endAngleR)))
|
||||
currentsubsector->flags |= SSECMF_DRAWN;
|
||||
|
||||
uint8_t ispoly = uint8_t(seg->sidedef->Flags & WALLF_POLYOBJ);
|
||||
|
|
|
|||
|
|
@ -141,6 +141,8 @@ void HWDrawInfo::StartScene(FRenderViewpoint &parentvp, HWViewpointUniforms *uni
|
|||
VPUniforms.SunDir = FVector3(level.SunDirection.X, level.SunDirection.Z, level.SunDirection.Y);
|
||||
VPUniforms.SunColor = level.SunColor;
|
||||
VPUniforms.SunIntensity = level.SunIntensity;
|
||||
VPUniforms.mThickFogDistance = Level->thickfogdistance;
|
||||
VPUniforms.mThickFogMultiplier = Level->thickfogmultiplier;
|
||||
}
|
||||
mClipper->SetViewpoint(Viewpoint);
|
||||
vClipper->SetViewpoint(Viewpoint);
|
||||
|
|
@ -1139,17 +1141,6 @@ void HWDrawInfo::DrawCorona(FRenderState& state, AActor* corona, float coronaFad
|
|||
state.Draw(DT_TriangleStrip, vertexindex, 4);
|
||||
}
|
||||
|
||||
static ETraceStatus CheckForViewpointActor(FTraceResults& res, void* userdata)
|
||||
{
|
||||
FRenderViewpoint* data = (FRenderViewpoint*)userdata;
|
||||
if (res.HitType == TRACE_HitActor && res.Actor && res.Actor == data->ViewActor)
|
||||
{
|
||||
return TRACE_Skip;
|
||||
}
|
||||
|
||||
return TRACE_Stop;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// TraceCallbackForDitherTransparency
|
||||
|
|
@ -1189,7 +1180,7 @@ static ETraceStatus TraceCallbackForDitherTransparency(FTraceResults& res, void*
|
|||
res.Line->sidedef[res.Side]->dithertranscount = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case TRACE_HitFloor:
|
||||
if (res.Sector->subsectorcount > 0 && (*CurMapSections)[res.Sector->subsectors[0]->mapsection] && res.HitVector.dot(res.Sector->floorplane.Normal()) < 0.0)
|
||||
|
|
@ -1298,6 +1289,16 @@ void HWDrawInfo::SetDitherTransFlags(AActor* actor)
|
|||
}
|
||||
}
|
||||
|
||||
static ETraceStatus CheckForViewpointActor(FTraceResults& res, void* userdata)
|
||||
{
|
||||
FRenderViewpoint* data = (FRenderViewpoint*)userdata;
|
||||
if (res.HitType == TRACE_HitActor && res.Actor && res.Actor == data->ViewActor)
|
||||
{
|
||||
return TRACE_Skip;
|
||||
}
|
||||
|
||||
return TRACE_Stop;
|
||||
}
|
||||
|
||||
void HWDrawInfo::DrawCoronas(FRenderState& state)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -287,8 +287,10 @@ struct HWDrawInfo
|
|||
void AddSpecialPortalLines(subsector_t * sub, sector_t * sector, linebase_t *line);
|
||||
public:
|
||||
void DoSubsector(subsector_t * sub);
|
||||
void DrawPSprite(HUDSprite* huds, FRenderState& state);
|
||||
WeaponLighting GetWeaponLighting(sector_t* viewsector, const DVector3& pos, int cm, area_t in_area, const DVector3& playerpos);
|
||||
int SetupLightsForOtherPlane(subsector_t * sub, FDynLightData &lightdata, const secplane_t *plane);
|
||||
int CreateOtherPlaneVertices(subsector_t *sub, const secplane_t *plane);
|
||||
void DrawPSprite(HUDSprite *huds, FRenderState &state);
|
||||
WeaponLighting GetWeaponLighting(sector_t *viewsector, const DVector3 &pos, int cm, area_t in_area, const DVector3 &playerpos, bool weaponPureLightLevel);
|
||||
|
||||
void PreparePlayerSprites2D(sector_t* viewsector, area_t in_area, FRenderState& state);
|
||||
void PreparePlayerSprites3D(sector_t* viewsector, area_t in_area, FRenderState& state);
|
||||
|
|
@ -413,7 +415,7 @@ public:
|
|||
void AddOtherFloorPlane(int sector, gl_subsectorrendernode * node, FRenderState& state);
|
||||
void AddOtherCeilingPlane(int sector, gl_subsectorrendernode * node, FRenderState& state);
|
||||
|
||||
void GetDynSpriteLight(AActor *self, sun_trace_cache_t * traceCache, double x, double y, double z, FLightNode *node, int portalgroup, float *out, bool fullbright);
|
||||
void GetDynSpriteLight(AActor *self, sun_trace_cache_t * traceCache, double x, double y, double z, FSection *sec, int portalgroup, float *out, bool fullbright);
|
||||
void GetDynSpriteLight(AActor *thing, particle_t *particle, sun_trace_cache_t * traceCache, float *out);
|
||||
|
||||
void GetDynSpriteLightList(AActor *self, double x, double y, double z, sun_trace_cache_t * traceCache, FDynLightData &modellightdata, bool isModel);
|
||||
|
|
@ -503,7 +505,7 @@ inline bool isDarkLightMode(ELightMode lightmode)
|
|||
return lightmode == ELightMode::Doom || lightmode == ELightMode::DoomDark;
|
||||
}
|
||||
|
||||
int CalcLightLevel(ELightMode lightmode, int lightlevel, int rellight, bool weapon, int blendfactor);
|
||||
int CalcLightLevel(ELightMode lightmode, int lightlevel, int rellight, bool weapon, int blendfactor, bool weaponPureLightLevel = false);
|
||||
PalEntry CalcLightColor(ELightMode lightmode, int light, PalEntry pe, int blendfactor);
|
||||
float GetFogDensity(FLevelLocals* Level, ELightMode lightmode, int lightlevel, PalEntry fogcolor, int sectorfogdensity, int blendfactor);
|
||||
bool CheckFog(FLevelLocals* Level, sector_t* frontsector, sector_t* backsector, ELightMode lightmode);
|
||||
|
|
|
|||
|
|
@ -345,7 +345,7 @@ public:
|
|||
bool stack;
|
||||
bool ceiling;
|
||||
uint8_t renderflags;
|
||||
uint8_t hacktype;
|
||||
uint8_t hacktype;
|
||||
int iboindex;
|
||||
//int vboheight;
|
||||
|
||||
|
|
@ -354,7 +354,7 @@ public:
|
|||
F3DFloor* controlsector;
|
||||
|
||||
void CreateSkyboxVertices(FFlatVertex *buffer);
|
||||
void SetupLights(HWFlatDispatcher *di, FRenderState& state, FLightNode *head, FDynLightData &lightdata, int portalgroup);
|
||||
void SetupLights(HWFlatDispatcher *di, FRenderState& state, FDynLightData &lightdata, int portalgroup);
|
||||
|
||||
void PutFlat(HWFlatDispatcher *di, bool fog = false);
|
||||
void Process(HWFlatDispatcher *di, FRenderState& state, sector_t * model, int whichplane, bool notexture);
|
||||
|
|
@ -364,8 +364,8 @@ public:
|
|||
void DrawSubsectors(HWFlatDispatcher *di, FRenderState &state);
|
||||
void DrawFlat(HWFlatDispatcher *di, FRenderState &state, bool translucent);
|
||||
|
||||
void DrawOtherPlanes(HWDrawInfo *di, FRenderState &state);
|
||||
void DrawFloodPlanes(HWDrawInfo *di, FRenderState &state);
|
||||
void DrawOtherPlanes(HWDrawInfo *di, FRenderState &state);
|
||||
void DrawFloodPlanes(HWDrawInfo *di, FRenderState &state);
|
||||
};
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
|||
|
|
@ -159,7 +159,7 @@ void HWFlat::CreateSkyboxVertices(FFlatVertex *vert)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void HWFlat::SetupLights(HWFlatDispatcher *di, FRenderState& state, FLightNode * node, FDynLightData &lightdata, int portalgroup)
|
||||
void HWFlat::SetupLights(HWFlatDispatcher *di, FRenderState& state, FDynLightData &lightdata, int portalgroup)
|
||||
{
|
||||
if (!di->di)
|
||||
{
|
||||
|
|
@ -175,29 +175,37 @@ void HWFlat::SetupLights(HWFlatDispatcher *di, FRenderState& state, FLightNode *
|
|||
dynlightindex = -1;
|
||||
return; // no lights on additively blended surfaces.
|
||||
}
|
||||
while (node)
|
||||
|
||||
auto flatLightList = di->Level->lightlists.flat_dlist.CheckKey(section);
|
||||
|
||||
if (flatLightList)
|
||||
{
|
||||
FDynamicLight * light = node->lightsource;
|
||||
|
||||
if (!light->IsActive() || light->DontLightMap())
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Iterator it(*flatLightList);
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Pair *pair;
|
||||
while (it.NextPair(pair))
|
||||
{
|
||||
node = node->nextLight;
|
||||
continue;
|
||||
}
|
||||
iter_dlightf++;
|
||||
auto node = pair->Value.get();
|
||||
if (!node) continue;
|
||||
|
||||
FDynamicLight * light = node->lightsource;
|
||||
|
||||
// we must do the side check here because gl_GetLight needs the correct plane orientation
|
||||
// which we don't have for Legacy-style 3D-floors
|
||||
double planeh = plane.plane.ZatPoint(light->Pos);
|
||||
if ((planeh<light->Z() && ceiling) || (planeh>light->Z() && !ceiling))
|
||||
{
|
||||
node = node->nextLight;
|
||||
continue;
|
||||
}
|
||||
if (!light->IsActive() || light->DontLightMap())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
iter_dlightf++;
|
||||
|
||||
p.Set(plane.plane.Normal(), plane.plane.fD());
|
||||
draw_dlightf += GetLight(lightdata, portalgroup, p, light, false);
|
||||
node = node->nextLight;
|
||||
// we must do the side check here because gl_GetLight needs the correct plane orientation
|
||||
// which we don't have for Legacy-style 3D-floors
|
||||
double planeh = plane.plane.ZatPoint(light->Pos);
|
||||
if ((planeh<light->Z() && ceiling) || (planeh>light->Z() && !ceiling))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
p.Set(plane.plane.Normal(), plane.plane.fD());
|
||||
draw_dlightf += GetLight(lightdata, portalgroup, p, light, false);
|
||||
}
|
||||
}
|
||||
|
||||
dynlightindex = state.UploadLights(lightdata);
|
||||
|
|
@ -213,7 +221,7 @@ void HWFlat::DrawSubsectors(HWFlatDispatcher *di, FRenderState &state)
|
|||
{
|
||||
if (di->Level->HasDynamicLights && !di->isFullbrightScene() && !lm_dynlights)
|
||||
{
|
||||
SetupLights(di, state, section->lighthead, lightdata, sector->PortalGroup);
|
||||
SetupLights(di, state, lightdata, sector->PortalGroup);
|
||||
}
|
||||
state.SetLightIndex(dynlightindex);
|
||||
state.DrawIndexed(DT_Triangles, iboindex + section->vertexindex, section->vertexcount);
|
||||
|
|
@ -329,8 +337,9 @@ void HWFlat::DrawFlat(HWFlatDispatcher *di, FRenderState &state, bool translucen
|
|||
|
||||
int rel = getExtraLight();
|
||||
|
||||
double zshift = (plane.plane.Normal().Z > 0.0 ? 0.1f : -0.1f); // The HWPlaneMirrorPortal::DrawPortalStencil() z-fights with flats
|
||||
|
||||
state.SetNormal(plane.plane.Normal().X, plane.plane.Normal().Z, plane.plane.Normal().Y);
|
||||
double zshift = (plane.plane.Normal().Z > 0.0 ? 0.01f : -0.01f); // The HWPlaneMirrorPortal::DrawPortalStencil() z-fights with flats
|
||||
state.SetLightProbeIndex(sector->lightProbe.index);
|
||||
|
||||
SetColor(state, di->Level, di->lightmode, lightlevel, rel, di->isFullbrightScene(), Colormap, alpha);
|
||||
|
|
@ -384,12 +393,12 @@ void HWFlat::DrawFlat(HWFlatDispatcher *di, FRenderState &state, bool translucen
|
|||
if (!texture->GetTranslucency()) state.AlphaFunc(Alpha_GEqual, gl_mask_threshold);
|
||||
else state.AlphaFunc(Alpha_GEqual, 0.f);
|
||||
state.SetMaterial(texture, UF_Texture, 0, CLAMP_NONE, NO_TRANSLATION, -1);
|
||||
|
||||
bool texmatrix = SetPlaneTextureRotation(state, &plane, texture);
|
||||
if (di->di) // dpjudas, gl_levelmesh could use zshift for reflective flats. - [DVR]
|
||||
if (di->di)
|
||||
{
|
||||
di->di->VPUniforms.mViewMatrix.translate(0.0, zshift, 0.0);
|
||||
di->di->vpIndex = state.SetViewpoint(di->di->VPUniforms);
|
||||
// screen->mViewpoints->SetViewpoint(state, &di->di->VPUniforms);
|
||||
}
|
||||
DrawSubsectors(di, state);
|
||||
if (di->di)
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ CUSTOM_CVAR(Int, gl_distfog, 70, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
int CalcLightLevel(ELightMode lightmode, int lightlevel, int rellight, bool weapon, int blendfactor)
|
||||
int CalcLightLevel(ELightMode lightmode, int lightlevel, int rellight, bool weapon, int blendfactor, bool weaponPureLightLevel)
|
||||
{
|
||||
int light;
|
||||
|
||||
|
|
@ -84,7 +84,7 @@ int CalcLightLevel(ELightMode lightmode, int lightlevel, int rellight, bool weap
|
|||
|
||||
bool darklightmode = (isDarkLightMode(lightmode)) || (isSoftwareLighting(lightmode) && blendfactor > 0);
|
||||
|
||||
if (darklightmode && lightlevel < 192 && !weapon)
|
||||
if ((darklightmode && lightlevel < 192 && !weapon) || (weapon && weaponPureLightLevel))
|
||||
{
|
||||
if (lightlevel > 100)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -13,9 +13,9 @@ class FSkyBox;
|
|||
|
||||
struct HWSkyInfo
|
||||
{
|
||||
float x_offset[2];
|
||||
float x_offset[3];
|
||||
float y_offset; // doubleskies don't have a y-offset
|
||||
FGameTexture * texture[2];
|
||||
FGameTexture * texture[3];
|
||||
FTextureID skytexno1;
|
||||
bool mirrored;
|
||||
bool doublesky;
|
||||
|
|
@ -351,7 +351,6 @@ public:
|
|||
|
||||
};
|
||||
|
||||
|
||||
struct HWSkyPortal : public HWPortal
|
||||
{
|
||||
HWSkyInfo * origin;
|
||||
|
|
|
|||
|
|
@ -119,23 +119,30 @@ int HWDrawInfo::SetupLightsForOtherPlane(subsector_t * sub, FDynLightData &light
|
|||
{
|
||||
Plane p;
|
||||
|
||||
FLightNode * node = sub->section->lighthead;
|
||||
|
||||
lightdata.Clear();
|
||||
while (node)
|
||||
|
||||
auto flatLightList = Level->lightlists.flat_dlist.CheckKey(sub->section);
|
||||
|
||||
if (flatLightList)
|
||||
{
|
||||
FDynamicLight * light = node->lightsource;
|
||||
|
||||
if (!light->IsActive())
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Iterator it(*flatLightList);
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Pair *pair;
|
||||
while (it.NextPair(pair))
|
||||
{
|
||||
node = node->nextLight;
|
||||
continue;
|
||||
}
|
||||
iter_dlightf++;
|
||||
auto node = pair->Value.get();
|
||||
if (!node) continue;
|
||||
|
||||
p.Set(plane->Normal(), plane->fD());
|
||||
draw_dlightf += GetLight(lightdata, sub->sector->PortalGroup, p, light, true);
|
||||
node = node->nextLight;
|
||||
FDynamicLight * light = node->lightsource;
|
||||
|
||||
if (!light->IsActive())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
iter_dlightf++;
|
||||
|
||||
p.Set(plane->Normal(), plane->fD());
|
||||
draw_dlightf += GetLight(lightdata, sub->sector->PortalGroup, p, light, true);
|
||||
}
|
||||
}
|
||||
|
||||
return state.UploadLights(lightdata);
|
||||
|
|
|
|||
|
|
@ -118,6 +118,9 @@ void HWSkyInfo::init(HWDrawInfo *di, sector_t* sec, int skypos, int sky1, PalEnt
|
|||
}
|
||||
else fadecolor = 0;
|
||||
|
||||
texture[2] = TexMan.GetGameTexture(di->Level->skymisttexture, true);
|
||||
x_offset[2] = di->Level->hw_skymistpos;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -319,7 +322,7 @@ void HWWall::SkyTop(HWWallDispatcher *di, FRenderState& state, seg_t * seg,secto
|
|||
// float backreflect = bs->GetReflect(sector_t::ceiling);
|
||||
// if (backreflect > 0 && bs->ceilingplane.fD() == fs->ceilingplane.fD() && !bs->isClosed())
|
||||
// {
|
||||
// // Don't add intra-portal line to the portal.
|
||||
// Don't add intra-portal line to the portal.
|
||||
// if (!(di->di && di->di->Viewpoint.IsAllowedOoB()))
|
||||
// {
|
||||
// return;
|
||||
|
|
|
|||
|
|
@ -74,19 +74,26 @@ void HWSkyPortal::DrawContents(HWDrawInfo *di, FRenderState &state)
|
|||
vertexBuffer->RenderDome(state, origin->texture[0], origin->x_offset[0], origin->y_offset, origin->mirrored, FSkyVertexBuffer::SKYMODE_MAINLAYER, !!(di->Level->flags & LEVEL_FORCETILEDSKY));
|
||||
state.SetTextureMode(TM_NORMAL);
|
||||
}
|
||||
|
||||
|
||||
state.AlphaFunc(Alpha_Greater, 0.f);
|
||||
|
||||
if (origin->doublesky && origin->texture[1])
|
||||
{
|
||||
vertexBuffer->RenderDome(state, origin->texture[1], origin->x_offset[1], origin->y_offset, false, FSkyVertexBuffer::SKYMODE_SECONDLAYER, !!(di->Level->flags & LEVEL_FORCETILEDSKY));
|
||||
}
|
||||
}
|
||||
|
||||
if (di->Level->skyfog>0 && !di->isFullbrightScene() && (origin->fadecolor & 0xffffff) != 0)
|
||||
if (di->Level->skyfog>0 && (origin->fadecolor & 0xffffff) != 0)
|
||||
{
|
||||
PalEntry FadeColor = origin->fadecolor;
|
||||
FadeColor.a = clamp<int>(di->Level->skyfog, 0, 255);
|
||||
|
||||
if (di->Level->flags3 & LEVEL3_SKYMIST && origin->texture[2])
|
||||
{
|
||||
vertexBuffer->RenderDome(state, origin->texture[2], origin->x_offset[2], 0.f, false, FSkyVertexBuffer::SKYMODE_FOGLAYER, !!(di->Level->flags & LEVEL_FORCETILEDSKY), 0, 0, FadeColor);
|
||||
}
|
||||
else if (!di->isFullbrightScene())
|
||||
{
|
||||
PalEntry FadeColor = origin->fadecolor;
|
||||
FadeColor.a = clamp<int>(di->Level->skyfog, 0, 255);
|
||||
|
||||
state.EnableTexture(false);
|
||||
state.SetObjectColor(FadeColor);
|
||||
state.Draw(DT_Triangles, 0, 12);
|
||||
|
|
|
|||
|
|
@ -131,10 +131,8 @@ 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, FLightNode *node, 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)
|
||||
{
|
||||
if (fullbright || get_gl_spritelight() > 0)
|
||||
return;
|
||||
|
||||
FDynamicLight *light;
|
||||
float frac, lr, lg, lb;
|
||||
|
|
@ -142,6 +140,11 @@ void HWDrawInfo::GetDynSpriteLight(AActor *self, sun_trace_cache_t * traceCache,
|
|||
|
||||
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)))
|
||||
|
|
@ -157,22 +160,24 @@ void HWDrawInfo::GetDynSpriteLight(AActor *self, sun_trace_cache_t * traceCache,
|
|||
}
|
||||
|
||||
// Go through both light lists
|
||||
while (node)
|
||||
auto flatLightList = Level->lightlists.flat_dlist.CheckKey(sec);
|
||||
|
||||
if (flatLightList)
|
||||
{
|
||||
light=node->lightsource;
|
||||
if (light->ShouldLightActor(self))
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Iterator it(*flatLightList);
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Pair *pair;
|
||||
while (it.NextPair(pair))
|
||||
{
|
||||
float dist;
|
||||
FVector3 L;
|
||||
auto node = pair->Value.get();
|
||||
if (!node) continue;
|
||||
|
||||
// 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)
|
||||
light=node->lightsource;
|
||||
if (light->ShouldLightActor(self))
|
||||
{
|
||||
int fromgroup = light->Sector->PortalGroup;
|
||||
int togroup = portalgroup;
|
||||
if (fromgroup == togroup || fromgroup == 0 || togroup == 0) goto direct;
|
||||
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());
|
||||
}
|
||||
|
|
@ -221,6 +226,53 @@ void HWDrawInfo::GetDynSpriteLight(AActor *self, sun_trace_cache_t * traceCache,
|
|||
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)
|
||||
{
|
||||
int fromgroup = light->Sector->PortalGroup;
|
||||
int togroup = portalgroup;
|
||||
if (fromgroup == togroup || fromgroup == 0 || togroup == 0) goto direct;
|
||||
|
||||
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 (dist < radius * radius)
|
||||
{
|
||||
dist = sqrtf(dist); // only calculate the square root if we really need it.
|
||||
|
||||
frac = 1.0f - (dist / radius);
|
||||
|
||||
if (light->IsSpot())
|
||||
{
|
||||
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 }))))
|
||||
{
|
||||
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))
|
||||
{
|
||||
float alpha = (float)light->target->Alpha;
|
||||
|
|
@ -250,19 +302,19 @@ void HWDrawInfo::GetDynSpriteLight(AActor *self, sun_trace_cache_t * traceCache,
|
|||
}
|
||||
}
|
||||
}
|
||||
node = node->nextLight;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void HWDrawInfo::GetDynSpriteLight(AActor *thing, particle_t *particle, sun_trace_cache_t * traceCache, float *out)
|
||||
{
|
||||
if (thing)
|
||||
{
|
||||
GetDynSpriteLight(thing, &thing->StaticLightsTraceCache, thing->X(), thing->Y(), thing->Center(), thing->section->lighthead, thing->Sector->PortalGroup, out, (thing->flags5 & MF5_BRIGHT));
|
||||
GetDynSpriteLight(thing, &thing->StaticLightsTraceCache, thing->X(), thing->Y(), thing->Center(), thing->section, thing->Sector->PortalGroup, out, (thing->flags5 & MF5_BRIGHT));
|
||||
}
|
||||
else if (particle)
|
||||
{
|
||||
GetDynSpriteLight(nullptr, traceCache, particle->Pos.X, particle->Pos.Y, particle->Pos.Z, particle->subsector->section->lighthead, particle->subsector->sector->PortalGroup, out, (particle->flags & SPF_FULLBRIGHT));
|
||||
GetDynSpriteLight(nullptr, traceCache, particle->Pos.X, particle->Pos.Y, particle->Pos.Z, particle->subsector->section, particle->subsector->sector->PortalGroup, out, (particle->flags & SPF_FULLBRIGHT));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -271,6 +323,8 @@ 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;
|
||||
|
||||
|
|
@ -304,6 +358,7 @@ void HWDrawInfo::GetDynSpriteLightList(AActor *self, double x, double y, double
|
|||
FLightNode * node = section->lighthead;
|
||||
while (node) // check all lights touching a subsector
|
||||
{
|
||||
<<<<<<< HEAD
|
||||
FDynamicLight *light = node->lightsource;
|
||||
if (light->ShouldLightActor(self))
|
||||
{
|
||||
|
|
@ -327,6 +382,36 @@ void HWDrawInfo::GetDynSpriteLightList(AActor *self, double x, double y, double
|
|||
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
|
||||
{
|
||||
AddLightToList(modellightdata, group, light, true);
|
||||
addedLights.Push(light);
|
||||
}
|
||||
>>>>>>> gzdoom/master
|
||||
}
|
||||
|
||||
addedLights.Insert(index, light);
|
||||
|
|
@ -336,6 +421,7 @@ void HWDrawInfo::GetDynSpriteLightList(AActor *self, double x, double y, double
|
|||
node = node->nextLight;
|
||||
}
|
||||
});
|
||||
#endif
|
||||
}
|
||||
|
||||
void HWDrawInfo::GetDynSpriteLightList(AActor *thing, particle_t *particle, sun_trace_cache_t * traceCache, FDynLightData &modellightdata, bool isModel)
|
||||
|
|
|
|||
|
|
@ -509,11 +509,14 @@ bool HWSprite::CalculateVertices(HWDrawInfo* di, FVector3* v, DVector3* vp)
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// [DVR] +ANGLEDROLL
|
||||
const bool AngledRoll = (actor != nullptr && actor->renderflags2 & RF2_ANGLEDROLL);
|
||||
|
||||
// [BB] Billboard stuff
|
||||
const bool drawWithXYBillboard = ((particle && gl_billboard_particles && !(particle->flags & SPF_NO_XY_BILLBOARD)) || (!(actor && actor->renderflags & RF_FORCEYBILLBOARD)
|
||||
//&& di->mViewActor != nullptr
|
||||
&& (gl_billboard_mode == 1 || (actor && actor->renderflags & RF_FORCEXYBILLBOARD))));
|
||||
&& (gl_billboard_mode == 1 || (actor && actor->renderflags & RF_FORCEXYBILLBOARD)))) && !AngledRoll;
|
||||
|
||||
const bool drawBillboardFacingCamera = hw_force_cambbpref ? gl_billboard_faces_camera :
|
||||
gl_billboard_faces_camera
|
||||
|
|
@ -620,13 +623,31 @@ bool HWSprite::CalculateVertices(HWDrawInfo* di, FVector3* v, DVector3* vp)
|
|||
// Compute center of sprite
|
||||
float angleRad = (FAngle::fromDeg(270.) - HWAngles.Yaw).Radians();
|
||||
float rollDegrees = Angles.Roll.Degrees();
|
||||
float pitchDegrees = 0.0;
|
||||
|
||||
if (AngledRoll)
|
||||
{
|
||||
rollDegrees = fmodf(rollDegrees, 360.0f);
|
||||
DAngle ang = di->Viewpoint.Angles.Yaw + actor->Angles.Yaw + actor->AngledRollOffset - DAngle::fromDeg(90.0);
|
||||
angleRad = ang.Radians();
|
||||
FVector3 relPos = center - FVector3(di->Viewpoint.Pos);
|
||||
if (useOffsets) relPos += FVector3(xx, yy, zz);
|
||||
|
||||
Matrix3x4 rolltilt;
|
||||
rolltilt.MakeIdentity();
|
||||
ang = actor->Angles.Yaw + actor->AngledRollOffset;
|
||||
rolltilt.Rotate(ang.Cos(), ang.Sin(), 0.0, -rollDegrees);
|
||||
pitchDegrees = 270.0 - DVector3(rolltilt * relPos).Angle().Degrees();
|
||||
}
|
||||
|
||||
mat.Translate(center.X, center.Z, center.Y);
|
||||
mat.Scale(1.0, 1.0/pixelstretch, 1.0); // unstretch sprite by level aspect ratio
|
||||
if (useOffsets) mat.Translate(xx, zz, yy);
|
||||
mat.Scale(1.0, 1.0/pixelstretch, 1.0); // unstretch sprite by level aspect ratio
|
||||
if (AngledRoll) mat.Rotate(0.0, 1.0, 0.0, -HWAngles.Yaw.Degrees()); // Cancel regular Y-billboarding
|
||||
mat.Rotate(cos(angleRad), 0, sin(angleRad), rollDegrees);
|
||||
if (useOffsets) mat.Translate(-xx, -zz, -yy);
|
||||
if (AngledRoll) mat.Rotate(0.0, 1.0, 0.0, pitchDegrees); // New Y-billboarding about rolled z-axis
|
||||
mat.Scale(1.0, pixelstretch, 1.0); // stretch sprite by level aspect ratio
|
||||
if (useOffsets) mat.Translate(-xx, -zz, -yy);
|
||||
mat.Translate(-center.X, -center.Z, -center.Y);
|
||||
}
|
||||
|
||||
|
|
@ -898,7 +919,8 @@ void HWSprite::Process(HWDrawInfo *di, FRenderState& state, AActor* thing, secto
|
|||
const auto &vp = di->Viewpoint;
|
||||
AActor *camera = vp.camera;
|
||||
|
||||
if (thing->renderflags & RF_INVISIBLE || !thing->RenderStyle.IsVisible(thing->Alpha))
|
||||
const double alpha = thing->InterpolatedAlpha(vp.TicFrac);
|
||||
if (thing->renderflags & RF_INVISIBLE || !thing->RenderStyle.IsVisible(alpha))
|
||||
{
|
||||
if (!(thing->flags & MF_STEALTH) || !di->isStealthVision() || thing == camera)
|
||||
return;
|
||||
|
|
@ -911,7 +933,7 @@ void HWSprite::Process(HWDrawInfo *di, FRenderState& state, AActor* thing, secto
|
|||
return;
|
||||
|
||||
int spritenum = thing->sprite;
|
||||
DVector2 sprscale(thing->Scale.X, thing->Scale.Y);
|
||||
DVector2 sprscale = thing->InterpolatedScale(vp.TicFrac);
|
||||
if (thing->player != nullptr)
|
||||
{
|
||||
P_CheckPlayerSprite(thing, spritenum, sprscale);
|
||||
|
|
@ -1039,8 +1061,22 @@ void HWSprite::Process(HWDrawInfo *di, FRenderState& state, AActor* thing, secto
|
|||
if (!modelframe)
|
||||
{
|
||||
bool mirror = false;
|
||||
bool backfaced = false;
|
||||
DAngle ang = (thingpos - vp.Pos).Angle();
|
||||
if (di->Viewpoint.IsOrtho()) ang = vp.Angles.Yaw;
|
||||
else if (actor && thing->renderflags2 & RF2_ANGLEDROLL)
|
||||
{
|
||||
Matrix3x4 rolltilt;
|
||||
rolltilt.MakeIdentity();
|
||||
DAngle tempang = thing->Angles.Yaw + thing->AngledRollOffset;
|
||||
rolltilt.Rotate(tempang.Cos(), tempang.Sin(), 0.0, -thing->Angles.Roll.Degrees());
|
||||
tempang = DVector3(rolltilt * FVector3(thingpos - vp.Pos)).Angle();
|
||||
backfaced = fabs((ang - tempang).Degrees()) > 90.0;
|
||||
if (backfaced) // (ang - tempang).Cos() < 0.0)
|
||||
{
|
||||
ang = DAngle::fromDeg(180.0) - ang;
|
||||
}
|
||||
}
|
||||
FTextureID patch;
|
||||
// [ZZ] add direct picnum override
|
||||
if (isPicnumOverride)
|
||||
|
|
@ -1233,6 +1269,15 @@ void HWSprite::Process(HWDrawInfo *di, FRenderState& state, AActor* thing, secto
|
|||
|
||||
depth = (float)((x - vp.Pos.X) * vp.TanCos + (y - vp.Pos.Y) * vp.TanSin);
|
||||
if(thing->renderflags2 & RF2_ISOMETRICSPRITES) depth = depth * vp.PitchCos - vp.PitchSin * z2; // Helps with stacking actors with small xy offsets
|
||||
if(actor && (thing->renderflags2 & RF2_ANGLEDROLL) && !(thing->renderflags & RF_ROLLCENTER))
|
||||
{
|
||||
double rollsin = thing->Angles.Roll.Sin();
|
||||
DAngle tempang2 = thing->Angles.Yaw + thing->AngledRollOffset + DAngle::fromDeg(rollsin < 0.0
|
||||
? 90.0 : -90.0);
|
||||
double r2 = 0.5 * fabs((z2 - z1) * rollsin);
|
||||
depth = (float)((x + r2 * tempang2.Cos() - vp.Pos.X) * vp.TanCos
|
||||
+ (y + r2 * tempang2.Sin() - vp.Pos.Y) * vp.TanSin);
|
||||
}
|
||||
if (isSpriteShadow) depth += 1.f/65536.f; // always sort shadows behind the sprite.
|
||||
|
||||
if (gl_spriteclip == -1 && (thing->renderflags & RF_SPRITETYPEMASK) == RF_FACESPRITE) // perform anamorphosis
|
||||
|
|
@ -1282,7 +1327,7 @@ void HWSprite::Process(HWDrawInfo *di, FRenderState& state, AActor* thing, secto
|
|||
z1 = z1 * spbias + vpz * vpbias;
|
||||
x2 = x2 * spbias + vpx * vpbias;
|
||||
y2 = y2 * spbias + vpy * vpbias;
|
||||
z2 = z2 * spbias + vpz * vpbias;
|
||||
z2 = z2 * spbias + vpz * vpbias;
|
||||
}
|
||||
|
||||
// light calculation
|
||||
|
|
@ -1348,7 +1393,7 @@ void HWSprite::Process(HWDrawInfo *di, FRenderState& state, AActor* thing, secto
|
|||
translation = thing->Translation;
|
||||
|
||||
OverrideShader = -1;
|
||||
trans = thing->Alpha;
|
||||
trans = alpha;
|
||||
hw_styleflags = STYLEHW_Normal;
|
||||
|
||||
if (RenderStyle.BlendOp >= STYLEOP_Fuzz && RenderStyle.BlendOp <= STYLEOP_FuzzOrRevSub)
|
||||
|
|
|
|||
|
|
@ -427,76 +427,138 @@ void HWWall::SetupLights(HWDrawInfo*di, FRenderState& state, FDynLightData &ligh
|
|||
auto normal = glseg.Normal();
|
||||
p.Set(normal, -normal.X * glseg.x1 - normal.Z * glseg.y1);
|
||||
|
||||
FLightNode *node;
|
||||
if (seg->sidedef == NULL)
|
||||
{
|
||||
node = NULL;
|
||||
}
|
||||
else if (!(seg->sidedef->Flags & WALLF_POLYOBJ))
|
||||
{
|
||||
node = seg->sidedef->lighthead;
|
||||
}
|
||||
else if (sub)
|
||||
if ((seg->sidedef->Flags & WALLF_POLYOBJ) && sub)
|
||||
{
|
||||
// Polobject segs cannot be checked per sidedef so use the subsector instead.
|
||||
node = sub->section->lighthead;
|
||||
}
|
||||
else node = NULL;
|
||||
auto flatLightList = di->Level->lightlists.flat_dlist.CheckKey(sub->section);
|
||||
|
||||
// Iterate through all dynamic lights which touch this wall and render them
|
||||
while (node)
|
||||
{
|
||||
if (node->lightsource->IsActive() && !node->lightsource->DontLightMap())
|
||||
if (flatLightList)
|
||||
{
|
||||
iter_dlight++;
|
||||
|
||||
DVector3 posrel = node->lightsource->PosRelative(seg->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)
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Iterator it(*flatLightList);
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Pair *pair;
|
||||
while (it.NextPair(pair))
|
||||
{
|
||||
FVector3 nearPt, up, right;
|
||||
auto node = pair->Value.get();
|
||||
if (!node) continue;
|
||||
|
||||
pos = { x, z, y };
|
||||
fn = p.Normal();
|
||||
|
||||
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 (node->lightsource->IsActive() && !node->lightsource->DontLightMap())
|
||||
{
|
||||
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;
|
||||
iter_dlight++;
|
||||
|
||||
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]++;
|
||||
DVector3 posrel = node->lightsource->PosRelative(seg->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 (outcnt[0]!=4 && outcnt[1]!=4 && outcnt[2]!=4 && outcnt[3]!=4)
|
||||
{
|
||||
draw_dlight += GetLight(lightdata, seg->frontsector->PortalGroup, p, node->lightsource, true);
|
||||
if (radius > 0.f && dist < radius)
|
||||
{
|
||||
FVector3 nearPt, up, right;
|
||||
|
||||
pos = { x, z, y };
|
||||
fn = p.Normal();
|
||||
|
||||
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, seg->frontsector->PortalGroup, p, node->lightsource, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
node = node->nextLight;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto wallLightList = di->Level->lightlists.wall_dlist.CheckKey(seg->sidedef);
|
||||
|
||||
if (wallLightList)
|
||||
{
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Iterator it(*wallLightList);
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Pair *pair;
|
||||
while (it.NextPair(pair))
|
||||
{
|
||||
auto node = pair->Value.get();
|
||||
if (!node) continue;
|
||||
|
||||
if (node->lightsource->IsActive() && !node->lightsource->DontLightMap())
|
||||
{
|
||||
iter_dlight++;
|
||||
|
||||
DVector3 posrel = node->lightsource->PosRelative(seg->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)
|
||||
{
|
||||
FVector3 nearPt, up, right;
|
||||
|
||||
pos = { x, z, y };
|
||||
fn = p.Normal();
|
||||
|
||||
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, seg->frontsector->PortalGroup, p, node->lightsource, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dynlightindex = state.UploadLights(lightdata);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -54,6 +54,8 @@ EXTERN_CVAR(Bool, r_drawplayersprites)
|
|||
EXTERN_CVAR(Bool, r_deathcamera)
|
||||
|
||||
|
||||
CVARD(Bool, gl_weapon_purelightlevel, false, CVAR_GLOBALCONFIG | CVAR_ARCHIVE, "Makes the lighting on weapon sprites (or models) purely match the sector's light level you're standing in");
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// R_DrawPSprite
|
||||
|
|
@ -94,6 +96,7 @@ void HWDrawInfo::DrawPSprite(HUDSprite *huds, FRenderState &state)
|
|||
|
||||
FHWModelRenderer renderer(this, state, huds->lightindex);
|
||||
RenderHUDModel(&renderer, huds->weapon, huds->translation, huds->rotation + FVector3(huds->mx / 4., (huds->my - WEAPONTOP) / -4., 0), huds->pivot, huds->mframe, Viewpoint.TicFrac);
|
||||
|
||||
state.SetFlatVertexBuffer();
|
||||
state.SetShadeVertex(false);
|
||||
}
|
||||
|
|
@ -326,7 +329,7 @@ static FVector2 BobWeapon3D(WeaponPosition3D &weap, DPSprite *psp, FVector3 &tra
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
WeaponLighting HWDrawInfo::GetWeaponLighting(sector_t *viewsector, const DVector3 &pos, int cm, area_t in_area, const DVector3 &playerpos)
|
||||
WeaponLighting HWDrawInfo::GetWeaponLighting(sector_t *viewsector, const DVector3 &pos, int cm, area_t in_area, const DVector3 &playerpos, bool weaponPureLightLevel = false)
|
||||
{
|
||||
WeaponLighting l;
|
||||
|
||||
|
|
@ -374,7 +377,7 @@ WeaponLighting HWDrawInfo::GetWeaponLighting(sector_t *viewsector, const DVector
|
|||
if (Level->flags3 & LEVEL3_NOCOLOREDSPRITELIGHTING) l.cm.ClearColor();
|
||||
}
|
||||
|
||||
l.lightlevel = CalcLightLevel(lightmode, l.lightlevel, getExtraLight(), true, 0);
|
||||
l.lightlevel = CalcLightLevel(lightmode, l.lightlevel, getExtraLight(), true, 0, weaponPureLightLevel);
|
||||
|
||||
if (isSoftwareLighting(lightmode) || l.lightlevel < 92)
|
||||
{
|
||||
|
|
@ -706,7 +709,7 @@ void HWDrawInfo::PreparePlayerSprites2D(sector_t * viewsector, area_t in_area, F
|
|||
AActor *camera = vp.camera;
|
||||
|
||||
WeaponPosition2D weap = GetWeaponPosition2D(camera->player, vp.TicFrac);
|
||||
WeaponLighting light = GetWeaponLighting(viewsector, vp.Pos, isFullbrightScene(), in_area, camera->Pos());
|
||||
WeaponLighting light = GetWeaponLighting(viewsector, vp.Pos, isFullbrightScene(), in_area, camera->Pos(), gl_weapon_purelightlevel);
|
||||
|
||||
VMFunction * ModifyBobLayer = nullptr;
|
||||
DVector2 bobxy = DVector2(weap.bobx , weap.boby);
|
||||
|
|
@ -796,7 +799,7 @@ void HWDrawInfo::PreparePlayerSprites3D(sector_t * viewsector, area_t in_area, F
|
|||
AActor *camera = vp.camera;
|
||||
|
||||
WeaponPosition3D weap = GetWeaponPosition3D(camera->player, vp.TicFrac);
|
||||
WeaponLighting light = GetWeaponLighting(viewsector, vp.Pos, isFullbrightScene(), in_area, camera->Pos());
|
||||
WeaponLighting light = GetWeaponLighting(viewsector, vp.Pos, isFullbrightScene(), in_area, camera->Pos(), gl_weapon_purelightlevel);
|
||||
|
||||
VMFunction * ModifyBobLayer3D = nullptr;
|
||||
VMFunction * ModifyBobPivotLayer3D = nullptr;
|
||||
|
|
|
|||
|
|
@ -79,6 +79,10 @@ void InitSkyMap(FLevelLocals *Level)
|
|||
{
|
||||
Level->skytexture1 = TexMan.GetFrontSkyLayer(Level->skytexture1);
|
||||
}
|
||||
if (Level->skymisttexture.isNull())
|
||||
{
|
||||
Level->skymisttexture = TexMan.CheckForTexture("skymist1", ETextureType::Any);
|
||||
}
|
||||
|
||||
skytex1 = TexMan.GetGameTexture(Level->skytexture1, false);
|
||||
skytex2 = TexMan.GetGameTexture(Level->skytexture2, false);
|
||||
|
|
@ -143,6 +147,7 @@ void R_UpdateSky (uint64_t mstime)
|
|||
// The hardware renderer uses a different value range and clamps it to a single rotation
|
||||
Level->hw_sky1pos = (float)(fmod((double(mstime) * Level->skyspeed1), 1024.) * (90. / 256.));
|
||||
Level->hw_sky2pos = (float)(fmod((double(mstime) * Level->skyspeed2), 1024.) * (90. / 256.));
|
||||
Level->hw_skymistpos = (float)(fmod((double(mstime) * Level->skymistspeed), 1024.) * (90. / 256.));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -922,6 +922,8 @@ static void R_DoActorTickerAngleChanges(player_t* const player, DRotator& angles
|
|||
EXTERN_CVAR(Float, chase_dist)
|
||||
EXTERN_CVAR(Float, chase_height)
|
||||
|
||||
int WorldPaused();
|
||||
|
||||
void R_SetupFrame(FRenderViewpoint& viewPoint, const FViewWindow& viewWindow, AActor* const actor, int side)
|
||||
{
|
||||
viewPoint.TicFrac = I_GetTimeFrac();
|
||||
|
|
@ -958,8 +960,17 @@ void R_SetupFrame(FRenderViewpoint& viewPoint, const FViewWindow& viewWindow, AA
|
|||
iView->AngleOffsets.Zero();
|
||||
if (iView->prevTic != -1 && curTic > iView->prevTic)
|
||||
{
|
||||
iView->prevTic = curTic;
|
||||
iView->Old = iView->New;
|
||||
// If it's been more than a tic since it was rendered, don't interpolate
|
||||
// from whatever last position it had (it's probably no longer valid).
|
||||
if (curTic - iView->prevTic > 1)
|
||||
{
|
||||
iView->prevTic = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
iView->prevTic = curTic;
|
||||
iView->Old = iView->New;
|
||||
}
|
||||
}
|
||||
|
||||
const auto& mainView = r_viewpoint;
|
||||
|
|
@ -1034,7 +1045,7 @@ void R_SetupFrame(FRenderViewpoint& viewPoint, const FViewWindow& viewWindow, AA
|
|||
viewPoint.sector = viewPoint.ViewLevel->PointInRenderSubsector(camPos)->sector;
|
||||
}
|
||||
|
||||
if (!paused)
|
||||
if (!WorldPaused())
|
||||
{
|
||||
FQuakeJiggers jiggers;
|
||||
if (DEarthquake::StaticGetQuakeIntensities(viewPoint.TicFrac, viewPoint.camera, jiggers) > 0)
|
||||
|
|
|
|||
|
|
@ -209,11 +209,57 @@ namespace swrenderer
|
|||
|
||||
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)
|
||||
return curline->sidedef->lighthead;
|
||||
{
|
||||
auto Level = curline->Subsector->sector->Level;
|
||||
auto wallLightList = Level->lightlists.wall_dlist.CheckKey(curline->sidedef);
|
||||
if (wallLightList)
|
||||
{
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Iterator it(*wallLightList);
|
||||
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 light_list;
|
||||
}
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ namespace swrenderer
|
|||
fillshort(top, viewwidth, 0x7fff);
|
||||
}
|
||||
|
||||
void VisiblePlane::AddLights(RenderThread *thread, FLightNode *node)
|
||||
void VisiblePlane::AddLights(RenderThread *thread, FSection *sec)
|
||||
{
|
||||
if (!r_dynlights)
|
||||
return;
|
||||
|
|
@ -75,30 +75,39 @@ namespace swrenderer
|
|||
if (cameraLight->FixedColormap() != NULL || cameraLight->FixedLightLevel() >= 0)
|
||||
return; // [SP] no dynlights if invul or lightamp
|
||||
|
||||
while (node)
|
||||
auto Level = sec->sector->Level;
|
||||
auto flatLightList = Level->lightlists.flat_dlist.CheckKey(sec);
|
||||
if (flatLightList)
|
||||
{
|
||||
if (node->lightsource->IsActive() && (height.PointOnSide(node->lightsource->Pos) > 0))
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Iterator it(*flatLightList);
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Pair *pair;
|
||||
while (it.NextPair(pair))
|
||||
{
|
||||
bool found = false;
|
||||
VisiblePlaneLight *light_node = lights;
|
||||
while (light_node)
|
||||
auto node = pair->Value.get();
|
||||
if (!node) continue;
|
||||
|
||||
if (node->lightsource->IsActive() && (height.PointOnSide(node->lightsource->Pos) > 0))
|
||||
{
|
||||
if (light_node->lightsource == node->lightsource)
|
||||
bool found = false;
|
||||
VisiblePlaneLight *light_node = lights;
|
||||
while (light_node)
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
if (light_node->lightsource == node->lightsource)
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
light_node = light_node->next;
|
||||
}
|
||||
if (!found)
|
||||
{
|
||||
VisiblePlaneLight *newlight = thread->FrameMemory->NewObject<VisiblePlaneLight>();
|
||||
newlight->next = lights;
|
||||
newlight->lightsource = node->lightsource;
|
||||
lights = newlight;
|
||||
}
|
||||
light_node = light_node->next;
|
||||
}
|
||||
if (!found)
|
||||
{
|
||||
VisiblePlaneLight *newlight = thread->FrameMemory->NewObject<VisiblePlaneLight>();
|
||||
newlight->next = lights;
|
||||
newlight->lightsource = node->lightsource;
|
||||
lights = newlight;
|
||||
}
|
||||
}
|
||||
node = node->nextLight;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ namespace swrenderer
|
|||
{
|
||||
VisiblePlane(RenderThread *thread);
|
||||
|
||||
void AddLights(RenderThread *thread, FLightNode *node);
|
||||
void AddLights(RenderThread *thread, FSection *sec);
|
||||
void Render(RenderThread *thread, fixed_t alpha, bool additive, bool masked);
|
||||
|
||||
VisiblePlane *next = nullptr; // Next visplane in hash chain -- killough
|
||||
|
|
|
|||
|
|
@ -561,7 +561,7 @@ namespace swrenderer
|
|||
Fake3DOpaque::Normal,
|
||||
0);
|
||||
|
||||
ceilingplane->AddLights(Thread, sub->section->lighthead);
|
||||
ceilingplane->AddLights(Thread, sub->section);
|
||||
}
|
||||
|
||||
int adjusted_floorlightlevel = floorlightlevel;
|
||||
|
|
@ -601,7 +601,7 @@ namespace swrenderer
|
|||
Fake3DOpaque::Normal,
|
||||
0);
|
||||
|
||||
floorplane->AddLights(Thread, sub->section->lighthead);
|
||||
floorplane->AddLights(Thread, sub->section);
|
||||
}
|
||||
|
||||
Add3DFloorPlanes(sub, frontsector, basecolormap, foggy, adjusted_ceilinglightlevel, adjusted_floorlightlevel);
|
||||
|
|
@ -738,7 +738,7 @@ namespace swrenderer
|
|||
Fake3DOpaque::FakeFloor,
|
||||
fakeAlpha);
|
||||
|
||||
floorplane3d->AddLights(Thread, sub->section->lighthead);
|
||||
floorplane3d->AddLights(Thread, sub->section);
|
||||
|
||||
FakeDrawLoop(sub, &tempsec, floorplane3d, nullptr, Fake3DOpaque::FakeFloor);
|
||||
}
|
||||
|
|
@ -806,7 +806,7 @@ namespace swrenderer
|
|||
Fake3DOpaque::FakeCeiling,
|
||||
fakeAlpha);
|
||||
|
||||
ceilingplane3d->AddLights(Thread, sub->section->lighthead);
|
||||
ceilingplane3d->AddLights(Thread, sub->section);
|
||||
|
||||
FakeDrawLoop(sub, &tempsec, nullptr, ceilingplane3d, Fake3DOpaque::FakeCeiling);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -208,42 +208,50 @@ namespace swrenderer
|
|||
float lit_red = 0;
|
||||
float lit_green = 0;
|
||||
float lit_blue = 0;
|
||||
auto node = vis->section->lighthead;
|
||||
while (node != nullptr)
|
||||
auto Level = vis->sector->Level;
|
||||
auto flatLightList = Level->lightlists.flat_dlist.CheckKey(vis->section);
|
||||
if (flatLightList)
|
||||
{
|
||||
FDynamicLight *light = node->lightsource;
|
||||
if (light->ShouldLightActor(thing))
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Iterator it(*flatLightList);
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Pair *pair;
|
||||
while (it.NextPair(pair))
|
||||
{
|
||||
float lx = (float)(light->X() - thing->X());
|
||||
float ly = (float)(light->Y() - thing->Y());
|
||||
float lz = (float)(light->Z() - thing->Center());
|
||||
float LdotL = lx * lx + ly * ly + lz * lz;
|
||||
float radius = node->lightsource->GetRadius();
|
||||
if (radius * radius >= LdotL)
|
||||
auto node = pair->Value.get();
|
||||
if (!node) continue;
|
||||
|
||||
FDynamicLight *light = node->lightsource;
|
||||
if (light->ShouldLightActor(thing))
|
||||
{
|
||||
float distance = sqrt(LdotL);
|
||||
float attenuation = 1.0f - distance / radius;
|
||||
if (attenuation > 0.0f)
|
||||
{
|
||||
float red = light->GetRed() * (1.0f / 255.0f);
|
||||
float green = light->GetGreen() * (1.0f / 255.0f);
|
||||
float blue = light->GetBlue() * (1.0f / 255.0f);
|
||||
/*if (light->IsSubtractive())
|
||||
{
|
||||
float bright = FVector3(lr, lg, lb).Length();
|
||||
FVector3 lightColor(lr, lg, lb);
|
||||
red = (bright - lr) * -1;
|
||||
green = (bright - lg) * -1;
|
||||
blue = (bright - lb) * -1;
|
||||
}*/
|
||||
|
||||
lit_red += red * attenuation;
|
||||
lit_green += green * attenuation;
|
||||
lit_blue += blue * attenuation;
|
||||
float lx = (float)(light->X() - thing->X());
|
||||
float ly = (float)(light->Y() - thing->Y());
|
||||
float lz = (float)(light->Z() - thing->Center());
|
||||
float LdotL = lx * lx + ly * ly + lz * lz;
|
||||
float radius = node->lightsource->GetRadius();
|
||||
if (radius * radius >= LdotL)
|
||||
{
|
||||
float distance = sqrt(LdotL);
|
||||
float attenuation = 1.0f - distance / radius;
|
||||
if (attenuation > 0.0f)
|
||||
{
|
||||
float red = light->GetRed() * (1.0f / 255.0f);
|
||||
float green = light->GetGreen() * (1.0f / 255.0f);
|
||||
float blue = light->GetBlue() * (1.0f / 255.0f);
|
||||
/*if (light->IsSubtractive())
|
||||
{
|
||||
float bright = FVector3(lr, lg, lb).Length();
|
||||
FVector3 lightColor(lr, lg, lb);
|
||||
red = (bright - lr) * -1;
|
||||
green = (bright - lg) * -1;
|
||||
blue = (bright - lb) * -1;
|
||||
}*/
|
||||
|
||||
lit_red += red * attenuation;
|
||||
lit_green += green * attenuation;
|
||||
lit_blue += blue * attenuation;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
node = node->nextLight;
|
||||
}
|
||||
lit_red = clamp(lit_red * 255.0f, 0.0f, 255.0f);
|
||||
lit_green = clamp(lit_green * 255.0f, 0.0f, 255.0f);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue