amethyst / bracket-lib

The Roguelike Toolkit (RLTK), implemented for Rust.
MIT License
1.5k stars 107 forks source link

SDL/WGPU support #159

Open MichaelMackus opened 3 years ago

MichaelMackus commented 3 years ago

I noticed I can't get the default frontend to run on my older laptops and my arm-based linux laptop (using the open-sourced panfrost driver). I get an error with:

error: GLSL 3.30 is not supported. Supported versions are: 1.10, 1.20, and 1.00 ES

I think a proper SDL renderer would solve this. I feel like this would be a great default/fallback renderer, since SDL is supported pretty much everywhere (and runs via an abstracted OpenGL/DirectX backend by default). With this we could probably even get this running on most all android devices.

Is this something that would be of interest?

Des-Nerger commented 2 years ago

Not only the OpenGL version, here's another problem I have which using SDL could prevent:

libEGL warning: DRI2: failed to authenticate
Error: CreationErrors([NoAvailablePixelFormat, NoAvailablePixelFormat])

But alas, it all looks like a deliberate decision from the author: prefering pure-Rust libs over C bindings, perhaps to ease building for Web.

thebracket commented 2 years ago

Funny story. When I first started out trying to build this on Rust, I actually started by pulling up SDL and starting from there. I was greeted by a sea of error messages, and just couldn't get SDL to build on my system. I was pretty new to the Rust ecosystem at the time, but I went with a native GL setup to try and not have those problems - and it's been pretty good to me since. I have a definite preference for native Rust when I can use it. (I just implemented wgpu for DX11/12/Vulkan/Metal support - not sure if Vulkan is going to work on older systems, though).

Usually, when I've used SDL it's just a thin wrapper over GL anyway - so unfortunately, you'd still run into that. GLSL 3.3 has been around since 2010 (it's the first release that lets you write real shaders), so I figured it was a safe one to target!

libEGL warning: DRI2: failed to authenticate
Error: CreationErrors([NoAvailablePixelFormat, NoAvailablePixelFormat])

This is an error that has been causing lots of people issues, including Veloren and Alacrity. Apparently, if you don't have vsync support in your drivers, GL refuses to run at all. That's a strange one.

Now that I've got the high-end working (wgpu), I'll see what I can come up with for the lower end. I'd been considering trying to get the wasm version to work with WebGL1 rather than 3 - so it'd work in Safari. I'm also going to have to re-learn some stuff to dive back into pre-shaders GL!

Des-Nerger commented 2 years ago

if you don't have vsync support in your drivers, GL refuses to run at all.

I think the error message has to do with my ancient pre-2008 NVidia not supplying libEGL.so in its (proprietary) drivers. Anyway, I hope to repair and switch back to a more modern card soon, so personally not much of a concern.

GLSL 3.3 has been around since 2010 (it's the first release that lets you write real shaders)

What is unreal about the GLSL shaders from 1.10 (OpenGL 2.0) to 1.50 (OpenGL 3.2), I wonder. At most I can think of GLSL 1.00 (OpenGL ES 2.0 / WebGL 1.0) where there were control flow limitations. Citing its specification:

In general, control flow is limited to forward branching and to loops where the maximum number of iterations can easily be determined at compile time.

Which makes the shaders not Turing-complete, and so, not "real" in some sense.

MichaelMackus commented 2 years ago

SDL is available pre-built on almost every platform, so building shouldn't be too difficult. I've never ran into any issues building SDL so that seems a bit strange (I've built on Mac OSX before and it was fairly straightforward there - I think there's a homebrew build as well).

I understand the use of the newer shaders, but using SDL would avoid all that altogether since it is an abstraction layer (you don't need to write the shaders for SDL). SDL apps run on all my systems - even my thinkbooks from early 2000s, armbooks, and SoCs - so it is a nice option. Really, I see it mainly being used as a fallback option to improve support for other platforms. I don't really see any downside to it (other than the development time of course... the SDL API is really simple but I'm not sure how good the rust bindings are). You can even make it a compile time switch if some people would just prefer the pure 3d implementation for a leaner build.

Obviously it is not going to have the best performance, but having something running vs. not running at all is always better IMO.

Des-Nerger commented 2 years ago

Error: CreationErrors([NoAvailablePixelFormat, NoAvailablePixelFormat])

I was able to track down my problem and found a fix:

--- src/hal/native/mod.orig.rs  2020-04-01 02:44:01.000000000 +1000
+++ src/hal/native/mod.rs   2021-11-16 08:24:04.878485000 +1000
@@ -66,7 +66,7 @@
             gl_version: glutin::GlRequest::Latest,
             gl_profile: glutin::GlProfile::Core,
             hardware_acceleration: true,
-            srgb: true,
+            srgb: false,
             frame_sleep_time: None,
             resize_scaling: false,
         }

But now I have another error:

thread 'main' panicked at '[GL] Error: INVALID_ENUM', src/hal/gl_common/glerror.rs:19:35
stack backtrace:
   0: std::panicking::begin_panic
             at /rustc/53cb7b09b00cbea8754ffb78e7e3cb521cb8af4b/library/std/src/panicking.rs:519:12
   1: bracket_terminal::hal::gl_common::glerror::gl_error
             at ./src/hal/gl_common/glerror.rs:19:35
   2: bracket_terminal::hal::gl_common::font::Font::setup_gl_texture
             at ./src/hal/gl_common/font.rs:131:9
   3: bracket_terminal::hal::native::mainloop::main_loop
             at ./src/hal/native/mainloop.rs:73:13
   4: bracket_terminal::bterm::main_loop
             at ./src/bterm.rs:1058:5
   5: hello_minimal::main
             at ./examples/hello_minimal.rs:43:5
MichaelMackus commented 1 year ago

So after looking into this, it does appear that this library supports WebGPU which should support 99% of targets. This supports Vulkan, OpenGL ES3, and Metal I believe. I don't understand why this was failing on my arm-book, since it should have proper OpenGL ES 3 & vulkan support, but I'll have to take a look again.