# vectordesert An infinite wire-mesh vector desert flythrough, written in C with OpenGL (GLFW). A vast, mostly-flat wireframe plain rolls past, interrupted now and then by vector mountain ranges, with saguaro cacti scattered across both. The terrain is built from **square wire-mesh frames**; the saguaros are ribbed wire-mesh tubes shaped to resemble real cacti (tapered, dome-tipped trunks with arms that curve out and sweep upward). ## Build Requires a C compiler, GLFW 3, and OpenGL. Debian/Ubuntu: ``` sudo apt install build-essential libglfw3-dev ``` Fedora: ``` sudo dnf install glfw-devel ``` macOS (Homebrew): ``` brew install glfw ``` Then: ``` make ``` ## Run ``` ./vectordesert # windowed ./vectordesert --fullscreen # full screen ``` ### Command-line settings ``` --terrain-hue=0..1 hue of the terrain mesh (default 0.075) --mountain-freq=0.2..4 how often the plain is interrupted by a range (low = rare; high = frequent) (default 1.0) --mountain-rough=0..1 flat-topped mesas .. jagged peaks (default 0.5) --mountain-min-height=0..80 height of a range's low parts (default 6) --mountain-max-height=0..80 height of the tallest peaks (default 26) --cactus-freq=0..1 chance of a cactus per cell (default 0.35) --cactus-size-var=0..0.95 random cactus size spread (default 0.55) --cactus-min-size=1..30 smallest cactus height (default 4) --cactus-max-size=1..30 largest cactus height (default 12) --cactus-hue=0..1 hue of the cacti (default 0.33) --max-arms=0..12 arms on the largest cacti (default 5) ``` Example: ``` ./vectordesert --fullscreen --terrain-hue=0.55 --mountain-freq=1.8 \ --cactus-hue=0.30 --cactus-freq=0.5 --max-arms=8 ``` ### Camera | keys | does | |------|------| | `W` / `S` | throttle: accelerate / decelerate forward speed (holds when released; `S` past zero goes into reverse) | | `X` | full stop (zero the camera's velocity) | | `A` / `D` | strafe left / right | | `Page Up` / `Page Down` | raise / lower camera altitude | | `←` / `→` | pan view left / right | | `↑` / `↓` | pan view up / down | | `[` / `]` | decrease / increase rendering distance | | `G` | toggle the floor-altitude indicator | | `Space` | drop a bomb | Velocity is held in world space, so panning the view with the arrow keys only changes where you look — it does not change the direction you are travelling. To steer, turn and then apply throttle. The terrain is generated around the camera and cached — rebuilt only as you travel out of the cached region — so the plain extends infinitely in every direction. Rendering distance (`[` / `]`) ranges from 40 up to 960 units. ### Live setting controls | keys | adjusts | |------|---------| | `1` / `2` | terrain hue | | `3` / `4` | mountain range frequency | | `,` / `.` | mountain roughness (flat mesas ↔ jagged peaks) | | `T` / `Y` | minimum mountain range height | | `U` / `I` | maximum mountain range height | | `5` / `6` | cactus frequency | | `7` / `8` | cactus size variation | | `J` / `K` | minimum cactus size | | `N` / `M` | maximum cactus size | | `9` / `0` | cactus hue | | `-` / `=` | maximum cactus arms | | `F` | toggle fullscreen | | `ESC` | quit | Current settings are printed to the terminal as you change them, and an on-screen heads-up display (drawn in the same vector style) lists every setting next to the key(s) that change it. The HUD fades out after 10 seconds with no keypresses and snaps back as soon as you press a key. All settings (and the rendering distance) are saved to `~/.vectordesert.cfg` on exit and reloaded at startup, so the program resumes with the values from your last session. Command-line options still override the saved values for that run. ## Bombs Press `Space` to drop a bomb. It falls from the sky onto a random spot in your field of view, between half the rendering distance and the full rendering distance away. When it strikes the ground it detonates into an animated, all-vector mushroom cloud twenty times the height of the tallest mountains, in an extremely bright random hue (additively blended so it glows): - an initial blinding fireball, - a rising stem with climbing vortex rings, - a billowing cap that stays joined to the stem — a rolling vortex torus whose outer edge curls up and over — and keeps animating as the whole cloud fades away. The blast **obliterates every mountain and cactus within the cloud's total radius** and **gouges a deep crater** — a steep-walled bowl with a raised rim thrown up above the surrounding surface — at the impact point. Every bomb leaves its own permanent crater, and craters never erase one another: repeated blasts in the same place **accumulate**, deepening and reshaping the crater. Drop as many as you like; the clouds animate and dissipate independently. ## Notes - **Arms scale with size:** the number of arms is derived from a cactus's normalized size, so the smallest cacti always have the fewest arms (down to a bare trunk) and the largest always reach `max-arms`. - The world is generated procedurally from a hash-based value-noise height field, so it is effectively infinite — the camera flies forever. As well as mountain ranges rising above the plain, the terrain carves valleys and basins below it (and bomb craters), so it has real depth, not just relief. - Distance fog fades distant geometry into the dusk sky for depth. ## Performance The renderer is built for throughput at large draw distances: - All wireframe segments for a frame are collected into one vertex/colour array and drawn with a single `glDrawArrays(GL_LINES)` per mesh, instead of per-object immediate-mode `glBegin`/`glEnd`. - Terrain and cactus meshes are **cached** and only rebuilt when a relevant setting changes or the camera leaves the cached region; most frames do no geometry work at all. - Terrain uses a **cell budget** (level of detail): the grid spacing grows with the rendering distance, so the cell count stays bounded as the radius scales up. - Each terrain vertex's height is computed once and shared by its edges (no redundant noise evaluations). - Cacti render out to the full rendering distance (like the terrain), but drop ring facets and trunk segments with distance so far-off ones stay cheap. The distance fade is done by **hardware fog** rather than the CPU.