Dunge
Features
- Simple but flexible API
- Desktop, WASM and Android (WIP) support
- Pixel perfect render
- Texture and color vertex modes
- Primitives for object positioning and camera view out of the box
Getting Started
Let's render a colorful triangle for example. First, we need to add the dependency of dunge in the Cargo.toml
:
cargo add dunge
Then, let's create a new window to draw something in it:
use dunge::{
color::Srgba,
handles::*,
input::{Input, Key},
transform::Position,
vertex::ColorVertex,
Context, Error, Frame, InitialState, Loop, MeshData, Perspective, View, WindowMode,
};
fn main() {
dunge::make_window(InitialState::default())
.run_blocking(App::new);
}
make_window
creates a new instance of Canvas
type and sets up window properties, it allows us to handle an input from users. run_blocking
runs our application by calling the constructor of it and passes the Context
object there. Context uses for creation and updating of meshes, textures, views, instances etc.
The App
is our application type, we need to create it:
struct App {
layer: LayerHandle<ColorVertex>,
instance: InstanceHandle,
mesh: MeshHandle<ColorVertex>,
view: ViewHandle,
}
impl App {
fn new(context: &mut Context) -> Self {
let layer = context.create_layer();
let instance = context.create_instances([Position::default()]);
let mesh = {
const VERTICES: [ColorVertex; 3] = [
ColorVertex { pos: [-0.5, -0.5, 0.], col: [1., 0., 0.] },
ColorVertex { pos: [ 0.5, -0.5, 0.], col: [0., 1., 0.] },
ColorVertex { pos: [ 0., 0.5, 0.], col: [0., 0., 1.] },
];
let data = MeshData::from_verts(&VERTICES);
context.create_mesh(&data)
};
let view = context.create_view::<Perspective>(View::default());
Self { layer, instance, mesh, view }
}
}
To be able to pass the App
in run_blocking
we need to implement a Loop
trait for it:
impl Loop for App {
type Error = Error;
fn update(&mut self, context: &mut Context, input: &Input) -> Result<(), Self::Error> {
Ok(())
}
fn render(&self, frame: &mut Frame) -> Result<(), Self::Error> {
let mut layer = frame
.layer(self.layer)?
.with_clear_color(Srgba([0, 0, 0, 255]))
.with_clear_depth()
.start();
layer.bind_view(self.view)?;
layer.bind_instance(self.instance)?;
layer.draw(self.mesh)
}
}
Finally, let's run our code:
cargo run
Now you should see something like this:
Examples
See examples directory for more examples.
To build and run an example do:
cargo r -p <example_name>