toji/gl-matrix

How to pass data to webgl?

Norbert515 opened this issue · 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.

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.

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);