Browse Source

WebGL fixes after disabling threaded chunk builder (#451)

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
pull/460/head
iceiix 10 months ago
committed by GitHub
parent
commit
22f6c83d59
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 5
      src/chunk_builder.rs
  2. 9
      src/gl/mod.rs
  3. 8
      src/main.rs
  4. 20
      src/render/mod.rs
  5. 6
      src/render/model.rs
  6. 8
      src/render/shaders/chunk_frag.glsl
  7. 2
      std_or_web/src/lib.rs
  8. 5
      www/README.md

5
src/chunk_builder.rs

@ -10,8 +10,13 @@ use std::sync::mpsc;
use std::sync::{Arc, RwLock};
use std::thread;
#[cfg(not(target_arch = "wasm32"))]
const NUM_WORKERS: usize = 8;
// TODO: threads or web workers on wasm
#[cfg(target_arch = "wasm32")]
const NUM_WORKERS: usize = 0;
pub struct ChunkBuilder {
threads: Vec<(mpsc::Sender<BuildReq>, thread::JoinHandle<()>)>,
free_builders: Vec<(usize, Vec<u8>, Vec<u8>)>,

9
src/gl/mod.rs

@ -213,6 +213,7 @@ pub type Type = u32;
pub const UNSIGNED_BYTE: Type = gl::UNSIGNED_BYTE;
pub const UNSIGNED_SHORT: Type = gl::UNSIGNED_SHORT;
pub const UNSIGNED_INT: Type = gl::UNSIGNED_INT;
pub const BYTE: Type = gl::BYTE;
pub const SHORT: Type = gl::SHORT;
pub const FLOAT: Type = gl::FLOAT;
@ -587,9 +588,11 @@ impl Uniform {
}
}
#[allow(clippy::missing_safety_doc)]
pub unsafe fn set_float_multi_raw(&self, data: *const f32, len: usize) {
glow_context().uniform_4_f32_slice(Some(&self.0), std::slice::from_raw_parts(data, len));
pub fn set_float_multi(&self, v: &[[f32; 4]]) {
unsafe {
glow_context()
.uniform_4_f32_slice(Some(&self.0), &*(v as *const [[f32; 4]] as *const [f32; 4]))
}
}
pub fn set_matrix4(&self, m: &::cgmath::Matrix4<f32>) {

8
src/main.rs

@ -278,8 +278,8 @@ fn main2() {
let canvas = canvas.dyn_into::<web_sys::HtmlCanvasElement>().unwrap();
let webgl2_context = canvas
.get_context("webgl2")
.unwrap()
.unwrap()
.expect("Failed to get WebGL2 context")
.expect("Failed to create WebGL2 context, is WebGL2 support enabled? (https://get.webgl.org/webgl2/)")
.dyn_into::<web_sys::WebGl2RenderingContext>()
.unwrap();
(
@ -399,7 +399,6 @@ fn main2() {
let mut last_resource_version = 0;
/* TODO: fix move of winit_window
#[cfg(target_arch = "wasm32")]
render_loop.run(move |running: &mut bool| {
tick_all(
@ -413,8 +412,9 @@ fn main2() {
);
println!("render_loop");
});
*/
// TODO: enable events_loop for wasm, too, fix borrow with render_loop
#[cfg(not(target_arch = "wasm32"))]
events_loop.run(move |event, _event_loop, control_flow| {
#[cfg(target_arch = "wasm32")]
{

20
src/render/mod.rs

@ -316,6 +316,7 @@ impl Renderer {
gl::active_texture(0);
self.gl_texture.bind(gl::TEXTURE_2D_ARRAY);
#[cfg(not(target_arch = "wasm32"))]
gl::enable(gl::MULTISAMPLE);
let time_offset = self.sky_offset * 0.9;
@ -453,6 +454,8 @@ impl Renderer {
gl::enable(gl::DEPTH_TEST);
gl::depth_mask(true);
gl::blend_func(gl::SRC_ALPHA, gl::ONE_MINUS_SRC_ALPHA);
#[cfg(not(target_arch = "wasm32"))]
gl::disable(gl::MULTISAMPLE);
self.ui.tick(width, height);
@ -809,7 +812,7 @@ impl TransInfo {
None,
);
accum.set_parameter(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, gl::LINEAR);
accum.set_parameter(gl::TEXTURE_2D, gl::TEXTURE_MAX_LEVEL, gl::LINEAR);
accum.set_parameter(gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, gl::LINEAR);
trans.texture_2d(gl::COLOR_ATTACHMENT_0, gl::TEXTURE_2D, &accum, 0);
let revealage = gl::Texture::new();
@ -825,7 +828,7 @@ impl TransInfo {
None,
);
revealage.set_parameter(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, gl::LINEAR);
revealage.set_parameter(gl::TEXTURE_2D, gl::TEXTURE_MAX_LEVEL, gl::LINEAR);
revealage.set_parameter(gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, gl::LINEAR);
trans.texture_2d(gl::COLOR_ATTACHMENT_1, gl::TEXTURE_2D, &revealage, 0);
let trans_depth = gl::Texture::new();
@ -837,16 +840,19 @@ impl TransInfo {
height,
gl::DEPTH_COMPONENT24,
gl::DEPTH_COMPONENT,
gl::UNSIGNED_BYTE,
gl::UNSIGNED_INT,
None,
);
trans_depth.set_parameter(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, gl::LINEAR);
trans_depth.set_parameter(gl::TEXTURE_2D, gl::TEXTURE_MAX_LEVEL, gl::LINEAR);
trans_depth.set_parameter(gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, gl::LINEAR);
trans.texture_2d(gl::DEPTH_ATTACHMENT, gl::TEXTURE_2D, &trans_depth, 0);
chunk_shader.program.use_program();
gl::bind_frag_data_location(&chunk_shader.program, 0, "accum");
gl::bind_frag_data_location(&chunk_shader.program, 1, "revealage");
#[cfg(not(target_arch = "wasm32"))] // bound with layout(location=)
{
gl::bind_frag_data_location(&chunk_shader.program, 0, "accum");
gl::bind_frag_data_location(&chunk_shader.program, 1, "revealage");
}
gl::check_framebuffer_status();
gl::draw_buffers(&[gl::COLOR_ATTACHMENT_0, gl::COLOR_ATTACHMENT_1]);
@ -879,7 +885,7 @@ impl TransInfo {
height,
gl::DEPTH_COMPONENT24,
gl::DEPTH_COMPONENT,
gl::UNSIGNED_BYTE,
gl::UNSIGNED_INT,
None,
);
fb_depth.set_parameter(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, gl::LINEAR);

6
src/render/model.rs

@ -114,7 +114,7 @@ impl Manager {
v.vertex_pointer(4, gl::UNSIGNED_BYTE, true, 36, 28)
}
if let Some(v) = collection.shader.id {
v.vertex_pointer_int(1, gl::UNSIGNED_BYTE, 36, 32)
v.vertex_pointer_int(1, gl::BYTE, 36, 32)
}
let mut model = Model {
@ -283,9 +283,7 @@ impl Manager {
v.set_matrix4_multi(&model.matrix)
}
if let Some(v) = &collection.shader.color_mul {
unsafe {
v.set_float_multi_raw(model.colors.as_ptr() as *const _, model.colors.len())
}
v.set_float_multi(&model.colors)
}
gl::draw_elements(gl::TRIANGLES, model.count, self.index_type, 0);
}

8
src/render/shaders/chunk_frag.glsl

@ -7,12 +7,16 @@ in float vAtlas;
in vec3 vLighting;
#ifndef alpha
#ifdef ES
layout(location = 2) out vec4 fragColor;
#else
out vec4 fragColor;
#endif
#else
#ifdef ES
layout(location = 1) out vec4 accum;
layout(location = 2) out float revealage;
layout(location = 0) out vec4 accum;
layout(location = 1) out float revealage;
#else
out vec4 accum;
out float revealage;

2
std_or_web/src/lib.rs

@ -19,7 +19,7 @@ cfg_if! {
pub fn open<P: AsRef<Path>>(path: P) -> Result<File> {
println!("File open {}", path.as_ref().to_str().unwrap());
Ok(File{})
Err(std::io::Error::new(std::io::ErrorKind::Other, "No files exist on web"))
}
}

5
www/README.md

@ -12,7 +12,8 @@ To build for wasm32-unknown-unknown, run in the top-level directory (not www):
```sh
rustup target add wasm32-unknown-unknown
cargo install wasm-bindgen-cli
wasm-pack build
cargo install wasm-pack
wasm-pack build --dev
```
or:
@ -27,7 +28,7 @@ After building the Rust app, run the NodeJS web server as follows:
```sh
cd pkg
npm link
sudo npm link
cd ..
cd www
npm link stevenarella

Loading…
Cancel
Save