-
Notifications
You must be signed in to change notification settings - Fork 56
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WIP: next #299
base: develop
Are you sure you want to change the base?
WIP: next #299
Conversation
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. |
Notan's new core
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): gfx_clear.rsuse 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();
} gfx_triangle.rsuse 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: draw_triangle.rsuse 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();
} draw_sprite.rsuse 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: