feat(app): load landblock from dats and upload mesh to GPU
GameWindow now owns a DatCollection + TerrainRenderer. On load it opens the dat directory passed as argv[0] (or ACDREAM_DAT_DIR), finds Holtburg (landblock 0xA9B4FFFF) by default with a fallback to the first landblock in the cell b-tree, builds the CPU mesh from LandblockMesh.Build, and uploads VBO+EBO+VAO with a 3f/3f/2f attribute layout. No draw call yet — shader and matrix uniforms land in Task 9. Enabled AllowUnsafeBlocks on the App csproj so the fixed-buffer upload in TerrainRenderer compiles. Uses dats.Get<LandBlock>(id) instead of TryGet(..., out T) to sidestep the [MaybeNullWhen(false)] analysis that TreatWarningsAsErrors was flagging. Smoke verified against the real retail dats: prints "loaded landblock 0xA9B4FFFF" and the window stays alive with no GL errors or exceptions. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
6d18e0bd38
commit
8356fe65a0
4 changed files with 113 additions and 1 deletions
|
|
@ -1,3 +1,7 @@
|
|||
using AcDream.Core.Terrain;
|
||||
using DatReaderWriter;
|
||||
using DatReaderWriter.DBObjs;
|
||||
using DatReaderWriter.Options;
|
||||
using Silk.NET.Input;
|
||||
using Silk.NET.Maths;
|
||||
using Silk.NET.OpenGL;
|
||||
|
|
@ -7,9 +11,14 @@ namespace AcDream.App.Rendering;
|
|||
|
||||
public sealed class GameWindow : IDisposable
|
||||
{
|
||||
private readonly string _datDir;
|
||||
private IWindow? _window;
|
||||
private GL? _gl;
|
||||
private IInputContext? _input;
|
||||
private TerrainRenderer? _terrain;
|
||||
private DatCollection? _dats;
|
||||
|
||||
public GameWindow(string datDir) => _datDir = datDir;
|
||||
|
||||
public void Run()
|
||||
{
|
||||
|
|
@ -45,15 +54,46 @@ public sealed class GameWindow : IDisposable
|
|||
};
|
||||
|
||||
_gl.ClearColor(0.05f, 0.10f, 0.18f, 1.0f);
|
||||
_gl.Enable(EnableCap.DepthTest);
|
||||
|
||||
_dats = new DatCollection(_datDir, DatAccessType.Read);
|
||||
|
||||
// Find ANY landblock ending in 0xFFFF. Holtburg 0xA9B4FFFF is a
|
||||
// good default; fall back to the first one we find.
|
||||
uint landblockId = 0xA9B4FFFFu;
|
||||
var block = _dats.Get<LandBlock>(landblockId);
|
||||
if (block is null)
|
||||
{
|
||||
foreach (var file in _dats.Cell.Tree)
|
||||
{
|
||||
if ((file.Id & 0xFFFFu) == 0xFFFFu)
|
||||
{
|
||||
landblockId = file.Id;
|
||||
block = _dats.Get<LandBlock>(landblockId);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (block is null)
|
||||
throw new InvalidOperationException("no landblock found in cell dat");
|
||||
|
||||
Console.WriteLine($"loaded landblock 0x{landblockId:X8}");
|
||||
|
||||
var meshData = LandblockMesh.Build(block);
|
||||
_terrain = new TerrainRenderer(_gl, meshData);
|
||||
}
|
||||
|
||||
private void OnRender(double deltaSeconds)
|
||||
{
|
||||
_gl!.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
|
||||
_terrain?.Draw();
|
||||
}
|
||||
|
||||
private void OnClosing()
|
||||
{
|
||||
_terrain?.Dispose();
|
||||
_dats?.Dispose();
|
||||
_input?.Dispose();
|
||||
_gl?.Dispose();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue