diff --git a/src/AcDream.App/Rendering/Wb/EnvCellRenderer.cs b/src/AcDream.App/Rendering/Wb/EnvCellRenderer.cs index cf713c0..4820f51 100644 --- a/src/AcDream.App/Rendering/Wb/EnvCellRenderer.cs +++ b/src/AcDream.App/Rendering/Wb/EnvCellRenderer.cs @@ -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);