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
113
src/AcDream.App/Rendering/RenderFrameGlStateController.cs
Normal file
113
src/AcDream.App/Rendering/RenderFrameGlStateController.cs
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
using Silk.NET.OpenGL;
|
||||
|
||||
namespace AcDream.App.Rendering;
|
||||
|
||||
internal interface IRenderFrameGlState
|
||||
{
|
||||
void RestoreFrameDefaults();
|
||||
}
|
||||
|
||||
internal interface IRenderFrameGlStateApi
|
||||
{
|
||||
void SetCapability(EnableCap capability, bool enabled);
|
||||
|
||||
void ColorMask(bool red, bool green, bool blue, bool alpha);
|
||||
|
||||
void StencilMask(uint mask);
|
||||
|
||||
void DepthMask(bool enabled);
|
||||
|
||||
void DepthFunc(DepthFunction function);
|
||||
|
||||
void CullFace(TriangleFace face);
|
||||
|
||||
void FrontFace(FrontFaceDirection direction);
|
||||
|
||||
void UseProgram(uint program);
|
||||
|
||||
void BindVertexArray(uint vertexArray);
|
||||
|
||||
void BindBuffer(BufferTargetARB target, uint buffer);
|
||||
}
|
||||
|
||||
internal sealed class SilkRenderFrameGlStateApi : IRenderFrameGlStateApi
|
||||
{
|
||||
private readonly GL _gl;
|
||||
|
||||
public SilkRenderFrameGlStateApi(GL gl)
|
||||
{
|
||||
_gl = gl ?? throw new ArgumentNullException(nameof(gl));
|
||||
}
|
||||
|
||||
public void SetCapability(EnableCap capability, bool enabled)
|
||||
{
|
||||
if (enabled)
|
||||
_gl.Enable(capability);
|
||||
else
|
||||
_gl.Disable(capability);
|
||||
}
|
||||
|
||||
public void ColorMask(bool red, bool green, bool blue, bool alpha) =>
|
||||
_gl.ColorMask(red, green, blue, alpha);
|
||||
|
||||
public void StencilMask(uint mask) => _gl.StencilMask(mask);
|
||||
|
||||
public void DepthMask(bool enabled) => _gl.DepthMask(enabled);
|
||||
|
||||
public void DepthFunc(DepthFunction function) => _gl.DepthFunc(function);
|
||||
|
||||
public void CullFace(TriangleFace face) => _gl.CullFace(face);
|
||||
|
||||
public void FrontFace(FrontFaceDirection direction) => _gl.FrontFace(direction);
|
||||
|
||||
public void UseProgram(uint program) => _gl.UseProgram(program);
|
||||
|
||||
public void BindVertexArray(uint vertexArray) => _gl.BindVertexArray(vertexArray);
|
||||
|
||||
public void BindBuffer(BufferTargetARB target, uint buffer) =>
|
||||
_gl.BindBuffer(target, buffer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Restores the frame-global OpenGL convention shared by frame clear and
|
||||
/// exceptional world-pass rollback. This prevents a failed doorway scissor or
|
||||
/// portal depth mask from clipping/color-masking the next frame's clear.
|
||||
/// </summary>
|
||||
internal sealed class RenderFrameGlStateController : IRenderFrameGlState
|
||||
{
|
||||
private readonly IRenderFrameGlStateApi _gl;
|
||||
|
||||
public RenderFrameGlStateController(IRenderFrameGlStateApi gl)
|
||||
{
|
||||
_gl = gl ?? throw new ArgumentNullException(nameof(gl));
|
||||
}
|
||||
|
||||
public void RestoreFrameDefaults()
|
||||
{
|
||||
_gl.SetCapability(EnableCap.ScissorTest, enabled: false);
|
||||
_gl.SetCapability(EnableCap.StencilTest, enabled: false);
|
||||
_gl.SetCapability(EnableCap.Blend, enabled: false);
|
||||
_gl.SetCapability(EnableCap.SampleAlphaToCoverage, enabled: false);
|
||||
for (int index = 0; index < ClipFrame.MaxPlanes; index++)
|
||||
{
|
||||
_gl.SetCapability(
|
||||
EnableCap.ClipDistance0 + index,
|
||||
enabled: false);
|
||||
}
|
||||
|
||||
_gl.ColorMask(true, true, true, true);
|
||||
_gl.StencilMask(0xFF);
|
||||
_gl.DepthMask(true);
|
||||
_gl.DepthFunc(DepthFunction.Less);
|
||||
_gl.SetCapability(EnableCap.DepthTest, enabled: true);
|
||||
// Renderers that need face culling establish it locally. The shared
|
||||
// frame convention is culling off; SkyRenderer restores the state it
|
||||
// observed, so enabling it here would leak culling into later passes.
|
||||
_gl.SetCapability(EnableCap.CullFace, enabled: false);
|
||||
_gl.CullFace(TriangleFace.Back);
|
||||
_gl.FrontFace(FrontFaceDirection.CW);
|
||||
_gl.UseProgram(0);
|
||||
_gl.BindVertexArray(0);
|
||||
_gl.BindBuffer(BufferTargetARB.ArrayBuffer, 0);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue