quicksilver icon indicating copy to clipboard operation
quicksilver copied to clipboard

Version 0.4 Full Release Tracking Issue

Open ryanisaacg opened this issue 4 years ago • 30 comments

During Alpha

Features that have yet to be (re-)implemented, and are planned:

  • [x] Render-to-texture / Surface (#537, #561)
  • [x] Text rendering (#581)
  • [x] Resize handling (#566)
  • [x] Blending support (#562)
  • [x] Helpers for planning when to update / draw (#587)
  • [x] Texture filtering and tiling (#561)
  • [x] https://github.com/ryanisaacg/blinds/issues/5
  • [x] https://github.com/ryanisaacg/blinds/issues/14
  • [x] Re-export crates in that appear in the public API, like blinds and mint (#568)
  • [x] Expose mipmapping?
  • [x] Expose setting the log level to the user (#604)
  • [x] Wrap blinds types (#604)

Features that are yet to be (re-)implemented, and are a maybe:

  • [x] Input state caches (like Keyboard, Mouse, Modifiers) (https://github.com/ryanisaacg/blinds/pull/22)
  • [x] Direct access to the golem graphics API (#588)

Documentation:

  • [x] Overhaul the workflow docs (like the issue templates, PR template, CONTRIBUTING, etc.)
  • [x] Indicate which libraries/tutorials/games are 0.3.x and which are 0.4.x
  • [x] Examples:
    • [x] Window resize example (#616)
    • [x] Reading keyboard and mouse states (#604)
    • [x] Responding to events (#604)
    • [x] Font rendering (#581)

Feedback required:

  • [x] Should the Scalar API be kept? (e.g. keep paying the compile-time process for generics to be able to write terse things like Rectangle::new((x, y), (width, height)) or require explicitness)
  • [x] Should geometry be split into a separate crate to allow use outside Quicksilver?
  • [x] Should image formats other than PNG be supported out-of-the-box? They're not widely used, can cause issues (#508), and cause binary bloat.
  • [x] How should key repeats be handled? (See #523)

Bugs / tickets:

  • [x] #601 (#643)
  • [x] #602 / #594 (#616)
  • [x] #606
  • [x] #607
  • [x] #620 (#641)
  • [x] #623 (#641)
  • [x] #631 (#641)
  • [x] #633 / #607 (#642)
  • [ ] #636
  • [ ] #639

Investigate:

  • [x] Canvas high-dpi
  • [x] Are all the re-export paths sensible or do some require referencing external crates?

API reworks from alpha experience:

  • [ ] #617
  • [x] Take away control of viewport, and automatically set it when you retarget the window (maybe additionally have an automatic orthographic projection, to address #623?) (#641)

When Alpha ends:

  • [x] Update the website (#596)

During Beta

  • [ ] Migration guide from 0.3 to 0.4
  • [ ] Note how to use mint to convert Quicksilver types into other geometry library types
  • [ ] Migrate to web-sys (#653)

Future Minor Release

  • A Lyon helper (#638)
  • https://github.com/ryanisaacg/golem/issues/28
  • End-to-end game example
  • Document the async workflow for loading assets / using other event sources during the event loop

Future Major Release

  • Audio support
  • Migrate default / recommended web backend to web-sys

ryanisaacg avatar Jan 05 '20 16:01 ryanisaacg

Should image formats other than PNG be supported out-of-the-box? They're not widely used, can cause issues (#508), and cause binary bloat.

Personally I can see someone writing code that on the web it first loads jpg versions of (some of) the textures to get the loading done quicker and after that load the better png versions on the background. Especially combined with a service worker to get the png images in cache for next time.

However, according to the linked issue this isn't an option anyway as jpg's crash on the web. Add to this that I see no benefit for them on native and my vote is a clear remove. At least for the time being until it can work again on the web.

As for svg's (Which I assume is the other format being talked about). I have no problem with their removal as I don't use them myself. I don't think they are great for textures leaving their use just for UI elements. I also don't think most other engines have support for svg anyway (at the very least unity doesn't) so not having support for svg's isn't even that surprising.

So, my vote on svg support: It is nice to have but I won't care if it gets removed.

lenscas avatar Jan 05 '20 22:01 lenscas

Svgs aren't actually the other formats I was mentioning (though they are vaguely supported through lyon, once that is re-implemented). The image crate includes tiff, gif, jpeg, bmp, ico, and png. Of those, I think png is used the most, but every crate that pulls in Quicksilver takes a compile time and binary size hit to support the others.

ryanisaacg avatar Jan 05 '20 22:01 ryanisaacg

Huzzah, progress! Some minor notes from an upgrade attempt, since I'm not sure if these are just tracking missing API bits, or if they include default implementation stuff:

Features

  • [ ] Blending support

The default blending mode in 0.4.0-alpha0 appears to ignore the image alpha channel now on both desktop (transparent areas are black) and web (transparent areas are white!).

  • [ ] Resize handling

Settings already exposes resize, but the GL viewport is neither automatically set, nor settable through quicksilver, making it impossible to render to the expanded window size.

Feedback

  • [ ] Should the Scalar API be kept? (e.g. keep paying the compile-time process for generics to be able to write terse things like Rectangle::new((x, y), (width, height)) or require explicitness)

No strong preference either way. The case where I get more annoyed is when encountering things like Window::size() or Image::size() returning f32 vectors that I want to convert back to integers, triggering paranoia about fractional pixels, negative dimensions, and NaNs.

  • [ ] Should geometry be split into a separate crate to allow use outside Quicksilver?

Might be better to try and extend an existing math crate like nalgebra to contain the types?

  • [ ] Should image formats other than PNG be supported out-of-the-box? They're not widely used, can cause issues (#508), and cause binary bloat.

I think it's fine for the default feature set to not support PNGs. Just have a decent error message for devs when you try to load .jpeg s anyways.

  • [ ] How should key repeats be handled? (See #523)

This is a whole rabbit hole, be aware that fully solving the problem perfectly is nontrivial to impossible. Having a basic "best effort" BTreeSet<Key> somewhere that's set on keydown - and cleared on keyup and window blur - would be reasonable and nice. Forwarding any OS-provided "repeat" bits might also be useful (maybe as a Modifiers bit?)

Some rabbit hole details:

OS event queues may conflate left/right modifiers like control, shift, alt, etc. in a way that makes perfect key state tracking annoying, impossible, or expensive.

XB1 chatpads like https://user-images.githubusercontent.com/33192525/63055071-f323e380-be99-11e9-81c2-9fe66b51310c.jpg send keyup despite holding buttons, and then re-spam keydown / keyup pairs on repeats.

IE11 also doesn't set the input event repeat field on repeat events, but IE11 doesn't natively support WASM so we probably don't care, even if some crazy person might try to get it working via polyfill.

MaulingMonkey avatar Jan 08 '20 05:01 MaulingMonkey

Svgs aren't actually the other formats I was mentioning (though they are vaguely supported through lyon, once that is re-implemented). The image crate includes tiff, gif, jpeg, bmp, ico, and png. Of those, I think png is used the most, but every crate that pulls in Quicksilver takes a compile time and binary size hit to support the others.

bmp is (if I remember correctly) uncompressed and thus a bad choice for anything web related. That alone is in my opinion enough reason not to support it.

I don't think anyone will try tiff and ico files, because at least to me they seem like weird choices for sprites. So, I think they are save to go.

I care little about what happens to gif support.

Png's should stay

Obviously, nice error messages along with documentation on what is supported is always appreciated :)

lenscas avatar Jan 08 '20 13:01 lenscas

JPEG would have been nice for web target.

elsassph avatar Jan 08 '20 14:01 elsassph

It seems like jpeg support is desired, so it stays! See #558. As a nice side effect, rayon is no longer included in the build.

@MaulingMonkey

The default blending mode in 0.4.0-alpha0 appears to ignore the image alpha channel now on both desktop (transparent areas are black) and web (transparent areas are white!).

That was a bug, my bad. Fixed in #560

Settings already exposes resize, but the GL viewport is neither automatically set, nor settable through quicksilver, making it impossible to render to the expanded window size.

Yup, that's part of what remains to be done.

No strong preference either way. The case where I get more annoyed is when encountering things like Window::size() or Image::size() returning f32 vectors that I want to convert back to integers, triggering paranoia about fractional pixels, negative dimensions, and NaNs.

Good point; things that can be ints, probably should be.

Might be better to try and extend an existing math crate like nalgebra to contain the types?

With the exception of maybe vek, most math crates have some minor or major problem that puts me off using them.

keyboard event rabbit hole

Thanks for that info, which is a good look into how horrifying platform APIs are. I think I agree, that a simple best-effort set of currently-down keys (and maybe a separate set for mouse buttons, gamepad buttons, etc

ryanisaacg avatar Jan 08 '20 18:01 ryanisaacg

What's the story for framerate control? Will there be a helper in the lib?

elsassph avatar Jan 11 '20 18:01 elsassph

Yup, the checkmark for that is "Helpers for planning when to update / draw"

ryanisaacg avatar Jan 13 '20 00:01 ryanisaacg

Would you be open to having a "canvas size matches screen/web-window size" feature for full screen?

Something along the lines of:

canvas.set_width(canvas.offset_width() as u32);
canvas.set_height(canvas.offset_height() as u32);

( https://github.com/koute/stdweb/blob/master/examples/canvas/src/main.rs )

paulirotta avatar Jan 19 '20 11:01 paulirotta

Related to @paulirotta 's question: I noticed the canvas isn't high dpi.

elsassph avatar Jan 19 '20 12:01 elsassph

@paulirotta Hm, why match the canvas to the size of the window rather than native fullscreen?

@elsassph If the canvas isn't high-dpi, that could be a winit bug. I'll add investigating that as a task for this issue.

ryanisaacg avatar Jan 21 '20 19:01 ryanisaacg

@ryanisaacg Native full screen sounds great!

paulirotta avatar Jan 22 '20 05:01 paulirotta

Personally, I wouldn't mind to also have an option to set the width and height of the canvas to the size of the browser window. I can defiantly see people (Even myself) wanting to play a game in a screen as big as possible without hiding the rest of the browser.

On native this option should just be the same as maximizing a program.

lenscas avatar Jan 22 '20 09:01 lenscas

I have a question regarding font/text rendering.

I have a sudden urge to try and get a text input to work in Mergui. This will probably be done by rendering every character inside of it separately, instead of making 1 big image out of the text.

Do you foresee many changes between the current system and the new one? And if so, are there things I can already plan for?

Thanks in advance and also, thanks for making quicksilver :)

lenscas avatar Feb 24 '20 22:02 lenscas

@lenscas I've been working on font support locally, which I've just pushed up as #581. The new font system essentially bears no resemblance to the old one, so instead of trying to explain the differences I figured showing them would be better.

ryanisaacg avatar Feb 24 '20 22:02 ryanisaacg

Thanks for the previous answer, it gave me everything I needed to know to start porting mergui :)

However, a few more questions

I saw that there is no function to draw with an Z order. Is that function coming back/am I blind? I am also guessing that this means that draw order now works correctly? ( :tada: )

If it is coming back, how would a draw with a z value interact with one that doesn't? Specifically in the case where the draw without a z value comes after the one with one set? Its fine if you don't know this one, it is more to manage my own time :)

Thanks in advance for answering :)

lenscas avatar Feb 28 '20 20:02 lenscas

Z ordering is dead, and draw order Just Works correctly.

ryanisaacg avatar Feb 29 '20 02:02 ryanisaacg

In the case where you draw to a texture after having made some draw calls that are supposed to go to the window. Is it required to flush first before calling Graphics::fit_to_surface, or is there another way to get the desired result?

//these 2 are supposed to be rendered to the window
gfx.clear(Color::BLACK);
gfx.fill_rect(
    &Rectangle::new(Vector::new(350.0, 100.0), Vector::new(100.0, 100.0)),
    Color::BLUE,
);

gfx.flush(None)?; //This one seems to be needed

//the calls from this point on need to go to the surface
let mut surface = Surface::new(
    &gfx,
    Image::from_raw(&gfx, None, 512, 512, PixelFormat::RGBA)?,
)?;
// Set the render area to the surface size
gfx.fit_to_surface(&surface)?;
gfx.clear(Color::WHITE);

lenscas avatar Apr 21 '20 14:04 lenscas

This is a failure of the API to communicate what's actually happening. gfx.fit_to_surface doesn't change the render target; it changes what the viewport is. You need to call gfx.flush(None)? to send the previous draw commands to the window, and presumably later you'll call gfx.flush(Some(&surface))? to send some draw commands to that surface.

ryanisaacg avatar Apr 21 '20 17:04 ryanisaacg

Ok, then I'm not doing anything wrong :)

Maybe gfx.fit_to_surface should do the call to gfx.flush for you? And if there is a significant cost to flushing and a method that doesn't do it? Or perhaps an extra enum argument to tell it to either flush or not?

I can probably make a pull request for this this weekend.

lenscas avatar Apr 21 '20 18:04 lenscas

I have a weird problem when rendering to a texture. The generated image seems to always be black. However,if I copy the code to to another project it works as expected. The rest of the window gets rendered correctly. So, I'm not even sure if I have other drawing code that causes the problem :(

The code in question

gfx.flush(None)?;
let mut surface = Surface::new(
    gfx,
    Image::from_raw(gfx, None, 512, 512, PixelFormat::RGBA)?,
)?;
gfx.fit_to_surface(&surface)?;
gfx.clear(Color::BLUE);
gfx.fill_rect(&Rectangle::new((0, 0), (10, 10)), Color::GREEN);
gfx.flush(Some(&surface))?;
//gfx.clear(Color::RED);
gfx.fit_to_window(&window);
let image = surface
    .detach()
    .ok_or(quicksilver::QuicksilverError::SurfaceImageError)?;
gfx.draw_image(&image, Rectangle::new((10, 10), (512, 512)));

In case it helps, I commited how far I got, the code can be viewed at : https://github.com/lenscas/mergui/blob/21ea53807a9097fdd1638ec01c265475a29692ca/src/widgets/input.rs#L140

I use the all example to test it

Sorry in advance of the state of that file. I was busy in redoing how it worked to make use of rendering to texture and I tried many things after that to try and discover why it didn't work.

lenscas avatar Apr 23 '20 21:04 lenscas

It looks like everything you're doing is aboveboard, can you open this as an issue? I think it's probably a Quicksilver bug.

ryanisaacg avatar Apr 25 '20 17:04 ryanisaacg

I have a question about Graphics::into_raw_context(self) and what it means for libraries that need Graphics to draw things.

Right now, a library that needs to draw things can not be used by people who want to use custom shaders because there is no way to get the Graphics object back. A way to reduce this problem is to introduce a new trait that is implemented by Graphics and contains the same or a subset of the draw calls currently implemented by Graphics.

This means that libraries can be generic over this trait if the maintainer wants to support users with custom shaders, and developers who write custom shaders have a single trait to implement to be able to use these libraries.

My questions are:

  • Would a trait like this make sense to exist at all.
  • Would a trait like this make sense to be included inside quicksilver? Or do you think every library that needs to draw using quicksilver is better off making their own trait(s) for this purpose instead?

Thanks in advance for answering these 2 questions.

lenscas avatar May 03 '20 23:05 lenscas

@lenscas When using custom shaders, it's hard to maintain the soundness of the Graphics API. golem relies on the user upholding the contract of the prepare_draw. The reason you lose access to the Graphics API is to ensure the safety of flush.

It may be better, rather than trying to replicate the entire Graphics interface through a trait, to have a trait that just incorporates what you need.

ryanisaacg avatar May 04 '20 02:05 ryanisaacg

Ok, this makes sense. Thanks for the answer :)

lenscas avatar May 04 '20 10:05 lenscas

Rasperry Pi 4 raspbian, example 02_image throws a (kudos) clear whine:

ERROR [golem::shader] Failed to compile vertex shader: 0:1(10): error: GLSL 1.50 is not supported. Supported versions are: 1.10, 1.20, 1.00 ES, and 3.00 ES

paulirotta avatar May 08 '20 06:05 paulirotta

@paulirotta I opened an issue at https://github.com/ryanisaacg/golem/issues/28 to investigate / fix this.

ryanisaacg avatar May 08 '20 17:05 ryanisaacg

I decided to make a simple animation system that can either be its own library or be merged with Quicksilver (Whatever you prefer)

However when writing it I noticed that there doesn't seem to be a way to rotate a single image. I saw Graphics::set_transform() however that doesn't seem to work for this as simply setting the rotation causes my image to rotate around a certain point, rather than it spinning at its center.

I only needed it for an example so it isn't a huge deal right now as I can just change the color or something for the time being but it did kind of surprise me.

Note: it may very well just be me overlooking something. In case it is, the code I used is equivalent to

let step_size: f32 = 5.;
let amount_of_steps = (360. / step_size).ceil() as usize;
let step = tick % amount_of_steps;
let rotation = step as f32 * step_size;
let rotation = dbg!(rotation);
gfx.set_transform(Transform::rotate(rotation));
gfx.draw_image(state, location);
gfx.set_transform(Transform::IDENTITY);

lenscas avatar May 08 '20 19:05 lenscas

@lenscas Graphics::set_transform sets a transformation matrix; if you want to spin an image at its center, you have to offset the transform to the center of the image, like:

let origin = location.center();
gfx.set_transform(Transform::translate(origin) * Transform::rotate(rotation) * Transform::translate(-origin));
gfx.draw_image(state, location);
gfx.set_transform(Transform::IDENTITY);

ryanisaacg avatar May 12 '20 16:05 ryanisaacg

I’ve been following this with interest and just wanted to say thanks for making and improving Quicksilver!

nzsg avatar May 13 '20 10:05 nzsg