Skip to main content

Crate roxlap_render

Crate roxlap_render 

Source
Expand description

roxlap-render — unified CPU/GPU renderer facade.

One SceneRenderer hides the choice between the CPU opticast path (roxlap-core / roxlap-scene, presented via softbuffer) and the GPU compute-shader path (roxlap-gpu, presented via its own wgpu surface). Construction picks the GPU backend when asked and able, and falls back to CPU automatically when WGPU init fails — so a host never has to branch on GPU availability or carry the Scene→GPU upload/refresh/transform glue itself.

Hosts stay thin: build a Scene, advance it from input, then call SceneRenderer::render each frame. The facade owns the window surface, the framebuffer/z-buffer (CPU) or the resident scene + dirty-chunk tracking (GPU), and presentation.

The per-frame flow is render(optional overlays) → finish. Between SceneRenderer::render and the finishing SceneRenderer::present / [SceneRenderer::paint_egui] call, a host may overlay depth-tested world-space lines with SceneRenderer::draw_lines (editor gizmos, debug geometry — see Line3); they land in the framebuffer, occluded by the rendered scene, with egui still painting panels on top.

This is the RF.0 skeleton: backend selection + fallback + a clear-to-sky frame. RF.1/RF.2 fill in the real CPU/GPU scene render; RF.3 adds sprites; RF.4 adds framebuffer capture.

Structs§

ActorState
One animation state of a BillboardActorDef: its name plus the clips for each viewing direction. dirs.len() may be 1 (non-directional), 8 (classic Doom rotations), or any N (uniform angular bins). Index 0 is the view-from-front (camera in the actor’s facing direction), increasing counter-clockwise.
Attachment
One thing a bone draws: a mesh/clip reference, a local offset placing it on the bone, and (for clips) playback parameters (VCL.5).
BillboardActorDef
Recipe for add_billboard_actor.
BillboardActorId
Stable handle to a BillboardActor — a high-level directional billboard managed by the renderer (it owns one clip instance, picks the directional clip by view angle, and plays a named-state animation). Reset by set_sprites; a removed actor’s handle is stale → a safe no-op.
Character
A parsed rigged-character container.
CharacterId
Stable handle to a registered animated character (VCL.6) — the result of SceneRenderer::add_character, advanced each frame with advance_character and dropped with remove_character. Reset by set_sprites.
ClipMetadata
Public metadata for a registered clip — the inspector view returned by SceneRenderer::clip_metadata.
DecodedClip
A decoded clip: every frame expanded to a full VoxelFrame plus its recomputed dirs (parallel to frames[i].colors) and resolved durations. The runtime flipbook.
DirectionalLight
The sun — a single directional light for the whole scene. World space.
DynSpriteTransform
Orientation + position for a dynamic sprite instance — the per-frame pose passed to SceneRenderer::add_sprite_instance_posed and set_sprite_instance_transform.
FrameParams
Per-frame inputs both backends consume. The host builds the OpticastSettings (it owns scan distance etc.); the facade does everything else (pool config, sky fill, render, present).
GpuRendererSettings
Caller-controllable knobs for GpuRenderer::new. Defaults target “highest-performance GPU, prefer Mailbox/Immediate over vsync” — i.e. the same configuration the GPU.0 probe used to measure the FPS ceiling.
ImageId
A handle to an uploaded image-sprite texture, returned by SceneRenderer::upload_image. Positional (like SpriteModelId): it indexes the backend’s texture store. Pass it in an ImageSprite for SceneRenderer::draw_images, or to drop_image to release it. Opaque on purpose — there’s no arithmetic to do on it.
ImagePickHit
Result of SceneRenderer::pick_image — a resolved screen→sprite hit. uv is the normalised position within the quad ((0,0) = top-left corner); texel is the matching source-image pixel; world is the hit point; t is its euclidean distance from the camera.
ImageSprite
One placed 2D image sprite for the current frame: a flat textured quad in world space, composited over the rendered scene with the frame’s depth buffer (so the voxel model can occlude it). Built per frame and passed to SceneRenderer::draw_images, mirroring Line3 / SceneRenderer::draw_lines. The texture is uploaded once via SceneRenderer::upload_image and referenced by image.
KfaSprite
One animated KFA sprite — bones + hinges + per-bone live animation values.
Kv6
Parsed .kv6 model. Round-trips byte-equally via parse + serialize.
LightRig
The whole per-frame light environment, borrowed into crate::FrameParams. GPU-only.
Line3
A world-space line segment to draw over a rendered frame via SceneRenderer::draw_lines — editor gizmos (bounding boxes, floor grids, axes, hover wireframes), debug paths, etc.
Material
One material: an opacity and a blend mode, indexed out of a MaterialTable by a per-voxel material id.
PickHit
Result of SceneRenderer::pick — a resolved screen→world voxel hit. world is the surface point (cam.pos + t · normalize(ray)); grid + voxel are the owning grid and its grid-local voxel (transform-correct for rotated / translated grids).
PointLight
A colored point light. World space, with a hard radius cutoff (it contributes nothing beyond radius).
PosterizeConfig
Reduced-palette post (RP.2), applied at the logical resolution in the resolve step (after the SSAA box-downfilter, before the nearest upscale). Each channel is quantized to its own number of levels; levels <= 1 leaves that channel untouched. None posterize ⇒ the RP.0/RP.1 paths verbatim.
Ray
A world-space view ray: the canonical unproject output of SceneRenderer::view_ray. dir is unit-length. Feed it straight to roxlap_scene::Scene::raycast for depth-free, backend-agnostic voxel picking (scene.raycast(ray.origin, ray.dir, max_dist)), or intersect it with a plane for tile selection.
RenderOptions
Construction-time options for SceneRenderer::new.
SceneRenderer
Unified renderer over the CPU and GPU paths. See the crate docs.
SpotLight
A spot (cone) light — a PointLight with a direction and a soft angular cutoff, so it lights only a cone. World space. Internally folded into the point-light path (a point light is the 180°-cone degenerate), so spots share the point-light count + shadow-caster budgets.
Sprite
A KV6 voxel sprite positioned in world space.
SpriteInstanceDesc
One placed sprite instance: which SpriteSet::models entry and where in the world.
SpriteInstanceId
Stable handle to a dynamically added sprite instance — the result of SceneRenderer::add_sprite_instance, passed to remove_sprite_instance.
SpriteModelId
Stable handle to a registered sprite model, returned (one per SpriteSet::models entry, in order) by SceneRenderer::set_sprites. Pass it to refresh_sprite_model to re-register that model’s geometry after a content edit — so callers never track the positional usize index themselves. Opaque on purpose: there is no arithmetic to do on it.
SpriteSet
Backend-agnostic sprite description. The facade builds the CPU per-instance draw list and the GPU instanced registry from the same data, so both backends show identical sprites. The host owns content (which models, where, recolouring) — building a recoloured variant is just a second Sprite model with edited kv6.voxels.
StreamingClip
A seekable, O(1-frame)-memory cursor over a VoxelClip’s I/P stream — the streaming alternative to DecodedClip, which materialises every frame (and which the GPU/CPU flipbook then holds N volumes for). For a huge clip this keeps one reconstructed frame plus the compact encoded stream instead of N full frames.
StreamingClipId
Stable handle to a registered streaming voxel clip (follow-up #3) — the result of SceneRenderer::add_streaming_clip, advanced with set_streaming_clip_frame and dropped with remove_streaming_clip. Reset by set_sprites.
StreamingInstanceId
Handle to an instance of a streaming clip (add_streaming_clip_instance).
VoxelClip
On-disk animated voxel clip. Construct via VoxelClip::from_frames (the encoder) or VoxelClip::parse; expand to a runtime flipbook via VoxelClip::decode.
VoxelClipId
Stable handle to a registered animated voxel clip (VCL.4) — the result of SceneRenderer::add_voxel_clip, passed to add_clip_instance_posed and remove_voxel_clip. Like SpriteModelId, a removed clip’s handle is stale → a safe no-op. Reset by set_sprites (which drops the dynamic + clip layers).
VoxelFrame
One fully-reconstructed frame in the dense-column layout. Field shapes are validated against the clip’s dims by VoxelFrame::validate.

Enums§

Backend
Which renderer a SceneRenderer resolved to at construction.
BillboardLighting
How a sprite/billboard instance derives its shading normal (BB.2b) — a per-instance choice that rides the sprite flags. A camera-facing billboard’s DDA face normal tracks the camera, so its N·L would shift as you orbit; WorldUp / AmbientOnly tame that. Only affects the dynamic lighting path (a disabled rig is unaffected). Set via set_sprite_instance_lighting or BillboardActorDef::lighting.
BillboardMode
How a billboard instance turns to face the camera (BB.2). Set per instance via SceneRenderer::add_billboard_instance / set_billboard_mode; applied each face_billboards_to.
BlendMode
How a voxel’s colour combines with what is already behind it along a ray.
DecodeError
Why VoxelClip::decode failed.
DitherMode
Dither applied before the posterize quantization (RP.2), to break up banding and turn it into a stable retro pattern instead of crawling edges. Indexed by the logical pixel, so each hard pixel still resolves to one colour.
GpuInitError
Errors GpuRenderer::new surfaces to the host. The host’s expected flow is “try this, fall back to the CPU path on Err”.
ImageFacing
How an ImageSprite’s quad is oriented in the world.
LoopMode
How playback advances past the last frame.
MeshRef
Typed reference to what a bone attachment draws. The on-disk mesh_kind discriminant selects the variant.
PowerPreference
RenderResolution
Where the per-pixel raycaster actually runs, decoupled from the window size (RP.0). Both backends are per-pixel marchers, so frame cost scales with the pixel count — rendering into a fixed logical target and nearest-upscaling it to the window makes FPS independent of window size and creates the seam for the later posterize / SSAA post (RP.1/RP.2).

Traits§

HasDisplayHandle
A display that acts as a wrapper around a display handle.
HasWindowHandle
A handle to a window.