diff options
| author | hachem <im@hachem.wtf> | 2026-08-24 17:07:54 +0200 |
|---|---|---|
| committer | hachem <im@hachem.wtf> | 2026-08-24 17:07:54 +0200 |
| commit | 06398a7a176e123506de6e8851866a8bec0b3427 (patch) | |
| tree | 7167ef4818f2c224840122961882efb5ec26c80b /docs/architecture.md | |
| parent | 1c85c2ecaa826afd8bf80f93741cf1b2deba5798 (diff) | |
[chore]: cleanup shaders
Diffstat (limited to 'docs/architecture.md')
| -rw-r--r-- | docs/architecture.md | 58 |
1 files changed, 40 insertions, 18 deletions
diff --git a/docs/architecture.md b/docs/architecture.md index 5762dfd..c244586 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -28,7 +28,7 @@ and the interface can change independently. flowchart TD App["Application<br/>thin shell + main loop"] App --> Scene["Scene<br/>the document/world:<br/>objects, black hole, cameras"] - App --> UI["UILayer / Workspace<br/>the tabbed ImGui interface"] + App --> UI["UILayer<br/>the docking UI shell"] App --> RP["RenderPath<br/>device-side rendering"] App --> Dev["RHI::Device<br/>the GPU, abstracted"] @@ -48,7 +48,7 @@ flowchart TD | --- | --- | --- | | `Application` | [`src/core/application.cpp`](../src/core/application.cpp) | Owns everything; runs the main loop; handles input, resize, vsync, fullscreen; exposes actions to the UI | | `Scene` | [`src/scene/scene.h`](../src/scene/scene.h) | The world as plain data — placed objects, black-hole/disk parameters, the editor and simulation cameras, the HDRI path | -| `UILayer` / `Workspace` | [`src/ui/ui_layer.cpp`](../src/ui/ui_layer.cpp) | The tabbed interface; returns which view is live and drives the scene through `AppActions` | +| `UILayer` | [`src/ui/ui_layer.cpp`](../src/ui/ui_layer.cpp) | The docking shell: menu bar, dockable panels, default layouts; returns which view is live and drives the scene through `AppActions` | | `RenderPath` | [`src/rendering/render_path.cpp`](../src/rendering/render_path.cpp) | Turns the scene into pixels on whatever device is active; owns the two renderers and the environment cubemap | | `RHI::Device` | [`src/rendering/rhi.h`](../src/rendering/rhi.h) | The portable GPU interface every backend implements | @@ -145,13 +145,13 @@ path described below. world editor: a conventional rasteriser that draws the placed spheres, the ground grid, the selection outline and gizmo, and a near-black black-hole marker at the origin, sized to the horizon and ringed with an amber accretion-glow outline so it -reads against the dark background. This is what you manipulate on the Scene tab. +reads against the dark background. This is what you manipulate in the Scene view. `BlackHoleRenderer` ([`black_hole_renderer.cpp`](../src/rendering/black_hole_renderer.cpp)) is the geodesic ray tracer. It runs the physics shader from [`physics.md`](physics.md) as a full-screen fragment pass into an off-screen target, then presents that target -to the screen. This is the expensive work, and it runs only on the Simulation tab -and during export. +to the screen. This is the expensive work, and it runs only when the centre view is +Simulation, and during export. `RenderPath::render` routes to the right one based on the `View`: @@ -172,8 +172,8 @@ that radius, and `BlackHoleRenderer` takes every placed `SceneObject`, multiplie its position and radius by $r_s/3$ (the code's `SagA_rs / 3`) to reach physical metres, and uploads them into the shader's `Objects` uniform (up to 16 spheres). -So a sphere placed on the Scene tab shows up in the same spot on the Simulation -tab, except now the curved rays bend around the hole and lens it, and it can appear +So a sphere placed in the Scene view shows up in the same spot in the Simulation +view, except now the curved rays bend around the hole and lens it, and it can appear stretched, doubled, or smeared into an arc. The spheres are passive lit objects, planets and the like; they don't exert their own gravity, only the black hole bends light. @@ -219,20 +219,42 @@ fragment shader averages four sub-pixel samples in a rotated-grid ("4-rook") pat before tone-mapping, which cleans up the near-horizontal lensed edges and the thin photon ring. -## The workspace: tabs +## The workspace: docking and panels -The interface follows Dorico's mode tabs: separate workspaces, one active at a -time, each returning a `View` so the renderer knows what to draw. +The interface is a docking shell. A main menu bar sits above a full-viewport dock +space with a pass-through centre, so the live 3D render shows through the middle +while dockable tool panels attach to the edges — drag, tab, hide, or restore them +like a normal desktop app. The layout persists in `imgui.ini` between runs. -| Tab | View | For | +The panels are separate windows, each toggled from the **Window** menu: + +| Panel | For | +| --- | --- | +| Outliner | The sphere list: add, delete, select | +| Properties | The selected sphere's transform and colour, plus the viewport gizmo | +| Black Hole | Camera mode/FOV, the accretion disk, and integration quality | +| Settings | Display & renderer: vsync, frame cap, resolution, fullscreen, UI scale, API, overlay, HDRI | +| Export | Choose which observable channels, at what resolution and format, then render to disk | +| Stats | Device, backend, FPS and frame time | + +Two menus drive the rest. **View** picks what the centre viewport shows — `Scene` +(the world editor) or `Simulation` (the lensed black hole) — which is the `View` +`UILayer::draw` returns to the `RenderPath`. **Layout** applies one of the default +arrangements, each built programmatically with ImGui's `DockBuilder` API and paired +with a sensible view and panel set: + +| Layout | View | Panels shown | | --- | --- | --- | -| Setup | `None` | Display & quality: vsync, target FPS, resolution, fullscreen, UI scale, HDRI selection, integration quality, early-exit distance | -| Scene | `Scene` | The world builder: place, select and transform objects with a gizmo; orbit the editor camera around the black-hole marker | -| Simulation | `BlackHole` | The live lensed view — the only place the geodesic tracer runs; tune the black hole and disk; orbit or fly (FPS) the camera | -| Export | `None` | Choose which observable channels, at what resolution and format, then render them to disk | +| Simulation (default) | `Simulation` | Black Hole, Stats | +| Scene editing | `Scene` | Outliner, Properties, Stats | +| Export | `Simulation` | Export, Black Hole, Stats | -Tabs whose view is `None` have no live 3-D viewport, so `Application::update_input` -skips camera handling for them. +On first launch (no saved `imgui.ini`) the Simulation layout is built by +`DockBuilder`; after that the user's arrangement is restored, and *Layout → Reset* +rebuilds the current preset. Only panels are docked windows — the centre stays a +pass-through hole onto the full-frame 3D render, so `Application::update_input` +drives the camera whenever the cursor is over that centre (ImGui reports it doesn't +want the mouse) and yields to the panels otherwise. ## The export pipeline @@ -283,7 +305,7 @@ there is no separate "OpenGL build" and "Vulkan build". Generate and build (arm64 macOS): ```bash -premake5 gmake && make config=debug-macosx +premake5 gmake && make config=debug ``` `premake5 clean` is wired up as a custom action that removes the generated build |
