4 releases

new 0.3.0 May 15, 2025
0.2.2 May 14, 2025
0.2.1 May 14, 2025
0.2.0 May 14, 2025

#90 in Graphics APIs

Download history 182/week @ 2025-05-09

182 downloads per month
Used in 2 crates

MIT license

390KB
4K SLoC

NVGX: Pure-rust NanoVG

nvgx is a pure Rust implementation and enhanced version of NanoVG, not merely a direct C API wrapper. Compared to nvg, it provides more comprehensive API functionality support, extensive performance optimizations, and improvements in certain visual effects.

  • Support Framebuffer
  • Support Path and Instanced API
  • Support WGPU backend

NanoVG is small antialiased vector graphics rendering library for OpenGL. It has lean API modeled after HTML5 canvas API. It is aimed to be a practical and fun toolset for building scalable user interfaces and visualizations.

Note

The current OpenGL backend API is based on OpenGL 3.1, while WebGL 2.0 (GLES 3.0) compatibility has been considered but not yet tested. The fragmentation and problematic nature of GPU driver implementations across different vendors remain significant issues, as discussed in the Glium post-mortem. With OpenGL 4.0+ APIs being gradually replaced by the more standardized Vulkan, the OpenGL backend should prioritize the relatively stable and unified OpenGL 3.1 standard. Although OpenGL 4.0 has been in existence for 15 years and is supported by the vast majority of modern GPUs, backward compatibility concerns for OpenGL 3.1 are largely obsolete for contemporary hardware. Earlier versions like OpenGL 2.0+ are no longer supported due to their lack of instanced rendering APIs and the excessive complexity of cross-version API and shader compatibility, which introduces unnecessary technical debt.

Goal

This is a goal that the project hopes to achieve in the future, and everyone is welcome to participate actively. see: TODO List

Usage

In the current graphics library, you can select different backend implementations according to your needs, such as WGPU and OpenGL.

[dependencies]
nvgx = "0.2.0"
# Use wgpu backend
nvgx-wgpu = "0.2.0"
# Use OpenGL 3.1 backend
nvgx-ogl = "0.2.0"

Example Code

  • draw a round rect
fn update(
        &mut self,
        width: f32,
        height: f32,
        ctx: &mut Context<Renderer>,
    ) -> Result<(), Error> {
    ctx.begin_path();
    ctx.fill_paint(nvgx::Color::rgb(0.9, 0.3, 0.4));
    ctx.rounded_rect(nvgx::Rect::new(
      Point::new(250.0, 300.0),
        Extent::new(80.0, 80.0),
    ), 5.0);
    ctx.fill()?;
}
  • draw path instance
pub fn draw(&mut self, ctx: &mut Context<R>) -> anyhow::Result<()> {
    if self.update {
        let path = self.line_path.reset();
        path.move_to(self.control_points[0].p);
        path.line_to(self.control_points[1].p);
        path.line_to(self.control_points[2].p);
        let path = self.path.reset();
        path.move_to(self.control_points[0].p);
        path.arc_to(
            self.control_points[1].p,
            self.control_points[2].p,
            self.radius,
        );
        self.update = false;
    }
    ctx.draw_path(
        &self.line_path,
        &self.line_paint,
        DrawPathStyle::WIRELINES,
        None,
    )?;
    ctx.draw_path(&self.path, &self.paint, DrawPathStyle::STROKE, None)?;
    for cp in self.control_points.iter() {
        cp.draw(ctx)?;
    }

    Ok(())
}

Bench OpenGL with WGPU backend

Bench commands

cargo run -p nvgx-demo --example demo-cutout --features "nvgx-demo/ogl","nvgx-demo/save-fps"
cargo run -p nvgx-demo --example demo-cutout --features "nvgx-demo/wgpu","nvgx-demo/save-fps"
cargo run -p nvgx-demo --example demo-inst --features "nvgx-demo/ogl","nvgx-demo/save-fps"
cargo run -p nvgx-demo --example demo-inst --features "nvgx-demo/wgpu","nvgx-demo/save-fps"

Demos

The following command allows you to quickly run a demo, provided that you have cloned the entire project's code — fortunately, the total amount of code is not large.

git clone https://github.com/rede97/nvgx
cd nvgx

Simple and Framebuffer

The tiniest way to use nvgx and framebuffer, can help beginner to start with nvgx.
cargo run -p nvgx-demo --example demo-square

Use WGPU backend by default

cargo run -p nvgx-demo --example demo-square --features "nvgx-demo/ogl"

Use OpenGL backend

Clock

cargo run -p nvgx-demo --example demo-clock

Cutout

cargo run -p nvgx-demo --example demo-cutout

Use canvas api to draw cutout

cargo run -p nvgx-demo --example demo-inst

Use Path and instanced API to draw cutout

Draw

cargo run -p nvgx-demo --example demo-draw

Bezier and ArcTo

cargo run -p nvgx-demo --example demo-bezier

Dependencies

~5MB
~96K SLoC