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

WebGL fixes after disabling threaded chunk builder #451

Merged
merged 28 commits into from
Dec 31, 2020
Merged

WebGL fixes after disabling threaded chunk builder #451

merged 28 commits into from
Dec 31, 2020

Conversation

iceiix
Copy link
Owner

@iceiix iceiix commented Dec 28, 2020

std::thread vs wasm32

for 🕸️ Web support #446

@iceiix iceiix mentioned this pull request Dec 28, 2020
29 tasks
@iceiix
Copy link
Owner Author

iceiix commented Dec 28, 2020

src/chunk_builder.rs is going to be a problem. It uses a thread pool of 8 threads to build chunks. This crate attempts to be a replacement for std::thread on wasm: https://lib.rs/crates/wasm_thread - though it requires some tricks to support atomics.

Another option is web workers. More akin to processes than threads, pass messages between workers. mpsc::channel()? What's the canonical way to use web workers in wasm from Rust, while also supporting native threads?

WASI (wasm32-wasi) is looking more and more interesting (versus wasm32-unknown-unknown, which doesn't specify the target platform — not necessarily running in the browser), found this: https://lib.rs/crates/wasi-worker

Disabling chunk builder, enabling only the renderer, hits a more interesting error: "Bind frag data location is not supported", a call to glow bind_frag_data_location(), used in src/render/mod.rs for the chunk shader program "accum" and "revealage" attributes:

Screen Shot 2020-12-27 at 4 24 20 PM

(after fixing this, since layout is already specified in-shader: https://www.khronos.org/opengl/wiki/Fragment_Shader#Output_buffers, get GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT, right before the bind_frag_data_location() calls)

At a fork in the road here, could try to disable threading as much as possible and work on getting the rendering up to snuff. Threads are non-trivial, but some kind of multiprocessing will likely be needed ultimately. Uses of std::thread:

  • src/chunk_builder.rs - NUM_WORKERS = 8, chunk computation
  • src/main.rs - Game connect_to thread::spawn (network I/O), fps cap thread::sleep (n/a to web)
  • src/resources.rs - download_assets reqwest blocking
  • src/render/mod.rs - skin_thread (already compiled out for wasm)
  • src/screen/login.rs - tick() profile refresh send (network I/O)
  • src/screen/server_list.rs - // Don't block the main thread whilst pinging the server
  • src/server/mod.rs - spawn_reader() thread::spawn read_packet (network I/O)

Most of these are network I/O. On the web, the way to do I/O without blocking is asynchronous callbacks, either functions passed in directly as arguments, or using Promises - analogous to Rust Futures, sugaring to async/.await (not dissimilar to JavaScript async/await).

Our use of reqwest, in particular, should be switched from reqwest::blocking in a thread, to async, and since reqwest supports WASM, this probably should "just work" on the web. As for the protocol/packet sending and receiving, similar idea, convert to async to prepare for implementing I/O on the web using Web Sockets, maybe using: https://lib.rs/crates/ws_stream_wasm (A convenience library for using websockets in WASM) - "AsyncRead/AsyncWrite on top of websockets"

…der 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
@iceiix
Copy link
Owner Author

iceiix commented Dec 28, 2020

TransInfo framebuffer is incomplete, but continuing past this error, at last something finally appears on screen! (albeit with more errors):

Screen Shot 2020-12-28 at 2 54 19 PM

glGetError 1280 = GL_INVALID_ENUM
glGetError 1286 = GL_INVALID_FRAMEBUFFER_OPERATION
glGetError 1281 = GL_INVALID_VALUE

Interesting the UI is rendered, so that is working, just not the chunks. The logo splash text animates, demonstrating the std::time replacement paid off (#449, replacing with instant crate, it works on the web):

web.mov

@iceiix
Copy link
Owner Author

iceiix commented Dec 31, 2020

Firefox 84.0 (64-bit) gives more information on the incomplete trans Framebuffer:

WebGL warning: texImage: Mismatched internalFormat and format/type: 0x81a6 and 0x1902/0x1401 0.bootstrap.js line 11 > eval:704:21
WebGL warning: checkFramebufferStatus: Framebuffer not complete. (status: 0x8cd6) DEPTH_ATTACHMENT: Attachment has no width or height. 0.bootstrap.js line 11 > eval:768:31

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.
@iceiix
Copy link
Owner Author

iceiix commented Dec 31, 2020

Latest GL warnings/errors in Firefox 84:

WebGL warning: enabled: cap: Invalid enum value <enum 0x809d> [GL_MULITSAMPLE] 0.bootstrap.js line 11 > eval:851:21
WebGL warning: uniform setter: (uniform colorMul[0]) `values` length (1) must be a positive integer multiple of size of <enum 0x8b52> [GL_ FLOAT_VEC4] [. 0.bootstrap.js line 11 > eval:728:21
WebGL warning: drawElementsInstanced: Vertex attrib 0 requires data of type INT, but is being supplied with type UINT. 0.bootstrap.js line 11 > eval:847:21
WebGL warning: uniform setter: (uniform colorMul[0]) `values` length (1) must be a positive integer multiple of size of <enum 0x8b52>. 0.bootstrap.js line 11 > eval:728:21
WebGL warning: drawElementsInstanced: Vertex attrib 0 requires data of type INT, but is being supplied with type UINT. 0.bootstrap.js line 11 > eval:847:21
WebGL warning: disabled: cap: Invalid enum value <enum 0x809d> 0.bootstrap.js line 11 > eval:839:21
[gl/mod.rs:855][ERROR] glGetError = 1280 [GL_INVALID_ENUM ] stevenarella_bg.js:1475:13
[gl/mod.rs:855][ERROR] glGetError = 1280 stevenarella_bg.js:1475:13
WebGL warning: enabled: cap: Invalid enum value <enum 0x809d> 0.bootstrap.js line 11 > eval:851:21
WebGL warning: uniform setter: (uniform colorMul[0]) `values` length (1) must be a positive integer multiple of size of <enum 0x8b52>. 0.bootstrap.js line 11 > eval:728:21
WebGL warning: drawElementsInstanced: Vertex attrib 0 requires data of type INT, but is being supplied with type UINT. 0.bootstrap.js line 11 > eval:847:21
WebGL warning: uniform setter: (uniform colorMul[0]) `values` length (1) must be a positive integer multiple of size of <enum 0x8b52>. 0.bootstrap.js line 11 > eval:728:21
WebGL warning: drawElementsInstanced: Vertex attrib 0 requires data of type INT, but is being supplied with type UINT. 0.bootstrap.js line 11 > eval:847:21
WebGL warning: disabled: cap: Invalid enum value <enum 0x809d> 0.bootstrap.js line 11 > eval:839:21
WebGL warning: enabled: cap: Invalid enum value <enum 0x809d> 0.bootstrap.js line 11 > eval:851:21
WebGL warning: uniform setter: (uniform colorMul[0]) `values` length (1) must be a positive integer multiple of size of <enum 0x8b52>. 0.bootstrap.js line 11 > eval:728:21
WebGL warning: drawElementsInstanced: Vertex attrib 0 requires data of type INT, but is being supplied with type UINT. 0.bootstrap.js line 11 > eval:847:21
[gl/mod.rs:855][ERROR] glGetError = 1280 stevenarella_bg.js:1475:13
WebGL warning: uniform setter: (uniform colorMul[0]) `values` length (1) must be a positive integer multiple of size of <enum 0x8b52>. 0.bootstrap.js line 11 > eval:728:21
WebGL warning: drawElementsInstanced: Vertex attrib 0 requires data of type INT, but is being supplied with type UINT. 0.bootstrap.js line 11 > eval:847:21
WebGL warning: disabled: cap: Invalid enum value <enum 0x809d> 0.bootstrap.js line 11 > eval:839:21
WebGL warning: enabled: cap: Invalid enum value <enum 0x809d> 0.bootstrap.js line 11 > eval:851:21
[gl/mod.rs:855][ERROR] glGetError = 1280 stevenarella_bg.js:1475:13
WebGL warning: uniform setter: (uniform colorMul[0]) `values` length (1) must be a positive integer multiple of size of <enum 0x8b52>. 0.bootstrap.js line 11 > eval:728:21
WebGL warning: drawElementsInstanced: Vertex attrib 0 requires data of type INT, but is being supplied with type UINT. 0.bootstrap.js line 11 > eval:847:21
WebGL warning: uniform setter: (uniform colorMul[0]) `values` length (1) must be a positive integer multiple of size of <enum 0x8b52>. 0.bootstrap.js line 11 > eval:728:21
WebGL warning: drawElementsInstanced: Vertex attrib 0 requires data of type INT, but is being supplied with type UINT. 0.bootstrap.js line 11 > eval:847:21
WebGL warning: disabled: cap: Invalid enum value <enum 0x809d> 0.bootstrap.js line 11 > eval:839:21
WebGL warning: enabled: cap: Invalid enum value <enum 0x809d> 0.bootstrap.js line 11 > eval:851:21
[gl/mod.rs:855][ERROR] glGetError = 1280 stevenarella_bg.js:1475:13
WebGL warning: uniform setter: (uniform colorMul[0]) `values` length (1) must be a positive integer multiple of size of <enum 0x8b52>. 0.bootstrap.js line 11 > eval:728:21
WebGL warning: drawElementsInstanced: Vertex attrib 0 requires data of type INT, but is being supplied with type UINT. 0.bootstrap.js line 11 > eval:847:21
WebGL warning: uniform setter: (uniform colorMul[0]) `values` length (1) must be a positive integer multiple of size of <enum 0x8b52>. 0.bootstrap.js line 11 > eval:728:21
WebGL warning: drawElementsInstanced: Vertex attrib 0 requires data of type INT, but is being supplied with type UINT. 0.bootstrap.js line 11 > eval:847:21
WebGL warning: disabled: cap: Invalid enum value <enum 0x809d> 0.bootstrap.js line 11 > eval:839:21
WebGL warning: enabled: cap: Invalid enum value <enum 0x809d> 0.bootstrap.js line 11 > eval:851:21
WebGL warning: uniform setter: (uniform colorMul[0]) `values` length (1) must be a positive integer multiple of size of <enum 0x8b52>. 0.bootstrap.js line 11 > eval:728:21
WebGL: No further warnings will be reported for this WebGL context. (already reported 32 warnings) 0.bootstrap.js line 11 > eval:728:21
[gl/mod.rs:855][ERROR] glGetError = 1280

Fixes WebGL warning: enabled: cap: Invalid enum value <enum 0x809d> 0.bootstrap.js line 11 > eval:851:21
@iceiix
Copy link
Owner Author

iceiix commented Dec 31, 2020

WebGL warning: uniform setter: (uniform colorMul[0]) values length (1) must be a positive integer multiple of size of <enum 0x8b52>.

0x8b52 = FLOAT_VEC4 per FLOAT_VEC4

color_mul is set with:

                if let Some(v) = &collection.shader.color_mul {
                    unsafe {
                        v.set_float_multi_raw(model.colors.as_ptr() as *const _, model.colors.len())
                    }
                }

model.colors.len() is 1, a Vec<[f32; 4]> vector with one element (of [f32; 4])

bug in the wrapper?

    #[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));
    }

"length (1)" -- the passed in len is 1, this seems wrong. The original wrapper using raw OpenGL, before #262:

    pub fn set_float_mutli_raw(&self, data: *const f32, len: usize) {
        unsafe {
            gl::Uniform4fv(self.0, len as i32, data);
        }
    }

The wrapper in glow https://github.com/grovesNL/glow/blob/main/src/native.rs#L1374

    unsafe fn uniform_4_f32_slice(&self, location: Option<&Self::UniformLocation>, v: &[f32]) {
        let gl = &self.raw;
        if let Some(loc) = location {
            gl.Uniform4fv(*loc as i32, v.len() as i32 / 4, v.as_ptr());
        }
    }

https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glUniform.xhtml

https://www.khronos.org/opengl/wiki/GLSL_:_common_mistakes#How_to_use_glUniform says the count is of the type, glUniform4fv type (4f, which corresponds to vec4, so it should be 1. glow is dividing by 4.


declaration:

pub struct Model {
...
    pub colors: Vec<[f32; 4]>,

initialization:

            for (i, part) in parts.into_iter().enumerate() {
                model.matrix.push(Matrix4::identity());
                model.colors.push([1.0, 1.0, 1.0, 1.0]);

used in src/render/shaders/model_frag.glsl

uniform vec4 colorMul[10];   fragColor = col * colorMul[int(vID)];

and src/render/shaders/sun_frag.glsl

uniform vec4 colorMul[10];    fragColor = col * colorMul[int(vID)];

Passing in a raw pointer (set_float_multi_raw) seems suboptimal, better way to do this? Model matrix is a Vec<Matrix4<f32>> and it is set on the uniform simply through v.set_matrix4_multi(&model.matrix), not clear why raw pointers were needed for setting multiple floats. I guess to try to convert Vec<[f32; 4]> to &[f32].

Removes use of passing raw pointers in set_float_multi_raw parameters
Instead, casts raw pointers to flatten, similar to set_matrix_multi
Fixes WebGL warning: uniform setter: (uniform colorMul[0]) values length (1) must be a positive integer multiple of size of <enum 0x8b52>.
@iceiix
Copy link
Owner Author

iceiix commented Dec 31, 2020

Final remaining warning is:

WebGL warning: drawElementsInstanced: Vertex attrib 0 requires data of type INT, but is being supplied with type UINT.

https://stackoverflow.com/questions/46437800/webgl-2-0-integer-attribute-throws-type-error-if-vertexattribarray-is-disabled
https://www.khronos.org/registry/webgl/specs/latest/2.0/#5.31

If any of the following situations are true, attempting to draw with drawArrays, drawElements, drawRangeElements or their instanced variants generates an INVALID_OPERATION error:

  • vertexAttribIPointer is used with type UNSIGNED_BYTE, UNSIGNED_SHORT or UNSIGNED_INT, or vertexAttribI4ui or vertexAttribI4uiv is used, and the base type of the shader attribute at slot index is not unsigned integer (e.g. is floating-point or signed integer);

glGetError = 1282
is GL_INVALID_OPERATION

check the draw_elements() call

[gl/mod.rs:57][ERROR] about to draw_elements ty=4 count=6 dty=5123 offset=0 2 stevenarella_bg.js:1475:13
WebGL warning: drawElementsInstanced: Vertex attrib 0 requires data of type INT, but is being supplied with type UINT. 2 0.bootstrap.js line 11 > eval:847:21
[gl/mod.rs:57][ERROR] about to draw_elements ty=4 count=20640 dty=5123 offset=0 stevenarella_bg.js:1475:13
panicked at 'glGetError = 1282', src/gl/mod.rs:857:13

uses:

src/render/ui.rs:            gl::draw_elements(gl::TRIANGLES, self.count as i32, self.index_type, 0);
src/render/mod.rs:                                        gl::draw_elements(
                        gl::TRIANGLES,
                        solid.count as i32,
                        self.element_buffer_type,
                        0,
                    );
src/render/mod.rs:                                        gl::draw_elements(
                        gl::TRIANGLES,
                        trans.count as i32,
                        self.element_buffer_type,
                        0,
                    );
src/render/model.rs:                gl::draw_elements(gl::TRIANGLES, model.count, self.index_type, 0);

src/render/ui.rs index_type: gl::UNSIGNED_BYTE,
src/render/model.rs index_type: gl::UNSIGNED_SHORT,
src/render/mod.rs element_buffer_type: gl::UNSIGNED_BYTE,

vertex_pointer and vertex_pointer in src/gl go to glow vertex_attrib_pointer_f32 and vertex_attrib_pointer_i32, to native glVertexAttribPointer and glVertexAttribIPointer. https://stackoverflow.com/questions/46437800/webgl-2-0-integer-attribute-throws-type-error-if-vertexattribarray-is-disabled says:

If the actual attribute in a shader is an integer on unsigned integer value, you should specify its value manually via a call from vertexAttribI4* family, i.e.:

gl.vertexAttribI4i(2, 0, 0, 0, 0);

https://developer.mozilla.org/en-US/docs/Web/API/WebGL2RenderingContext/vertexAttribI
https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.8

The error in Chrome 87:

[.WebGL-0x7f8e4a189e00]GL ERROR :GL_INVALID_OPERATION : glDrawElements: vertexAttrib function must match shader attrib type

@iceiix
Copy link
Owner Author

iceiix commented Dec 31, 2020

[main.rs:240][INFO] Starting steven stevenarella_bg.js:1483:13
[main.rs:334][INFO] Shader version: #version 300 es stevenarella_bg.js:1483:13
[render/model.rs:289][INFO] about to draw elements model stevenarella_bg.js:1483:13
WebGL warning: drawElementsInstanced: Vertex attrib 0 requires data of type INT, but is being supplied with type UINT. 0.bootstrap.js line 11 > eval:847:21
[render/model.rs:289][INFO] about to draw elements model stevenarella_bg.js:1483:13
WebGL warning: drawElementsInstanced: Vertex attrib 0 requires data of type INT, but is being supplied with type UINT. 0.bootstrap.js line 11 > eval:847:21
[render/ui.rs:183][INFO] about to draw_elements in src/render/ui.rs stevenarella_bg.js:1483:13
[gl/mod.rs:857][ERROR] glGetError = 1282 stevenarella_bg.js:1475:13
[render/model.rs:289][INFO] about to draw elements model 2 stevenarella_bg.js:1483:13
WebGL warning: drawElementsInstanced: Vertex attrib 0 requires data of type INT, but is being supplied with type UINT. 2 0.bootstrap.js line 11 > eval:847:21
[render/ui.rs:183][INFO] about to draw_elements in src/render/ui.rs stevenarella_bg.js:1483:13
[gl/mod.rs:857][ERROR] glGetError = 1282 stevenarella_bg.js:1475:13
[render/model.rs:289][INFO] about to draw elements model 2 stevenarella_bg.js:1483:13
[render/ui.rs:183][INFO] about to draw_elements in src/render/ui.rs stevenarella_bg.js:1483:13
[gl/mod.rs:857][ERROR] glGetError = 1282 stevenarella_bg.js:1475:13
WebGL warning: drawElementsInstanced: Vertex attrib 0 requires data of type INT, but is being supplied with type UINT. 2 0.bootstrap.js line 11 > eval:847:21
[render/model.rs:289][INFO] about to draw elements model 2 stevenarella_bg.js:1483:13
WebGL warning: drawElementsInstanced: Vertex attrib 0 requires data of type INT, but is being supplied with type UINT. 0.bootstrap.js line 11 > eval:847:21
[render/ui.rs:183][INFO] about to draw_elements in src/render/ui.rs stevenarella_bg.js:1483:13
[gl/mod.rs:857][ERROR] glGetError = 1282 stevenarella_bg.js:1475:13
WebGL warning: drawElementsInstanced: Vertex attrib 0 requires data of type INT, but is being supplied with type UINT. 0.bootstrap.js line 11 > eval:847:21
[render/model.rs:289][INFO] about to draw elements model 2 stevenarella_bg.js:1483:13
[render/ui.rs:183][INFO] about to draw_elements in src/render/ui.rs stevenarella_bg.js:1483:13
WebGL warning: drawElementsInstanced: Vertex attrib 0 requires data of type INT, but is being supplied with type UINT. 2 0.bootstrap.js line 11 > eval:847:21
[gl/mod.rs:857][ERROR] glGetError = 1282 stevenarella_bg.js:1475:13
[render/model.rs:289][INFO] about to draw elements model 2 stevenarella_bg.js:1483:13
WebGL warning: drawElementsInstanced: Vertex attrib 0 requires data of type INT, but is being supplied with type UINT. 2 0.bootstrap.js line 11 > eval:847:21
[render/ui.rs:183][INFO] about to draw_elements in src/render/ui.rs stevenarella_bg.js:1483:13
[gl/mod.rs:857][ERROR] glGetError = 1282 stevenarella_bg.js:1475:13
[render/model.rs:289][INFO] about to draw elements model 2 stevenarella_bg.js:1483:13
WebGL warning: drawElementsInstanced: Vertex attrib 0 requires data of type INT, but is being supplied with type UINT. 2 0.bootstrap.js line 11 > eval:847:21
[render/ui.rs:183][INFO] about to draw_elements in src/render/ui.rs stevenarella_bg.js:1483:13
[gl/mod.rs:857][ERROR] glGetError = 1282 stevenarella_bg.js:1475:13
[render/model.rs:289][INFO] about to draw elements model 2 stevenarella_bg.js:1483:13
[render/ui.rs:183][INFO] about to draw_elements in src/render/ui.rs stevenarella_bg.js:1483:13
[gl/mod.rs:857][ERROR] glGetError = 1282 stevenarella_bg.js:1475:13
WebGL warning: drawElementsInstanced: Vertex attrib 0 requires data of type INT, but is being supplied with type UINT. 2 0.bootstrap.js line 11 > eval:847:21
[render/model.rs:289][INFO] about to draw elements model 2 stevenarella_bg.js:1483:13
WebGL warning: drawElementsInstanced: Vertex attrib 0 requires data of type INT, but is being supplied with type UINT. 0.bootstrap.js line 11 > eval:847:21
[render/ui.rs:183][INFO] about to draw_elements in src/render/ui.rs stevenarella_bg.js:1483:13
[gl/mod.rs:857][ERROR] glGetError = 1282 stevenarella_bg.js:1475:13
WebGL warning: drawElementsInstanced: Vertex attrib 0 requires data of type INT, but is being supplied with type UINT. 0.bootstrap.js line 11 > eval:847:21
[render/model.rs:289][INFO] about to draw elements model 2 stevenarella_bg.js:1483:13
WebGL warning: drawElementsInstanced: Vertex attrib 0 requires data of type INT, but is being supplied with type UINT. 2 0.bootstrap.js line 11 > eval:847:21
[render/ui.rs:183][INFO] about to draw_elements in src/render/ui.rs stevenarella_bg.js:1483:13
[gl/mod.rs:857][ERROR] glGetError = 1282 stevenarella_bg.js:1475:13
[render/model.rs:289][INFO] about to draw elements model 2 stevenarella_bg.js:1483:13
WebGL warning: drawElementsInstanced: Vertex attrib 0 requires data of type INT, but is being supplied with type UINT. 2 0.bootstrap.js line 11 > eval:847:21
[render/ui.rs:183][INFO] about to draw_elements in src/render/ui.rs stevenarella_bg.js:1483:13
[gl/mod.rs:857][ERROR] glGetError = 1282 stevenarella_bg.js:1475:13
[render/model.rs:289][INFO] about to draw elements model 2 stevenarella_bg.js:1483:13
WebGL warning: drawElementsInstanced: Vertex attrib 0 requires data of type INT, but is being supplied with type UINT. 2 0.bootstrap.js line 11 > eval:847:21
[render/ui.rs:183][INFO] about to draw_elements in src/render/ui.rs stevenarella_bg.js:1483:13
[gl/mod.rs:857][ERROR] glGetError = 1282 stevenarella_bg.js:1475:13
[render/model.rs:289][INFO] about to draw elements model 2 stevenarella_bg.js:1483:13
[render/ui.rs:183][INFO] about to draw_elements in src/render/ui.rs stevenarella_bg.js:1483:13
[gl/mod.rs:857][ERROR] glGetError = 1282 stevenarella_bg.js:1475:13
WebGL warning: drawElementsInstanced: Vertex attrib 0 requires data of type INT, but is being supplied with type UINT. 2 0.bootstrap.js line 11 > eval:847:21
[render/model.rs:289][INFO] about to draw elements model 2 stevenarella_bg.js:1483:13
WebGL warning: drawElementsInstanced: Vertex attrib 0 requires data of type INT, but is being supplied with type UINT. 2 0.bootstrap.js line 11 > eval:847:21
[render/ui.rs:183][INFO] about to draw_elements in src/render/ui.rs stevenarella_bg.js:1483:13
[gl/mod.rs:857][ERROR] glGetError = 1282 stevenarella_bg.js:1475:13
[render/model.rs:289][INFO] about to draw elements model 2 stevenarella_bg.js:1483:13
WebGL warning: drawElementsInstanced: Vertex attrib 0 requires data of type INT, but is being supplied with type UINT. 2 0.bootstrap.js line 11 > eval:847:21
[render/ui.rs:183][INFO] about to draw_elements in src/render/ui.rs stevenarella_bg.js:1483:13
[gl/mod.rs:857][ERROR] glGetError = 1282 stevenarella_bg.js:1475:13
[render/model.rs:289][INFO] about to draw elements model 2 stevenarella_bg.js:1483:13
[render/ui.rs:183][INFO] about to draw_elements in src/render/ui.rs stevenarella_bg.js:1483:13
[gl/mod.rs:857][ERROR] glGetError = 1282 stevenarella_bg.js:1475:13
WebGL warning: drawElementsInstanced: Vertex attrib 0 requires data of type INT, but is being supplied with type UINT. 2 0.bootstrap.js line 11 > eval:847:21
WebGL: No further warnings will be reported for this WebGL context. (already reported 32 warnings)

@iceiix iceiix changed the title Threads vs web Threads vs web + WebGL fixes Dec 31, 2020
@iceiix
Copy link
Owner Author

iceiix commented Dec 31, 2020

The error seems to be in model's draw_elements, commenting it out avoids the error (while the ui draw_elements continues without error; chunk rendering draw_elements is not invoked). What could be the type mismatch with this call?

src/render/model.rs

``rust
gl::draw_elements(gl::TRIANGLES, model.count, self.index_type, 0);


set from 

```rust
        Self::rebuild_model(&mut model);
        if self.max_index < model.count as usize {
            let (data, ty) = super::generate_element_buffer(model.count as usize);
            self.index_buffer.bind(gl::ELEMENT_ARRAY_BUFFER);
            self.index_buffer
                .set_data(gl::ELEMENT_ARRAY_BUFFER, &data, gl::DYNAMIC_DRAW);
            self.max_index = model.count as usize;
            self.index_type = ty;
        }

super::generate_element_buffer is in src/render/mod.rs, ty is UNSIGNED_SHORT or if exceeds u16::max_value() then UNSIGNED_INT:

#[allow(unused_must_use)]
pub fn generate_element_buffer(size: usize) -> (Vec<u8>, gl::Type) {
    let mut ty = gl::UNSIGNED_SHORT;
    let mut data = if (size / 6) * 4 * 3 >= u16::max_value() as usize {
        ty = gl::UNSIGNED_INT;
        Vec::with_capacity(size * 4)
    } else {
        Vec::with_capacity(size * 2)
    };
    for i in 0..size / 6 {
        for val in &[0, 1, 2, 2, 1, 3] {
            if ty == gl::UNSIGNED_INT {
                data.write_u32::<NativeEndian>((i as u32) * 4 + val);
            } else {
                data.write_u16::<NativeEndian>((i as u16) * 4 + (*val as u16));
            }
        }
    }

    (data, ty)
}

both unsigned. Where is the signed int coming from, what is vertex attrib 0?

WebGL warning: drawElementsInstanced: Vertex attrib 0 requires data of type INT, but is being supplied with type UINT. 2 0.bootstrap.js line 11 > eval:847:21


https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glDrawElements.xhtml says valid values are:

type Specifies the type of the values in indices. Must be one of GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT, or GL_UNSIGNED_INT.

changing to SHORT fails WebGL warning: drawElementsInstanced: type: Invalid enum value <enum 0x1402> (= GL_SHORT)


Chrome: glDrawElements: vertexAttrib function must match shader attrib type

Found how this other project fixed a similar issue: google/filament#1726

google/filament@89c6e1d

                // In some OpenGL implementation, (e.g. WebGL and maybe Angle), we must supply a
                 // properly-typed placeholder for every input that is declared in the vertex shader,
                 // similar to Vulkan and Metal.
                 const uint32_t kBoneIndicesLocation = 5; // VertexAttribute::BONE_INDICES
                 if (i == kBoneIndicesLocation) {
                     glVertexAttribI4ui(GLuint(i), 0, 0, 0, 0);
                 }

@iceiix
Copy link
Owner Author

iceiix commented Dec 31, 2020

First cut at adding glVertexAttribI4ui() wrappers to glow in iceiix/glow#2 (if useful, can PR to https://github.com/grovesNL/glow/compare/main). glow doesn't seem to have many of the glVertexAttrib(I) family even though they are available in OpenGL ES 3.0: https://www.khronos.org/registry/OpenGL-Refpages/es3.0/html/glVertexAttrib.xhtml and probably WebGL 2.0.

These glVertexAttrib functions we haven't used before. glVertexAttribPointer is used extensively, however, through vertex_pointer and vertex_pointer_int. https://stackoverflow.com/questions/13603956/glvertexattrib-vs-glvertexattribpointer explains the difference:

glVertexAttrib sets the value of an attribute for a given set of vertices.

glVertexAttribPointer sets the location of the attribute for every vertex.

tried to call glVertexAttribI4ui(0, 0, 0, 0, 0, 0) to effectively set the type of attribute 0 to uint, to no effect.

@iceiix
Copy link
Owner Author

iceiix commented Dec 31, 2020

Attributes in the model renderer:

stevenarella_bg.js:1483 [render/model.rs:91][INFO] enabling position Some(Attribute(0))
stevenarella_bg.js:1483 [render/model.rs:97][INFO] enabling texture_info Some(Attribute(2))
stevenarella_bg.js:1483 [render/model.rs:103][INFO] enabling texture_offset Some(Attribute(3))
stevenarella_bg.js:1483 [render/model.rs:112][INFO] not enabling color None
stevenarella_bg.js:1483 [render/model.rs:115][INFO] enabling id Some(Attribute(1))
stevenarella_bg.js:1483 [render/model.rs:91][INFO] enabling position Some(Attribute(0))
stevenarella_bg.js:1483 [render/model.rs:97][INFO] enabling texture_info Some(Attribute(2))
stevenarella_bg.js:1483 [render/model.rs:103][INFO] enabling texture_offset Some(Attribute(3))
stevenarella_bg.js:1483 [render/model.rs:112][INFO] not enabling color None

color is not enabled
Attrib 0 is position... in Chrome

In Firefox, which logged the attrib 0 error, it is id:

[main.rs:240][INFO] Starting steven stevenarella_bg.js:1483:13
[main.rs:334][INFO] Shader version: #version 300 es stevenarella_bg.js:1483:13
[render/model.rs:91][INFO] enabling position Some(Attribute(2)) stevenarella_bg.js:1483:13
[render/model.rs:97][INFO] enabling texture_info Some(Attribute(3)) stevenarella_bg.js:1483:13
[render/model.rs:103][INFO] enabling texture_offset Some(Attribute(1)) stevenarella_bg.js:1483:13
[render/model.rs:112][INFO] not enabling color None stevenarella_bg.js:1483:13
[render/model.rs:115][INFO] enabling id Some(Attribute(0)) stevenarella_bg.js:1483:13
[render/model.rs:91][INFO] enabling position Some(Attribute(2)) stevenarella_bg.js:1483:13
[render/model.rs:97][INFO] enabling texture_info Some(Attribute(3)) stevenarella_bg.js:1483:13
[render/model.rs:103][INFO] enabling texture_offset Some(Attribute(1)) stevenarella_bg.js:1483:13
[render/model.rs:112][INFO] not enabling color None stevenarella_bg.js:1483:13
[render/model.rs:115][INFO] enabling id Some(Attribute(0)) stevenarella_bg.js:1483:13
[render/model.rs:304][INFO] about to draw elements model

in the Vertex struct, id is u8 (unsigned), and it is populated with:

            if let Some(v) = collection.shader.id {
                v.vertex_pointer_int(1, gl::UNSIGNED_BYTE, 36, 32)
            }

which calls into glow_context().vertex_attrib_pointer_i32 -> glVertexAttribIPointer

https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glVertexAttribPointer.xhtml family shows three functions:

glVertexAttribPointer, glVertexAttribIPointer, glVertexAttribLPointer

Specifies the data type of each component in the array. The symbolic constants GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT, GL_UNSIGNED_SHORT, GL_INT, and GL_UNSIGNED_INT are accepted by glVertexAttribPointer and glVertexAttribIPointer.

In the shader (model_vertex.glsl), id was an int, changed to uint earlier, but still a mismatch

@iceiix
Copy link
Owner Author

iceiix commented Dec 31, 2020

Turns out glVertexAttribI4ui (iceiix/glow#2) is not needed, the fix was to change UNSIGNED_BYTE to BYTE in v.vertex_pointer_int(1, gl::BYTE, 36, 32 for collection.shader.id, for some reason with in int id or in uint id in src/render/shaders/model_vertex.glsl did not make a difference, always appeared to expect int (signed).

@iceiix iceiix changed the title Threads vs web + WebGL fixes WebGL fixes after disabling threaded chunk builder Dec 31, 2020
@iceiix
Copy link
Owner Author

iceiix commented Dec 31, 2020

This pull request ended up being more about miscellaneous fixes for WebGL, after getting past the chunk builder threading, but now we are back to src/chunk_builder.rs — without it, no chunks will be built. This will have to be solved to actually show the world, nonetheless, the fixes so far are enough to show the UI, so I'll merge this (continue in #446).

@iceiix iceiix marked this pull request as ready for review December 31, 2020 22:24
@iceiix iceiix merged commit 22f6c83 into master Dec 31, 2020
@iceiix iceiix deleted the thread branch December 31, 2020 22:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant