acdream/src/AcDream.App/Rendering/Sky
Erik 3d21c1352a refactor(sky): replace per-frame wrap-mode mutation with persistent samplers
Ports WorldBuilder's GL sampler-object pattern
(references/WorldBuilder/Chorizite.OpenGLSDLBackend/OpenGLGraphicsDevice.cs:115-132,
SkyboxRenderManager.cs:312). Two persistent samplers (Repeat +
ClampToEdge) are created once at GL init; the sky pass binds the
appropriate one to texture unit 0 per submesh instead of mutating
per-texture GL_TEXTURE_WRAP_S/T state.

Why this is better than the prior M1 track-and-restore hack:

  1. Sampler state is decoupled from texture state. Two renderers can
     share the same texture handle but sample it with different wrap
     modes simultaneously and safely — sampler state at the bind point
     overrides the texture's own wrap parameters.

  2. No bookkeeping. Drops the HashSet<uint> clamped-textures tracking
     and the end-of-pass restore loop. The only restore needed is
     BindSampler(0, 0) to release unit 0 back to per-texture state.

  3. Constant cost. Sampler objects are created once per GL context,
     not per draw. Filter modes match TextureCache's upload defaults
     (Linear/Linear, no mipmaps) so the binding is purely a wrap-mode
     selection.

Field count: SkyRenderer.cs -28 lines, +14 lines. GameWindow.cs gets
the SamplerCache field + ctor + Dispose. SkyRenderer disposed before
SamplerCache so the sky teardown path doesn't reference a freed
sampler handle.

dotnet build green, dotnet test green: 695 / 393 / 243 = 1331 passed
(unchanged).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 08:08:26 +02:00
..
SkyRenderer.cs refactor(sky): replace per-frame wrap-mode mutation with persistent samplers 2026-04-29 08:08:26 +02:00