-
-
Notifications
You must be signed in to change notification settings - Fork 5
Hacker Guide
Ziv edited this page Jun 1, 2026
·
1 revision
graph TB
subgraph PublicAPI["📦 Public API"]
Streamer["🎬 streamer<br/>(Main Orchestrator)<br/>- update: camera→tiles<br/>- draw: render tiles<br/>- ground_height: O(1) query"]
end
subgraph ConfigStructs["⚙️ Configuration Objects"]
WC["world_config<br/>- anchor_x/z_tile<br/>- base_zoom / max_zoom<br/>- tile_size<br/>- skirt_overlap"]
SC["streaming_config<br/>- rendering_radius<br/>- thresholds per zoom<br/>- update_distance_sq<br/>- upload budget"]
RC["rendering_config<br/>- fog color/distance<br/>- ambient light<br/>- sun direction/scale<br/>- height/normals scale"]
PC["pool_config<br/>- download_threads<br/>- cache paths<br/>- tile URLs<br/>- TLS settings"]
end
subgraph InternalComponents["🔧 Internal Components"]
TR["tiles_renderer<br/>- Owns tile_shader<br/>- Owns material<br/>- Draws tiles with lighting"]
TM["tiles_manager<br/>- Manages tile lifecycle<br/>- Owns pool<br/>- Frustum culling<br/>- LOD subdivision"]
Pool["pool (workers)<br/>- 4+ worker threads<br/>- Download manager<br/>- Cache I/O<br/>- Image decoding"]
end
subgraph ShaderComponents["🎨 Shader & Rendering"]
TS["tile_shader<br/>- Displacement mapping<br/>- Normal mapping<br/>- Fog blending<br/>- Lighting (sun+ambient)"]
Mat["Material<br/>(raylib)<br/>- Shader binding<br/>- Texture units<br/>- Uniform state"]
end
subgraph TileLifecycle["🔄 Tile States"]
DK["desired_keys<br/>Set of tiles needed"]
LT["loading_tile<br/>- 3x futures<br/>- tx/tz position<br/>- stb_image decode"]
LDT["loaded_tile<br/>- GPU textures<br/>- CPU heightmap<br/>- Mesh (vertex buf)"]
end
subgraph DataStructures["📊 Data Structures"]
TK["tile_key<br/>zoom, x, z"]
TV["tile_value<br/>size, threshold, mesh"]
TImage["raylib Image<br/>(texture, heightmap,<br/>normals)"]
end
subgraph ExternalDeps["📚 External Dependencies"]
Raylib["raylib<br/>- Window / GL context<br/>- Image / Shader<br/>- Camera / Matrix"]
STBI["stb_image<br/>- PNG decode<br/>(reentrant)<br/>- runs in worker"]
httplib["httplib<br/>- HTTPS downloads<br/>- Keep-alive<br/>(main thread only)"]
end
%% Connections: Streamer to Configs
Streamer -->|takes| WC
Streamer -->|takes| SC
Streamer -->|takes| RC
Streamer -->|takes| PC
%% Connections: Streamer to Internal
Streamer -->|owns| TR
Streamer -->|owns| TM
%% Connections: Internal to Internal
TR -->|uses| TS
TR -->|owns| Mat
TM -->|owns| Pool
%% Connections: to Tile States
TM -->|maintains| DK
TM -->|manages| LT
TM -->|promotes to| LDT
%% Connections: Tile Lifecycle
DK -->|triggers| LT
LT -->|future resolves| LDT
%% Connections: Data Structures
TK -->|used by| TM
TV -->|used by| TM
LT -->|contains| TImage
LDT -->|contains| TImage
%% Connections: Shader and Rendering
TS -->|used by| Mat
TR -->|renders| LDT
%% Connections: External Dependencies
Streamer -->|requires| Raylib
TR -->|uses| Raylib
Pool -->|uses| STBI
Pool -->|uses| httplib
Raylib -->|provides| TImage
%% Styling
classDef publicStyle fill:#90EE90,stroke:#2d5016,stroke-width:2px,color:#000
classDef configStyle fill:#87CEEB,stroke:#003d99,stroke-width:2px,color:#000
classDef internalStyle fill:#FFB6C1,stroke:#8b0000,stroke-width:2px,color:#000
classDef shaderStyle fill:#FFE4B5,stroke:#8b4513,stroke-width:2px,color:#000
classDef tileStyle fill:#DDA0DD,stroke:#4b0082,stroke-width:2px,color:#000
classDef dataStyle fill:#F0E68C,stroke:#556b2f,stroke-width:2px,color:#000
classDef externalStyle fill:#D3D3D3,stroke:#404040,stroke-width:2px,color:#000
class Streamer publicStyle
class WC,SC,RC,PC configStyle
class TR,TM,Pool internalStyle
class TS,Mat shaderStyle
class DK,LT,LDT tileStyle
class TK,TV,TImage dataStyle
class Raylib,STBI,httplib externalStyle
sequenceDiagram
participant App as Application
participant S as streamer
participant TM as tiles_manager
participant Pool as pool
participant TR as tiles_renderer
participant GPU as GPU
App->>S: update(camera, offset)
activate S
S->>TM: compute desired tiles (LOD/frustum)
activate TM
TM->>Pool: request new downloads
activate Pool
Pool-->>TM: futures (shared_future<Image>)
deactivate Pool
TM->>TM: poll finished futures
TM->>GPU: upload ready tiles (budget capped)
note over GPU: max_uploads_per_frame<br/>upload_budget_sec
deactivate TM
deactivate S
App->>S: draw()
activate S
S->>TR: render tiles in frustum
activate TR
TR->>GPU: bind shader + textures
TR->>GPU: render loaded_tile meshes
deactivate TR
deactivate S
App->>S: ground_height(pos)
activate S
S->>TM: find loaded_tile at pos
TM->>TM: pixel read from<br/>CPU heightmap buffer
S-->>App: altitude (O(1))
deactivate S
| Component | Responsibility | Key Methods |
|---|---|---|
| streamer | Main entry point, orchestrates update/draw cycle, caches frame state |
update(), draw(), ground_height(), set_*()
|
| tiles_manager | Tile lifecycle (desired→loading→loaded), LOD/frustum, GPU upload scheduling |
update(), post_process(), promoted_tiles()
|
| tiles_renderer | Shader binding, material state, tile mesh rendering |
draw(), debug(), set_*()
|
| pool | Background downloads, cache I/O, stb_image decode, future resolution |
request_image(), worker_loop()
|
| tile_shader | Displacement mapping, normal maps, lighting, fog, skirts | shader program compilation |
| world_config | Immutable world topology (anchor, zoom range, tile size, skirt overlap) | — |
| streaming_config | LOD thresholds, update gating, upload budget, frustum planes | — |
| rendering_config | Runtime shader uniforms (fog, lighting, drama factors) | — |
| pool_config | URL/cache templates, worker thread count, TLS settings | — |
1. desired_keys (set of tile_key)
↓
2. pool::request_image() for each tile
├── cache hit → immediate Image
└── cache miss → HTTPS download
↓
3. shared_future<Image> (3 per tile: tx, hm, nl)
↓
4. Poll futures in tiles_manager::post_process()
├── texture → UnloadImage + GPU upload
├── heightmap → adopt into raii::image (keep CPU copy)
└── normals → UnloadImage + GPU upload
↓
5. loaded_tile ⊂ rendering_tiles
↓
6. tiles_renderer::draw() renders in frustum
↓
7. ground_height() reads CPU heightmap buffer (O(1))
-
Window first:
InitWindow()must exist before constructingstreamer - Thread safety: Pool workers never call raylib functions (stb_image only)
- GPU upload on main thread: Only streamer/tiles_manager can upload to GPU
-
Zoom range: Every zoom in
[base_zoom, max_zoom]needs entries in boththresholdsandskirt_overlap -
Tile coordinate order:
- Esri texture:
zoom/y/x(intentional swap) - Mapzen heightmap/normals:
zoom/x/y(standard)
- Esri texture:
-
Large-world shifting: Camera in user space, streamer converts to absolute via
world_offset - Heightmap format: Mapzen Terrarium (RGB encoding of altitude)
graph LR
A["world_config"] -->|base/max_zoom| B["streaming_config"]
A -->|tile_size| C["tiles_manager"]
A -->|anchor| C
B -->|thresholds| C
B -->|upload budget| C
C -->|rendering_config| D["tiles_renderer"]
D -->|shader uniforms| E["tile_shader"]
A -->|pool_config| F["pool"]
C -->|pool| F
Raytiles