acdream/src/AcDream.App/Rendering/Wb
Erik 0940d7961a fix(render): Phase A8 — cell-mesh Landblock CullMode → None + cull state restore
The cull A/B diagnostic (prior commit's ACDREAM_A8_DISABLE_CULL=1) in
visual-gate-#3 confirmed: cell-mesh polys are being culled by back-face
culling, which is why floors disappear when looking down from inside a
room. Per-cell audit data showed every cell-mesh batch has
CullMode.Landblock — assigned because AC's CellStruct polys carry
SidesType=Landblock in the dat. Our SetCullMode maps Landblock to
glCullFace(Back), matching WB.

Root cause:
WB sets `glFrontFace(GLEnum.CW)` globally at GameScene.cs:843. Our
WbDrawDispatcher.cs:1056 sets `glFrontFace(CCW)` — the GL default,
opposite of WB. With our flipped-from-natural fan triangulation in
BuildCellStructPolygonIndices (which emits (i, i-1, 0) for each fan
triangle, reversing the input vertex order), the resulting effective
winding from the camera's perspective is OPPOSITE WB's. Cull-back then
removes the OPPOSITE face from what WB does — hiding the floor side
that should be visible from inside the room.

Within a single cell-mesh batch, the polys face every direction (walls
outward, floor up, ceiling down) but all share CullMode.Landblock. No
single cull setting can be correct for all three orientations
simultaneously — the retail-faithful approach is to render cell polys
double-sided (cull off).

Two changes scoped to EnvCellRenderer.RenderModernMDIInternal so other
renderers aren't affected:
  1. Remap CullMode.Landblock → None when iterating per-cull-mode
     batch groups. Cell polys render with cull disabled, all faces
     visible. CullMode.Landblock is only assigned by
     PrepareCellStructMeshData (cell polys) in this codebase — terrain
     uses a different render path. Scope is exactly right.
  2. Explicitly Enable(CullFace) + CullFace(Back) at Render exit so the
     dispatcher's subsequent IndoorPass + LiveDynamic Draws don't
     inherit the cull-disabled state. The see-through-head symptom in
     visual-gate-#3 was caused by exactly this state leak from the
     ACDREAM_A8_DISABLE_CULL=1 diagnostic; the proper fix needs the
     explicit restore. Also updates the static `_currentCullMode` cache
     so the next Render call's first SetCullMode comparison is correct.

Removed the ACDREAM_A8_DISABLE_CULL diagnostic env var — its role as
A/B test is complete. 14/14 EnvCellRenderer tests pass. Build green.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 20:12:20 +02:00
..
AcSurfaceMetadata.cs phase(N.4): AcSurfaceMetadata side-table for WB-pristine surface props 2026-05-08 13:08:56 +02:00
AcSurfaceMetadataTable.cs phase(N.4): AcSurfaceMetadata side-table for WB-pristine surface props 2026-05-08 13:08:56 +02:00
ActiveParticleEmitter.cs feat(O-T7): drop WB project references; complete extraction 2026-05-21 17:17:33 +02:00
AnimatedEntityState.cs phase(N.4) Tasks 16+18+19: AnimatedEntityState + AnimPartChange + HiddenParts 2026-05-08 14:37:09 +02:00
BindlessSupport.cs fix(N.5b): black terrain — switch to uvec2 handle + sampler constructor 2026-05-09 12:53:21 +02:00
BufferUsageExtensions.cs feat(O-T3): extract GL infrastructure to AcDream.App 2026-05-21 16:00:31 +02:00
Building.cs feat(render): Phase A8 RR3 — Building + BuildingRegistry + BuildingLoader 2026-05-27 11:08:43 +02:00
BuildingLoader.cs Revert "fix(render): Phase A8 RR7.3 — dat-driven BFS in BuildingLoader" 2026-05-27 14:07:13 +02:00
BuildingRegistry.cs feat(render): Phase A8 RR3 — Building + BuildingRegistry + BuildingLoader 2026-05-27 11:08:43 +02:00
CachedBatch.cs feat(render #53): EntityClassificationCache skeleton + first test 2026-05-10 17:23:37 +02:00
DatCollectionAdapter.cs feat(O-T7): drop WB project references; complete extraction 2026-05-21 17:17:33 +02:00
DebugRenderSettings.cs feat(O-T3): extract GL infrastructure to AcDream.App 2026-05-21 16:00:31 +02:00
DrawElementsIndirectCommand.cs phase(N.5) Task 7: dispatcher SSBO + indirect buffer infrastructure 2026-05-08 20:25:29 +02:00
EdgeLineBuilder.cs feat(O-T4): extract ObjectMeshManager + mesh pipeline closure into AcDream.App.Rendering.Wb 2026-05-21 16:37:55 +02:00
EmbeddedResourceReader.cs fix(O-T4): address spec-review findings — InstanceData + using cleanups 2026-05-21 16:50:05 +02:00
EntityClassificationCache.cs fix(render #53): key cache by (entityId, landblockHint) to defeat ID collision 2026-05-10 23:02:14 +02:00
EntitySpawnAdapter.cs feat(A.5 T18): use cached WorldEntity AABB in dispatcher; populate at register 2026-05-10 08:20:20 +02:00
EnvCellRenderer.cs fix(render): Phase A8 — cell-mesh Landblock CullMode → None + cull state restore 2026-05-27 20:12:20 +02:00
EnvCellSceneryInstance.cs feat(render): Phase A8 Wave 1 — WB scaffolding extraction + stencil low-level method 2026-05-27 14:46:07 +02:00
EnvCellVisibilitySnapshot.cs fix(render): Phase A8 — pool aliasing in EnvCellRenderer (visual chaos root cause) 2026-05-27 19:08:49 +02:00
GeometryUtils.cs feat(O-T7): drop WB project references; complete extraction 2026-05-21 17:17:33 +02:00
GLHelpers.cs feat(O-T3): extract GL infrastructure to AcDream.App 2026-05-21 16:00:31 +02:00
GlobalMeshBuffer.cs feat(O-T4): extract ObjectMeshManager + mesh pipeline closure into AcDream.App.Rendering.Wb 2026-05-21 16:37:55 +02:00
GLSLShader.cs feat(O-T3): extract GL infrastructure to AcDream.App 2026-05-21 16:00:31 +02:00
GLStateScope.cs feat(O-T3): extract GL infrastructure to AcDream.App 2026-05-21 16:00:31 +02:00
GpuMemoryTracker.cs feat(O-T3): extract GL infrastructure to AcDream.App 2026-05-21 16:00:31 +02:00
GroupKey.cs refactor(render): extract WbDrawDispatcher.GroupKey to internal type at namespace scope 2026-05-10 17:13:44 +02:00
IDatReaderWriter.cs chore(O-T7): code-review housekeeping after WB extraction 2026-05-21 17:29:06 +02:00
InstanceData.cs fix(O-T4): address spec-review findings — InstanceData + using cleanups 2026-05-21 16:50:05 +02:00
ITextureCachePerInstance.cs phase(N.4) Task 17: EntitySpawnAdapter for server-spawned per-instance content 2026-05-08 14:46:34 +02:00
IWbMeshAdapter.cs phase(N.4): WbMeshAdapter stub + IWbMeshAdapter interface 2026-05-08 13:18:50 +02:00
LandblockSpawnAdapter.cs phase(N.4) Task 11: LandblockSpawnAdapter (atlas-tier ref-count bridge) 2026-05-08 13:53:38 +02:00
ManagedGLFrameBuffer.cs feat(O-T3): extract GL infrastructure to AcDream.App 2026-05-21 16:00:31 +02:00
ManagedGLIndexBuffer.cs feat(O-T7): drop WB project references; complete extraction 2026-05-21 17:17:33 +02:00
ManagedGLTexture.cs feat(O-T7): drop WB project references; complete extraction 2026-05-21 17:17:33 +02:00
ManagedGLTextureArray.cs feat(O-T7): drop WB project references; complete extraction 2026-05-21 17:17:33 +02:00
ManagedGLUniformBuffer.cs feat(O-T3): extract GL infrastructure to AcDream.App 2026-05-21 16:00:31 +02:00
ManagedGLVertexArray.cs feat(O-T3): extract GL infrastructure to AcDream.App 2026-05-21 16:00:31 +02:00
ManagedGLVertexBuffer.cs feat(O-T3): extract GL infrastructure to AcDream.App 2026-05-21 16:00:31 +02:00
ModernRenderData.cs feat(O-T4): extract ObjectMeshManager + mesh pipeline closure into AcDream.App.Rendering.Wb 2026-05-21 16:37:55 +02:00
ObjectMeshManager.cs feat(O-T7): drop WB project references; complete extraction 2026-05-21 17:17:33 +02:00
OpenGLGraphicsDevice.cs fix(O-T4): address spec-review findings — InstanceData + using cleanups 2026-05-21 16:50:05 +02:00
ParticleBatcher.cs feat(O-T7): drop WB project references; complete extraction 2026-05-21 17:17:33 +02:00
ParticleEmitterRenderer.cs feat(O-T4): extract ObjectMeshManager + mesh pipeline closure into AcDream.App.Rendering.Wb 2026-05-21 16:37:55 +02:00
RenderStateCache.cs chore(O-T7): code-review housekeeping after WB extraction 2026-05-21 17:29:06 +02:00
SceneData.cs feat(O-T3): extract GL infrastructure to AcDream.App 2026-05-21 16:00:31 +02:00
TextureAtlasManager.cs feat(O-T4): extract ObjectMeshManager + mesh pipeline closure into AcDream.App.Rendering.Wb 2026-05-21 16:37:55 +02:00
TextureFormatExtensions.cs feat(O-T3): extract GL infrastructure to AcDream.App 2026-05-21 16:00:31 +02:00
TextureParameters.cs feat(O-T3): extract GL infrastructure to AcDream.App 2026-05-21 16:00:31 +02:00
WbDrawDispatcher.cs feat(render): Phase A8 RR5 — WbDrawDispatcher Draw(cellIds:) overload 2026-05-27 11:18:21 +02:00
WbFrustum.cs feat(render): Phase A8 Wave 1 — WB scaffolding extraction + stencil low-level method 2026-05-27 14:46:07 +02:00
WbMeshAdapter.cs feat(render): Phase A8 Wave 3 — wire EnvCellRenderer into landblock streaming 2026-05-27 15:03:17 +02:00
WbRenderPass.cs feat(render): Phase A8 Wave 1 — WB scaffolding extraction + stencil low-level method 2026-05-27 14:46:07 +02:00