Skip to main content

SceneRenderer

Struct SceneRenderer 

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

Unified renderer over the CPU and GPU paths. See the crate docs.

Implementations§

Source§

impl SceneRenderer

Source

pub fn new<W>(window: Arc<W>, size: (u32, u32), opts: &RenderOptions) -> Self
where W: HasWindowHandle + HasDisplayHandle + Send + Sync + 'static,

Build a renderer for window — any raw-window-handle provider (winit, SDL, GLFW, …) in an Arc. size is the window’s initial physical framebuffer size in pixels; thereafter the host reports changes via Self::resize. Passing the size explicitly keeps the facade decoupled from any one windowing library’s size API.

Selects the GPU backend when opts.want_gpu and WGPU initialises; otherwise the CPU backend. Never fails — a missing/incompatible GPU silently yields the CPU path (the message is logged to stderr).

Source

pub fn backend(&self) -> Backend

Which backend was selected.

Source

pub fn adapter_info(&self) -> Option<&str>

The GPU adapter description when on the GPU backend, else None.

Source

pub fn set_sky_panorama(&mut self, rgba: &[u8], w: u32, h: u32)

Upload an equirectangular sky panorama (RGBA8, w×h) for the GPU marcher’s sky sampling. No-op on the CPU backend, which samples the Sky passed in each FrameParams instead.

Source

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

Follow a window resize. CPU resizes its framebuffer lazily, so this only matters to the GPU swapchain — but it’s safe to call for both.

Source

pub fn render( &mut self, scene: &mut Scene, camera: &Camera, frame: &FrameParams<'_>, )

Composite scene from camera with frame params into the backend’s frame buffer — without presenting. The CPU backend fills sky + runs the opticast compositor into an owned buffer; the GPU backend uploads/refreshes the scene, runs the compute marcher + sprite pass, and acquires (but does not present) the swapchain frame.

Finish the frame with exactly one of present (no overlay) or paint_egui (UI overlay). Calling render again without finishing drops the pending frame.

Source

pub fn present(&mut self)

Present the frame render composited, with no UI overlay. Pairs with render; use paint_egui instead to overlay an egui UI before presenting.

Source

pub fn set_sprites(&mut self, set: &SpriteSet)

Register sprite models + instances. The CPU backend builds a per-instance draw list; the GPU backend builds an instanced model registry. Call once at setup (or again to replace).

Source

pub fn set_kfa_sprites(&mut self, kfas: &mut [KfaSprite])

Register animated KFA sprites (one or more bone hierarchies). The GPU backend uploads each limb’s kv6 as an instanced model once (appended to the sprite registry) and seeds the limb instances at their current pose; the CPU backend caches the posed limbs for drawing. Call once at setup, after set_sprites, then drive motion per frame with update_kfa_poses.

Limbs are posed from the sprites’ current kfaval (advance animsprite first if using a baked curve), so kfas is taken &mut.

Source

pub fn update_kfa_poses(&mut self, kfas: &mut [KfaSprite])

Re-pose the registered KFA sprites from their current kfaval[]. Call each frame after advancing the animation (kfa.animsprite(dt_ms) or poking kfaval[]). The GPU backend takes the cheap transform-only update (no model-volume re-upload); the CPU backend re-solves limb transforms for the next render. Must follow a set_kfa_sprites with the same sprites.

Source

pub fn carve_active_sprite(&mut self) -> u32

Carve the next z-layer off the SpriteSet::carve_model and re-upload (the demo’s G hotkey + GPU.12 copy-on-modify). GPU only; a no-op on the CPU backend. Returns the voxels removed.

Source

pub fn request_capture(&mut self)

Request that the next render capture its framebuffer for take_capture. CPU only (the GPU swapchain isn’t read back) — a no-op on GPU.

Source

pub fn take_capture(&mut self) -> Option<(Vec<u32>, u32, u32)>

Take the most recently captured frame as packed 0x00RRGGBB pixels + dimensions, or None if no capture is ready / GPU.

Source

pub fn pick_depth(&self, x: u32, y: u32) -> Option<f32>

Screen→world picking input: the world-space hit distance t at window pixel (x, y) from the last rendered frame, or None for out-of-bounds pixels and sky / no-hit. The host reconstructs the world hit point as cam.pos + t * normalize(ray_dir), where ray_dir is the same per-pixel ray the frame was rendered with (see the backend’s projection).

t is the distance to the nearest scene-grid surface (terrain + grids); sprites do not occlude it (the sprite pass reads depth read-only), so a cursor sprite under the pointer is transparent to the pick.

Cost: the CPU backend reads its in-memory z-buffer (free); the GPU backend stages the depth buffer and blocks on a device poll (cheap at click time — do not call every frame). The GPU path only has depth when the last frame drew sprites (write_depth).

Source

pub fn pixel_ray(&self, camera: &Camera, x: f64, y: f64) -> Option<[f64; 3]>

World-space view-ray direction (un-normalised) for window pixel (x, y), under the projection the last frame rendered with. The backends differ (CPU setcamera vs GPU vertical-FOV pinhole), so this hides which one is active. None before the first frame. Intersect it with a plane for tile picking, or feed it to Self::pick for a voxel.

Source

pub fn view_ray(&self, camera: &Camera, x: f64, y: f64) -> Option<Ray>

Canonical screen→world unproject: the full view Ray (camera.pos origin + unit direction) for window pixel (x, y), under whichever projection the last frame used. The one entry point both backends honour — hosts never reconstruct the projection. None before the first frame or for a degenerate ray.

Compose with roxlap_scene::Scene::raycast for depth-free picking that’s identical on CPU and GPU: renderer.view_ray(cam, x, y).and_then(|r| scene.raycast(r.origin, r.dir, max)).

Source

pub fn pick( &self, scene: &Scene, camera: &Camera, x: u32, y: u32, ) -> Option<PickHit>

One-call screen→world voxel pick: unproject pixel (x, y) with the active backend’s projection, read the last frame’s depth there, reconstruct the world hit, and resolve it to the owning grid + grid-local voxel via Scene::resolve_voxel. None on sky / no-hit, or when no grid claims the surface.

scene and camera must be the ones the last frame rendered; the projection (size + FOV / hx,hy,hz) is taken from that frame. Cheap on CPU (in-memory z-buffer); on GPU it stages the depth buffer (a click-time device poll — not per frame).

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 for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Convert Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Convert Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
Source§

fn as_any(&self) -> &(dyn Any + 'static)

Convert &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
Source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Convert &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
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> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
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> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
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> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more