From e5848ead7ab1a6c8b9b100c00e16d9a6e8b86c16 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Thu, 6 Apr 2023 16:13:03 +0200 Subject: [PATCH] Add sunlight trace --- src/g_levellocals.h | 2 ++ src/maploader/maploader.cpp | 21 +++++++------- src/rendering/hwrenderer/hw_dynlightdata.cpp | 29 +++++++++++++++++++ .../hwrenderer/scene/hw_drawstructs.h | 1 + .../hwrenderer/scene/hw_spritelight.cpp | 11 +++++-- 5 files changed, 51 insertions(+), 13 deletions(-) diff --git a/src/g_levellocals.h b/src/g_levellocals.h index 544d9b0a6b..79916b6f8a 100644 --- a/src/g_levellocals.h +++ b/src/g_levellocals.h @@ -459,6 +459,8 @@ public: int LMTextureCount = 0; int LMTextureSize = 0; TArray LMTextureData; + FVector3 SunDirection; + FVector3 SunColor; // Portal information. FDisplacementTable Displacements; diff --git a/src/maploader/maploader.cpp b/src/maploader/maploader.cpp index 7e38454b25..567eb1fe07 100644 --- a/src/maploader/maploader.cpp +++ b/src/maploader/maploader.cpp @@ -3343,7 +3343,12 @@ void MapLoader::LoadLightmap(MapData *map) int version = fr.ReadInt32(); - if (version != 0) + if (version == 0) + { + Printf(PRINT_HIGH, "LoadLightmap: This is an old unsupported alpha version of the lightmap lump. Please rebuild the map with a newer version of zdray.\n"); + return; + } + if (version != 1) { Printf(PRINT_HIGH, "LoadLightmap: unsupported lightmap lump version\n"); return; @@ -3353,26 +3358,22 @@ void MapLoader::LoadLightmap(MapData *map) uint16_t numTextures = fr.ReadUInt16(); uint32_t numSurfaces = fr.ReadUInt32(); uint32_t numTexCoords = fr.ReadUInt32(); - uint32_t numLightProbes = fr.ReadUInt32(); uint32_t numSubsectors = fr.ReadUInt32(); uint32_t numTexBytes = numTextures * textureSize * textureSize * 3 * 2; - if (numSurfaces == 0 || numTexCoords == 0 || numTexBytes == 0) return; - Printf(PRINT_HIGH, "WARNING! Lightmaps are an experimental feature and are subject to change before being finalized. Do not expect this to work as-is in future releases of %s!\n", GAMENAME); + float sunDir[3], sunColor[3]; + fr.Read(sunDir, sizeof(float) * 3); + fr.Read(sunColor, sizeof(float) * 3); + Level->SunDirection = FVector3(sunDir); + Level->SunColor = FVector3(sunColor); /*if (numSubsectors != Level->subsectors.Size()) { Printf(PRINT_HIGH, "LoadLightmap: subsector count for level doesn't match (%d in wad vs %d in engine)\n", (int)numSubsectors, (int)Level->subsectors.Size()); }*/ - if (numLightProbes > 0) - { - Printf(PRINT_HIGH, "LoadLightmap: This is an old unsupported alpha version of the lightmap lump. Please rebuild the map with a newer version of zdray.\n"); - return; - } - Level->LMTexCoords.Resize(numTexCoords * 2); // Allocate room for all surfaces diff --git a/src/rendering/hwrenderer/hw_dynlightdata.cpp b/src/rendering/hwrenderer/hw_dynlightdata.cpp index 044d34d3d5..68312f3243 100644 --- a/src/rendering/hwrenderer/hw_dynlightdata.cpp +++ b/src/rendering/hwrenderer/hw_dynlightdata.cpp @@ -155,3 +155,32 @@ void AddLightToList(FDynLightData &dld, int group, FDynamicLight * light, bool f data[15] = 0.0f; // unused } +void AddSunLightToList(FDynLightData& dld, float x, float y, float z, float r, float g, float b) +{ + int i = 0; + float lightType = 0.0f; + float spotInnerAngle = 0.0f; + float spotOuterAngle = 0.0f; + float spotDirX = 0.0f; + float spotDirY = 0.0f; + float spotDirZ = 0.0f; + float shadowIndex = -1025.f; // Note: 1025 disables shadowmap and the attenuate flag is in the sign bit of the float + + float* data = &dld.arrays[i][dld.arrays[i].Reserve(16)]; + data[0] = float(x); + data[1] = float(z); + data[2] = float(y); + data[3] = 100000.0f; + data[4] = r; + data[5] = g; + data[6] = b; + data[7] = shadowIndex; + data[8] = spotDirX; + data[9] = spotDirY; + data[10] = spotDirZ; + data[11] = lightType; + data[12] = spotInnerAngle; + data[13] = spotOuterAngle; + data[14] = 0.0f; // unused + data[15] = 0.0f; // unused +} diff --git a/src/rendering/hwrenderer/scene/hw_drawstructs.h b/src/rendering/hwrenderer/scene/hw_drawstructs.h index 1cec671a46..9a0d3c4616 100644 --- a/src/rendering/hwrenderer/scene/hw_drawstructs.h +++ b/src/rendering/hwrenderer/scene/hw_drawstructs.h @@ -441,4 +441,5 @@ struct FDynLightData; struct FDynamicLight; bool GetLight(FDynLightData& dld, int group, Plane& p, FDynamicLight* light, bool checkside); void AddLightToList(FDynLightData &dld, int group, FDynamicLight* light, bool forceAttenuate); +void AddSunLightToList(FDynLightData& dld, float x, float y, float z, float r, float g, float b); void SetSplitPlanes(FRenderState& state, const secplane_t& top, const secplane_t& bottom); diff --git a/src/rendering/hwrenderer/scene/hw_spritelight.cpp b/src/rendering/hwrenderer/scene/hw_spritelight.cpp index 3ff56701f6..0ac1991a25 100644 --- a/src/rendering/hwrenderer/scene/hw_spritelight.cpp +++ b/src/rendering/hwrenderer/scene/hw_spritelight.cpp @@ -61,7 +61,7 @@ static bool TraceLightVisbility(FLightNode* node, const FVector3& L, float dist) static bool TraceSunVisibility(float x, float y, float z) { - return level.levelMesh->TraceSky(FVector3(x, y, z), FVector3(0.0f, 0.0, 1.0f), 10000.0f); + return level.LMTextureCount != 0 && level.levelMesh->TraceSky(FVector3(x, y, z), level.SunDirection, 10000.0f); } //========================================================================== @@ -80,7 +80,9 @@ void HWDrawInfo::GetDynSpriteLight(AActor *self, float x, float y, float z, FLig if (TraceSunVisibility(x, y, z)) { - //out[0] = 1.0f; + out[0] = Level->SunColor.X; + out[1] = Level->SunColor.Y; + out[2] = Level->SunColor.Z; } // Go through both light lists @@ -195,7 +197,10 @@ void hw_GetDynModelLight(AActor *self, FDynLightData &modellightdata) if (TraceSunVisibility(x, y, z)) { - //AddSunLightToList(modellightdata); + const FVector3& sundir = self->Level->SunDirection; + const FVector3& suncolor = self->Level->SunColor; + float dist = 100000.0f; // Cheap way of faking a directional light + AddSunLightToList(modellightdata, x - sundir.X * dist, y - sundir.Y * dist, z - sundir.Z * dist, suncolor.X, suncolor.Y, suncolor.Z); } BSPWalkCircle(self->Level, x, y, radiusSquared, [&](subsector_t *subsector) // Iterate through all subsectors potentially touched by actor