rust-tutorials / triangle-from-scratch

Drawing a triangle with no other crate dependencies.
https://rust-tutorials.github.io/triangle-from-scratch/
40 stars 6 forks source link

using WebGL #8

Open Lokathor opened 3 years ago

Lokathor commented 3 years ago

For WebGL, and general "web stuff", I think we could cave and use wasm_pack, and the associated proc_macro and such.

Lokathor commented 3 years ago

via @17cupsofcoffee

okay so steps to get to that screenshot:

  1. wasm-pack new triangle
  2. add the dependencies listed on https://rustwasm.github.io/docs/wasm-bindgen/examples/webgl.html (wasm-bindgen, js-sys, web-sys with the relevant APIs features enabled)
  3. yeet all the code from src and add the code from that link to lib.rs
  4. wasm-pack build --target web (the --target web gives you output that can run natively in the browser without webpack)
  5. create an index.html that loads the compiled JS
  6. spin up a web server in that folder

I believe you could dispense with the js-sys and web-sys dependencies but you'd have to write your own externs for the JS functions

17cupsofcoffee commented 3 years ago

One slight amendment to the above after a little bit more tinkering - you can get away with just doing cargo new instead of wasm-pack new, which removes the need to delete a load of existing code. It's probably worth linking to their docs to be like "hey here's how you do it with all the bells and whistles" though, as there is some nice extra libraries that came with their template.

17cupsofcoffee commented 3 years ago

Created a gist with the minimal version of the example I described above, with a step by step of how to write it from scratch:

https://gist.github.com/17cupsofcoffee/7589c6c78cabb021d397e1e6022ead09

If you want to look at the code that'd be required to get rid of the web-sys dependency, have a look at the source on docs.rs. You'd basically need one of those extern definitions for every type/method/getter/setter you want to call. Maybe just show how to do that for the first JS API you interact with, and then switch to the dependency for the rest? Depends how 'from scratch' you want to go, I guess 😛

I don't know if I'll have the time/energy to write the chapter itself, but I'm happy to answer questions/proofread at the very least.

Lokathor commented 3 years ago

very cool, very cool.

I think I'll focus on getting the desktop GL working on at least windows before I begin to tackle the writeup for this one, but I'm sure I'll have questions.

kettle11 commented 3 years ago

Here's a "zero dependency" version: https://github.com/kettle11/hello_triangle_wasm_rust

All the actual function calls to WebGL have to be on the Javascript side, so some communication layer is needed between JS and Wasm. In that repository I implemented a pretty minimal communication layer.

But really this is a question about what's best to teach:

Both are valuable, but certainly teach different things.

Lokathor commented 3 years ago

This feels like a "part 1" and "part 2" sort of subject.

To keep things clearly separated we can put the "web stuff" in a project of its own in a sub-folder (and it can pull in our triangle_from_scratch lib via a path dependency, if there's any general TFS utils that would be useful for it to use).

thomcc commented 3 years ago

But really this is a question about what's best to teach:

  • The ultra minimalist thing that requires people to write their own bindings and sets them up in an incompatible way with most of the Rust WASM ecosystem.
  • The more main-stream Rust way that depends on a really large and complex libraries but is an easier jumping point to making 'real' stuff.

I don't think this is the right way to frame this at all. Is the Rustonomicon covering how Vec is implemented setting people up to be incompatible with the broader Vec-using Rust ecosystem?

Teaching the way these things work, and why libraries do the things they do isn't really for sake of minimalism. It also help document and explain why things are the way they are, and what tradeoffs have been made by the libraries in the Rust ecosystem. Otherwise, a lot of the knowledge behind low level details here ends up being trapped in the mind of systems engineers and library maintainers, and either poorly documented, or only documented in commit messages and issue comments.

My personal experience is that this is probably more true in the platform interaction libraries than perhaps anywhere else in the Rust ecosystem. From my time maintaining rust-android-gradle and some Mozilla build systems I know this is extremely true for Rust on iOS and Android

For Wasm in particular, there are many reasons you may not be able to interact with the Rust Wasm ecosystem for various reasons anyway, unfortunately. (There's a cost to the extremely high-level approach and it's that it kinda wants to own the world). That said, the Wasm ecosystem (and wasm_bindgen in particular) does a better job documenting low level details of how it works than most.


All that is to say, I think this is the question along the lines of: is triangle-from-scratch something like the Rustonomicon, or is it more like the Book?

I think there are plenty of guides out there that cover how to use the ecosystem libraries to build applications in Rust using ecosystem libaries (perhaps not cross-platfrom ones).

Personally, I feel that given the "from scratch" goal, and the fact that bringing a triangle up essentially covers just the lowest level parts of the platform interaction, stopping basically right when you've gotten enough of that done to be useful.

Lokathor commented 3 years ago

It's very much aiming to be more like Rustonomicon (obscure details you won't often personally use) than The Book (which is a beginner's guide)

Lokathor commented 3 years ago

Someone pointed me at this blog post so I'll note it down here: http://cliffle.com/blog/bare-metal-wasm/

Lokathor commented 3 years ago

Notes for next WebGL lesson:

Kreijstal commented 2 years ago

thank you for this guide, considering you use zero dependencies, you actually understand stuff