refactor(app): compose world rendering startup

Move Region/environment, mandatory modern rendering, terrain, WB, texture, and sampler construction behind the typed Phase-4 composition boundary. Give every fallible GL constructor prefix retryable ownership so partial startup failure cannot leak or replay resource deletion while preserving the accepted render path and DAT inputs.

Co-authored-by: Codex <codex@openai.com>
This commit is contained in:
Erik 2026-07-22 16:46:05 +02:00
parent cd7b519f78
commit 6a2fe98cc4
22 changed files with 1983 additions and 634 deletions

View file

@ -88,6 +88,7 @@ void main() { } // depth-only: color writes are masked off by the caller state
private readonly int _locForceFarZ;
private readonly int _locDepthBias;
private readonly int _locDepthBiasEyeCapN;
private readonly ResourceCleanupGroup _resources;
private const int MaxFanVerts = 32;
private readonly float[] _scratch = new float[MaxFanVerts * 3];
@ -109,28 +110,52 @@ void main() { } // depth-only: color writes are masked off by the caller state
public PortalDepthMaskRenderer(GL gl)
{
_gl = gl ?? throw new ArgumentNullException(nameof(gl));
var resources = new ResourceCleanupGroup();
try
{
_program = ShaderProgramConstruction.Build(
new GlShaderProgramBuildApi(gl),
VertSrc,
FragSrc);
resources.Add(
"portal-depth program",
() => GlResourceCommand.DeleteProgram(
gl,
_program,
$"delete PortalDepthMask program {_program}"));
uint vs = Compile(ShaderType.VertexShader, VertSrc);
uint fs = Compile(ShaderType.FragmentShader, FragSrc);
_program = _gl.CreateProgram();
_gl.AttachShader(_program, vs);
_gl.AttachShader(_program, fs);
_gl.LinkProgram(_program);
_gl.GetProgram(_program, ProgramPropertyARB.LinkStatus, out int linked);
if (linked == 0)
throw new InvalidOperationException($"PortalDepthMask link failed: {_gl.GetProgramInfoLog(_program)}");
_gl.DeleteShader(vs);
_gl.DeleteShader(fs);
(
_locViewProjection,
_locPlaneCount,
_locPlanes,
_locForceFarZ,
_locDepthBias,
_locDepthBiasEyeCapN) = GlResourceCommand.Execute(
_gl,
"resolve PortalDepthMask uniforms",
() => (
_gl.GetUniformLocation(_program, "uViewProjection"),
_gl.GetUniformLocation(_program, "uPlaneCount"),
_gl.GetUniformLocation(_program, "uPlanes"),
_gl.GetUniformLocation(_program, "uForceFarZ"),
_gl.GetUniformLocation(_program, "uDepthBias"),
_gl.GetUniformLocation(_program, "uDepthBiasEyeCapN")));
_locViewProjection = _gl.GetUniformLocation(_program, "uViewProjection");
_locPlaneCount = _gl.GetUniformLocation(_program, "uPlaneCount");
_locPlanes = _gl.GetUniformLocation(_program, "uPlanes");
_locForceFarZ = _gl.GetUniformLocation(_program, "uForceFarZ");
_locDepthBias = _gl.GetUniformLocation(_program, "uDepthBias");
_locDepthBiasEyeCapN = _gl.GetUniformLocation(_program, "uDepthBiasEyeCapN");
for (int i = 0; i < _frameBuffers.Length; i++)
{
FrameBufferSet set = CreateFrameBufferSet(resources, i);
_frameBuffers[i] = set;
}
}
catch (Exception constructionFailure)
{
resources.RollbackConstructionAndThrow(
"PortalDepthMaskRenderer construction failed and its GL prefix did not cleanly roll back.",
constructionFailure);
throw new System.Diagnostics.UnreachableException();
}
for (int i = 0; i < _frameBuffers.Length; i++)
_frameBuffers[i] = CreateFrameBufferSet();
_resources = resources;
}
/// <summary>
@ -146,19 +171,34 @@ void main() { } // depth-only: color writes are masked off by the caller state
_activeFrameBuffer.UsedVertices = 0;
}
private FrameBufferSet CreateFrameBufferSet()
private FrameBufferSet CreateFrameBufferSet(
ResourceCleanupGroup resources,
int frameIndex)
{
uint vao = 0;
uint vbo = 0;
try
uint vao = TrackedGlResource.CreateVertexArray(
_gl,
"PortalDepthMask frame VAO creation");
RetryableGpuResourceRelease vaoRelease =
TrackedGlResource.CreateRetryableVertexArrayDeletion(
_gl,
vao,
"PortalDepthMask frame VAO disposal");
resources.Add($"portal-depth frame {frameIndex} VAO", vaoRelease.Run);
uint vbo = TrackedGlResource.CreateBuffer(
_gl,
"PortalDepthMask frame VBO creation");
var set = new FrameBufferSet { Vao = vao, Vbo = vbo };
RetryableGpuResourceRelease vboRelease =
TrackedGlResource.CreateRetryableBufferDeletion(
_gl,
vbo,
() => set.CapacityBytes,
"PortalDepthMask frame VBO disposal");
resources.Add($"portal-depth frame {frameIndex} VBO", vboRelease.Run);
GlResourceCommand.Execute(_gl, "configure PortalDepthMask frame buffers", () =>
{
vao = TrackedGlResource.CreateVertexArray(
_gl,
"PortalDepthMask frame VAO creation");
vbo = TrackedGlResource.CreateBuffer(
_gl,
"PortalDepthMask frame VBO creation");
var set = new FrameBufferSet { Vao = vao, Vbo = vbo };
_gl.BindVertexArray(set.Vao);
_gl.BindBuffer(BufferTargetARB.ArrayBuffer, set.Vbo);
unsafe
@ -168,29 +208,8 @@ void main() { } // depth-only: color writes are masked off by the caller state
_gl.EnableVertexAttribArray(0);
_gl.BindVertexArray(0);
_gl.BindBuffer(BufferTargetARB.ArrayBuffer, 0);
return set;
}
catch
{
if (vbo != 0)
TrackedGlResource.DeleteBuffer(
_gl, vbo, 0, "PortalDepthMask frame VBO rollback");
if (vao != 0)
TrackedGlResource.DeleteVertexArray(
_gl, vao, "PortalDepthMask frame VAO rollback");
throw;
}
}
private uint Compile(ShaderType type, string src)
{
uint s = _gl.CreateShader(type);
_gl.ShaderSource(s, src);
_gl.CompileShader(s);
_gl.GetShader(s, ShaderParameterName.CompileStatus, out int ok);
if (ok == 0)
throw new InvalidOperationException($"PortalDepthMask {type} compile failed: {_gl.GetShaderInfoLog(s)}");
return s;
});
return set;
}
/// <summary>
@ -387,18 +406,6 @@ void main() { } // depth-only: color writes are masked off by the caller state
public void Dispose()
{
_gl.DeleteProgram(_program);
foreach (FrameBufferSet set in _frameBuffers)
{
TrackedGlResource.DeleteVertexArray(
_gl,
set.Vao,
"PortalDepthMask frame VAO disposal");
TrackedGlResource.DeleteBuffer(
_gl,
set.Vbo,
set.CapacityBytes,
"PortalDepthMask frame VBO disposal");
}
_resources.RetryCleanup();
}
}