feat(world): Phase G.1 — debug-time override tests + clear-color clamp
Small polish commit: - Clamp ClearColor inputs to [0, 1] because retail keyframes store sun/fog colors pre-multiplied by their brightness scalars, which can exceed 1.0; some drivers treat ClearColor > 1 as a saturate-bright hint and produce visible color shifts at the edges. - 4 new tests cover WorldTimeService.SetDebugTime / ClearDebugTime / SyncFromServer-clears-override / SetProvider hot-swap. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
cd89e9a498
commit
756def5ceb
2 changed files with 67 additions and 1 deletions
|
|
@ -3040,7 +3040,15 @@ public sealed class GameWindow : IDisposable
|
|||
var kf = WorldTime.CurrentSky;
|
||||
var atmo = Weather.Snapshot(in kf);
|
||||
var fogColor = atmo.FogColor;
|
||||
_gl!.ClearColor(fogColor.X, fogColor.Y, fogColor.Z, 1f);
|
||||
// Clamp to 0..1 — keyframes may store over-1 values (retail uses the
|
||||
// dir-bright scalar pre-multiplied into color) and GL's ClearColor
|
||||
// will silently accept them, but some drivers interpret > 1 as
|
||||
// "bright clamp", producing ugly pink/green frames.
|
||||
_gl!.ClearColor(
|
||||
System.Math.Clamp(fogColor.X, 0f, 1f),
|
||||
System.Math.Clamp(fogColor.Y, 0f, 1f),
|
||||
System.Math.Clamp(fogColor.Z, 0f, 1f),
|
||||
1f);
|
||||
|
||||
_gl!.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
|
||||
|
||||
|
|
|
|||
58
tests/AcDream.Core.Tests/World/WorldTimeDebugTests.cs
Normal file
58
tests/AcDream.Core.Tests/World/WorldTimeDebugTests.cs
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
using System;
|
||||
using AcDream.Core.World;
|
||||
using Xunit;
|
||||
|
||||
namespace AcDream.Core.Tests.World;
|
||||
|
||||
public sealed class WorldTimeDebugTests
|
||||
{
|
||||
[Fact]
|
||||
public void SetDebugTime_OverridesDayFraction()
|
||||
{
|
||||
var service = new WorldTimeService(SkyStateProvider.Default());
|
||||
service.SyncFromServer(0); // midnight
|
||||
|
||||
service.SetDebugTime(0.5f); // force noon
|
||||
Assert.InRange(service.DayFraction, 0.499, 0.501);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ClearDebugTime_RestoresServerTime()
|
||||
{
|
||||
var service = new WorldTimeService(SkyStateProvider.Default());
|
||||
service.SyncFromServer(DerethDateTime.DayTicks * 0.25); // dawn
|
||||
service.SetDebugTime(0.5f);
|
||||
service.ClearDebugTime();
|
||||
|
||||
Assert.InRange(service.DayFraction, 0.24, 0.26);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SyncFromServer_ClearsDebugOverride()
|
||||
{
|
||||
var service = new WorldTimeService(SkyStateProvider.Default());
|
||||
service.SetDebugTime(0.75f);
|
||||
service.SyncFromServer(0); // midnight — this should clear the override
|
||||
|
||||
Assert.InRange(service.DayFraction, 0.0, 0.01);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SetProvider_AcceptsNewKeyframes()
|
||||
{
|
||||
var service = new WorldTimeService(SkyStateProvider.Default());
|
||||
var custom = new SkyStateProvider(new[]
|
||||
{
|
||||
new SkyKeyframe(
|
||||
Begin: 0f,
|
||||
SunHeadingDeg: 0f,
|
||||
SunPitchDeg: 90f,
|
||||
SunColor: System.Numerics.Vector3.One,
|
||||
AmbientColor: System.Numerics.Vector3.One,
|
||||
FogColor: System.Numerics.Vector3.Zero,
|
||||
FogDensity: 0f),
|
||||
});
|
||||
service.SetProvider(custom);
|
||||
Assert.Equal(1, custom.KeyframeCount);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue