An egui UI
With the egui feature, render_egui runs your UI closure, applies egui's texture uploads and tessellates at one pixel per point.
Library active
A CPU rasterizer for 2D triangle meshes and egui frames. It writes premultiplied RGBA8 into a buffer you own, and the same draw calls give the same bytes on every platform.
cargo add dream-soft-render
A handheld running PortMaster has a framebuffer, a small ARM core, and no GPU a program can count
on. An egui interface still has to be drawn. dream-soft-render draws it on the CPU: rectangles,
textured rectangles and triangle meshes go in, and premultiplied RGBA8 comes out, in a buffer you
own. Copying it to /dev/fb0, writing a PNG or hashing it in a test is up to you.
There is no window, no swapchain and no driver. There is also no randomness: the same draw calls produce the same bytes on x86-64 and on AArch64, whose NEON code is held to the portable code by tests. It was pulled out of dream-ini, whose PortMaster build draws its whole GUI through it; the header image is one of the egui scenes its golden tests pin, drawn by this crate.
Both ways in rasterize into one surface, through the same recognizers and the same blending, so identical geometry gives identical bytes.
Frame::clear, fill_rect, textured_rect and mesh, each rasterized the moment you make it.
Rectangles, one-color fans and triangles with one texel draw as spans. Everything else is covered pixel by pixel. NEON on AArch64, the same bytes either way.
width x height x 4 bytes of premultiplied RGBA8, top row first. Yours to copy to a framebuffer, a file or a hash.
With the egui feature, render_egui runs your UI closure, applies egui's texture uploads and tessellates at one pixel per point.
Premultiplied RGBA8, created and freed through the renderer. egui's font atlas lives in the same store, under the same 8 MiB budget.
egui feature, render_egui runs a UI closure into the
same surface, and skips frames that came out identical to the last.egui feature the crate has no dependencies, and no
platform code beyond its NEON kernels.use dream_soft_render::{ClipRect, Color, Error, Rect, SoftwareRenderer};
fn main() -> Result<(), Error> {
let mut renderer = SoftwareRenderer::default();
let mut frame = renderer.begin_frame(320, 240)?;
frame.clear(Color::from_rgb(17, 20, 28));
frame.fill_rect(
Rect::from_min_size([8.0, 8.0], [304.0, 40.0]),
Color::from_rgba_unmultiplied(80, 160, 255, 192),
ClipRect::ALL,
)?;
// 320 * 240 * 4 bytes, top row first.
let rgba: &[u8] = &frame.surface().pixels;
assert_eq!(&rgba[..4], &[17, 20, 28, 255]);
Ok(())
}This site is the crate’s documentation, its API reference included.
render_egui, textures, unchanged frames and feathering.2 items
Rust crate · 1.0.0
From your project's directory:
cargo add dream-soft-render
Or by hand, in Cargo.toml:
[dependencies]
dream-soft-render = "1.0.0"
Cargo reads a bare version as "this or any compatible newer release" and records the exact one in Cargo.lock.
[dependencies]
dream-soft-render = { git = "https://github.com/DreamWeave-MP/dream-soft-render" }
Cargo pins the commit it fetched in Cargo.lock; cargo update -p dream-soft-render moves it forward.
First release: the software rasterizer from dream-ini’s PortMaster build, with a drawing API of its own and egui as an option.
SoftwareRenderer and Frame: clear, fill_rect, textured_rect and mesh, rasterized immediately into a premultiplied RGBA8 surface.create_texture, update_texture and free_texture, with handles issued process-wide and never reused.Color, Vertex, Rect, ClipRect and TextureId, and one Error type for every rejected call.egui feature: render_egui, RenderFrame, RenderOutcome, and skipping frames whose output did not change.draw and frame benchmarks, and golden hashes of four whole frames.render_egui, a frame after one whose texture uploads failed part way can be skipped as unchanged and keep the old texels. Fixed on the default branch.render_egui, textures egui releases in a frame that fails stay in the store and count against the budget. Fixed on the default branch.render_egui, a mesh with an index past its vertices, or a trailing partial triangle, is skipped instead of failing the frame. Fixed on the default branch.The same digest as the crates.io index's checksum, which Cargo checks on every download.