3 unstable releases

0.2.0 Jun 14, 2022
0.1.1 Jan 16, 2021
0.1.0 Jan 16, 2021

#437 in Graphics APIs

MIT license

26KB
646 lines

WebGL State Machine in Rust

Package Build Publish

An opinionated wrapper for low-level WebGL API with intention to provide a bit of explicit state management with reasonable defaults. Primary goals for this library is to support WebGL 1.0 so it is built on top of raw bindings from web-sys crate.

Key concepts

  • Program - GL program description including vertex shader, fragment shader, attributes and uniforms. Program takes care of compiling shaders, getting attributes / uniforms locations and finally disposing resources once it goes out of scope.
  • Mesh - structure that holds references to data uploaded to GPU, takes care of disposing array / element buffers once it goes out of scope.
  • Framebuffer - render target, has depth and color slot, can also be initialized as empty then rendering would go to the screen.
  • Pipeline - a primitive for drawing stuff to screen, sole purpose of which is to set GL context configuration and provide shade method for drawing.

Usage example

Get it from crates.io

[dependencies]
# ...
glsmrs = "0.2.0"

Import crate

use glsmrs as gl;

Create context, Ctx is a wrapper that is using Rc internally so you can clone it and pass around without worrying too much about lifetimes.

let ctx = gl::util::get_ctx("canvas-name", "webgl")?;

Create some mesh, like an RGB triangle

let vertices = vec![[0.5, -0.5], [0.0, 0.5], [-0.5, -0.5]];
let colors = vec![[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]];
let indices = [0, 1, 2];

let triangle = gl::mesh::Mesh::new(&ctx, &indices)?
    .with_attribute::<gl::attributes::AttributeVector2>("position", &vertices)?
    .with_attrubute::<gl::attributes::AttributeVector3>("color", &colors)?;

Define render target

let viewport = gl::texture::Viewport::new(720, 480);
let displayfb = gl::texture::EmptyFramebuffer::new(&ctx, viewport);

Create a program description

let program = gl::Program::new(
    &ctx,
    include_str!("../shaders/dummy.vert"),
    include_str!("../shaders/dummy.frag"),
)?;

Run program on state supplying necessary inputs

let uniforms: HashMap<_, _> = vec![
    ("time", gl::UniformData::Scalar(time as f32)),
].into_iter().collect();

let pipeline = gl::Pipeline::new(&ctx);

pipeline.shade(
    &program,
    uniforms,
    vec![&mut triangle],
    &mut displayfb
)?;

For example project using this library check out https://github.com/wg-romank/wasm-game-of-life a tweaked version of original WASM tutorial that runs entierly on GPU.

Dependencies

~6.5–9MB
~171K SLoC