Giter Club home page Giter Club logo

valora's Introduction

valora

crates.io Rust

A brush for generative fine art. Read the guide!

This a graphics library and CLI focused on generative fine art for print.

Features

  • Repeatable works at arbitrary resolutions without changing the work
  • Managed rngs for repeatable works and controlled rng trees
  • Support for using a different, custom GLSL shader for each vector path
  • GLSL live coding with "#include" support
  • An ergonomic derive-based GLSL uniforms interface
  • Animation support for brainstorming and cumulative pieces

valora's People

Contributors

atul9 avatar sqwishy avatar turnage avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

valora's Issues

'gl function was not loaded' in example code

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

Create spawners

I want functions that I can use to spawn polygons. For example f(x) = sin(x) and spawn a triangle on some interval.

glium issue

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?

typos in the gitbook

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.

Old

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)));
        })
    })
}

New

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)));
        })
    })
}

Question: Pixel manipulation and alpha

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!

Logging

Pick out a logging crate with runtime-configurable verbosity and instrument the code with logs.

The first example in the docs does not work

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.

Said window

Replace Tessellator

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.

Stroke join(?) changes based on angle, maybe?

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!

Winding Rules

The rasterizer should support specifying winding rules for paths.

Low Degree Curves

The rasterizer should support

  • Quadratic curves
  • Cubic curves

It should either intersect the grid lines analytically or take a parameter for subdivision depth.

Rendering compound bezier curves with holes

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:
image

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):

image

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:

image

But of course this breaks rendering glyphs which are actually made out of multiple overlapping paths:

image

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.

thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: GlutinCreationError(CreationErrors([NoAvailablePixelFormat, NoAvailablePixelFormat]))',

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.

Crash when drawing many Ngons per frame

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!)

Matrix Transforms

Users should be able to supply matrix transforms for the composition and read the current one.

Define an API for Colorspace control

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.

Precomposition

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.

Project strokes in the rasterizer

Today the rasterizer only supports fills.

To support strokes, it must project strokes. It should support the following line caps:

  • Capless
  • Round
  • Square

It should also accept a parameter for thickness.

Create windowed display

Create a display to target when there is no output file, which indefinitely renders frames forward, and re-seeds on 'r' keypress.

Runtime error following example

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.

"triangle" example is broken

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.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.