Skip to content

Rust WebGL2 wrapper with a focus on making high-performance WebAssembly graphics code easier to write and maintain

License

Notifications You must be signed in to change notification settings

jamsocket/limelight

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Limelight

GitHub Repo stars crates.io docs.rs Rust

Limelight is a WebGL2 wrapper with a focus on making high-performance WebAssembly graphics code easier to write and maintain.

demo.mov

live demo (code)

Specifically, limelight:

  • Provides a functional interface that abstracts away the statefulness of WebGL. It accomplishes this by using a shadow GPU that tracks the GPU's state, diffs it with the desired state, and sends only the necessary instructions to WebGL.
  • Provides abstractions for buffers and uniforms that defer GPU data transfer until the next draw cycle.
  • Provides a typed interface to uniforms and buffers, and automatically generates bindings between shader attributes and Rust structs through a derive macro.
  • Provides an interface for transforms like zoom and pan through limelight-transform.
  • Provides 2D shape primitives like circles and lines through limelight-primitives.

Getting started

Abstract art made from circles and rectangles.

(full code, demo)

This example uses limelight-primitives and limelight-yew to construct a basic, static image made from circles and rectangles.

use anyhow::Result;
use limelight::{renderer::Drawable, Renderer};
use limelight_primitives::{Circle, CircleLayer, Rect, RectLayer};
use limelight_yew::{LimelightComponent, LimelightController};

struct Primitives {
    rects: RectLayer,
    circles: CircleLayer,
}

impl LimelightController for Primitives {
    fn draw(
        &mut self,
        renderer: &mut Renderer,
        _ts: f64,
    ) -> Result<limelight_yew::ShouldRequestAnimationFrame> {
        self.rects.draw(renderer)?;
        self.circles.draw(renderer)?;

        Ok(false)
    }
}

impl Default for Primitives {
    fn default() -> Self {
        let rects = RectLayer::new();
        let circles = CircleLayer::new();

        rects.buffer().set_data(vec![
            Rect {
                lower_right: [0.4, 0.1],
                upper_left: [-0.8, 0.2],
                color: palette::named::TOMATO.into(),
            },
            Rect {
                lower_right: [0.4, 0.25],
                upper_left: [-0.6, 0.5],
                color: palette::named::SLATEBLUE.into(),
            },
        ]);

        circles.buffer().set_data(vec![
            Circle {
                position: [0., 0.25],
                radius: 0.2,
                color: palette::named::WHITE.into(),
            },
            Circle {
                position: [0., 0.25],
                radius: 0.1,
                color: palette::named::ORANGERED.into(),
            },
        ]);

        Primitives { rects, circles }
    }
}

fn main() {
    console_error_panic_hook::set_once();
    wasm_logger::init(wasm_logger::Config::default());
    yew::start_app::<LimelightComponent<Primitives>>();
}

More Examples

About

Rust WebGL2 wrapper with a focus on making high-performance WebAssembly graphics code easier to write and maintain

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published