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>
This commit is contained in:
parent
8356fe65a0
commit
87c45c70ac
7 changed files with 154 additions and 7 deletions
|
|
@ -16,7 +16,11 @@ public sealed class GameWindow : IDisposable
|
|||
private GL? _gl;
|
||||
private IInputContext? _input;
|
||||
private TerrainRenderer? _terrain;
|
||||
private Shader? _shader;
|
||||
private OrbitCamera? _camera;
|
||||
private DatCollection? _dats;
|
||||
private float _lastMouseX;
|
||||
private float _lastMouseY;
|
||||
|
||||
public GameWindow(string datDir) => _datDir = datDir;
|
||||
|
||||
|
|
@ -53,9 +57,37 @@ public sealed class GameWindow : IDisposable
|
|||
_window!.Close();
|
||||
};
|
||||
|
||||
foreach (var mouse in _input.Mice)
|
||||
{
|
||||
mouse.MouseMove += (m, pos) =>
|
||||
{
|
||||
if (m.IsButtonPressed(MouseButton.Left))
|
||||
{
|
||||
_camera!.Yaw -= (pos.X - _lastMouseX) * 0.005f;
|
||||
_camera!.Pitch = Math.Clamp(
|
||||
_camera.Pitch + (pos.Y - _lastMouseY) * 0.005f,
|
||||
0.1f, 1.5f);
|
||||
}
|
||||
_lastMouseX = pos.X;
|
||||
_lastMouseY = pos.Y;
|
||||
};
|
||||
mouse.Scroll += (_, scroll) =>
|
||||
_camera!.Distance = Math.Clamp(_camera.Distance - scroll.Y * 20f, 50f, 2000f);
|
||||
}
|
||||
|
||||
_gl.ClearColor(0.05f, 0.10f, 0.18f, 1.0f);
|
||||
_gl.Enable(EnableCap.DepthTest);
|
||||
|
||||
string shadersDir = Path.Combine(AppContext.BaseDirectory, "Rendering", "Shaders");
|
||||
_shader = new Shader(_gl,
|
||||
Path.Combine(shadersDir, "terrain.vert"),
|
||||
Path.Combine(shadersDir, "terrain.frag"));
|
||||
|
||||
_camera = new OrbitCamera
|
||||
{
|
||||
Aspect = _window!.Size.X / (float)_window.Size.Y,
|
||||
};
|
||||
|
||||
_dats = new DatCollection(_datDir, DatAccessType.Read);
|
||||
|
||||
// Find ANY landblock ending in 0xFFFF. Holtburg 0xA9B4FFFF is a
|
||||
|
|
@ -81,18 +113,19 @@ public sealed class GameWindow : IDisposable
|
|||
Console.WriteLine($"loaded landblock 0x{landblockId:X8}");
|
||||
|
||||
var meshData = LandblockMesh.Build(block);
|
||||
_terrain = new TerrainRenderer(_gl, meshData);
|
||||
_terrain = new TerrainRenderer(_gl, meshData, _shader);
|
||||
}
|
||||
|
||||
private void OnRender(double deltaSeconds)
|
||||
{
|
||||
_gl!.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
|
||||
_terrain?.Draw();
|
||||
_terrain?.Draw(_camera!);
|
||||
}
|
||||
|
||||
private void OnClosing()
|
||||
{
|
||||
_terrain?.Dispose();
|
||||
_shader?.Dispose();
|
||||
_dats?.Dispose();
|
||||
_input?.Dispose();
|
||||
_gl?.Dispose();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue