Skip to main content

WgpuMapRenderer

Struct WgpuMapRenderer 

Source
pub struct WgpuMapRenderer { /* private fields */ }
Expand description

The WGPU-based map renderer.

Owns all persistent GPU resources (pipelines, uniform buffer, atlas, sampler, depth texture) and provides render / render_full to draw one frame.

See the module-level documentation for the full resource layout and frame lifecycle.

§Construction

let renderer = WgpuMapRenderer::new(&device, &queue, surface_format, width, height);

§Resize

Call resize whenever the surface dimensions change. This recreates the depth texture. Passing width=0 or height=0 is clamped to 1x1 to avoid WGPU validation errors.

§GPU batching

Tile textures are packed into shared 4096x4096 atlas pages (TileAtlas). All tiles on the same page are drawn in a single batched draw call, reducing draw calls from N (one per tile) to P (one per atlas page, typically 1-2). Terrain meshes are batched identically. Vector layers are one draw call each. Model mesh GPU buffers are cached by identity fingerprint across frames.

Implementations§

Source§

impl WgpuMapRenderer

Source

pub fn new( device: &Device, _queue: &Queue, format: TextureFormat, width: u32, height: u32, ) -> Self

Create a new renderer.

§Arguments
  • device – WGPU device.
  • _queue – WGPU queue (reserved for future lazy init; unused today).
  • format – Colour target format (must match the surface’s preferred format).
  • width – Initial surface width in pixels.
  • height – Initial surface height in pixels.
Source

pub fn resize(&mut self, device: &Device, width: u32, height: u32)

Notify the renderer that the surface was resized.

Recreates the depth texture. Dimensions are clamped to at least 1x1 – passing 0 is safe and produces a 1-pixel texture.

Source

pub fn set_glyph_provider(&mut self, provider: Box<dyn GlyphProvider>)

Replace the glyph provider used for symbol text rendering.

By default the renderer uses [ProceduralGlyphProvider] which produces placeholder glyphs. Pass a ShapedGlyphProvider (when the text-shaping feature is enabled) to render real font-based SDF text.

Source

pub fn upload_tile( &mut self, device: &Device, tile_id: TileId, image: &DecodedImage, )

Enqueue a decoded tile image for deferred GPU upload.

If the tile is already present this is a no-op. Otherwise the slot is allocated and a deferred upload is enqueued. The actual GPU write_texture happens when [flush_atlas_uploads] is called during the frame. Page bind groups are rebuilt if a new atlas page was created.

Source

pub fn upload_hillshade( &mut self, device: &Device, tile_id: TileId, image: &DecodedImage, )

Enqueue a prepared hillshade texture for deferred GPU upload.

Source

pub fn flush_atlas_uploads(&mut self, queue: &Queue)

Flush all pending atlas texture uploads to the GPU.

Writes only the affected slot pixel rectangles (partial writes) rather than re-uploading full atlas pages. Call once per frame after all upload_tile / upload_hillshade calls and before building batched geometry.

Source

pub fn render( &mut self, state: &MapState, device: &Device, queue: &Queue, color_view: &TextureView, visible_tiles: &[VisibleTile], )

Render one frame of the map (tiles only, no vectors or models).

Convenience wrapper around render_full that passes empty slices for vector_meshes and model_instances.

Source

pub fn render_full(&mut self, params: &RenderParams<'_>)

Render one full frame: tiles (or terrain), vectors, and models.

See the module-level frame lifecycle for the step-by-step breakdown.

§Batching strategy
  1. Tiles / terrain – all quads / meshes sharing the same atlas page are merged into a single vertex + index buffer and drawn with one draw_indexed call per page.
  2. Vectors – each vector layer produces one draw call (already pre-merged by the engine tessellator).
  3. Models – mesh GPU buffers are cached by identity fingerprint; per-instance transform uniform + bind group are allocated per-frame (future: dynamic UBO).
Source

pub fn cache_model_meshes( &mut self, device: &Device, model_instances: &[ModelInstance], )

Pre-cache model mesh GPU buffers before the render pass begins.

Called automatically by render_full. This keeps stable model meshes resident on the GPU instead of re-uploading them every frame.

Source

pub fn render_to_buffer( &mut self, state: &MapState, device: &Device, queue: &Queue, visible_tiles: &[VisibleTile], vector_meshes: &[VectorMeshData], model_instances: &[ModelInstance], ) -> Option<Vec<u8>>

Render one full frame to an offscreen texture and return the pixel data as a Vec<u8> in RGBA8 format (4 bytes per pixel, width * height * 4 total bytes).

This is the primary entry-point for headless rendering and cross-renderer comparison tests. It creates a transient colour texture, calls render_full, copies the result to a readback buffer, and returns the pixels.

§Arguments
  • state - Engine map state (camera, layers, terrain).
  • device - WGPU device.
  • queue - WGPU queue.
  • visible_tiles - Tile set for this frame.
  • vector_meshes - Tessellated vector layers.
  • model_instances - 3D model instances.
§Returns

Some(pixels) on success, None if the GPU readback fails.

Source

pub fn width(&self) -> u32

Return the current renderer width in pixels.

Source

pub fn height(&self) -> u32

Return the current renderer height in pixels.

Source

pub fn visualization_perf_stats(&self) -> VisualizationPerfStats

Return per-frame visualization cache activity from the last render.

Source

pub fn tile_atlas_diagnostics(&self) -> AtlasDiagnostics

Return atlas health diagnostics for the tile atlas.

Useful for performance overlays and automated tests. Call after render_full for post-frame metrics, or at any time for the current snapshot.

Source

pub fn hillshade_atlas_diagnostics(&self) -> AtlasDiagnostics

Return atlas health diagnostics for the hillshade atlas.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> Downcast<T> for T

Source§

fn downcast(&self) -> &T

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> Upcast<T> for T

Source§

fn upcast(&self) -> Option<&T>

Source§

impl<T> WasmNotSend for T
where T: Send,

Source§

impl<T> WasmNotSendSync for T

Source§

impl<T> WasmNotSync for T
where T: Sync,