This is a quick post to describe a little Rust crate that I created for fun: a WebAssembly graphics library.
The library is not meant for any serious work; it has no hardware acceleration and is not highly optimised. I created it to help me to learn Rust, WebAssembly, general graphics routines and unit testing and benchmarking in Rust. I’m sharing it mainly for fun, but also with the hope that it might help someone who is learning this type of thing too.
Why I made it
I have always been interested in graphical routines. Some of my earliest experiments on the Amstrad CPC464 and Commodore 64 involved rendering graphics of some kind. Since then, as the years have passed, I have dabbled in graphical routines in various different languages/frameworks (e.g. Delphi, C/SDL and C#).
Since then I have become very interested in both Rust and WebAssembly, so I decided to update my previous work to the present day.
What can it do?
The goal of the library is simplicity. As such, rendering canvases are simply arrays of 32-bit integers, allowing all 24-bit RGB colours to be used together with an 8-bit alpha channel.
The library provides the following routines: -
- Clearing a canvas to an ARGB colour;
- Copying one canvas to another at an arbitrary destination location;
- Loading pixels from a
- Performing UV sampling of any canvas;
- Line drawing;
- Outline and filled rectangle drawing;
- Triangle drawing: outline, filled and textured; and
- Arbitrary polygon drawing (convex and concave, filled or outline).
The library is intended to be used as a WebAssembly module within a browser context, but as it renders to simple integer arrays it could theoretically be used in a wide variety of other situations.
wasm-bindgen, tests and benchmarks
Whenever possible I write unit tests for my projects. In order to learn how to write tests in Rust I added a simple test suite to this project. The tests can be run using the
cargo test command.
Another goal of this project was to learn how to run code benchmarks in Rust. A library of graphics routines – which need to be as fast as possible – was a really good way to learn how to do this!
I decided to use the Criterion crate for this. To run the benchmarks, use the
cargo bench command.
The project is bundled with a simple demonstration web page. This page loads the library and then executes a rendering loop with a number of examples to show off the features of the library. Please check the demo!
create-wasm-app NPM template.
To build the project you’ll need a Rust development toolchain as well as
wasm-pack. Once these are installed, simply run the following to build the WebAssembly module and JS bindings: -
wasm-pack build --release
To build the example application, change to the
www directory and run
npm install, followed by
npm run build. To run a local development server, use
npm start instead. The example app uses the
create-wasm-app NPM template, so please check its GitHub repository for more details.
Ultimately this project is not intended to provide a graphics library for serious use. It was made for fun and as a learning exercise, and is an example of Rust and WebAssembly with benchmarks, tests and implementations of a number of graphical routines. I’m sharing it in the hope that it’ll help others who are researching these topics too!