-
Notifications
You must be signed in to change notification settings - Fork 474
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
Emscripten support. #884
Comments
@agausmann if you're still interested I've got rust-sdl2 partially working with Emscripten. My prototype at https://github.com/tanis2000/minigame-rust/tree/webgl is actually compiling to wasm through Emscripten but I've still got an issue with the SDL_Renderer that seems to be invalid in the browser for some unknown reason. The error I get is the following:
Maybe you already stumbled upon it and know why it's happening? |
As I unfortunately discovered here, that this crate wants to link against |
@hikari-no-yume This is extremely simple to fix, remove However, this line https://github.com/Rust-SDL2/rust-sdl2/blob/master/sdl2-sys/build.rs#L304 hints that someone was actually able to run this as emscripten, but I could be wrong? |
@Cobrand Indeed it's a trivial fix, I might contribute a pull request with that at some point (once I can, unfortunately can't for reasons). I think that either a previous Emscripten toolchain or a previous version of this crate worked, just not any more. |
@Cobrand that line in |
Emscripten targeting should be fixed by #937 But on Windows specifically, there is still an issue when building the emscripten ports for SDL_mixer. I think it's using a 32bit binary when it expected a 64bit or vice versa. It gives an error of the form "%1 is not an application" or something like that. Workaround for now: build on OSX/Linux ¯_(ツ)_/¯ |
@bsurmanski unfortunately, that does not fix it for me:
I think this library needs to tell emscripten |
Ah, but while it doesn't tell emscripten to use its SDL2 port, it does appear fix the |
How are you targeting emscripten? It works for me if I use Cargo Web. Creating a Web.toml will allow you to pass in the USE_SDL=2 flags. See: https://github.com/koute/cargo-web |
I'm not using Cargo web, just plain cargo. But I'll check that out, it sounds useful. |
Even without cargo-web, it is possible: .cargo/config
|
I'm doing exactly that right now, but it feels like a hack. I don't know enough to think of what a better way would be though. |
What's the state of Emscripten support now? Has anyone tried using this since Rust switched away from fastcomp to upstream as its Emscripten backend? |
IMO it needs more work. I just tried it right now on OSX, and the last few times I tried (this time included) the build broke on some LLVM IR issue. For example, I tried to compile nalgebra from git. Using the stable toolchain (1.40.0 - 2019-12-16) and it segfaulted compiling the num_integer package. Using the nightly toolchain (1.42.0 - 2020-01-01), I got the following error:
If I remember correctly, things worked better before the fastcomp->upstream transition; but maybe I just got lucky when I was using it then (around last January). Proccess Details: I'm on OSX 10.14.6 |
Looks like you're running into rust-lang/rust#66308. I wasn't aware that this issue was present when targeting |
num-integer is not required anymore on master. Try rebuilding it using the latest git version? |
@Cobrand: I was using git master. looks like num-integer is a dependency of num-rational (which is still a dependency of nalgebra). |
Finally! I was able to build this study-case snake game using this fork without lazy_static (I created an issue there to see why it doesn't compiles to wasm) and downgrading Emscripten SDK because of this issue. Hope it helps. Edit: https://github.com/Rust-SDL2/rust-sdl2/blob/master/src/sdl2/render.rs#L910 It sets the background, but for some reason the |
I think the renderer support is a WIP for emscripten. Perhaps you can try to use manual OpenGL calls or whatever emscripten uses as a video driver? If someone managed to use the SDL2 renderer with emscripten, then this is probably coming from this crate, but since it's basically a one to one translation of the C version, I doubt it's coming from this crate... |
Sorry, I'm a total newbie and I'm not sure what you mean, but from what I searched for, the support of Emscripten is fairly great for SDL2. |
I've used the SDL2 renderer before in C code which I compiled with emscripten, and it could at the very least do a background clear colour and draw sprites. So I wonder why it wouldn't work in Rust, then? |
ok so I got to the bottom of this issue.... the challenge lies in the way the current rust-sdl2 API requires some stack variables to track lifetimes. Since you can't have self-referential structs, you're forced to keep things like the texture_creator on the stack. I wish there were a better solution: can we avoid the texture_creator paradigm and somehow keep all the texture_creators easily accessible from the canvas? I think splitting part of the canvas state into texture creator prevents us from bundling all the variables into a struct. Ideally Textures would have their own safe way of being found using just a Canvas/TextureCreator and linking lifetimes together. |
I think ironically using global variables would be cleaner than using mem::forget on boxes. I don't see any other way a language like C or C++ can otherwise share data between the calls of the loop, aside from global variables. It's dirty but to be expected when working with libraries designed with only C in mind.
That would either require a self-referential struct, (e.g. struct { canvas: Canvas, Hashmap<Id, Texture<'canvas>> }) or the textures "stored" directly in the Canvas, which we would like to avoid (remember that while we make it a bit easier, this crate is mainly designed to be as close as the original SDL2 as possible API-wise). A tricky problem for sure. |
@danielrh Thanks for posting with your idea -- I studied your code and tried to implement it in the most basic possible form so the solution is reproducible, but it still gives me the pernicious "thread 'main' panicked at 'Invalid renderer'" error. Would you mind glancing at this gist and helping me figure it out? EDIT: Figured it out -- I was missing an asterisk before the first "arg" on line 92. |
sdl2 crate builds on emscripten properly. needs a couple emscripten rust flags in for a minimal example, https://github.com/coderedart/rust-sdl2-wasm live version with opengl (glow + sdl2), https://coderedart.github.io/rust-sdl2-wasm/ There are some problems like sdl2 canvas not working, but idc about those. just wanted a window so i can start drawing with glow (and maybe wgpu eventualy). |
Where I'm at, I'm able to get it to draw the graphics when I set the code to the below. debug!("Starting Render Loop...");
/*
* Intentionally not targetting feature "browser" here
* as emscripten is multi-platform.
*/
// #[cfg(all(target_family="wasm", target_os="emscripten"))]
// unsafe {
// emscripten_set_main_loop_arg(render_loop, Box::from(&mut loopstruct), 0, 1);
// }
// #[cfg(not(all(target_family="wasm", target_os="emscripten")))]
loop {
let exit_loop: bool = render_loop(Box::from(&mut loopstruct));
if exit_loop {
// Ending Loop
break;
}
// Slow Down Rendering (60 FPS)
// thread::sleep(Duration::new(0, 1_000_000_000u32 / 60));
} When I set the code to the below, it only gets to the point of drawing the cyan screen before it crashes on the line I create and attempt to read /*
* Intentionally not targetting feature "browser" here
* as emscripten is multi-platform.
*/
#[cfg(all(target_family="wasm", target_os="emscripten"))]
unsafe {
emscripten_set_main_loop_arg(render_loop, Box::from(&mut loopstruct), 0, 1);
}
#[cfg(not(all(target_family="wasm", target_os="emscripten")))]
loop {
let exit_loop: bool = render_loop(Box::from(&mut loopstruct));
if exit_loop {
// Ending Loop
break;
}
// Slow Down Rendering (60 FPS)
thread::sleep(Duration::new(0, 1_000_000_000u32 / 60));
} Be warned, the example that "works" can cause epileptic seizures and doesn't take user input for some reason If you want to see my current work, it's at https://github.com/alexisart/catgirl-engine/blob/9e4e1ed06ab295a86c04719a0c805c922b80bc20/src/game/render.rs#L162-L181 I'll upload the Emscripten build of the engine as soon as the CI finishes building it Edit: Here's the promised build. CatgirlEngine-Linux-WebAssembly-Emscripten-32-Zip.zip |
wasm32-unknown-emscripten
is a great target for compiling and running games using WebAssembly, particularly because it can produce web pages that run on most browser platforms instead of having to maintain and ship binaries for Windows, Linux, etc. separately.There is a port of SDL2 officially maintained by the emscripten project. I have been using it off and on for about a year, bundling and statically linking it with this crate behind
pistoncore-sdl_window
You can see the progress I've made on my
rust-sdl2
fork, though it is hacked together and breaks other targets in its current state, that can theoretically be fixed. I'd love to eventually get it cleaned up and merged upstream.The text was updated successfully, but these errors were encountered: