fix(render): Phase A8 — invalidate GL state caches at Render entry

User report from second visual gate (Step 5 disabled, ColorMask fixed):
"Cant see anything, flickering colors, sometimes I see textures and
sometimes I see inside, the house is missing lots of walls. 10 FPS."

Root cause: EnvCellRenderer._currentVao and _currentCullMode are STATIC
caches that let SetCullMode / BindVertexArray skip redundant GL state
changes when "already" in the right state. But other consumers
(WbDrawDispatcher, terrain renderer, the Step 1+2 stencil pipeline)
change the actual GL state without updating these caches. The cache
lies, the per-batch SetCullMode in RenderModernMDIInternal skips its
glCullFace call, and the cottage's mixed-cull-mode batches end up
rendering with whatever stale cull state was leaked from the prior
consumer. Walls with backface-only geometry vanish. The flicker is
the state alternating depending on which Render call set the cache
this frame.

WB invalidates these caches at line 404-410 of EnvCellRenderManager.cs:
  CurrentVAO = 0;
  CurrentIBO = 0;
  CurrentAtlas = 0;
  CurrentInstanceBuffer = 0;
  CurrentCullMode = null;

Our port missed this. Adding _currentVao = 0; _currentCullMode = null;
at Render entry forces each Render call to re-establish the GL state
it expects. (We only track Vao + CullMode in our minimal port; IBO/
Atlas/InstanceBuffer aren't cached in our class.)

Build green.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Erik 2026-05-27 16:10:52 +02:00
parent 9c5991061f
commit 9ee42d408a

View file

@ -613,6 +613,26 @@ public sealed unsafe class EnvCellRenderer : IDisposable
_shader.Use();
_poolIndex = snapshot.BatchedByCell.Count; // reset point (mirrors WB line 405)
// FIX 2026-05-28: invalidate static GL-state caches at start of Render.
// Mirrors WB EnvCellRenderManager.cs:404-410:
// CurrentVAO = 0; CurrentIBO = 0; CurrentAtlas = 0;
// CurrentInstanceBuffer = 0; CurrentCullMode = null;
//
// These caches let SetCullMode / BindVertexArray skip redundant GL
// calls when the state is already correct. BUT: between two Render()
// invocations, OTHER consumers (WbDrawDispatcher, terrain, the
// RenderInsideOutAcdream stencil pipeline) change the actual GL
// state without updating these caches. The cache then lies, and
// the per-batch SetCullMode in RenderModernMDIInternal skips its
// glCullFace call — leaving stale cull state from the prior
// consumer. For a cottage with mixed CullMode batches, half the
// walls end up culled and the user sees "missing walls".
//
// Forcing the cache to null/0 at entry guarantees each Render call
// re-establishes the GL state it expects.
_currentVao = 0;
_currentCullMode = null;
// WB EnvCellRenderManager.cs:406-409: uniform state setup.
_shader.SetInt("uRenderPass", (int)renderPass);
_shader.SetInt("uFilterByCell", 0);