diag(render): §4 flap apparatus — eye-vs-terrain field + GL-state tripwire

Two probe additions from the §4 outdoor full-world flap investigation
(world turns to fog-tinted clear color at specific outdoor spots;
strobes then holds; camera rotation recovers; forward-walk triggers):

- [pv-input] gains terrZ=/eyeAbove= (terrain height under the camera
  eye) — used to REFUTE the buried-eye hypothesis (eyeAbove stayed
  +1.6..2.1 m through every held-flap block).
- [gl-state] (ACDREAM_PROBE_GLSTATE=1): snapshots the GL fixed-function
  state entering the world passes (depth, blend, cull, scissor + box,
  viewport, FBO, color/clip masks, glGetError), printing on change.
  Delivered the frame-exact flap-onset marker: the leftover scissor box
  flips from full-screen to a drifting 9x21 px doorway footprint at the
  exact frame the nearby building flood merges in (pv-input flood 1->5).

Both probes are gated and zero-cost when off. Strip with the rest of
the §4 apparatus when the flap ships.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Erik 2026-06-10 08:18:26 +02:00
parent 41fa3cbbc4
commit fafe5d66e8
2 changed files with 78 additions and 1 deletions

View file

@ -7102,6 +7102,11 @@ public sealed class GameWindow : IDisposable
_gl.CullFace(TriangleFace.Back);
_gl.FrontFace(FrontFaceDirection.CW);
// §4 flap apparatus: GL-state tripwire — one [gl-state] line whenever the
// state entering the world passes differs from the previous frame.
if (AcDream.Core.Rendering.RenderingDiagnostics.ProbeGlStateEnabled)
EmitGlStateTripwireIfChanged();
// Phase N.6 slice 1: one-shot surface-format histogram dump under
// ACDREAM_DUMP_SURFACES=1. Zero cost when off.
_textureCache?.TickSurfaceHistogramDumpIfEnabled();
@ -7615,8 +7620,16 @@ public sealed class GameWindow : IDisposable
// flickers while idle, exactly one of {eye, player, rawPlayer, yaw} is the varying input.
var pvRawPlayer = _playerController?.Position ?? playerViewPos;
float pvYaw = _playerController?.Yaw ?? 0f;
// §4 outdoor flap (2026-06-09): terrain height under the EYE — if the
// camera boom is buried in a hillside (eyeAbove < 0), every nearby
// terrain triangle backface-culls and the view punches through the
// world to the clear color. Pin or refute eye-under-terrain.
float? pvTerrZ = _physicsEngine.SampleTerrainZ(camPos.X, camPos.Y);
string pvTerr = pvTerrZ is { } tz
? System.FormattableString.Invariant($"terrZ={tz:F3} eyeAbove={camPos.Z - tz:F3}")
: "terrZ=n/a eyeAbove=n/a";
Console.WriteLine(System.FormattableString.Invariant(
$"[pv-input] outRoot={pvOutRoot} flood={pvFrame.OrderedVisibleCells.Count} eye=({camPos.X:F6},{camPos.Y:F6},{camPos.Z:F6}) player=({playerViewPos.X:F6},{playerViewPos.Y:F6},{playerViewPos.Z:F6}) rawPlayer=({pvRawPlayer.X:F6},{pvRawPlayer.Y:F6},{pvRawPlayer.Z:F6}) yaw={pvYaw:F8} vp=[{vp.M11:F6} {vp.M13:F6} {vp.M22:F6} {vp.M31:F6} {vp.M33:F6} {vp.M41:F6} {vp.M42:F6} {vp.M43:F6}]"));
$"[pv-input] outRoot={pvOutRoot} flood={pvFrame.OrderedVisibleCells.Count} eye=({camPos.X:F6},{camPos.Y:F6},{camPos.Z:F6}) player=({playerViewPos.X:F6},{playerViewPos.Y:F6},{playerViewPos.Z:F6}) rawPlayer=({pvRawPlayer.X:F6},{pvRawPlayer.Y:F6},{pvRawPlayer.Z:F6}) yaw={pvYaw:F8} {pvTerr} vp=[{vp.M11:F6} {vp.M13:F6} {vp.M22:F6} {vp.M31:F6} {vp.M33:F6} {vp.M41:F6} {vp.M42:F6} {vp.M43:F6}]"));
}
sigPvFrame = pviewResult.PortalFrame;
@ -9535,6 +9548,58 @@ public sealed class GameWindow : IDisposable
}
}
// §4 flap apparatus (2026-06-09): GL-state tripwire. Snapshots the fixed-function
// state entering the world passes; prints [gl-state] only when it CHANGES from the
// previous frame. Every CPU-side input is probe-exonerated for the outdoor
// full-world flap; this pins or refutes the leaked-GL-state family
// (feedback_render_self_contained_gl_state — 3 prior hits). Throwaway.
private string? _lastGlStateSig;
private long _glStateFrame;
private long _glStateStable;
private void EmitGlStateTripwireIfChanged()
{
var gl = _gl;
if (gl is null) return;
_glStateFrame++;
Span<int> sbox = stackalloc int[4];
Span<int> vp = stackalloc int[4];
gl.GetInteger(GetPName.ScissorBox, sbox);
gl.GetInteger(GetPName.Viewport, vp);
int clipBits = 0;
for (int i = 0; i < ClipFrame.MaxPlanes; i++)
if (gl.IsEnabled(EnableCap.ClipDistance0 + i)) clipBits |= 1 << i;
var err = gl.GetError();
// All-integer fields — culture-safe with plain interpolation.
string sig =
$"depth={(gl.IsEnabled(EnableCap.DepthTest) ? 1 : 0)} " +
$"dmask={(gl.GetBoolean(GetPName.DepthWritemask) ? 1 : 0)} " +
$"dfunc=0x{gl.GetInteger(GetPName.DepthFunc):X} " +
$"blend={(gl.IsEnabled(EnableCap.Blend) ? 1 : 0)} " +
$"bsrc=0x{gl.GetInteger(GetPName.BlendSrcRgb):X} bdst=0x{gl.GetInteger(GetPName.BlendDstRgb):X} " +
$"cull={(gl.IsEnabled(EnableCap.CullFace) ? 1 : 0)} cmode=0x{gl.GetInteger(GetPName.CullFaceMode):X} " +
$"fface=0x{gl.GetInteger(GetPName.FrontFace):X} " +
$"scis={(gl.IsEnabled(EnableCap.ScissorTest) ? 1 : 0)} sbox=({sbox[0]},{sbox[1]},{sbox[2]},{sbox[3]}) " +
$"vp=({vp[0]},{vp[1]},{vp[2]},{vp[3]}) " +
$"fbo={gl.GetInteger(GetPName.DrawFramebufferBinding)} " +
$"a2c={(gl.IsEnabled(EnableCap.SampleAlphaToCoverage) ? 1 : 0)} " +
$"stencil={(gl.IsEnabled(EnableCap.StencilTest) ? 1 : 0)} " +
$"clip=0x{clipBits:X2} err=0x{(int)err:X}";
if (sig == _lastGlStateSig)
{
_glStateStable++;
return;
}
Console.WriteLine($"[gl-state] frame={_glStateFrame} stable={_glStateStable} {sig}");
_lastGlStateSig = sig;
_glStateStable = 0;
}
private void EnableClipDistances()
{
for (int i = 0; i < ClipFrame.MaxPlanes; i++)

View file

@ -143,6 +143,18 @@ public static class RenderingDiagnostics
public static bool ProbePvInputEnabled { get; set; } =
Environment.GetEnvironmentVariable("ACDREAM_PROBE_PVINPUT") == "1";
/// <summary>
/// §4 outdoor full-world flap apparatus (2026-06-09). When true, GameWindow snapshots the
/// GL fixed-function state entering the world passes each frame (depth test/mask/func, blend
/// + factors, cull, front-face, scissor + box, viewport, draw-FBO, color mask, glGetError)
/// and emits one <c>[gl-state]</c> line whenever the snapshot CHANGES. Pins or refutes the
/// "leaked GL state" family for the flap (every CPU-side input — matrix, flood, clip planes,
/// scissor box, membership, eye-vs-terrain — is already probe-exonerated). Throwaway
/// apparatus — strip once §4 ships. Initial state from <c>ACDREAM_PROBE_GLSTATE=1</c>.
/// </summary>
public static bool ProbeGlStateEnabled { get; set; } =
Environment.GetEnvironmentVariable("ACDREAM_PROBE_GLSTATE") == "1";
/// <summary>
/// Bounded-propagation port apparatus (2026-06-08). When true, PortalVisibilityBuilder.Build emits
/// one [portal-churn] summary line per call: per-cell pop count (re-pops = churn), total re-enqueues,