refactor(render): extract world scene frame owner
Move fallback and PView world drawing, shared alpha, particles, visibility, selection, and diagnostics behind focused frame owners. Make exceptional frames failure-atomic by restoring the shared GL baseline and preserving primary alpha failures through cleanup. Co-authored-by: Codex <codex@openai.com>
This commit is contained in:
parent
85239fb373
commit
28e1cf8029
25 changed files with 2679 additions and 844 deletions
|
|
@ -0,0 +1,106 @@
|
|||
using AcDream.App.Rendering;
|
||||
using Silk.NET.OpenGL;
|
||||
|
||||
namespace AcDream.App.Tests.Rendering;
|
||||
|
||||
public sealed class RenderFrameGlStateControllerTests
|
||||
{
|
||||
[Fact]
|
||||
public void RestoreFrameDefaults_ReestablishesTheCompleteFrameGlobalContract()
|
||||
{
|
||||
var api = new RecordingApi();
|
||||
var state = new RenderFrameGlStateController(api);
|
||||
|
||||
state.RestoreFrameDefaults();
|
||||
|
||||
Assert.Equal(
|
||||
[
|
||||
"cap:ScissorTest:False",
|
||||
"cap:StencilTest:False",
|
||||
"cap:Blend:False",
|
||||
"cap:SampleAlphaToMaskSgis:False",
|
||||
"cap:ClipDistance0:False",
|
||||
"cap:ClipDistance1:False",
|
||||
"cap:ClipDistance2:False",
|
||||
"cap:ClipDistance3:False",
|
||||
"cap:ClipDistance4:False",
|
||||
"cap:ClipDistance5:False",
|
||||
"cap:ClipDistance6:False",
|
||||
"cap:ClipDistance7:False",
|
||||
"color-mask:True:True:True:True",
|
||||
"stencil-mask:255",
|
||||
"depth-mask:True",
|
||||
"depth-func:Less",
|
||||
"cap:DepthTest:True",
|
||||
"cap:CullFace:False",
|
||||
"cull:Back",
|
||||
"front:CW",
|
||||
"program:0",
|
||||
"vao:0",
|
||||
"buffer:ArrayBuffer:0",
|
||||
],
|
||||
api.Calls);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void PortalDepthMask_SuccessExitRestoresTheSameCullOffConvention()
|
||||
{
|
||||
string source = File.ReadAllText(Path.Combine(
|
||||
FindRepoRoot(),
|
||||
"src",
|
||||
"AcDream.App",
|
||||
"Rendering",
|
||||
"PortalDepthMaskRenderer.cs"));
|
||||
int restore = source.IndexOf(
|
||||
"// ---- restore the frame-global convention ----",
|
||||
StringComparison.Ordinal);
|
||||
|
||||
Assert.True(restore >= 0, "Missing portal-depth state restore block.");
|
||||
string restoreBlock = source[restore..];
|
||||
Assert.Contains("_gl.Disable(EnableCap.CullFace);", restoreBlock);
|
||||
Assert.DoesNotContain("_gl.Enable(EnableCap.CullFace);", restoreBlock);
|
||||
}
|
||||
|
||||
private static string FindRepoRoot()
|
||||
{
|
||||
DirectoryInfo? directory = new(AppContext.BaseDirectory);
|
||||
while (directory is not null)
|
||||
{
|
||||
if (File.Exists(Path.Combine(directory.FullName, "AcDream.slnx")))
|
||||
return directory.FullName;
|
||||
directory = directory.Parent;
|
||||
}
|
||||
|
||||
throw new DirectoryNotFoundException("Could not find AcDream.slnx.");
|
||||
}
|
||||
|
||||
private sealed class RecordingApi : IRenderFrameGlStateApi
|
||||
{
|
||||
public List<string> Calls { get; } = [];
|
||||
|
||||
public void SetCapability(EnableCap capability, bool enabled) =>
|
||||
Calls.Add($"cap:{capability}:{enabled}");
|
||||
|
||||
public void ColorMask(bool red, bool green, bool blue, bool alpha) =>
|
||||
Calls.Add($"color-mask:{red}:{green}:{blue}:{alpha}");
|
||||
|
||||
public void StencilMask(uint mask) => Calls.Add($"stencil-mask:{mask}");
|
||||
|
||||
public void DepthMask(bool enabled) => Calls.Add($"depth-mask:{enabled}");
|
||||
|
||||
public void DepthFunc(DepthFunction function) =>
|
||||
Calls.Add($"depth-func:{function}");
|
||||
|
||||
public void CullFace(TriangleFace face) => Calls.Add($"cull:{face}");
|
||||
|
||||
public void FrontFace(FrontFaceDirection direction) =>
|
||||
Calls.Add($"front:{direction}");
|
||||
|
||||
public void UseProgram(uint program) => Calls.Add($"program:{program}");
|
||||
|
||||
public void BindVertexArray(uint vertexArray) => Calls.Add($"vao:{vertexArray}");
|
||||
|
||||
public void BindBuffer(BufferTargetARB target, uint buffer) =>
|
||||
Calls.Add($"buffer:{target}:{buffer}");
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue