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
andInstanced 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.
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.
This is a goal that the project hopes to achieve in the future, and everyone is welcome to participate actively. see: TODO List
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"
- Reference example project nvgx-demo/Cargo.toml
- 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(())
}
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"
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