acdream/src/AcDream.App/Rendering/Shader.cs
Erik c87b15303d refactor(lifetime): own render resource prefixes
Give terrain, sky, retained UI, portal preparation, and the update/render frame pair explicit single owners. Make shader, texture, text, bindless, and GL construction prefixes checked and retryable so partial failure cannot lose or replay resource ownership.

Co-authored-by: Codex <codex@openai.com>
2026-07-22 14:42:14 +02:00

82 lines
2.2 KiB
C#

using System.Numerics;
using Silk.NET.OpenGL;
namespace AcDream.App.Rendering;
public sealed class Shader : IDisposable
{
private readonly GL _gl;
private readonly Dictionary<string, int> _uniformLocations = new(StringComparer.Ordinal);
public uint Program { get; private set; }
public Shader(GL gl, string vertexPath, string fragmentPath)
{
_gl = gl;
string vertexSource = File.ReadAllText(vertexPath);
string fragmentSource = File.ReadAllText(fragmentPath);
Program = ShaderProgramConstruction.Build(
new GlShaderProgramBuildApi(gl),
vertexSource,
fragmentSource);
}
public void Use() => _gl.UseProgram(Program);
public unsafe void SetMatrix4(string name, Matrix4x4 m)
{
int loc = GetUniformLocation(name);
_gl.UniformMatrix4(loc, 1, false, (float*)&m);
}
public void SetInt(string name, int value)
{
int loc = GetUniformLocation(name);
_gl.Uniform1(loc, value);
}
public void SetFloat(string name, float value)
{
int loc = GetUniformLocation(name);
_gl.Uniform1(loc, value);
}
public void SetVec3(string name, Vector3 v)
{
int loc = GetUniformLocation(name);
_gl.Uniform3(loc, v.X, v.Y, v.Z);
}
public void SetVec2(string name, Vector2 v)
{
int loc = GetUniformLocation(name);
_gl.Uniform2(loc, v.X, v.Y);
}
public void SetVec4(string name, Vector4 v)
{
int loc = GetUniformLocation(name);
_gl.Uniform4(loc, v.X, v.Y, v.Z, v.W);
}
private int GetUniformLocation(string name)
{
ArgumentException.ThrowIfNullOrWhiteSpace(name);
if (_uniformLocations.TryGetValue(name, out int location))
return location;
location = _gl.GetUniformLocation(Program, name);
_uniformLocations.Add(name, location);
return location;
}
public void Dispose()
{
uint program = Program;
if (program == 0)
return;
_uniformLocations.Clear();
GlResourceCommand.DeleteProgram(_gl, program, $"delete Shader program {program}");
Program = 0;
}
}