Without this, ObjectMeshManager.StagedMeshData and
OpenGLGraphicsDevice._glThreadQueue grow unbounded as background
workers prep mesh data + queue GL actions. Visual stress test of
flag-on at radius 7 showed real FPS drop and rising frame latency
from this leak.
Tick() drains both queues:
1. _graphicsDevice.ProcessGLQueue() applies pending GL state.
2. Loop _meshManager.StagedMeshData.TryDequeue -> UploadMeshData
to materialize VAO/VBO/IBO for each prepared mesh.
Wired into GameWindow's render loop before draw work begins.
No-op when adapter is uninitialized or disposed.
Pattern matches WB's reference ObjectRenderManagerBase.ProcessUploads
without the prioritization heuristics (we're not yet drawing the
results — Task 22's WbDrawDispatcher will add prioritization when
visual budget matters).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
WbMeshAdapter now actually constructs the WB pipeline:
- OpenGLGraphicsDevice(gl, logger, DebugRenderSettings)
- DefaultDatReaderWriter(datDir) — opens its own file handles for now
(memory cost ~50-100MB of duplicate index caches, acceptable for
foundation work per plan Adjustment 1)
- ObjectMeshManager(graphicsDevice, dats, NullLogger)
InstancedMeshRenderer.EnsureUploaded routes through the adapter when
ACDREAM_USE_WB_FOUNDATION=1 is set; uses a WbManagedSentinel entry
in the local cache to mark "this GfxObj lives in WB now". CollectGroups
skips sentinel entries; both Draw passes skip them; Dispose skips them
(no GL resources to free — ObjectMeshManager owns those). Task 22's
WbDrawDispatcher will eventually draw WB-managed objects. With flag
off, behavior is byte-identical to before.
WbMeshAdapter constructor signature changed from (GL, DatCollection,
Logger) to (GL, string datDir, Logger). Updated tests to use
CreateUninitialized() for behavior tests and single null-GL guard test
for constructor validation. GameWindow updated to pass _datDir and to
wire _wbMeshAdapter into InstancedMeshRenderer.
AcDream.App.csproj gets direct ProjectReferences to WorldBuilder.Shared
and Chorizite.OpenGLSDLBackend — project refs are not transitive in
.NET, so AcDream.App must list them explicitly even though AcDream.Core
already references them.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Stub adapter that validates constructor args and exposes the public
shape (IncrementRefCount / DecrementRefCount / GetRenderData / Dispose).
Real ObjectMeshManager init is deferred to Task 9 — for now methods
no-op so call sites can wire the adapter without behavioral effect.
IWbMeshAdapter interface enables mocking in subsequent tasks
(LandblockSpawnAdapter tests in Task 11 need it).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>