BlazorExtensions / Canvas

HTML5 Canvas API implementation for Microsoft Blazor
MIT License
620 stars 144 forks source link

parameter 'pixels' of TexImage2DAsync can't be deserialization to ArrayBufferView #65

Open TFeast opened 4 years ago

TFeast commented 4 years ago

I'm add a parameter for TexImage2DAsync() and test,It's throw a error : "Failed to execute 'texImage2D' on 'WebGLRenderingContext': parameter 9 is not of type 'ArrayBufferView'"

    var tempdata = new byte[3]
    {
        1,255,255
    }; 
    await _context.TexImage2DAsync<byte>(Texture2DType.TEXTURE_2D, 0,
            PixelFormat.RGB, 1, 1, 0, PixelFormat.RGB, PixelType.UNSIGNED_BYTE, tempdata);

then call JSRuntime wraps data to Uint8Array,I can render the texture

    var tempdata = new byte[3] {1,255,255};
    await JSRuntime.InvokeVoidAsync("TextureTest", _context.Canvas, tempdata);

   window.TextureTest = (canvas,data) => {
       var gl = canvas.getContext("webgl");
       var tempData = new Uint8Array(data);
       gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB,1,1,0, gl.RGB, gl.UNSIGNED_BYTE , tempData);
   }
2ndwolf commented 4 years ago

TFeast's solution didn't work for me... so:

As we know, inputting bytes in texImage2D's last parameter throws an error, but ints work.

I also noticed that Uint8Array.from(object) (which allows for bigger filesizes than .as) didn't like being sent ints to be converted into bytes. So I did this work around:

Encode your image data's RGBA into an uint array in c#:

for(var i = 0; i < width * height; i++){ 
          abView[i] = (uint)255 << 24; // R
          abView[i] = abView[i] | (0 << 16); //G
          abView[i] = abView[i] | (255 << 8); //B
          abView[i] = abView[i] | 128; //A
        }

Then decode it in typescript by putting this else before the one looking for !method.endsWidth("v"):

else if (Array.isArray(object) && method.startsWith("texImage")) {
      let bytes = new Uint8Array(object.length * 4);
      for(var i = 0; i < object.length; i++){
        bytes[i * 4] = object[i] >> 24;
        bytes[i * 4 + 1] = object[i] >> 16 & 0xff;
        bytes[i * 4 + 2] = object[i] >> 8 & 0xff;
        bytes[i * 4 + 3] = object[i] & 0xff;
      }
      return bytes;
    }

Obviously this is just a quick hack, RGBA becomes a requirement and it's going to be slow. Kudos, team.

Alois-xx commented 3 years ago

I get a similar exception when loading a texture from an array. I am trying a port of the official sample (https://github.com/mdn/webgl-examples/blob/gh-pages/tutorial/sample6/webgl-demo.js#L200) to Blazor but this seems currently not working. Any chance this will get fixed soon? At least the OpenGL samples should work out of the box to be useful.


        public async Task<WebGLTexture> LoadTextureAsync()
        {
            WebGLTexture texture = await myGlContext.CreateTextureAsync();
            await myGlContext.BindTextureAsync(TextureType.TEXTURE_2D, texture);
            byte[] bluePixel = new byte[] { 0, 0, 255, 255 };
            await myGlContext.TexImage2DAsync(Texture2DType.TEXTURE_2D, 0, PixelFormat.RGBA, 1, 1, PixelFormat.RGB, PixelType.UNSIGNED_BYTE, bluePixel);
            return texture;
        }

Microsoft.JSInterop.JSException: WebGLRenderingContext.texImage2D: 8 is not a valid argument count for any overload.
this.callWithContext@https://localhost:44391/_content/Blazor.Extensions.Canvas/blazor.extensions.canvas.js:1:2426
this.callBatch@https://localhost:44391/_content/Blazor.Extensions.Canvas/blazor.extensions.canvas.js:1:2251
beginInvokeJSFromDotNet/i<@https://localhost:44391/_framework/blazor.webassembly.js:1:3942
beginInvokeJSFromDotNet@https://localhost:44391/_framework/blazor.webassembly.js:1:3908
w@https://localhost:44391/_framework/blazor.webassembly.js:1:64218
_mono_wasm_invoke_js_blazor@https://localhost:44391/_framework/dotnet.5.0.1.js:1:190800
mono_wasm_invoke_js_blazor@:wasm-function[45]:0x0
do_icall@:wasm-function[10596]:0x194e58
do_icall_wrapper@:wasm-function[3305]:0x79df9
interp_exec_method@:wasm-function[2155]:0x44ad3
interp_runtime_invoke@:wasm-function[7862]:0x12efff
mono_jit_runtime_invoke@:wasm-function[7347]:0x118e5f
do_runtime_invoke@:wasm-function[3304]:0x79d42
mono_runtime_try_invoke@:wasm-function[629]:0x12982
mono_runtime_invoke@:wasm-function[7118]:0x10ec2b
mono_wasm_invoke_method@:wasm-function[6922]:0x108e48
Module._mono_wasm_invoke_method@https://localhost:44391/_framework/dotnet.5.0.1.js:1:214819
call_method@https://localhost:44391/_framework/dotnet.5.0.1.js:1:180044
bind_static_method/<@https://localhost:44391/_framework/dotnet.5.0.1.js:1:182638
endInvokeJSFromDotNet@https://localhost:44391/_framework/blazor.webassembly.js:1:22064
beginInvokeJSFromDotNet/<@https://localhost:44391/_framework/blazor.webassembly.js:1:3997

   at Microsoft.JSInterop.JSRuntime.<InvokeAsync>d__15`1[[System.Object, System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].MoveNext()
   at Blazor.Extensions.RenderingContext.BatchCallInnerAsync()
   at Blazor.Extensions.RenderingContext.BatchCallAsync(String name, Boolean isMethodCall, Object[] value)
   at Blazor.Extensions.Canvas.WebGL.WebGLContext.<TexImage2DAsync>d__256`1[[System.Byte, System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].MoveNext()
   at BlazorApp1.Client.Pages.WebGL.LoadTextureAsync()