fix: use Glow renderer for app smoke startup #17

Merged
moldybits merged 4 commits from feat/terrain-gen-abstraction into main 2026-05-25 21:02:10 -04:00
5 changed files with 17 additions and 9 deletions
Showing only changes of commit dda4eeb97c - Show all commits
+1
View File
@@ -32,6 +32,7 @@ cargo run --features app --bin openvistapro_app
The optional app shell is gated behind the `app` feature so default CLI builds stay GPU-free. The optional app shell is gated behind the `app` feature so default CLI builds stay GPU-free.
It opens an `eframe`/`egui` window titled `OpenVistaPro` with scene controls, top-level menus/dialogs, and a CPU-rendered terrain preview. It opens an `eframe`/`egui` window titled `OpenVistaPro` with scene controls, top-level menus/dialogs, and a CPU-rendered terrain preview.
The native shell uses eframe's Glow renderer under X11/Xvfb, which keeps the app smoke launch independent of WGPU backend feature selection.
Importer status: Importer status:
+1 -1
View File
@@ -5,7 +5,7 @@
Start simple, then split into crates when module boundaries stabilize. Start simple, then split into crates when module boundaries stabilize.
- `src/terrain.rs`: height grid, bounds, sampling, and deterministic terrain fixtures. - `src/terrain.rs`: height grid, bounds, sampling, and deterministic terrain fixtures.
- `src/terrain_gen.rs`: `TerrainGenerationSpec` and `DeterministicTerrainGenerator` for the seeded terrain-generation pipeline; `cargo test terrain_gen` exercises the determinism/seed note. - `src/terrain_gen.rs`: `TerrainGenerationSpec`, `TerrainGenerationSettings`, and `DeterministicTerrainGenerator` for the seeded terrain-generation pipeline; `cargo test terrain_gen` exercises the determinism/seed note and the first shipped `fractal` preset.
- `src/import.rs`: importers for open/safe formats (`ovp-text`, feature-gated HGT, feature-gated ESRI ASCII Grid, and feature-gated GeoTIFF via `src/import/geotiff.rs`); historical compatibility later. Each importer yields the same internal `HeightGrid` plus `TerrainSourceMetadata`, keeping source formats out of renderer code. - `src/import.rs`: importers for open/safe formats (`ovp-text`, feature-gated HGT, feature-gated ESRI ASCII Grid, and feature-gated GeoTIFF via `src/import/geotiff.rs`); historical compatibility later. Each importer yields the same internal `HeightGrid` plus `TerrainSourceMetadata`, keeping source formats out of renderer code.
- `src/scene.rs` and `src/scene_file.rs`: camera, light, atmosphere, water/vegetation thresholds, and `.ovp.toml` persistence. - `src/scene.rs` and `src/scene_file.rs`: camera, light, atmosphere, water/vegetation thresholds, and `.ovp.toml` persistence.
- `src/render.rs`: deterministic CPU top-down renderer plus CPU perspective demo renderer; WGPU renderer later. - `src/render.rs`: deterministic CPU top-down renderer plus CPU perspective demo renderer; WGPU renderer later.
+3 -3
View File
@@ -8,12 +8,12 @@ This is a normalized modern shell map derived from the VistaPro manuals, screens
|---|---|---|---|---| |---|---|---|---|---|
| Viewport / preview | Main render window, map preview, perspective view, preview/final render output | Center dock | Partial | `src/app.rs` renders the CPU preview into `CentralPanel`; perspective and top-down preview modes exist, but there is no GPU viewport or direct manipulation overlay yet. | | Viewport / preview | Main render window, map preview, perspective view, preview/final render output | Center dock | Partial | `src/app.rs` renders the CPU preview into `CentralPanel`; perspective and top-down preview modes exist, but there is no GPU viewport or direct manipulation overlay yet. |
| Terrain / import | Load Landscape, Import, terrain source selection, generated terrain presets | Left dock or collapsible section | Partial | The current shell exposes project-owned terrain presets (`Plane`, `RadialHill`) and a working heightmap import action; legacy format import UI is still absent. | | Terrain / import | Load Landscape, Import, terrain source selection, generated terrain presets | Left dock or collapsible section | Partial | The current shell exposes project-owned terrain presets (`Plane`, `RadialHill`) and a working heightmap import action; legacy format import UI is still absent. |
| Scene / camera | Camera and target gadgets, lens/range, bank/heading/pitch, water/tree/snow/haze controls | Left dock or inspector stack | Partial | Position/target, explicit heading/pitch/bank controls, lens/FOV/clip range controls, vertical exaggeration, color-map editing, and hydrology overlays now live in `src/app.rs` and `src/app_state.rs`; `src/scene.rs`, `src/render.rs`, and `src/script_exec.rs` carry the model/render semantics. The shell covers the main VistaPro scene controls, but its camera semantics are intentionally simplified and not yet tied to any map-click placement workflow. | | Scene / camera | Camera and target gadgets, lens/range, bank/heading/pitch, water/tree/snow/haze controls | Left dock or inspector stack | Partial | Position/target, explicit heading/pitch/bank controls, lens/FOV/clip range controls, vertical exaggeration, lighting direction/intensity gadgets, color-map editing, and hydrology overlays now live in `src/app.rs` and `src/app_state.rs`; `src/scene.rs`, `src/render.rs`, and `src/script_exec.rs` carry the model/render semantics. The shell covers the main VistaPro scene controls, but its camera semantics are intentionally simplified and not yet tied to any map-click placement workflow. |
| Render | Preview vs final render, quality/smoothing, detail tradeoffs | Left dock, toolbar, or render tab | Partial | Current code now exposes preview/balanced/final quality presets alongside top-down vs perspective render mode; the shell still lacks the full legacy menu chrome and fine-grained smoothing sliders. | | Render | Preview vs final render, quality/smoothing, detail tradeoffs | Left dock, toolbar, or render tab | Partial | Current code now exposes preview/balanced/final quality presets alongside top-down vs perspective render mode; the shell still lacks the full legacy menu chrome and fine-grained smoothing sliders. |
| Scripts / paths | Script menu, Run Script, MakePath path tools, animation-frame workflows | Right dock or modal workflow | Partial | Script parsing/execution and MakePath-style path generation now run end-to-end in the backend; the shell surfaces a script editor, Run Script, and Make Path controls, but animation-frame export and richer path editing are still future work. | | Scripts / paths | Script menu, Run Script, MakePath path tools, animation-frame workflows | Right dock or modal workflow | Partial | Script parsing/execution and MakePath-style path generation now run end-to-end in the backend; the shell surfaces a script editor, Run Script, and Make Path controls, but animation-frame export and richer path editing are still future work. |
| File / project actions | New/Open/Save landscape, scene load/save, export commands | Top bar / file menu | Partial | The shell now shows scene-file status and working New/Open/Save controls; legacy menu chrome and export dialogs are still missing. | | File / project actions | New/Open/Save landscape, scene load/save, export commands | Top bar / file menu | Partial | The shell now shows scene-file status plus working New/Open/Save controls, and the top menu mirrors those actions alongside import and help/about entry points; legacy menu chrome and export dialogs are still missing. |
| Status / feedback | Coordinate readouts, render state, file path, progress, messages | Bottom status bar | Present | The shell now has a bottom status bar driven by `AppData::ui_snapshot()`. | | Status / feedback | Coordinate readouts, render state, file path, progress, messages | Bottom status bar | Present | The shell now has a bottom status bar driven by `AppData::ui_snapshot()`. |
| Legacy compatibility / advanced dialogs | Dense menu hierarchy, advanced lighting, hydrology, vertical exaggeration, palette editing, legacy image/landscape exports | Right dock, tool drawer, or dialogs | Partial | These are best surfaced as future tabs or dialogs rather than cluttering the initial shell; some sub-features already exist in the backend, but direct legacy export compatibility is intentionally out of scope for now. | | Legacy compatibility / advanced dialogs | Dense menu hierarchy, advanced lighting, hydrology, vertical exaggeration, palette editing, legacy image/landscape exports | Right dock, tool drawer, or dialogs | Partial | These are best surfaced as future tabs or dialogs rather than cluttering the initial shell; some sub-features already exist in the backend, and the modern shell now exposes a top menu, about/help dialog, and lighting numeric controls, but the legacy-style menu/dialog workflow is still incomplete. |
## Recommended shell structure ## Recommended shell structure
+4 -2
View File
@@ -8,7 +8,7 @@ Define the next terrain-generation workstream so future slices stay small, deter
OpenVistaPro already has: OpenVistaPro already has:
- `src/terrain_gen.rs` with `TerrainGenerationSpec` and `DeterministicTerrainGenerator`, plus `cargo test terrain_gen` coverage for the determinism/seed note. - `src/terrain_gen.rs` with `TerrainGenerationSpec`, `TerrainGenerationSettings`, and `DeterministicTerrainGenerator`, plus `cargo test terrain_gen` coverage for the determinism/seed note.
- `src/terrain.rs` with immutable `HeightGrid` storage, safe indexing, min/max, and deterministic `plane` / `radial_hill` fixtures. - `src/terrain.rs` with immutable `HeightGrid` storage, safe indexing, min/max, and deterministic `plane` / `radial_hill` fixtures.
- `src/render.rs` with a deterministic top-down preview and a CPU perspective spike that only depends on `HeightGrid` + `Scene`. - `src/render.rs` with a deterministic top-down preview and a CPU perspective spike that only depends on `HeightGrid` + `Scene`.
@@ -16,7 +16,7 @@ OpenVistaPro already has:
- `src/import.rs` for the open-format import boundary. - `src/import.rs` for the open-format import boundary.
- `docs/plans/initial-roadmap.md` and `docs/plans/phase-4-formats-scripts-ui.md` for the broader project sequence. - `docs/plans/initial-roadmap.md` and `docs/plans/phase-4-formats-scripts-ui.md` for the broader project sequence.
The missing piece is a dedicated procedural terrain generator pipeline that can produce richer synthetic landscapes without mixing algorithm state into `HeightGrid`. The core seeded procedural terrain pipeline now exists; the remaining work in this roadmap is about future generator variants and richer presets, not the first shipped fractal slice.
## Decision summary ## Decision summary
@@ -108,6 +108,7 @@ Suggested first presets:
- `plain`-like flat terrain via zeroed noise amplitude - `plain`-like flat terrain via zeroed noise amplitude
- `island` / `continental` profile with a radial falloff mask - `island` / `continental` profile with a radial falloff mask
- `mountain` profile with stronger octave contrast - `mountain` profile with stronger octave contrast
- `fractal` / `noise` preset exposed through the app shell and CLI as the first shipped procedural family
Acceptance: Acceptance:
@@ -154,6 +155,7 @@ cargo fmt --check
cargo test terrain cargo test terrain
cargo test cargo test
cargo clippy --all-targets -- -D warnings cargo clippy --all-targets -- -D warnings
cargo run -- render --preset fractal --seed 1337 --width 64 --height 64 --output /tmp/openvistapro-fractal-plan.png
``` ```
Add one feature-specific smoke command for the slice once the generator has a public entry point, for example a tiny render or sample-generation command that writes to `/tmp` and proves the generated grid is usable end-to-end. Add one feature-specific smoke command for the slice once the generator has a public entry point, for example a tiny render or sample-generation command that writes to `/tmp` and proves the generated grid is usable end-to-end.
+8 -3
View File
@@ -18,7 +18,7 @@
//! Supported commands: //! Supported commands:
//! //!
//! ```text //! ```text
//! use preset <name> # <name> is `hill` or `plane` //! use preset <name> # <name> is `fractal`, `hill`, or `plane`
//! set thresholds water=<f> tree=<f> snow=<f> //! set thresholds water=<f> tree=<f> snow=<f>
//! import heightmap "<path>" //! import heightmap "<path>"
//! render output "<path>" //! render output "<path>"
@@ -46,6 +46,8 @@ pub struct Script {
/// A built-in terrain preset selectable via `use preset <name>`. /// A built-in terrain preset selectable via `use preset <name>`.
#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum PresetName { pub enum PresetName {
/// Seeded procedural fractal terrain.
Fractal,
/// A single rolling hill. /// A single rolling hill.
Hill, Hill,
/// A flat plane. /// A flat plane.
@@ -182,6 +184,7 @@ fn parse_use(args: &[String], line: usize) -> Result<Command, ParseError> {
expect_keyword(args.first(), "preset", line, "use")?; expect_keyword(args.first(), "preset", line, "use")?;
let name = expect_arg(args.get(1), line, "use preset", "a preset name")?; let name = expect_arg(args.get(1), line, "use preset", "a preset name")?;
let preset = match name.as_str() { let preset = match name.as_str() {
"fractal" => PresetName::Fractal,
"hill" => PresetName::Hill, "hill" => PresetName::Hill,
"plane" => PresetName::Plane, "plane" => PresetName::Plane,
other => return Err(ParseError::new(line, format!("unknown preset {other:?}"))), other => return Err(ParseError::new(line, format!("unknown preset {other:?}"))),
@@ -278,6 +281,7 @@ mod tests {
fn parses_happy_path_script_into_ast() { fn parses_happy_path_script_into_ast() {
let script = r#" let script = r#"
# OpenVistaPro project-owned script, not legacy VistaPro syntax # OpenVistaPro project-owned script, not legacy VistaPro syntax
use preset fractal
use preset hill use preset hill
set thresholds water=0.18 tree=0.42 snow=0.77 set thresholds water=0.18 tree=0.42 snow=0.77
import heightmap "data/demo-height.png" import heightmap "data/demo-height.png"
@@ -289,6 +293,7 @@ mod tests {
assert_eq!( assert_eq!(
ast.commands, ast.commands,
vec![ vec![
Command::UsePreset(PresetName::Fractal),
Command::UsePreset(PresetName::Hill), Command::UsePreset(PresetName::Hill),
Command::SetThresholds(SceneThresholds { Command::SetThresholds(SceneThresholds {
water: 0.18, water: 0.18,
@@ -307,14 +312,14 @@ mod tests {
#[test] #[test]
fn ignores_comments_blank_lines_and_extra_whitespace() { fn ignores_comments_blank_lines_and_extra_whitespace() {
let script = "\n # comment\n\n\tuse preset plane \n render output \"out.png\" # trailing comment\n"; let script = "\n # comment\n\n\tuse preset fractal \n render output \"out.png\" # trailing comment\n";
let ast = parse_script(script).unwrap(); let ast = parse_script(script).unwrap();
assert_eq!( assert_eq!(
ast.commands, ast.commands,
vec![ vec![
Command::UsePreset(PresetName::Plane), Command::UsePreset(PresetName::Fractal),
Command::RenderOutput { Command::RenderOutput {
path: "out.png".into() path: "out.png".into()
}, },