fix(render): Phase A8 — EnvCellRenderer uses acdream Shader (not GLSLShader)

Task 5's subagent took GLSLShader (WB's abstract shader). Our existing
GameWindow wire-in uses the legacy AcDream.App.Rendering.Shader class
loaded once at startup for mesh_modern.{vert,frag} and shared with
WbDrawDispatcher. Matching that convention keeps the wire-in trivial
and avoids a second shader compile.

API mapping (acdream Shader is the surface here):
  Bind()                      -> Use()
  SetUniform(name, int)       -> SetInt(name, int)
  SetUniform(name, Vector4)   -> SetVec4(name, Vector4)
  SetUniform(name, Matrix4x4) -> SetMatrix4(name, Matrix4x4)  (unused)

Build green. 23/23 Wave 1+2 tests still pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Erik 2026-05-27 14:57:29 +02:00
parent f16b8e9812
commit aad9ed4cdb

View file

@ -48,7 +48,12 @@ public sealed unsafe class EnvCellRenderer : IDisposable
private EnvCellVisibilitySnapshot _activeSnapshot = new(); private EnvCellVisibilitySnapshot _activeSnapshot = new();
// Shader (set by caller via Initialize). // Shader (set by caller via Initialize).
private GLSLShader? _shader; // Uses acdream's legacy Shader type (not WB's GLSLShader) to match the
// existing wire-in pattern in GameWindow.cs where _meshShader is loaded
// for mesh_modern.{vert,frag} and shared across multiple consumers.
// API mapping: Bind() -> Use(), SetUniform(s, int) -> SetInt(s, int),
// SetUniform(s, Vector4) -> SetVec4(s, Vector4).
private AcDream.App.Rendering.Shader? _shader;
private bool _initialized; private bool _initialized;
// List pool — copied from WB ObjectRenderManagerBase. // List pool — copied from WB ObjectRenderManagerBase.
@ -94,7 +99,7 @@ public sealed unsafe class EnvCellRenderer : IDisposable
_frustum = frustum; _frustum = frustum;
} }
public void Initialize(GLSLShader shader) public void Initialize(AcDream.App.Rendering.Shader shader)
{ {
_shader = shader; _shader = shader;
AllocateMdiBuffers(); AllocateMdiBuffers();
@ -577,7 +582,10 @@ public sealed unsafe class EnvCellRenderer : IDisposable
// - Drop the _useModernRendering branch (our codebase asserts modern at startup per Phase N.5). // - Drop the _useModernRendering branch (our codebase asserts modern at startup per Phase N.5).
// - Drop SelectedInstance/HoveredInstance highlight block (lines 486-510) — no editor state. // - Drop SelectedInstance/HoveredInstance highlight block (lines 486-510) — no editor state.
// - Replace RenderModernMDI(base) with private RenderModernMDIInternal. // - Replace RenderModernMDI(base) with private RenderModernMDIInternal.
// - shader.Bind() / SetUniform API: use our GLSLShader.Bind() + SetUniform(string,int). // - shader.Bind() / SetUniform API: mapped to acdream's legacy Shader
// class (Use() + SetInt/SetVec4/SetMatrix4) to match the existing
// wire-in pattern in GameWindow.cs where _meshShader is loaded once
// for mesh_modern.{vert,frag} and shared with WbDrawDispatcher.
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
public void Render(WbRenderPass renderPass) public void Render(WbRenderPass renderPass)
@ -602,12 +610,12 @@ public sealed unsafe class EnvCellRenderer : IDisposable
{ {
var snapshot = _activeSnapshot; var snapshot = _activeSnapshot;
// WB EnvCellRenderManager.cs:403-404: // WB EnvCellRenderManager.cs:403-404:
_shader.Bind(); _shader.Use();
_poolIndex = snapshot.BatchedByCell.Count; // reset point (mirrors WB line 405) _poolIndex = snapshot.BatchedByCell.Count; // reset point (mirrors WB line 405)
// WB EnvCellRenderManager.cs:406-409: uniform state setup. // WB EnvCellRenderManager.cs:406-409: uniform state setup.
_shader.SetUniform("uRenderPass", (int)renderPass); _shader.SetInt("uRenderPass", (int)renderPass);
_shader.SetUniform("uFilterByCell", 0); _shader.SetInt("uFilterByCell", 0);
var allInstances = new List<InstanceData>(); var allInstances = new List<InstanceData>();
var drawCalls = new List<(ObjectRenderData renderData, int count, int offset)>(); var drawCalls = new List<(ObjectRenderData renderData, int count, int offset)>();
@ -687,8 +695,8 @@ public sealed unsafe class EnvCellRenderer : IDisposable
// WB EnvCellRenderManager.cs:486-510: selection/hover highlights — DROPPED (no editor state). // WB EnvCellRenderManager.cs:486-510: selection/hover highlights — DROPPED (no editor state).
// WB EnvCellRenderManager.cs:506-509: cleanup. // WB EnvCellRenderManager.cs:506-509: cleanup.
_shader.SetUniform("uHighlightColor", new System.Numerics.Vector4(0, 0, 0, 0)); _shader.SetVec4("uHighlightColor", new System.Numerics.Vector4(0, 0, 0, 0));
_shader.SetUniform("uRenderPass", (int)renderPass); _shader.SetInt("uRenderPass", (int)renderPass);
_gl.BindVertexArray(0); _gl.BindVertexArray(0);
_currentVao = 0; _currentVao = 0;
@ -710,7 +718,7 @@ public sealed unsafe class EnvCellRenderer : IDisposable
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
private void RenderModernMDIInternal( private void RenderModernMDIInternal(
GLSLShader shader, AcDream.App.Rendering.Shader shader,
List<(ObjectRenderData renderData, int count, int offset)> drawCalls, List<(ObjectRenderData renderData, int count, int offset)> drawCalls,
List<InstanceData> allInstances, List<InstanceData> allInstances,
WbRenderPass renderPass) WbRenderPass renderPass)
@ -722,8 +730,8 @@ public sealed unsafe class EnvCellRenderer : IDisposable
if (passIdx < 0 || passIdx > 2) return; if (passIdx < 0 || passIdx > 2) return;
// WB BaseObjectRenderManager.cs:715-716: // WB BaseObjectRenderManager.cs:715-716:
shader.Bind(); shader.Use();
shader.SetUniform("uFilterByCell", 0); shader.SetInt("uFilterByCell", 0);
// WB BaseObjectRenderManager.cs:718-740: group batches by CullMode + additive flag. // WB BaseObjectRenderManager.cs:718-740: group batches by CullMode + additive flag.
var batchesByCullMode = new Dictionary<int, List<(ObjectRenderBatch batch, int instanceCount, int instanceOffset)>>(); var batchesByCullMode = new Dictionary<int, List<(ObjectRenderBatch batch, int instanceCount, int instanceOffset)>>();
@ -873,15 +881,15 @@ public sealed unsafe class EnvCellRenderer : IDisposable
if (isAdditive) if (isAdditive)
{ {
_gl.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.One); _gl.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.One);
shader.SetUniform("uRenderPass", (int)renderPass | 0x100); shader.SetInt("uRenderPass", (int)renderPass | 0x100);
} }
else else
{ {
_gl.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha); _gl.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);
shader.SetUniform("uRenderPass", (int)renderPass); shader.SetInt("uRenderPass", (int)renderPass);
} }
shader.SetUniform("uDrawIDOffset", currentDrawOffset); shader.SetInt("uDrawIDOffset", currentDrawOffset);
int numDraws = group.Value.Count; int numDraws = group.Value.Count;
_gl.MultiDrawElementsIndirect( _gl.MultiDrawElementsIndirect(
PrimitiveType.Triangles, PrimitiveType.Triangles,
@ -894,7 +902,7 @@ public sealed unsafe class EnvCellRenderer : IDisposable
} }
// WB BaseObjectRenderManager.cs:845-847: // WB BaseObjectRenderManager.cs:845-847:
shader.SetUniform("uDrawIDOffset", 0); shader.SetInt("uDrawIDOffset", 0);
_gl.BindBuffer(GLEnum.DrawIndirectBuffer, 0); _gl.BindBuffer(GLEnum.DrawIndirectBuffer, 0);
} }