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

๐Ÿ•ธ๏ธ Web support #446

Open
15 of 29 tasks
iceiix opened this issue Dec 26, 2020 · 6 comments
Open
15 of 29 tasks

๐Ÿ•ธ๏ธ Web support #446

iceiix opened this issue Dec 26, 2020 · 6 comments
Labels
enhancement New feature or request help wanted Extra attention is needed

Comments

@iceiix
Copy link
Owner

iceiix commented Dec 26, 2020

Support running on the web platform target, in addition to the "native" (Windows/Linux/Mac) platform currently supported

@iceiix iceiix added enhancement New feature or request help wanted Extra attention is needed labels Dec 26, 2020
iceiix added a commit that referenced this issue Dec 26, 2020
@iceiix iceiix mentioned this issue Dec 26, 2020
iceiix added a commit that referenced this issue Dec 26, 2020
A small step for #446 ๐Ÿ•ธ๏ธ Web support, use web-sys to interface to the web.
Previously, we would try to use glutin on the web, which is not supported;
now glutin is only used on native: fixes #171 could not find Context in platform_impl.

winit is still used on both, but the GL context is created with web-sys and glow
(on the web), and created with glutin and used with glow (on native). stdweb is
no longer used, being replaced by web-sys.

Substantial refactoring to allow reusing the code between web/native:

* settings: use VirtualKeyCode from winit, not reexported from glutin
* std_or_web: remove broken localstoragefs/stdweb, add File placeholder
* render: disable skin_thread on wasm since we don't have threads

* gl: use glow types in gl wrapper (integers in native, but Web*Key in web)
* gl: web-sys WebGlUniformLocation does not implement Copy trait, so glow::UniformLocation doesn't so gl::Uniform can't
* gl: refactor context initialization, pass glow::Context to gl::init for consistency between native/web
* gl: update to glow with panicking tex_image_2d_multisample web-sys wrapper

* glsl: use shader version in GLSL for WebGL 2 and OpenGL 3.2

* shaders: add explicit float/int type conversions, required for WebGL
* shaders: specify mediump precision, required for WebGL
* shaders: specify fragment shader output locations for WebGL

* main: refactor handle_window_event to take a winit window, not glutin context
* main: handle resize outside of handle_window_event since it updates the glutin window (the only event which does this)
* main: use winit events in handle_window_event not reexported glutin events
* main: refactor game loop handling into tick_all()
* main: create winit window for WebGL, and use winit_window from glutin
* main: restore console_error_panic_hook,  mistakingly removed in (#260)
* main: remove force setting env RUST_BACKTRACE=1, no longer can set env on web

* www: index.js: fix wasm import path
* www: npm update, npm audit fix
* www: update readme to link to status on #446 ๐Ÿ•ธ๏ธ Web support
iceiix added a commit that referenced this issue Dec 26, 2020
A small step for #446 ๐Ÿ•ธ๏ธ Web support, use web-sys to interface to the web.
Previously, we would try to use glutin on the web, which is not supported;
now glutin is only used on native: fixes #171 could not find Context in platform_impl.

winit is still used on both, but the GL context is created with web-sys and glow
(on the web), and created with glutin and used with glow (on native). stdweb is
no longer used, being replaced by web-sys.

Substantial refactoring to allow reusing the code between web/native:

* settings: use VirtualKeyCode from winit, not reexported from glutin
* std_or_web: remove broken localstoragefs/stdweb, add File placeholder
* render: disable skin_thread on wasm since we don't have threads

* gl: use glow types in gl wrapper (integers in native, but Web*Key in web)
* gl: web-sys WebGlUniformLocation does not implement Copy trait, so glow::UniformLocation doesn't so gl::Uniform can't
* gl: refactor context initialization, pass glow::Context to gl::init for consistency between native/web
* gl: update to glow with panicking tex_image_2d_multisample web-sys wrapper

* glsl: use shader version in GLSL for WebGL 2 and OpenGL 3.2

* shaders: add explicit float/int type conversions, required for WebGL
* shaders: specify mediump precision, required for WebGL
* shaders: specify fragment shader output locations for WebGL

* main: refactor handle_window_event to take a winit window, not glutin context
* main: handle resize outside of handle_window_event since it updates the glutin window (the only event which does this)
* main: use winit events in handle_window_event not reexported glutin events
* main: refactor game loop handling into tick_all()
* main: create winit window for WebGL, and use winit_window from glutin
* main: restore console_error_panic_hook,  mistakingly removed in (#260)
* main: remove force setting env RUST_BACKTRACE=1, no longer can set env on web

* www: index.js: fix wasm import path
* www: npm update, npm audit fix
* www: update readme to link to status on #446 ๐Ÿ•ธ๏ธ Web support
@iceiix iceiix mentioned this issue Dec 27, 2020
3 tasks
iceiix added a commit that referenced this issue Dec 27, 2020
Steven used multisampled textures from the beginning, but this caused
incompatibilities: Thinkofname/steven#74.
Subsequently fixed by increasing the number of samples, but increasing
it beyond the limit caused more incompatibilities, so it was clamped to
the maximum samples reported as supported by the system.

Fast-forward to now, as part of adding WebGL support (#446), the use of
multisampled textures via the glTexImage2DMultisample() call is
unsupported on this platform. Replace the following:

* glTexImage2DMultisample -> glTexImage2D
* TEXTURE_2D_MULTISAMPLE -> TEXTURE_2D
* sampler2DMS -> sampler2D

This disables the custom multisampling anti-aliasing algorithm (MSAA)
implemented in the chunk fragment shader, increasing compatibility:

* Update to glow release, remove image_2d_sample()

MSAA may be added back at a later date using multisampled renderbuffers
instead, see #442.
iceiix added a commit that referenced this issue Dec 27, 2020
Steven used multisampled textures from the beginning, but this caused
incompatibilities: Thinkofname/steven#74.
Subsequently fixed by increasing the number of samples, but increasing
it beyond the limit caused more incompatibilities, so it was clamped to
the maximum samples reported as supported by the system.

Fast-forward to now, as part of adding WebGL support (#446), the use of
multisampled textures via the glTexImage2DMultisample() call is
unsupported on this platform. Replace the following:

* glTexImage2DMultisample -> glTexImage2D
* TEXTURE_2D_MULTISAMPLE -> TEXTURE_2D
* sampler2DMS -> sampler2D

This disables the custom multisampling anti-aliasing algorithm (MSAA)
implemented in the chunk fragment shader, increasing compatibility:

* Update to glow release, remove image_2d_sample()

MSAA may be added back at a later date using multisampled renderbuffers
instead, see #442.
iceiix added a commit that referenced this issue Dec 27, 2020
No clouds on wasm since no geo shaders on WebGL
Needed for ๐Ÿ•ธ๏ธ Web support #446, to fix "invalid shader type", see #442 (comment)
iceiix added a commit that referenced this issue Dec 27, 2020
Replace std::time with the `instant` crate, which bridges to std::time on
native but on wasm calls performance.now() instead of panicking.

A step towards ๐Ÿ•ธ๏ธ Web support #446

* logo: replace SystemTime/UNIX_EPOCH with Instant
iceiix added a commit that referenced this issue Dec 31, 2020
At this point, the UI renders in the browser through WebGL, with no GL errors.
Progress towards #446 ๐Ÿ•ธ๏ธ Web support

* main: enable render loop on wasm, disable events_loop on wasm for now
Allow for testing rendering on WebGL

* chunk_builder: disable on wasm due to no threads on wasm
Chunks will not be correctly rendered, but other parts of the program now can be tested instead of crashing in std::thread

* chunk_frag: glBindFragDataLocation is only on native, WebGL 2 uses in-shader specification layout(location=), which works on native in OpenGL 4.1 but we're on OpenGL 3.2 - see https://www.khronos.org/opengl/wiki/Fragment_Shader#Output_buffers

* std_or_web: always fail File::open() to avoid servers.json empty string JSON parse failing

* www: update installation instructions

* render: fix apparent TEXTURE_MAX_LEVEL -> TEXTURE_MAG_FILTER typo

* render: correct type for internalFormat DEPTH_COMPONENT24
Valid combinations of format, type, and internalFormat are listed at https://www.khronos.org/registry/OpenGL/specs/es/3.0/es_spec_3.0.pdf#page=124&zoom=100,168,206. We had UNSIGNED_BYTE for DEPTH_COMPONENT24, but only UNSIGNED_INT is a valid type for this internal format.

Fixes texImage: Mismatched internalFormat and format/type: 0x81a6 and 0x1902/0x1401
and fixes the subsequent GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT error.

* render: gl::MULTISAMPLE (0x809d) is not available on WebGL
Fixes WebGL warning: enabled: cap: Invalid enum value <enum 0x809d> 0.bootstrap.js line 11 > eval:851:21

* gl: replace set_float_multi_raw with a safer set_float_multi
Removes use of passing raw pointers in set_float_multi_raw parameters
Instead, casts raw pointers to flatten, similar to set_matrix_multi
Fixes uniform setter: (uniform colorMul[0]) values length (1) must be a positive integer multiple of size of <enum 0x8b52>.

* render: model: send BYTE to id attrib, fixes type mismatch
Fixes drawElementsInstanced: Vertex attrib 0 requires data of type INT, but is being supplied with type UINT
This was referenced Jan 1, 2021
iceiix added a commit that referenced this issue Jan 4, 2021
On the web, we have a separate render_loop (for window.requestAnimationFrame)
and events_loop (for winit/window events), so `game` and `ui_container` are shared
using an `Rc<RefCell>`, and `winit_window` as well for wasm only (on native,
`glutin_window` which provides access to the winit window is used instead).

With these changes, events (hover, click, etc.) and rendering now work in the web.
Another step towards ๐Ÿ•ธ๏ธ Web support (#446)

* wasm: enable events loop

* Use Rc<RefCell>'s for winit_window

* Use Rc<RefCell> for game and ui_container

* main: disable set_cursor_grab() call on wasm to get further until Pointer Lock is available
iceiix added a commit that referenced this issue Jan 8, 2021
Refactor the chunk builder to use multithreading on native, but no threads on
wasm, at least until we have web workers or wasm threads. With this change
and the shader fix, chunks now render on Chrome (albeit with no textures).
Another step towards ๐Ÿ•ธ๏ธ Web support #446.

* Single-threaded chunk builder

* shaders: chunk_frag: consistently enable outputs, fixes GL_INVALID_OPERATION on WebGL
iceiix added a commit that referenced this issue Jan 8, 2021
Refactor the chunk builder to use multithreading on native, but no threads on
wasm, at least until we have web workers or wasm threads. With this change
and the shader fix, chunks now render on Chrome (albeit with no textures).
Another step towards ๐Ÿ•ธ๏ธ Web support #446.

* Single-threaded chunk builder

* shaders: chunk_frag: consistently enable outputs, fixes GL_INVALID_OPERATION on WebGL
iceiix added a commit that referenced this issue Jan 19, 2021
Updates to enhance GitHub Actions continuous integration:

* ci: add macOS app bundle packaging using cargo-bundle, closes #352 
based on https://github.com/EndlessSkyCommunity/ESLauncher2/blob/master/Cargo.toml
* ci: add web target, building using wasm-pack (for #446) 
* ci: refactor and cleanup targets, split out instead of using matrix

* main: save config in consistent OS-specific dirs::config_dir()
Instead of storing and loading in the current working directory, change
to a consistent dedicated configuration directory. This is necessary for
.app launching since cwd is set to /. To preserve compatibility with
existing installations, if conf.cfg exists in cwd then it will be used instead,
but otherwise we will use the operating system specific config dirs:
// Lin: Some(/home/alice/.config)
// Win: Some(C:\Users\Alice\AppData\Roaming)
// Mac: Some(/Users/Alice/Library/Application Support)

* macos: add icons based on screenshotted logo
* macos: add Cmd-Q to quit
@iceiix
Copy link
Owner Author

iceiix commented May 25, 2021

Found this new project (via https://wiki.vg/Client_List) with similar goals: https://github.com/PrismarineJS/prismarine-web-client
It is further along in web support (actually works) than us, though needs optimization. Being written in JS, likely easier to develop, but harder to optimize than Rust.

Maybe worth contributing there instead or in addition to this project, could be useful to have a working alternative web client for reference.

iceiix added a commit that referenced this issue Jun 18, 2021
While the package lock is useful to consistently include the same
versions of each package, right now it causes too much noise with
dependabot, as new versions are released but with little or no impact on
this project because the web port is not yet usable (see #446 ๐Ÿ•ธ๏ธ Web
support)
iceiix added a commit that referenced this issue Jun 18, 2021
While the package lock is useful to consistently include the same
versions of each package, right now it causes too much noise with
dependabot, as new versions are released but with little or no impact on
this project because the web port is not yet usable (see #446 ๐Ÿ•ธ๏ธ Web
support)
@PureTryOut
Copy link
Contributor

Are you planning on dropping web support then? Seeing your comment in #581 (comment) makes me think so at least. Personally I love the idea of a webclient, but I don't think it's worth it if it blocks stuff like a renderer upgrade. Desktop platforms should probably be the number 1 priority.

@iceiix
Copy link
Owner Author

iceiix commented Aug 30, 2021

@PureTryOut I'm of two minds in removing web, it may help increase maintainability (lots of the dependency updates are web-related), but I do feel it is getting there, very close - the major missing piece is networking (well, also multithreading, and resources). The "rendering upgrade" I settled on was to use glow (GL on Whatever, #262), this abstracts away OpenGL/WebGL, but another possible upgrade, a different abstraction (was considering in #34, but it didn't seem there yet) is wgpu-rs. If/when Leafish supports wgpu or Vulkan (https://github.com/terrarier2111/Leafish/issues/20), I think that does appear to be a viable option - for also supporting the web (WebGPU).

My current thinking is its a good idea to keep (incomplete) web support around, so as I make changes I can ensure it at least still continues to compile for the web, but I may be wrong about this. If I had to choose, I'd be tempted to go with a new rendering backend (as long as it works on my macOS system too).

@iAmInActions
Copy link

Idea for networking: use a generic websocket proxy like for example wss://relay.widgetry.org/. From my testing in v86 is seems to be reliable and supports port 25565. Chunk loading might be a bit slow though as the proxy limits the bandwidth for each connected device due to it being a free proxy.

@mpfaff
Copy link

mpfaff commented Sep 18, 2021

To be completely honest, that sounds like a really bad idea. If you were to go that route (using a websocket proxy), you'd have to make it easily configurable or at the very least, include a big notice when you use it. Also, wouldn't the free proxy have a bandwidth, speed, or connection limit that would be a problem if stevenarella ever gets big? Just seems like you'd be digging yourself into a hole that would be tough to get out of.

@iceiix
Copy link
Owner Author

iceiix commented Sep 18, 2021

I think supporting the use of a public proxy could be an interesting experiment, but agree it has pitfalls making it probably not the best solution for normal everyday usage - bandwidth/connection limits, using a shared IP address, etc.

I was thinking instead the WebSocket proxy could be setup by the server owner, who wishes to make their server available through the "web". A plugin serving both WS and HTTP, for the web-based client which connects back to the WS, inspired by this plugin: https://www.spigotmc.org/resources/websandboxmc.39415/ - but more full-featured.

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

No branches or pull requests

4 participants