Open Nazariglez opened 10 months ago
Each example must be made on its own commit, and that commit must be referenced on this PR. Allowing users to check the diff easily as a guide for migrating.
Edit: I am thinking that this can be tricky if it's an iterative change, because the API can evolve a bit while this PR lands, but I'll try to do my best.
I added a checklist with things that must be done. Some of them are going to change quite a bit, so I am going to create separate PRs for those features or just leave comments to discuss the changes.
I am trying to keep the soul of the project without changes. However, some things must go, like graphics extensions, they are handy but too limiting (ie: we cannot use draw2d on EGUI because that design does not work with the borrow checker, etc...). This will make some things more verbose for the user, but not that much. We will see.
I want to do this in a way that works for me and for others as well, so I am not going to click the merge button until we're sure this is what we want to do with Notan.
Quick update on this, I am experimenting almost full-time in another repo with a new API for Notan. I really like the API made here, I do think it's elegant and functional, however it has still some issues and is not very ergonomic when dealing with plugins (egui paint callback, etc...). I hope to have something working and translated this repo soon. A sneak peak (this can still change):
use rkit::gfx::{self, Color, Renderer};
use rkit::time;
fn main() {
rkit::init().on_update(update).run().unwrap()
}
fn update() {
let t = time::elapsed_f32();
let color = Color::rgb(t.cos(), t.sin(), 1.0);
let mut renderer = Renderer::new();
renderer.begin_pass().clear_color(color);
gfx::render_to_frame(&renderer).unwrap();
}
use rkit::gfx::{self, Buffer, Color, RenderPipeline, Renderer, VertexFormat, VertexLayout};
// language=wgsl
const SHADER: &str = r#"
struct VertexInput {
@location(0) position: vec2<f32>,
@location(1) color: vec3<f32>,
};
struct VertexOutput {
@builtin(position) position: vec4<f32>,
@location(0) color: vec3<f32>,
};
@vertex
fn vs_main(
model: VertexInput,
) -> VertexOutput {
var out: VertexOutput;
out.color = model.color;
out.position = vec4<f32>(model.position - 0.5, 0.0, 1.0);
return out;
}
@fragment
fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
return vec4<f32>(in.color, 1.0);
}
"#;
struct State {
pip: RenderPipeline,
vbo: Buffer,
}
impl State {
fn new() -> Result<Self, String> {
let pip = gfx::create_render_pipeline(SHADER)
.with_vertex_layout(
VertexLayout::new()
.with_attr(0, VertexFormat::Float32x2)
.with_attr(1, VertexFormat::Float32x3),
)
.build()?;
#[rustfmt::skip]
let vertices: &[f32] = &[
0.5, 1.0, 1.0, 0.0, 0.0,
0.0, 0.0, 0.0, 1.0, 0.0,
1.0, 0.0, 0.0, 0.0, 1.0,
];
let vbo = gfx::create_vertex_buffer(vertices).build()?;
Ok(Self { pip, vbo })
}
}
fn main() {
rkit::init_with(|| State::new().unwrap())
.on_update(update)
.run()
.unwrap()
}
fn update(s: &mut State) {
let mut renderer = Renderer::new();
renderer
.begin_pass()
.clear_color(Color::rgb(0.1, 0.2, 0.3))
.pipeline(&s.pip)
.buffers(&[&s.vbo])
.draw(0..3);
gfx::render_to_frame(&renderer).unwrap();
}
Working on Draw2D API:
use rkit::draw::draw_2d;
use rkit::gfx::{self, Color};
use rkit::math::vec2;
fn main() -> Result<(), String> {
rkit::init().on_update(update).run()
}
fn update(s: &mut ()) {
let mut draw = draw_2d();
draw.clear(Color::rgb(0.1, 0.2, 0.3));
draw.triangle(vec2(400.0, 100.0), vec2(100.0, 500.0), vec2(700.0, 500.0));
gfx::render_to_frame(&draw).unwrap();
}
use rkit::app::window_size;
use rkit::draw::{draw_2d, Sprite};
use rkit::gfx::{self, Color};
struct State {
sprite: Sprite,
}
impl State {
fn new() -> Result<Self, String> {
let sprite = draw::create_sprite()
.from_image(include_bytes!("assets/ferris.png"))
.build()?;
Ok(Self { sprite })
}
}
fn main() -> Result<(), String> {
rkit::init_with(|| State::new().unwrap())
.on_update(update)
.run()
}
fn update(s: &mut State) {
let pos = window_size() * 0.5 - s.sprite.size() * 0.5;
let mut draw = draw_2d();
draw.clear(Color::rgb(0.1, 0.2, 0.3));
draw.image(&s.sprite).position(pos);
gfx::render_to_frame(&draw).unwrap();
}
I am trying to keep the API as similar as possible but improving (or trying) some parts.
Related to this, WGPU is a different beast, and I am not sure yet how to manage blending and masking in a easy way, so I am still experimenting a lot with this.
This is the next version of notan. We can consider it a rework, addressing some of the flaws, but also leaving behind some bad design decisions.
To merge this we need to reach a feature pair status, the API may change in some cases:
Then we can aim to get some extras, but they are not required: