Skip to content
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

Investigate rendering backends, such as gfx-rs or wgpu-rs or glow #34

Closed
iceiix opened this issue Nov 27, 2018 · 18 comments
Closed

Investigate rendering backends, such as gfx-rs or wgpu-rs or glow #34

iceiix opened this issue Nov 27, 2018 · 18 comments
Labels
enhancement New feature or request

Comments

@iceiix
Copy link
Owner

iceiix commented Nov 27, 2018

Currently, steven uses OpenGL 3.2 core profile, through SDL2 (#35) and gl_generator + khronos_api with a custom but lightweight wrapper, steven_gl: https://github.com/iceiix/steven/tree/updates/gl + https://github.com/iceiix/steven/blob/updates/src/gl/mod.rs. Is there a better way to do this? (3D graphics)

May help with graphical glitches such as https://github.com/iceiix/steven/issues/25, and/or cross-platform compatibility

@iceiix
Copy link
Owner Author

iceiix commented Nov 27, 2018

  • bgfx: "cross-platform rendering library", looks promising, supports a ton of rendering backends: OpenGL 3 but also OpenGL ES, WebGL, Metal, Direct3D, and numerous platforms including Android, asm.js/Emscripten, and even has Rust language bindings, and finally, is very actively maintained. No Vulkan API backend support but it is planned (Add Vulkan support bkaradzic/bgfx#274).
  • MoltenGL: implements OpenGL ES 2.0 on top of the Metal API graphics framework, only for OSX and iOS, commercial but has a free trial may be worth a try, as a different backend to see if rendering improves. From the makers of MoltenVK, which implements Vulkan on Metal.
  • gfx-rs: they are working on a hardware abstraction layer, gfx-hal targeting Vulkan, Metal, DirectX, there is a desire to support GL/WebGL but more interest in wgpu-rs for WebGPU API support, but not there yet, see /r/rust_gamedev I'm hella confused about the direction of gfx-rs.

@iceiix
Copy link
Owner Author

iceiix commented Nov 29, 2018

Games From Scratch: Cross Platform OpenGL Alternatives has a good list, several options. Use an existing rendering engine (no go, would like to stay lower level as Steven already is, but could be viable in some situations). Use Vulkan + MoltenVK (but then, another layer of abstraction, and does everything have Vulkan yet? Not quite ready to let go of OpenGL yet). Or what I'm interested in: use an abstraction layer. bgfx gets high marks but there is also:

  • Kha/Kore: "Modern low level game library and hardware abstraction.", supports a ridiculous number of platforms including PlayStation 4, Xbox One, Nintendo Switch. Very ambitious, but how mature is it? Gamesfromscratch made a video on it: What is Kha? Cross Platform Game Magic Sauce!. Compiles GLSL shaders down to HLSL or Unity. Kha requires Haxe and Node.js. Has its own IDE, Kode Studio, based on Visual Studio Code. A blank project targeting JavaScript runs on Electron and builds in a few seconds, but for Visual Studio it took nearly two minutes. You can use the C++ library, Kore, without Kha. Game engine built on it called Armory. Are there even Rust bindings?
  • ogre "straddles the line between game engine and framework", seems more like a game engine?
  • The Forge "The Forge Cross-Platform Rendering Framework PC, Linux, Ray Tracing, macOS / iOS, Android, XBOX, PS4", started last year, looks good
  • Veldrid: "A low-level, portable graphics and compute library for .NET. ", supports D3D, Vulkan, Metal, OGL3, and OGL ES 3, but its for dotnet.

Neither of these are too appealing. The other options are to implement our own rendering backends separately, or, stay on OpenGL (do nothing). But bgfx continues to tempt. An informative presentation: From the Dark Side of the Moon: GPU Programming with BGFX and Eclipse, a good introduction to bgfx (although for a different platform, general concepts apply). BGFX has its own shader compiler, shaderc, which accepts its own shading language language .sc, similar to glsl, but is preprocessed, so it is compiled to other rendering backend languages, examples:

$input a_position, a_color0, a_texcoord0
$output v_color0, v_texcoord0

#include "common.sh"
void main() {
    vec4 pos = vec4(a_position, 1.0);
    gl_Position = mul(u_modelViewProj, pos); v_color0 = a_color0;
    v_texcoord0 = a_texcoord0;
}

and:

$input v_color0, v_texcoord0 SAMPLER2D(u_texColor, 0);
void main()
{
    gl_FragColor = texture2D(u_texColor, v_texcoord0);
}

The only potential problem with bgfx is the Rust wrapper, https://github.com/rhoot/bgfx-rs was last modified 2 years ago, and isn't published on crates.io. There is an open pull request rhoot/bgfx-rs#3 to update to the latest bgfx and dependencies, but the CI failed. Last commit adds this disclaimer to the readme:

Note: I was originally using this crate as a way of learning Rust. Since I personally stopped using Rust again however, this crate has ended up more or less unmaintained. There are a couple of forks that have some more work put into it already, but if someone wants to take over the project for real, please let me know so I can direct users to your fork instead.

There are 7 forks, which one is the newest? fuzzybinary is 7 commits ahead, and jazzay in turn has a fork of it, even. TheJare is 18 commits ahead, 2 behind. Either way, using bgfx will likely mean I'll need to do some of my own maintenance on bgfx-rs.

And having bindings to a library written in another language is another downside, why not go all Rust? This is the mission of gfx-rs. Their goals are outlined in the 2017 blog post We need to go lower:

Today can be marked on the calendar as the end of an era in GFX history. An era of us wondering around and looking for a true path and destiny of the project. It is clear now: we want to be the low-level GPU abstraction focused on current-gen graphics APIs (Vulkan, D3D12, Metal). We want to be the playground and implementation of GPUWeb initiative. We want to be visible and viable.

There is no way back. We are going to branch out the current code and support it, leaving a window for a few breaking changes in follow-up versions, but the main development is going to be done inside LL code. We need to finish the migration, remove the duality of libraries, and make the code robust and performance enough to compete with production-quality libraries like MoltenVK. If you have experience with graphics APIs, join us in the journey of realizing Rust’s real power of low-level abstraction. A recent case study this year is detailed in RPCS3 and Dolphin on macOS using gfx-portability, where they successfully port two applications to gfx-rs:

gfx-rs is a Rust project aiming to make graphics programming more accessible and portable, focusing on exposing a universal Vulkan-like API. It’s a single Rust API with multiple backends that implement it: Direct3D 12/11, Metal, Vulkan, and even OpenGL. [...]

The initial focus on specific areas of CTS coverage and running Dota2 has proven to be a success. We were able to run RPCS3 and Dolphin on top of gfx-portability’s Metal backend and only had to address some minor issues in the process. As we continue to test additional real world use cases and expand CTS coverage, we expect stability and performance to continue to improve.

We gained great feedback while assisting RPCS3 and Dolphin to run well on macOS, and we look forward to helping other projects in the future as well. There are many projects only target Vulkan or OpenGL for rendering, yet would still like to be portable to other platforms, and the Vulkan Portability initiative aims to make this possible.

The momentum and community seems to be more behind gfx-rs than bgfx-rs, how much effort would it be to port Steven to it?

@iceiix iceiix changed the title Investigate rendering backends Investigate rendering backends, such as gfx-rs Nov 29, 2018
@iceiix iceiix changed the title Investigate rendering backends, such as gfx-rs Investigate rendering backends, such as gfx-rs/glutin Nov 29, 2018
@iceiix
Copy link
Owner Author

iceiix commented Nov 29, 2018

This is cool too: https://github.com/tomaka/glutin - bills itself as a "Pure Rust alternative to GLFW". Steven doesn't use GLFW, but it uses the tried and true SDL, which is in some ways a predecessor to GLFW.

SDL2 is the only 3rd party dependency that has to be manually installed (e.g., besides Rust crates through cargo) since OpenSSL was removed https://github.com/iceiix/steven/issues/2, would be nice to get rid of it, simplifying installation. SDL2 can be replaced with glutin independently of changing out the OpenGL rendering code with gfx-rs or whatever, and should be easier, Steven doesn't use it very much:

src/main.rs
50:use sdl2::Sdl;
51:use sdl2::keyboard;
169:    let sdl = sdl2::init().unwrap();
171:    let mut window = sdl2::video::WindowBuilder::new(&sdl_video, "Steven", 854, 480)
176:    sdl2::hint::set_with_priority("SDL_MOUSE_RELATIVE_MODE_WARP", "1", &sdl2::hint::Hint::Override);
182:    gl_attr.set_context_profile(sdl2::video::GLProfile::Core);
270:fn handle_window_event(window: &mut sdl2::video::Window,
273:                       event: sdl2::event::Event) {
274:    use sdl2::event::Event;
275:    use sdl2::keyboard::Keycode;
276:    use sdl2::mouse::MouseButton;
351:                sdl2::video::FullscreenType::Off => sdl2::video::FullscreenType::Desktop,
352:                sdl2::video::FullscreenType::True => sdl2::video::FullscreenType::Off,
353:                sdl2::video::FullscreenType::Desktop => sdl2::video::FullscreenType::Off,

src/settings.rs
3:use sdl2::keyboard::Keycode;

src/ui/mod.rs
21:use sdl2::keyboard::Keycode;

src/gl/mod.rs
16:use sdl2;
25:pub fn init(vid: & sdl2::VideoSubsystem) {

@iceiix
Copy link
Owner Author

iceiix commented Dec 2, 2018

Merged in the switch to glutin, but still using Steven's homegrown OpenGL 3.2 wrapper.

glium is another wrapper, intended to be higher-level and safer to use; very popular and it aims to detect undefined behaviors and manage state. But "Glium is no longer actively developed by its original author. That said, PRs are still welcome and maintenance is continued by the surrounding community." It may be nice to catch more bugs at compile-time or with glium library checks, especially since rendering can be so platform-specific, but it is no silver bullet. The author has moved onto vulkano, a Vulkan wrapper. Another newer lighter wrapper is grr but it is only for OpenGL 4.5+ (Difference between OpenGL 3.x and 4.x?). Would like to stick to OpenGL 3 to maximize compatibility for now (what about OpenGL 2? History of OpenGL, differences between OpenGL 2.1 and 3.0?, probably not worth going back to 2 now that 3 is widely supported). gfx-rs certainly worth keeping an eye on, if going to put in the effort to switch out the whole rendering system, would like to get some more benefits.

@iceiix iceiix changed the title Investigate rendering backends, such as gfx-rs/glutin Investigate rendering backends, such as gfx-rs Dec 2, 2018
@iceiix
Copy link
Owner Author

iceiix commented Dec 28, 2018

Update: gfx-hal is out: https://www.reddit.com/r/rust_gamedev/comments/a9vs20/gfxhal_is_finally_published/ but it has a regression from gfx in terms of supporting WebGL, because it is based on Vulkan instead of OpenGL. However, it may support WebGPU well:

OpenGL and Webgl were initially and still are on the list of backends, but as kvark said, the task is harder in hal than it was in old gfx. Making webgl support easier or better was never a goal of hal, you're probably confusing it with the fact that hal is in theory going to be the backbone of WebGPU, which is entirely different than WebGL.

How promising is WebGPU? https://en.wikipedia.org/wiki/WebGPU

On June 1, 2018, citing "resolution on most-high level issues" in the cross-browser standardization effort, Google's Chrome team announced intent to implement the future WebGPU standard.

as of yet unreleased, but once it is more supported, could consider using it.

@iceiix iceiix transferred this issue from iceiix/steven Jan 12, 2019
@iceiix iceiix added the enhancement New feature or request label Jan 12, 2019
@iceiix
Copy link
Owner Author

iceiix commented Jan 20, 2019

gfx-rs is coming up again in #92 WebAssembly support, once it supports wasm32-unknown-unknown/WebGL target, it will be quite appealing for this project. grovesNL is working on adding that, using his "GL on Whatever" set of bindings: https://github.com/grovesNL/glow to target OpenGL + OpenGL ES + WebGL avoiding target-specific code.

As an intermediate step, may want to see if can replace the homegrown steven_gl wrapper with glow? Though ultimately, gfx-rs may be the way to go. Start porting to it now? (for native at first). Another complication, from https://gfx-rs.github.io/2018/12/27/this-year.html:

Our API has settled to be at the lowest level, practically matching Vulkan semantics now, and became completely unsafe. To compensate for this, we have started WebGPU implementation with the idea of it becoming the lowest safe graphics abstraction that is a pleasure to use directly when targeting either native platforms or the future Web. Crossing fingers to tell you more about its progress in 2019 ;)

wgpu: https://github.com/gfx-rs/wgpu, still incomplete pre-"draw the first triangle" stage, but under active development, last modified within days. A pleasure to use for native or web, sounds promising. But is this too many abstractions, WebGPU to gfx-rs to Vulkan-like API/SPIR-V to WebGL?

@iceiix iceiix changed the title Investigate rendering backends, such as gfx-rs Investigate rendering backends, such as gfx-rs or wgpu Jan 20, 2019
@iceiix
Copy link
Owner Author

iceiix commented May 3, 2019

https://wiki.alopex.li/AGuideToRustGraphicsLibraries2019
https://old.reddit.com/r/rust/comments/bjnxd3/a_guide_to_rust_graphics_libraries_as_of_2019/
https://old.reddit.com/r/rust_gamedev/comments/bjsk1q/a_guide_to_rust_graphics_libraries_as_of_2019/

No clear winner still, but there are some important recent developments:

2019-04-26 https://phaazon.net/blog/pre-luminance-n-random-thoughts - for 1.0.0 the author is planning "At least one WebGL implementation and it must be WASM compatible."

2019-04-18 https://amethyst.rs/blog/moss-grant-announce/ - Amethyst was awarded a $10,000 grant for making it run in the browser with WebAssembly, and they plan to help where possible with:

https://github.com/rust-windowing/winit/pull//797 stdweb support for eventloop 2.0
https://github.com/gfx-rs/gfx/pull//2554 [WIP] Add wasm32-unknown-unknown/WebGL support

WebGPU working group https://www.w3.org/community/gpu/ https://github.com/gpuweb/ (not to be confused with https://github.com/webgpu and https://webgpu.com) is still active, as is https://github.com/gfx-rs/wgpu/, but isn't shipping in browsers yet. Targeting wgpu may very well be a good option, and the wgpu developers agree:

https://old.reddit.com/r/rust/comments/bjnxd3/a_guide_to_rust_graphics_libraries_as_of_2019/emeznnf/

My vision is that 95% of applications (that want to program graphics workloads directly instead of relying on engines like AmethysT) would be fine at building on top of wgpu even if they don't care about the Web. It's just a nice abstraction level to work with, and the safety guarantee plays quite nicely with Rust.

@iceiix
Copy link
Owner Author

iceiix commented May 3, 2019

Posted more thoughts at https://www.reddit.com/r/rust/comments/bjnxd3/a_guide_to_rust_graphics_libraries_as_of_2019/emfekoe/ (in https://www.reddit.com/r/rust/comments/bjnxd3/a_guide_to_rust_graphics_libraries_as_of_2019/), but looking at https://github.com/gfx-rs/wgpu/ more closely, it already supports Vulkan (Windows/Linux), D3D12/11 (Windows), and Metal (macOS/iOS) platforms. Could I port to wgpu to not regress on any supported platforms, while opening the door for WebGPU support when available?

@iceiix
Copy link
Owner Author

iceiix commented May 29, 2019

@iceiix
Copy link
Owner Author

iceiix commented May 29, 2019

https://old.reddit.com/r/rust_gamedev/comments/brehgw/rendy_02_released/ has some more insights:

You're right, basically users can write against wgpu-rs to target both native and web:

  • when they target native, wgpu-native (the native WebGPU implementation on top of gfx-hal) is used and it runs on Vulkan/Metal/DX12/etc.
  • when they target wasm32-unknown-unknown, the wgpu-native layer disappears and the browser's API is used instead

warming up to the idea of targeting wgpu-rs...it would require WebGPU support in browsers, but fine with targeting only the latest, presuming it would be supported eventually. The other dichotomy is gfx-hal/rendy, from https://www.reddit.com/r/rust_gamedev/comments/bn71it/gfxhal02_is_released/:

gfx-hal/rendy are for building demanding engines, wgpu is for applications and simpler engines/frameworks.

Is this project a demanding engine or a simpler engine/framework?

@iceiix iceiix changed the title Investigate rendering backends, such as gfx-rs or wgpu Investigate rendering backends, such as gfx-rs or wgpu-rs May 29, 2019
@iceiix
Copy link
Owner Author

iceiix commented May 31, 2019

https://github.com/Gordon-F/crossplatform_gfx_hal_example

https://www.reddit.com/r/rust_gamedev/comments/bv7w2f/wgpurs_now_uses_rendy_to_manage_memory_and/

Looks like wgpu-rs is again a good choice, as for "4. wgpu-rs for the lowest safe level",

@iceiix
Copy link
Owner Author

iceiix commented Dec 30, 2019

grovesNL is working on adding that, using his "GL on Whatever" set of bindings: https://github.com/grovesNL/glow to target OpenGL + OpenGL ES + WebGL avoiding target-specific code.

As an intermediate step, may want to see if can replace the homegrown steven_gl wrapper with glow? Though ultimately, gfx-rs may be the way to go.

https://github.com/rust-windowing/glutin now recommends glow:

Emscripten with asmjs

Emscripten support has been deprecated in favor of platforms like stdweb. To get an OpenGL > context on these platforms, please use crates like glow instead.

https://github.com/grovesNL/glow

GL on Whatever: a set of bindings to run GL anywhere (Open GL, OpenGL ES, and WebGL) and avoid target-specific code.

Looks great. The example shows targeting native through glutin, native through sdl2, and the web. Is this the cross-compatible crate I have been searching for? How hard would it be to adapt to use glow instead of glutin?

@iceiix iceiix changed the title Investigate rendering backends, such as gfx-rs or wgpu-rs Investigate rendering backends, such as gfx-rs or wgpu-rs or glow Dec 30, 2019
@iceiix
Copy link
Owner Author

iceiix commented Jan 4, 2020

Another new project, looks promising, bills itself as "Keep it simple, stupid 3d graphics engine for Rust " https://github.com/sebcrozet/kiss3d http://kiss3d.org

@iceiix
Copy link
Owner Author

iceiix commented Jan 5, 2020

Update: gfx-hal 0.3.0 is released, continues to march forward: https://www.reddit.com/r/rust/comments/cnvfrm/gfxhal03_release_notes/

Most notably, they added wasm32-unknown-unknown support to the GL backend so it runs on the web, and switched from gl-rs to glow.

Looking more and more that glow is the way to go. Not to rule out gfx-rs but would be a larger change. Ought to replace gl-generator/khronos_api (from steven_gl) with glow then see where we're at with #171 wasm support.

@iceiix
Copy link
Owner Author

iceiix commented Jan 5, 2020

icefoxen (no relation) has posted an excellent (as usual) "State of GGEZ 2020" report with many points also relevant to this project: https://wiki.alopex.li/TheStateOfGGEZ2020

A few takeaways: gfx-hal and rendy are promising cross-API compatible abstraction layers, a Vulkan-like API, but

I still can’t use something better than OpenGL on the web. My gut response to that is to say 'then help make it happen', but I’m just too tired to yak-shave that hard. So, for now, I’m giving up.

What about WebGPU? Not standardized yet, probably will happen some day with wgpu using gfx-hal and rendy so "its ability to run on Web is still tied to theirs".

The author speaks positively of newer versions of OpenGL:

WebGL 2 is now an explicit, strict subset of OpenGL ES 3.0, which is now an explicit, strict subset of OpenGL 4.3. So if you write your code and shaders to run on WebGL 2, they can run anywhere that supports ES 3 or OpenGL 4.3, without modifications, for realsies, no takebacks. (At least before the inevitable driver bugs occur, that is.)

This project currently targets OpenGL 3.2 and OpenGL ES 2.0, src/main.rs:

        .with_gl(glutin::GlRequest::GlThenGles{opengl_version: (3, 2), opengles_version: (2, 0)})

should update to OpenGL 4.3 and OpenGL ES 3.0, to target WebGL 2?

The author of ggez came to the same conclusion I was leaning towards:

Conclusions: So yeah, I’ve been rewriting ggez’s graphics backend in pure OpenGL, using the excellent glow crate to provide a modicum of abstraction between normal OpenGL and WebGL. It actually works pretty well

glow it is! (At least until gfx or wgpu are more ready)

iceiix added a commit that referenced this issue Jan 6, 2020
Update from glutin 0.21.x fork to glutin 0.22.0-alpha5 and corresponding
compatible version of winit. This removes our custom temporary wasm_stub
branches, back to mainline glutin and winit, and is a step towards WebAssembly
compatibility, most importantly merging the game loop and event loops as
required by winit _which now supports wasm_. Not yet functional on the web
because other web dependencies have to be added, see #171 and #34, but native
functionality is preserved.

* Update for 0.22 glutin API changes:

* Move game logic into event loop, run() replacing poll_events()

* Specify fullscreen Borderless mode

* Pass generic parameter of Event through handle_window_event
* hidpi_factor() replaces get_hidpi_factor()
* with_inner_size() replaces with_dimensions()
* No longer need to unwrap() LogicalSize
* set_cursor_grab/visible() replaces grab/hide_cursor()

* Fix modifiers deprecated warnings by destructuring only event fields we use, ignoring the rest with '..'

* Remove unnecessary mutability from events_loop

* Listen for ModifiersChanged event, fixing deprecated modifiers field

* Change to stdweb for web backend, replacing web-sys

* Pin to glutin =0.22.0-alpha5 and winit =0.20.0-alpha6
@iceiix iceiix mentioned this issue Jan 6, 2020
@iceiix
Copy link
Owner Author

iceiix commented May 24, 2020

More progress on wgpu-rs: https://gfx-rs.github.io/2020/04/21/wgpu-web.html wgpu-rs on the web

gfx-rs is a Rust project aiming to make low-level GPU programming portable with low overhead. It’s a single Vulkan-like Rust API with multiple backends that implement it: Direct3D 12/11, Metal, Vulkan, and even OpenGL.

wgpu-rs is a Rust project on top of gfx-rs that provides safety, accessibility, and even stronger portability.

@iceiix
Copy link
Owner Author

iceiix commented Dec 28, 2020

Decided for now to go with glow, GL on Whatever. A lightweight wrapper, supporting up to OpenGL 4.6 on native; we currently target OpenGL 3.2 on native so this works. For web, we could target WebGL 2 through glow (and also possibly OpenGL ES 3.0 for native).

Merged glow support in #262, only working with OpenGL at the moment but see #446 and #451 for progress on getting WebGL working.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant