Right now, there isn’t a good drawing framework for Rust. Actually, I lie, there is a good one; piet
. However, it’s pretty tightly tied to the druid
ecosystem. However, adapting it to other frameworks is relatively dfficult.
winit
is a fantastic crate, but it doesn’t come with a real way to draw to the screen. This is intentional; it prevents the winit
team from needing to maintain a drawing library in addition to the already-very-large windowing library. However, it means that, when it comes to drawing, there’s no real “out of the box” solution. When you Google “winit drawing”, the first post recommends using druid-shell
instead of winit
. There are other drawing frameworks, but they’re usually tightly integrated into a GUI framework, and are often difficult to extract into something useful.
The piet-glow
crate is a step towards solving this problem. It’s standalone and not tied to any particular GUI framework. It’s also hardware-accelerated, using the glow
crate as an interface to OpenGL.
Usage
First, you need to create a GlContext
, which is just a wrapper around a glow::Context
.
let context = unsafe {
let gl = glow::Context::from_loader_function(/* ... */);
piet_glow::GlContext::new(gl)
};
Note that creating a GlContext
is unsafe, since it assumes that the context is current.
Once you have a GlContext
, you can call the render_context
method to get a type that implements piet::RenderContext
.
unsafe {
let mut ctx = context.render_context(window_width, window_height);
ctx.clear(Color::WHITE);
ctx.finish().unwrap();
}
Implementation
I built piet-glow
on top of another crate I wrote, piet-hardware
. piet-hardware
does all of the heavy lifting; it converts the higher-level drawing operations to rendering textured triangles. From there, piet-glow
only implements the interface to OpenGL that piet-hardware
expects.
It is definitely possible to implement piet-hardware
for other GPU backends. Most notably, this would be nice for wgpu
drawing, but Vulkan and DirectX are also possible. However, I’m not familiar with those APIs. I could become familiar with them, but I’d rather move at a fast velocity with what I want to do rather than implement GPU APIs when I already know OpenGL. To clarify, it’s on the to-do list, but I’d rather move onto other things first. That being said, if you’d like to implement support for one of these APIs, I’m always open to PRs!
Thanks
piet-glow
, like any open-source project, is built on the sholders of giants. In that respect, I’d like to thank the following people:
- Raph Levien and the Druid team for creating the
piet
andkurbo
crates. Being able to build on top of an existing, robust drawing framework is a huge boon. - Josh Groves for creating
glow
, which has acted as a great abstraction over OpenGL. - Nicolas Silva for two important crates:
lyon-tesselation
andetagere
.lyon-tesselation
powers the tesselation process that converts shapes to triangles.etagere
is the allocation strategy for the text rendering code. Without these two crates,piet-hardware
would be much more difficult to implement. - Jeremy Soller and others for creating
cosmic_text
, which is used for font loading and text layout. - Yevhenii Reizner for creating
tiny-skia
, which is used for rendering gradients and clipping masks. - Alex Butler for creating
ab-glyph
, which is used to render text. - Many, many more people who have contributed to the above projects, among others. I’m grateful for all of you.