turnage / valora Goto Github PK
View Code? Open in Web Editor NEWpainting by functions
Home Page: https://paytonturnage.gitbook.io/valora/
License: MIT License
painting by functions
Home Page: https://paytonturnage.gitbook.io/valora/
License: MIT License
https://docs.rs/crate/valora/0.2.3/builds/209082
Caused by bluss/matrixmultiply#50
Which itself may be caused by rust-lang/rust#67743
Create a display to target when there is no output file, which indefinitely renders frames forward, and re-seeds on 'r' keypress.
Allow 'b' to enter 4 panel mode, showing 4 seeds of the sketch at once, with the option to pick and commit.
The rasterizer should support
It should either intersect the grid lines analytically or take a parameter for subdivision depth.
Debian 10.
Running the code from the first page of the gitbook:
use valora::prelude::*;
fn main() -> Result<()> {
run_fn(Options::from_args(), |_gpu, world, _rng| {
Ok(move |ctx: Context, canvas: &mut Canvas| {
canvas.set_color(LinSrgb::new(1., 1., 1.));
canvas.paint(Filled(ctx.world));
let max_radius = world.width / 3.;
let radius = ctx.time.as_secs_f32().cos().abs() * max_radius;
canvas.set_color(LinSrgb::new(1., 0., 0.));
canvas.paint(Filled(Ellipse::circle(world.center(), radius)));
})
})
}
Compiling khronos_api v3.1.0
Compiling gl_generator v0.13.1
Compiling gl_generator v0.11.0
Compiling glutin_egl_sys v0.1.4
Compiling glutin_glx_sys v0.1.6
Compiling glium v0.25.1
Compiling glutin v0.21.2
Compiling valora v0.2.9
Compiling valora v0.1.0 (~/Documents/valora)
Finished dev [unoptimized + debuginfo] target(s) in 27.95s
Running `target/debug/valora`
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: GlutinCreationError(CreationErrors([NoAvailablePixelFormat, NoAvailablePixelFormat]))', src/libcore/result.rs:1188:5
stack backtrace:
0: backtrace::backtrace::libunwind::trace
at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.40/src/backtrace/libunwind.rs:88
1: backtrace::backtrace::trace_unsynchronized
at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.40/src/backtrace/mod.rs:66
2: std::sys_common::backtrace::_print_fmt
at src/libstd/sys_common/backtrace.rs:84
3: <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt
at src/libstd/sys_common/backtrace.rs:61
4: core::fmt::write
at src/libcore/fmt/mod.rs:1025
5: std::io::Write::write_fmt
at src/libstd/io/mod.rs:1426
6: std::sys_common::backtrace::_print
at src/libstd/sys_common/backtrace.rs:65
7: std::sys_common::backtrace::print
at src/libstd/sys_common/backtrace.rs:50
8: std::panicking::default_hook::{{closure}}
at src/libstd/panicking.rs:193
9: std::panicking::default_hook
at src/libstd/panicking.rs:210
10: std::panicking::rust_panic_with_hook
at src/libstd/panicking.rs:471
11: rust_begin_unwind
at src/libstd/panicking.rs:375
12: core::panicking::panic_fmt
at src/libcore/panicking.rs:84
13: core::result::unwrap_failed
at src/libcore/result.rs:1188
14: core::result::Result<T,E>::unwrap
at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8/src/libcore/result.rs:956
15: valora::gpu::Gpu::with_window
at ~/.cargo/registry/src/github.com-1ecc6299db9ec823/valora-0.2.9/src/gpu.rs:190
16: valora::run_fn
at ~/.cargo/registry/src/github.com-1ecc6299db9ec823/valora-0.2.9/src/lib.rs:233
17: valora::main
at src/main.rs:4
18: std::rt::lang_start::{{closure}}
at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8/src/libstd/rt.rs:67
19: std::rt::lang_start_internal::{{closure}}
at src/libstd/rt.rs:52
20: std::panicking::try::do_call
at src/libstd/panicking.rs:292
21: __rust_maybe_catch_panic
at src/libpanic_unwind/lib.rs:78
22: std::panicking::try
at src/libstd/panicking.rs:270
23: std::panic::catch_unwind
at src/libstd/panic.rs:394
24: std::rt::lang_start_internal
at src/libstd/rt.rs:51
25: std::rt::lang_start
at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8/src/libstd/rt.rs:67
26: main
27: __libc_start_main
28: _start
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
Users should be able to supply matrix transforms for the composition and read the current one.
Wasn't sure where your gitbook source is, but in the "Introduction page", there're two typos: "lib.rs" should be "main.rs", and in run_fn
, the "world" variable is underscored when it is needed, while the "rng" variable is not underscored but should be.
Put the following in your lib.rs
:
use valora::prelude::*;
fn main() -> Result<()> {
run_fn(Options::from_args(), |_gpu, _world, rng| {
Ok(move |ctx: Context, canvas: &mut Canvas| {
canvas.set_color(LinSrgb::new(1., 1., 1.));
canvas.paint(Filled(ctx.world));
let max_radius = world.width / 3.;
let radius = ctx.time.as_secs_f32().cos().abs() * max_radius;
canvas.set_color(LinSrgb::new(1., 0., 0.));
canvas.paint(Filled(Ellipse::circle(world.center(), radius)));
})
})
}
Put the following in your main.rs
:
use valora::prelude::*;
fn main() -> Result<()> {
run_fn(Options::from_args(), |_gpu, world, _rng| {
Ok(move |ctx: Context, canvas: &mut Canvas| {
canvas.set_color(LinSrgb::new(1., 1., 1.));
canvas.paint(Filled(ctx.world));
let max_radius = world.width / 3.;
let radius = ctx.time.as_secs_f32().cos().abs() * max_radius;
canvas.set_color(LinSrgb::new(1., 0., 0.));
canvas.paint(Filled(Ellipse::circle(world.center(), radius)));
})
})
}
I want functions that I can use to spawn polygons. For example f(x) = sin(x) and spawn a triangle on some interval.
Pick out a logging crate with runtime-configurable verbosity and instrument the code with logs.
Tweening user shader values is awful; need a good way to work with the UniformStorage lifetime magic
Currently valora uses lyon for tessellation. Lyon does not handle complex self intersecting polygons well, especially small ones. It often crashes, returns an error, or enters infinite loops. It is not just lyon; I tested libtess2 as well. My understanding is that tessellation necessarily struggles with these inputs especially if it the vertices have small values.
The amicola
branch implements a replacement for the tessellator. It is a rasterizer that generates boundary segments and fill spans from flat paths which the GPU can rasterize instead of triangles. This algorithm is more robust against complex input and can eventually be migrated entirely to the GPU.
So continuing from my questions in #41 I tried replacing
canvas.move_to(w);
canvas.line_to(P2::new(w.x + 1., w.y));
canvas.stroke();
with
canvas.paint(Filled(Ngon::square(w, 1.)));
to see if it would be faster. Turns out that drawing 30 000 of those per frame causes the program to crash at runtime with the error message below while drawing a smaller number such as 1000 seems fine. In between it's kind of a grey area where it runs for a bit and then crashes.
thread 'main' panicked at 'attempt to subtract with overflow', /home/erik/.cargo/registry/src/github.com-1ecc6299db9ec823/lyon_tessellation-0.14.2/src/fixed.rs:245:33
stack backtrace:
0: 0x55fee7d01434 - backtrace::backtrace::libunwind::trace::h65597d255cb1398b
at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.40/src/backtrace/libunwind.rs:88
1: 0x55fee7d01434 - backtrace::backtrace::trace_unsynchronized::hd4f479d7150ec4a0
at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.40/src/backtrace/mod.rs:66
2: 0x55fee7d01434 - std::sys_common::backtrace::_print_fmt::h015072984a2b172c
at src/libstd/sys_common/backtrace.rs:77
3: 0x55fee7d01434 - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::h6df05d3335f32194
at src/libstd/sys_common/backtrace.rs:61
4: 0x55fee7d22cac - core::fmt::write::h1f444f4312eb6c27
at src/libcore/fmt/mod.rs:1028
5: 0x55fee7cfe797 - std::io::Write::write_fmt::h8d147888220078ef
at src/libstd/io/mod.rs:1412
6: 0x55fee7d0396e - std::sys_common::backtrace::_print::h8a6df0fa81d6af62
at src/libstd/sys_common/backtrace.rs:65
7: 0x55fee7d0396e - std::sys_common::backtrace::print::h6f05b4733407e509
at src/libstd/sys_common/backtrace.rs:50
8: 0x55fee7d0396e - std::panicking::default_hook::{{closure}}::h0d0a23bd02315dd8
at src/libstd/panicking.rs:188
9: 0x55fee7d03661 - std::panicking::default_hook::h8d15a9aecb4efac6
at src/libstd/panicking.rs:205
10: 0x55fee7d0406b - std::panicking::rust_panic_with_hook::hbe174577402a475d
at src/libstd/panicking.rs:464
11: 0x55fee7d03c0e - std::panicking::continue_panic_fmt::h4d855dad868accf3
at src/libstd/panicking.rs:373
12: 0x55fee7d03af6 - rust_begin_unwind
at src/libstd/panicking.rs:302
13: 0x55fee7d1fc1e - core::panicking::panic_fmt::hdeb7979ab6591473
at src/libcore/panicking.rs:139
14: 0x55fee7d1fb6a - core::panicking::panic::hb5daa85c7c72fc62
at src/libcore/panicking.rs:70
15: 0x55fee76faff3 - <lyon_tessellation::fixed::Fp32<F> as core::ops::arith::Sub>::sub::h0365ef83d4f26d9b
at /home/erik/.cargo/registry/src/github.com-1ecc6299db9ec823/lyon_tessellation-0.14.2/src/fixed.rs:245
16: 0x55fee7704a32 - <euclid::point::Point2D<T,U> as core::ops::arith::Sub>::sub::h353125170f56b9de
at /home/erik/.cargo/registry/src/github.com-1ecc6299db9ec823/euclid-0.20.7/src/point.rs:242
17: 0x55fee76cd2f8 - lyon_tessellation::path_fill::FillTessellator::tessellator_loop::h661aa92e0bd6972d
at /home/erik/.cargo/registry/src/github.com-1ecc6299db9ec823/lyon_tessellation-0.14.2/src/path_fill.rs:442
18: 0x55fee76ccc90 - lyon_tessellation::path_fill::FillTessellator::tessellate_events::h27618a730fa9db59
at /home/erik/.cargo/registry/src/github.com-1ecc6299db9ec823/lyon_tessellation-0.14.2/src/path_fill.rs:357
19: 0x55fee74020d4 - lyon_tessellation::path_fill::FillTessellator::tessellate_path::h22c5b42d131b2310
at /home/erik/.cargo/registry/src/github.com-1ecc6299db9ec823/lyon_tessellation-0.14.2/src/path_fill.rs:331
20: 0x55fee73cb8e1 - valora::raster::raster_path::ha8ae8a0dca5ad91d
at /home/erik/.cargo/registry/src/github.com-1ecc6299db9ec823/valora-0.2.2/src/raster.rs:39
21: 0x55fee7343425 - valora::gpu::Gpu::render::{{closure}}::h0e9c2fef0da63f13
at /home/erik/.cargo/registry/src/github.com-1ecc6299db9ec823/valora-0.2.2/src/gpu.rs:318
22: 0x55fee738da04 - core::iter::traits::iterator::Iterator::try_fold::hd519ec48e0f60eb6
at /rustc/73528e339aae0f17a15ffa49a8ac608f50c6cf14/src/libcore/iter/traits/iterator.rs:1709
23: 0x55fee738bc7c - <core::iter::adapters::Peekable<I> as core::iter::traits::iterator::Iterator>::try_fold::hc94bff2d12d4e559
at /rustc/73528e339aae0f17a15ffa49a8ac608f50c6cf14/src/libcore/iter/adapters/mod.rs:1319
24: 0x55fee73413f2 - valora::gpu::Gpu::render::h05b2145fcb6aeb4b
at /home/erik/.cargo/registry/src/github.com-1ecc6299db9ec823/valora-0.2.2/src/gpu.rs:313
25: 0x55fee73745c0 - valora::render::Renderer<F1,F2>::render_frame::h810aeb0df5a4959f
at /home/erik/.cargo/registry/src/github.com-1ecc6299db9ec823/valora-0.2.2/src/render.rs:143
26: 0x55fee73757f0 - valora::render::Renderer<F1,F2>::render_frames::h910b1637c619f2cb
at /home/erik/.cargo/registry/src/github.com-1ecc6299db9ec823/valora-0.2.2/src/render.rs:103
27: 0x55fee73b1523 - valora::run_fn::h9727d3813b4f0ba8
at /home/erik/.cargo/registry/src/github.com-1ecc6299db9ec823/valora-0.2.2/src/lib.rs:270
28: 0x55fee73b0455 - valora::run::h1e8cc6d235cab1b6
at /home/erik/.cargo/registry/src/github.com-1ecc6299db9ec823/valora-0.2.2/src/lib.rs:288
29: 0x55fee7333d48 - valora_test::main::hf6b039243421f43b
at src/main.rs:202
30: 0x55fee739d450 - std::rt::lang_start::{{closure}}::h9c61bd9ce008c062
at /rustc/73528e339aae0f17a15ffa49a8ac608f50c6cf14/src/libstd/rt.rs:61
31: 0x55fee7d03a93 - std::rt::lang_start_internal::{{closure}}::h6ea535ec5c50fc3e
at src/libstd/rt.rs:48
32: 0x55fee7d03a93 - std::panicking::try::do_call::h631c6408dfccc6f5
at src/libstd/panicking.rs:287
33: 0x55fee7d07d8a - __rust_maybe_catch_panic
at src/libpanic_unwind/lib.rs:78
34: 0x55fee7d0460d - std::panicking::try::hab539b2d1255d635
at src/libstd/panicking.rs:265
35: 0x55fee7d0460d - std::panic::catch_unwind::hd5e0a26424bd7f34
at src/libstd/panic.rs:396
36: 0x55fee7d0460d - std::rt::lang_start_internal::h3bdc4c7d98181bf9
at src/libstd/rt.rs:47
37: 0x55fee739d429 - std::rt::lang_start::hbe8c4f9be752a9be
at /rustc/73528e339aae0f17a15ffa49a8ac608f50c6cf14/src/libstd/rt.rs:61
38: 0x55fee7333d8a - main
39: 0x7fb171c5ab6b - __libc_start_main
40: 0x55fee73331ca - _start
41: 0x0 - <unknown>
Full code is in this repo: https://github.com/ErikNatanael/valora-dof-test
(I really like your default command line interface btw!)
Hi,
Im trying to run the example code from the first step of the book. This is my code
use valora::prelude::*;
fn main() -> Result<()> {
run_fn(Options::from_args(), |_gpu, world, _rng| {
Ok(move |ctx: Context, canvas: &mut Canvas| {
canvas.set_color(LinSrgb::new(1., 1., 1.));
canvas.paint(Filled(ctx.world));
let max_radius = world.width / 3.;
let radius = ctx.time.as_secs_f32().cos().abs() * max_radius;
canvas.set_color(LinSrgb::new(1., 0., 0.));
canvas.paint(Filled(Ellipse::circle(world.center(), radius)));
})
})
}
This is running on OS X 10.14.6.
[plat-us1] 3718:~/projects/generative_art mlakewood$ rustup show
Default host: x86_64-apple-darwin
rustup home: /Users/mlakewood/.rustup
installed toolchains
--------------------
stable-x86_64-apple-darwin
nightly-x86_64-apple-darwin
active toolchain
----------------
stable-x86_64-apple-darwin (default)
rustc 1.43.1 (8d69840ab 2020-05-04)
and im getting this error.
Compiling generative_art v0.1.0 (/Users/mlakewood/projects/generative_art)
Finished release [optimized] target(s) in 15.89s
Running `target/release/generative_art`
thread 'main' panicked at 'gl function was not loaded', /Users/mlakewood/projects/generative_art/target/release/build/glium-a14cc260c59976e8/out/gl_bindings.rs:2535:13
stack backtrace:
0: <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt
1: core::fmt::write
2: std::io::Write::write_fmt
3: std::panicking::default_hook::{{closure}}
4: std::panicking::default_hook
5: std::panicking::rust_panic_with_hook
6: std::panicking::begin_panic
7: glium::gl::missing_fn_panic
8: glium::texture::any::new_texture
9: valora::gpu::Gpu::build_texture
10: valora::run_fn
11: generative_art::main
12: std::rt::lang_start::{{closure}}
13: std::panicking::try::do_call
14: __rust_maybe_catch_panic
15: std::rt::lang_start_internal
16: main
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
Any ideas where I should be looking.
Thanks
I have copied the instructions to a tee, copy and pasted everything;
cargo new art --bin && cd art
cargo install cargo-edit && cargo add valora
// in main.rs...
use valora::prelude::*;
fn main() -> Result<()> {
run_fn(Options::from_args(), |_gpu, world, _rng| {
Ok(move |ctx: Context, canvas: &mut Canvas| {
canvas.set_color(LinSrgb::new(1., 1., 1.));
canvas.paint(Filled(ctx.world));
let max_radius = world.width / 3.;
let radius = ctx.time.as_secs_f32().cos().abs() * max_radius;
canvas.set_color(LinSrgb::new(1., 0., 0.));
canvas.paint(Filled(Ellipse::circle(world.center(), radius)));
})
})
}
When run, with cargo run --release
, it gives me a window entirely in black.
Allow hooking a function in to mutate pixels during a stage in the composition.
Hey, super cool project!
I'm coming from Processing and wanted to try this out since I've mostly switched to Rust for everyday stuff.
I wrote a tiny program that draws a few bezier curves and displaces the control points.
I noticed that the stroke join at the tip of the resulting triangle changes between MITER and BEVEL (that's what processing calls them, sorry, only way I know to describe it).
This is the code I'm using, I'll also try to attach a few images to show what I mean:
canvas.set_color(LinSrgb::new(1., 1., 1.));
canvas.paint(Filled(ctx.world));
let fbm = Fbm::new().set_seed(world.seed as u32);
let left_bottom = P2::new(150., 200.);
let right_bottom = P2::new(350., 200.);
let usual_top_point = P2::new(world.width / 2., world.height * 3. / 4.);
let displaced_top_point = usual_top_point.clone().translate(V2::new(
fbm.noise(P2::new(1., ctx.time.as_secs_f32() * 0.1)) * 200.,
fbm.noise(P2::new(2., ctx.time.as_secs_f32() * 0.1)) * 200.,
));
let left_middle_point = left_bottom.lerp(usual_top_point,0.2).translate(V2::new(20.,0.));
let left_c0 = left_bottom.clone().translate(V2::new(0.,10.));
let right_middle_point = right_bottom.lerp(usual_top_point,0.2).translate(V2::new(-20.,0.));
let right_c0 = right_bottom.clone().translate(V2::new(0.,10.));
canvas.move_to(left_bottom);
canvas.cubic_to(left_c0, left_middle_point, displaced_top_point);
canvas.cubic_to(right_middle_point,right_c0,right_bottom );
canvas.set_stroke_width(5.);
canvas.set_color(LinSrgb::new(0.8, 0., 0.));
canvas.stroke();
EDIT: I'm running this on Windows with an NVIDIA GPU, if that helps. Happy to provide more info or try out stuff!
Today all color values are linear RGB. Users should be able to specify sRGB as an output space, but by default all color values from the user should be considered linear.
I am seeing this on macOS 10.15.4 when I try the first sample from the guide. I tried with both stable
and nightly
.
thread 'main' panicked at 'gl function was not loaded', /Users/moritz/code/generative/target/release/build/glium-026141f5ee527852/out/gl_bindings.rs:2535:13
Not sure if I should report this upstream and re-open the glium
ticket?
It should be possible for users to specify an intermediate render target, and then use the result as the fill or stroke shader for a path.
This buffer should not leave GPU unless that is explicitly requested.
Today the rasterizer only supports fills.
To support strokes, it must project strokes. It should support the following line caps:
It should also accept a parameter for thickness.
Pick out a tracing crate and instrument the rasterizer.
Hi!
I don't know if this is where you want to keep discussions, feel free to delete.
I've been implementing Anders Hoff's DOF technique in valora as a starting project, but I can't find any pixel manipulation tools. Is there a way to directly set pixels on the canvas other than a line to 1 pixel away? The main issue I'm running into is that the technique require a very large number of samples at very low alpha, and using alpha values that low (e.g. 0.001) the colour never reaches full brightness. A solution would be to create my own array of brightness values and draw them as pixels.
MVP of low alpha:
use valora::prelude::*;
fn main() -> Result<()> {
run_fn(Options::from_args(), |_gpu, world, _rng| {
Ok(move |ctx: Context, canvas: &mut Canvas| {
canvas.set_color_alpha(LinSrgb::new(1., 1., 1.), 0.001);
canvas.paint(Filled(ctx.world));
})
})
}
Or perhaps this is simply not the intended use case for the framework.
Cheers!
I get a runtime error when I try and follow the guide:
Error: CompilationError("ERROR: 0:1: \'\' : version \'440\' is not supported\nERROR: 0:2: \'\' : #version required and missing.\n")
That's all the information that's included, so I'm not even sure where to start debugging it.
I'm trying to render glyphs by loading the control points from a font and issuing the relevant bezier curve commands to Canvas
, and of course this happens when I try to render an O:
This is because the O glyph consists of two paths in opposite winding directions (I've coloured the start and end points of each path segment going from red to green so I could see the winding directions):
But of course with me trying to render two paths and fill them in, the outer path just completely fills in the inner one. Is there a way to specify winding direction or something that lets me mark a path as negative space? I couldn't figure out how to move the pen without creating a new path.
One way which I've found which helps is to not close paths early and treat the whole glyph as one path, because it looks like the rasteriser treats overlaps in the path as negative space:
But of course this breaks rendering glyphs which are actually made out of multiple overlapping paths:
Although I will admit this has the possibility of looking cool.
I can't see a way of rendering bitmaps either with the drawing API, so I can't get around the problem by just rendering to bitmap and drawing it.
Love the ideas behind this crate and the quality of it!
examples/triangle.rs
doesn't compile, and has a lot of unused code and is generally a bit confusing, I'm wondering if it might be better to remove it and eventually replace it with more documented examples in the future.
The rasterizer should support specifying winding rules for paths.
The rasterizer should be backend agnostic; this belongs in another layer.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.