acdream/src/AcDream.App/Rendering/Shader.cs
Erik 87c45c70ac feat(app): render landblock with height-ramp shader + orbit camera
Adds a 2-stage GLSL shader (vertex + fragment), a Shader helper that
compiles/links and exposes SetMatrix4 for uniforms, and an OrbitCamera
with yaw/pitch/distance and a 192-unit-centered target for a single
landblock. TerrainRenderer now takes a Shader and issues an actual
DrawElements call with uView + uProjection uniforms. GameWindow owns
the Shader and Camera, routes mouse drag to camera yaw/pitch, and
scroll wheel to camera distance.

The fragment shader maps world Z to a green-brown-white ramp so
lowlands read green, midlands brown, and peaks white — no textures
yet, but enough to visually confirm the terrain shape.

Shaders are copied to the output dir via a <None Update> item group.

Smoke verified against real dats: process stays alive with no GL
errors, no shader compile/link failures, and no exception trail.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 16:44:08 +02:00

50 lines
1.6 KiB
C#

using System.Numerics;
using Silk.NET.OpenGL;
namespace AcDream.App.Rendering;
public sealed class Shader : IDisposable
{
private readonly GL _gl;
public uint Program { get; }
public Shader(GL gl, string vertexPath, string fragmentPath)
{
_gl = gl;
uint vert = Compile(File.ReadAllText(vertexPath), ShaderType.VertexShader);
uint frag = Compile(File.ReadAllText(fragmentPath), ShaderType.FragmentShader);
Program = _gl.CreateProgram();
_gl.AttachShader(Program, vert);
_gl.AttachShader(Program, frag);
_gl.LinkProgram(Program);
_gl.GetProgram(Program, ProgramPropertyARB.LinkStatus, out int linked);
if (linked == 0)
throw new Exception("program link failed: " + _gl.GetProgramInfoLog(Program));
_gl.DetachShader(Program, vert);
_gl.DetachShader(Program, frag);
_gl.DeleteShader(vert);
_gl.DeleteShader(frag);
}
private uint Compile(string source, ShaderType type)
{
uint id = _gl.CreateShader(type);
_gl.ShaderSource(id, source);
_gl.CompileShader(id);
_gl.GetShader(id, ShaderParameterName.CompileStatus, out int ok);
if (ok == 0)
throw new Exception($"{type} compile failed: " + _gl.GetShaderInfoLog(id));
return id;
}
public void Use() => _gl.UseProgram(Program);
public unsafe void SetMatrix4(string name, Matrix4x4 m)
{
int loc = _gl.GetUniformLocation(Program, name);
_gl.UniformMatrix4(loc, 1, false, (float*)&m);
}
public void Dispose() => _gl.DeleteProgram(Program);
}