gl-matrix icon indicating copy to clipboard operation
gl-matrix copied to clipboard

How to pass data to webgl?

Open Norbert515 opened this issue 4 years ago • 2 comments

Hey, so I've been pretty frustrated trying to get this basic thing to work.

I'm using typescript and I want to pass data to WebGL via 'bufferData'.

        let a: vec3[];
        let b: Array<vec3>;
        let c = b.flat();
        gl.bufferData(gl.ARRAY_BUFFER, a, gl.STATIC_DRAW);
        gl.bufferData(gl.ARRAY_BUFFER, b, gl.STATIC_DRAW);
        gl.bufferData(gl.ARRAY_BUFFER, c, gl.STATIC_DRAW);

None of these work because of this type error:

No overload matches this call.
  Overload 1 of 2, '(target: number, size: number, usage: number): void', gave the following error.
    Argument of type 'vec3[]' is not assignable to parameter of type 'number'.
  Overload 2 of 2, '(target: number, data: BufferSource, usage: number): void', gave the following error.
    Argument of type 'vec3[]' is not assignable to parameter of type 'BufferSource'.
      Type 'vec3[]' is missing the following properties from type 'ArrayBuffer': byteLength, [Symbol.toStringTag]

c because of:

No overload matches this call.
  Overload 1 of 2, '(target: number, size: number, usage: number): void', gave the following error.
    Argument of type '(number | Float32Array)[]' is not assignable to parameter of type 'number'.
  Overload 2 of 2, '(target: number, data: BufferSource, usage: number): void', gave the following error.
    Argument of type '(number | Float32Array)[]' is not assignable to parameter of type 'BufferSource'.
      Type '(number | Float32Array)[]' is missing the following properties from type 'ArrayBuffer': byteLength, [Symbol.toStringTag]ts(2769)

Am I doing something fundamentally wrong? I've tried a bunch of different type definitions for arrays but nothing seems to work.

Thanks in advance.

Norbert515 avatar Nov 13 '21 19:11 Norbert515

You can't submit an javascript array to WebGL. JS arrays hold javascript variables, but WebGL expects the raw values in memory, which don't match JS variables. If you want to give an array of Vec3's to javascript you need to first copy it to an ArrayBuffer or a typed array, then put the ArrayBuffer/typed array into the WebGL buffer.

mcthouacbb avatar Jan 26 '22 21:01 mcthouacbb

As a quick helper, you can use Float32Array.from() in your case:

const myVecs: vec3[] = [vec3.fromValues(1, 2, 3), vec3.fromValues(4, 5, 6)];
gl.bufferData(gl.ARRAY_BUFFER, Float32Array.from(myVecs.flat()), gl.STATIC_DRAW);

magcius avatar Jul 07 '22 21:07 magcius