@bigmistqke/view.gl 0.1.10 → 0.1.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/gl.d.mts CHANGED
@@ -1,6 +1,8 @@
1
- import { G as GL } from './types-DaV9McmR.mjs';
1
+ import { G as GL, R as RemoveSuffix } from './types-CHXzeNxF.mjs';
2
2
 
3
3
  declare function createShader(gl: GL, type: number, source: string): WebGLShader;
4
4
  declare function createProgram(gl: GL, vertexSource: string, fragmentSource: string): WebGLProgram;
5
+ declare function getInstancedArrays(gl: GL): RemoveSuffix<Pick<ANGLE_instanced_arrays, "drawArraysInstancedANGLE" | "drawElementsInstancedANGLE" | "vertexAttribDivisorANGLE">, "ANGLE"> | undefined;
6
+ declare function getVertexArrayObject(gl: GL): RemoveSuffix<Pick<OES_vertex_array_object, "bindVertexArrayOES" | "createVertexArrayOES" | "deleteVertexArrayOES">, "OES"> | null;
5
7
 
6
- export { createProgram, createShader };
8
+ export { createProgram, createShader, getInstancedArrays, getVertexArrayObject };
package/dist/gl.mjs CHANGED
@@ -32,8 +32,40 @@ function createProgram(gl, vertexSource, fragmentSource) {
32
32
  gl.deleteShader(fragmentShader);
33
33
  return program;
34
34
  }
35
+ var INSTANCED_ARRAYS_WRAPPER_MAP = /* @__PURE__ */ new WeakMap();
36
+ function getInstancedArrays(gl) {
37
+ if (gl instanceof WebGL2RenderingContext) return gl;
38
+ const cached = INSTANCED_ARRAYS_WRAPPER_MAP.get(gl);
39
+ if (cached) return cached;
40
+ const ext = gl.getExtension("ANGLE_instanced_arrays");
41
+ if (!ext) return void 0;
42
+ const wrapper = {
43
+ drawArraysInstanced: ext.drawArraysInstancedANGLE.bind(ext),
44
+ drawElementsInstanced: ext.drawElementsInstancedANGLE.bind(ext),
45
+ vertexAttribDivisor: ext.vertexAttribDivisorANGLE.bind(ext)
46
+ };
47
+ INSTANCED_ARRAYS_WRAPPER_MAP.set(gl, wrapper);
48
+ return wrapper;
49
+ }
50
+ var VERTEX_ARRAY_OBJECT_WRAPPER_MAP = /* @__PURE__ */ new WeakMap();
51
+ function getVertexArrayObject(gl) {
52
+ if (gl instanceof WebGL2RenderingContext) return gl;
53
+ const cached = VERTEX_ARRAY_OBJECT_WRAPPER_MAP.get(gl);
54
+ if (cached) return cached;
55
+ const ext = gl.getExtension("OES_vertex_array_object");
56
+ if (!ext) return null;
57
+ const wrapper = {
58
+ bindVertexArray: ext.bindVertexArrayOES.bind(ext),
59
+ createVertexArray: ext.createVertexArrayOES.bind(ext),
60
+ deleteVertexArray: ext.deleteVertexArrayOES.bind(ext)
61
+ };
62
+ VERTEX_ARRAY_OBJECT_WRAPPER_MAP.set(gl, wrapper);
63
+ return wrapper;
64
+ }
35
65
  export {
36
66
  createProgram,
37
- createShader
67
+ createShader,
68
+ getInstancedArrays,
69
+ getVertexArrayObject
38
70
  };
39
71
  //# sourceMappingURL=gl.mjs.map
package/dist/gl.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/gl.ts"],"sourcesContent":["import { GL } from \"./types\"\n\nexport function createShader(gl: GL, type: number, source: string): WebGLShader {\n const shader = gl.createShader(type)\n if (!shader) throw new Error('Failed to create shader')\n\n gl.shaderSource(shader, source)\n gl.compileShader(shader)\n\n if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n const info = gl.getShaderInfoLog(shader)\n gl.deleteShader(shader)\n throw new Error(\n `Failed to compile ${type === gl.VERTEX_SHADER ? 'vertex' : 'fragment'} shader: ${info}`,\n )\n }\n\n return shader\n}\n\nexport function createProgram(gl: GL, vertexSource: string, fragmentSource: string): WebGLProgram {\n const program = gl.createProgram()\n if (!program) throw new Error('Failed to create WebGL program')\n\n const vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexSource)\n const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentSource)\n\n gl.attachShader(program, vertexShader)\n gl.attachShader(program, fragmentShader)\n gl.linkProgram(program)\n\n if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n const info = gl.getProgramInfoLog(program)\n gl.deleteProgram(program)\n gl.deleteShader(vertexShader)\n gl.deleteShader(fragmentShader)\n throw new Error(`Failed to link program: ${info}`)\n }\n\n // Clean up shaders after linking\n gl.deleteShader(vertexShader)\n gl.deleteShader(fragmentShader)\n\n return program\n}"],"mappings":";AAEO,SAAS,aAAa,IAAQ,MAAc,QAA6B;AAC9E,QAAM,SAAS,GAAG,aAAa,IAAI;AACnC,MAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,yBAAyB;AAEtD,KAAG,aAAa,QAAQ,MAAM;AAC9B,KAAG,cAAc,MAAM;AAEvB,MAAI,CAAC,GAAG,mBAAmB,QAAQ,GAAG,cAAc,GAAG;AACrD,UAAM,OAAO,GAAG,iBAAiB,MAAM;AACvC,OAAG,aAAa,MAAM;AACtB,UAAM,IAAI;AAAA,MACR,qBAAqB,SAAS,GAAG,gBAAgB,WAAW,UAAU,YAAY,IAAI;AAAA,IACxF;AAAA,EACF;AAEA,SAAO;AACT;AAEO,SAAS,cAAc,IAAQ,cAAsB,gBAAsC;AAChG,QAAM,UAAU,GAAG,cAAc;AACjC,MAAI,CAAC,QAAS,OAAM,IAAI,MAAM,gCAAgC;AAE9D,QAAM,eAAe,aAAa,IAAI,GAAG,eAAe,YAAY;AACpE,QAAM,iBAAiB,aAAa,IAAI,GAAG,iBAAiB,cAAc;AAE1E,KAAG,aAAa,SAAS,YAAY;AACrC,KAAG,aAAa,SAAS,cAAc;AACvC,KAAG,YAAY,OAAO;AAEtB,MAAI,CAAC,GAAG,oBAAoB,SAAS,GAAG,WAAW,GAAG;AACpD,UAAM,OAAO,GAAG,kBAAkB,OAAO;AACzC,OAAG,cAAc,OAAO;AACxB,OAAG,aAAa,YAAY;AAC5B,OAAG,aAAa,cAAc;AAC9B,UAAM,IAAI,MAAM,2BAA2B,IAAI,EAAE;AAAA,EACnD;AAGA,KAAG,aAAa,YAAY;AAC5B,KAAG,aAAa,cAAc;AAE9B,SAAO;AACT;","names":[]}
1
+ {"version":3,"sources":["../src/gl.ts"],"sourcesContent":["import { RemoveSuffix } from './type-utils'\nimport { GL } from './types'\n\nexport function createShader(gl: GL, type: number, source: string): WebGLShader {\n const shader = gl.createShader(type)\n if (!shader) throw new Error('Failed to create shader')\n\n gl.shaderSource(shader, source)\n gl.compileShader(shader)\n\n if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n const info = gl.getShaderInfoLog(shader)\n gl.deleteShader(shader)\n throw new Error(\n `Failed to compile ${type === gl.VERTEX_SHADER ? 'vertex' : 'fragment'} shader: ${info}`,\n )\n }\n\n return shader\n}\n\nexport function createProgram(gl: GL, vertexSource: string, fragmentSource: string): WebGLProgram {\n const program = gl.createProgram()\n if (!program) throw new Error('Failed to create WebGL program')\n\n const vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexSource)\n const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentSource)\n\n gl.attachShader(program, vertexShader)\n gl.attachShader(program, fragmentShader)\n gl.linkProgram(program)\n\n if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n const info = gl.getProgramInfoLog(program)\n gl.deleteProgram(program)\n gl.deleteShader(vertexShader)\n gl.deleteShader(fragmentShader)\n throw new Error(`Failed to link program: ${info}`)\n }\n\n // Clean up shaders after linking\n gl.deleteShader(vertexShader)\n gl.deleteShader(fragmentShader)\n\n return program\n}\n\nconst INSTANCED_ARRAYS_WRAPPER_MAP = new WeakMap<\n GL,\n RemoveSuffix<\n Pick<\n ANGLE_instanced_arrays,\n 'drawArraysInstancedANGLE' | 'drawElementsInstancedANGLE' | 'vertexAttribDivisorANGLE'\n >,\n 'ANGLE'\n > | null\n>()\nexport function getInstancedArrays(gl: GL) {\n if (gl instanceof WebGL2RenderingContext) return gl\n\n const cached = INSTANCED_ARRAYS_WRAPPER_MAP.get(gl)\n if (cached) return cached\n\n const ext = gl.getExtension('ANGLE_instanced_arrays')\n if (!ext) return undefined\n\n const wrapper = {\n drawArraysInstanced: ext.drawArraysInstancedANGLE.bind(ext),\n drawElementsInstanced: ext.drawElementsInstancedANGLE.bind(ext),\n vertexAttribDivisor: ext.vertexAttribDivisorANGLE.bind(ext),\n }\n INSTANCED_ARRAYS_WRAPPER_MAP.set(gl, wrapper)\n\n return wrapper\n}\n\nconst VERTEX_ARRAY_OBJECT_WRAPPER_MAP = new WeakMap<\n GL,\n RemoveSuffix<\n Pick<\n OES_vertex_array_object,\n 'bindVertexArrayOES' | 'createVertexArrayOES' | 'deleteVertexArrayOES'\n >,\n 'OES'\n > | null\n>()\nexport function getVertexArrayObject(gl: GL) {\n if (gl instanceof WebGL2RenderingContext) return gl\n\n const cached = VERTEX_ARRAY_OBJECT_WRAPPER_MAP.get(gl)\n if (cached) return cached\n\n const ext = gl.getExtension('OES_vertex_array_object')\n if (!ext) return null\n\n const wrapper = {\n bindVertexArray: ext.bindVertexArrayOES.bind(ext),\n createVertexArray: ext.createVertexArrayOES.bind(ext),\n deleteVertexArray: ext.deleteVertexArrayOES.bind(ext),\n }\n VERTEX_ARRAY_OBJECT_WRAPPER_MAP.set(gl, wrapper)\n\n return wrapper\n}\n"],"mappings":";AAGO,SAAS,aAAa,IAAQ,MAAc,QAA6B;AAC9E,QAAM,SAAS,GAAG,aAAa,IAAI;AACnC,MAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,yBAAyB;AAEtD,KAAG,aAAa,QAAQ,MAAM;AAC9B,KAAG,cAAc,MAAM;AAEvB,MAAI,CAAC,GAAG,mBAAmB,QAAQ,GAAG,cAAc,GAAG;AACrD,UAAM,OAAO,GAAG,iBAAiB,MAAM;AACvC,OAAG,aAAa,MAAM;AACtB,UAAM,IAAI;AAAA,MACR,qBAAqB,SAAS,GAAG,gBAAgB,WAAW,UAAU,YAAY,IAAI;AAAA,IACxF;AAAA,EACF;AAEA,SAAO;AACT;AAEO,SAAS,cAAc,IAAQ,cAAsB,gBAAsC;AAChG,QAAM,UAAU,GAAG,cAAc;AACjC,MAAI,CAAC,QAAS,OAAM,IAAI,MAAM,gCAAgC;AAE9D,QAAM,eAAe,aAAa,IAAI,GAAG,eAAe,YAAY;AACpE,QAAM,iBAAiB,aAAa,IAAI,GAAG,iBAAiB,cAAc;AAE1E,KAAG,aAAa,SAAS,YAAY;AACrC,KAAG,aAAa,SAAS,cAAc;AACvC,KAAG,YAAY,OAAO;AAEtB,MAAI,CAAC,GAAG,oBAAoB,SAAS,GAAG,WAAW,GAAG;AACpD,UAAM,OAAO,GAAG,kBAAkB,OAAO;AACzC,OAAG,cAAc,OAAO;AACxB,OAAG,aAAa,YAAY;AAC5B,OAAG,aAAa,cAAc;AAC9B,UAAM,IAAI,MAAM,2BAA2B,IAAI,EAAE;AAAA,EACnD;AAGA,KAAG,aAAa,YAAY;AAC5B,KAAG,aAAa,cAAc;AAE9B,SAAO;AACT;AAEA,IAAM,+BAA+B,oBAAI,QASvC;AACK,SAAS,mBAAmB,IAAQ;AACzC,MAAI,cAAc,uBAAwB,QAAO;AAEjD,QAAM,SAAS,6BAA6B,IAAI,EAAE;AAClD,MAAI,OAAQ,QAAO;AAEnB,QAAM,MAAM,GAAG,aAAa,wBAAwB;AACpD,MAAI,CAAC,IAAK,QAAO;AAEjB,QAAM,UAAU;AAAA,IACd,qBAAqB,IAAI,yBAAyB,KAAK,GAAG;AAAA,IAC1D,uBAAuB,IAAI,2BAA2B,KAAK,GAAG;AAAA,IAC9D,qBAAqB,IAAI,yBAAyB,KAAK,GAAG;AAAA,EAC5D;AACA,+BAA6B,IAAI,IAAI,OAAO;AAE5C,SAAO;AACT;AAEA,IAAM,kCAAkC,oBAAI,QAS1C;AACK,SAAS,qBAAqB,IAAQ;AAC3C,MAAI,cAAc,uBAAwB,QAAO;AAEjD,QAAM,SAAS,gCAAgC,IAAI,EAAE;AACrD,MAAI,OAAQ,QAAO;AAEnB,QAAM,MAAM,GAAG,aAAa,yBAAyB;AACrD,MAAI,CAAC,IAAK,QAAO;AAEjB,QAAM,UAAU;AAAA,IACd,iBAAiB,IAAI,mBAAmB,KAAK,GAAG;AAAA,IAChD,mBAAmB,IAAI,qBAAqB,KAAK,GAAG;AAAA,IACpD,mBAAmB,IAAI,qBAAqB,KAAK,GAAG;AAAA,EACtD;AACA,kCAAgC,IAAI,IAAI,OAAO;AAE/C,SAAO;AACT;","names":[]}
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
- import { V as ViewSchema, G as GL, a as ViewOptions, b as View, U as UniformSchema, c as UniformView, A as AttributeSchema, d as AttributeView, I as InterleavedAttributeSchema, e as InterleavedAttributeView, B as BufferSchema, f as BufferView } from './types-DaV9McmR.mjs';
2
- export { v as AttributeDefinition, u as AttributeKind, w as AttributeMethods, t as AttributeShortHand, a1 as AttributeToken, a2 as AttributeTokenFn, C as BufferDefinition, D as BufferMethods, a8 as CompileResult, R as Format, E as Framebuffer, F as FramebufferDefinition, _ as GLSL, Y as GLSLResult, Z as GLSLSlot, a6 as GLSLSlotsToSchema, a4 as GLSLToSchema, a5 as GLSLToView, g as GLTarget, l as GLTextureFilter, j as GLTextureFormat, i as GLTextureTarget, k as GLTextureType, m as GLTextureWrap, h as GLUsage, a3 as InterleaveToken, y as InterleavedAttributeDefinition, x as InterleavedAttributeLayout, z as InterleavedAttributeMethods, Q as InternalFormat, n as KIND_TO_SIZE_MAP, K as KIND_TO_UNIFORM_FN_NAME_MAP, a7 as MergeGLSLSchema, S as PixelType, W as TexImage2DOptions, T as TextureDefinition, L as TextureMethods, N as TextureParameterName, O as TextureParameterValue, P as TextureParameters, J as TextureSchema, H as TextureTarget, M as TextureView, q as UniformDefinition, o as UniformFnName, p as UniformKind, s as UniformMethods, r as UniformSchemaPartial, $ as UniformToken, a0 as UniformTokenFn, X as ViewSchemaPartial } from './types-DaV9McmR.mjs';
1
+ import { V as ViewSchema, G as GL, a as ViewOptions, b as View, U as UniformSchema, c as UniformView, A as AttributeSchema, d as AttributeView, I as InterleavedAttributeSchema, e as InterleavedAttributeView, B as BufferSchema, f as BufferView } from './types-CHXzeNxF.mjs';
2
+ export { v as AttributeDefinition, u as AttributeKind, w as AttributeMethods, t as AttributeShortHand, a2 as AttributeToken, a3 as AttributeTokenFn, C as BufferDefinition, D as BufferMethods, a9 as CompileResult, S as Format, E as Framebuffer, F as FramebufferDefinition, $ as GLSL, Z as GLSLResult, _ as GLSLSlot, a7 as GLSLSlotsToSchema, a5 as GLSLToSchema, a6 as GLSLToView, g as GLTarget, l as GLTextureFilter, j as GLTextureFormat, i as GLTextureTarget, k as GLTextureType, m as GLTextureWrap, h as GLUsage, a4 as InterleaveToken, y as InterleavedAttributeDefinition, x as InterleavedAttributeLayout, z as InterleavedAttributeMethods, Q as InternalFormat, n as KIND_TO_SIZE_MAP, K as KIND_TO_UNIFORM_FN_NAME_MAP, a8 as MergeGLSLSchema, W as PixelType, X as TexImage2DOptions, T as TextureDefinition, L as TextureMethods, N as TextureParameterName, O as TextureParameterValue, P as TextureParameters, J as TextureSchema, H as TextureTarget, M as TextureView, q as UniformDefinition, o as UniformFnName, p as UniformKind, s as UniformMethods, r as UniformSchemaPartial, a0 as UniformToken, a1 as UniformTokenFn, Y as ViewSchemaPartial } from './types-CHXzeNxF.mjs';
3
3
 
4
4
  declare function toID(key: string | number | symbol): any;
5
5
  /**********************************************************************************/
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- // src/features.ts
1
+ // src/gl.ts
2
2
  var INSTANCED_ARRAYS_WRAPPER_MAP = /* @__PURE__ */ new WeakMap();
3
3
  function getInstancedArrays(gl) {
4
4
  if (gl instanceof WebGL2RenderingContext) return gl;
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/features.ts","../src/utils/index.ts","../src/utils/object.ts","../src/index.ts"],"sourcesContent":["import { RemoveSuffix } from './type-utils'\nimport type { GL } from './types'\n\nconst INSTANCED_ARRAYS_WRAPPER_MAP = new WeakMap<\n GL,\n RemoveSuffix<\n Pick<\n ANGLE_instanced_arrays,\n 'drawArraysInstancedANGLE' | 'drawElementsInstancedANGLE' | 'vertexAttribDivisorANGLE'\n >,\n 'ANGLE'\n > | null\n>()\nexport function getInstancedArrays(gl: GL) {\n if (gl instanceof WebGL2RenderingContext) return gl\n\n const cached = INSTANCED_ARRAYS_WRAPPER_MAP.get(gl)\n if (cached) return cached\n\n const ext = gl.getExtension('ANGLE_instanced_arrays')\n if (!ext) return undefined\n\n const wrapper = {\n drawArraysInstanced: ext.drawArraysInstancedANGLE.bind(ext),\n drawElementsInstanced: ext.drawElementsInstancedANGLE.bind(ext),\n vertexAttribDivisor: ext.vertexAttribDivisorANGLE.bind(ext),\n }\n INSTANCED_ARRAYS_WRAPPER_MAP.set(gl, wrapper)\n\n return wrapper\n}\n\nconst VERTEX_ARRAY_OBJECT_WRAPPER_MAP = new WeakMap<\n GL,\n RemoveSuffix<\n Pick<\n OES_vertex_array_object,\n 'bindVertexArrayOES' | 'createVertexArrayOES' | 'deleteVertexArrayOES'\n >,\n 'OES'\n > | null\n>()\nexport function getVertexArrayObject(gl: GL) {\n if (gl instanceof WebGL2RenderingContext) return gl\n\n const cached = VERTEX_ARRAY_OBJECT_WRAPPER_MAP.get(gl)\n if (cached) return cached\n\n const ext = gl.getExtension('OES_vertex_array_object')\n if (!ext) return null\n\n const wrapper = {\n bindVertexArray: ext.bindVertexArrayOES.bind(ext),\n createVertexArray: ext.createVertexArrayOES.bind(ext),\n deleteVertexArray: ext.deleteVertexArrayOES.bind(ext),\n }\n VERTEX_ARRAY_OBJECT_WRAPPER_MAP.set(gl, wrapper)\n\n return wrapper\n}\n","import type {\n AttributeKind,\n FramebufferDefinition,\n GL,\n KIND_TO_SIZE_MAP,\n KIND_TO_UNIFORM_FN_NAME_MAP,\n TextureDefinition,\n UniformKind,\n} from '../types'\n\nexport function assertedNotNullish<T>(value: T, message?: string): NonNullable<T> {\n if (value === undefined || value === null) throw new Error(message)\n return value\n}\n\n/**********************************************************************************/\n/* */\n/* Kind To Uniform Name */\n/* */\n/**********************************************************************************/\n\nexport const kindToUniformFnName = <T extends UniformKind>(\n kind: T,\n): KIND_TO_UNIFORM_FN_NAME_MAP[T] => {\n switch (kind[0]) {\n // mat\n case 'm':\n return ('Matrix' + kind.slice(3) + 'fv') as KIND_TO_UNIFORM_FN_NAME_MAP[T]\n // sampler/booleans/integer\n case 's':\n case 'b':\n case 'i':\n return ((kind.match(/\\d/)?.[0] ?? '1') + 'i') as KIND_TO_UNIFORM_FN_NAME_MAP[T]\n // unsigned integers\n case 'u':\n return ((kind[4] || '1') + 'ui') as KIND_TO_UNIFORM_FN_NAME_MAP[T]\n // vec\n case 'v':\n return (kind[3] + 'f') as KIND_TO_UNIFORM_FN_NAME_MAP[T]\n default:\n switch (kind) {\n case 'float':\n return '1f' as KIND_TO_UNIFORM_FN_NAME_MAP[T]\n case 'uint':\n return '1ui' as KIND_TO_UNIFORM_FN_NAME_MAP[T]\n default:\n return '1i' as KIND_TO_UNIFORM_FN_NAME_MAP[T]\n }\n }\n}\n\n/**********************************************************************************/\n/* */\n/* Kind To Size */\n/* */\n/**********************************************************************************/\n\nexport const kindToSize = <T extends UniformKind>(kind: T): KIND_TO_SIZE_MAP[T] => {\n switch (kind[0]) {\n case 'm':\n const [a, b] = kind.match(/\\d+/g)!.map(Number) as [number, number?]\n return (a * (b ?? a)) as KIND_TO_SIZE_MAP[T]\n case 'v':\n case 'i':\n case 'b':\n case 'u':\n const match = kind.match(/\\d/) as [string] | undefined\n return (match ? +match[0] : 1) as KIND_TO_SIZE_MAP[T]\n default:\n return 1 as KIND_TO_SIZE_MAP[T]\n }\n}\n\n/**********************************************************************************/\n/* */\n/* Guards */\n/* */\n/**********************************************************************************/\n\nexport const isMatKind = <\n T extends UniformKind | AttributeKind,\n TPrefix extends string,\n TPostfix extends string,\n>(\n kind: T,\n): kind is T & `${TPrefix}mat${TPostfix}` => kind.includes('mat')\n\nexport const isSamplerKind = <TPrefix extends string, TPostfix extends string>(\n kind: UniformKind,\n): kind is UniformKind & `${TPrefix}sampler${TPostfix}` => kind.includes('sampler')\n\nexport const isVecKind = <TPrefix extends string, TPostfix extends string>(\n kind: UniformKind,\n): kind is UniformKind & `${TPrefix}vec${TPostfix}` => kind.includes('vec')\n\n/**********************************************************************************/\n/* */\n/* Create Texture */\n/* */\n/**********************************************************************************/\n\nexport function createTexture(\n gl: GL,\n {\n target = 'TEXTURE_2D',\n internalFormat = 'RGBA',\n format = 'RGBA',\n type = 'UNSIGNED_BYTE',\n minFilter = 'NEAREST',\n magFilter = 'NEAREST',\n wrapS = 'CLAMP_TO_EDGE',\n wrapT = 'CLAMP_TO_EDGE',\n width,\n height,\n }: TextureDefinition,\n data?: ArrayBufferView | null,\n): WebGLTexture {\n const texture = gl.createTexture()\n\n function getTextureConstant(name: string) {\n if (!(name in gl)) {\n throw new Error(`Attempted to create webgl2-only texture (${name}) in webgl1`)\n }\n return gl[name as keyof typeof gl] as any\n }\n\n gl.bindTexture(gl[target], texture)\n gl.texImage2D(\n gl[target],\n 0,\n getTextureConstant(internalFormat),\n width,\n height,\n 0,\n getTextureConstant(format),\n getTextureConstant(type),\n data ?? null,\n )\n\n console.log(minFilter)\n // Set texture parameters\n gl.texParameteri(gl[target], gl.TEXTURE_MIN_FILTER, gl[minFilter])\n gl.texParameteri(gl[target], gl.TEXTURE_MAG_FILTER, gl[magFilter])\n gl.texParameteri(gl[target], gl.TEXTURE_WRAP_S, gl[wrapS])\n gl.texParameteri(gl[target], gl.TEXTURE_WRAP_T, gl[wrapT])\n\n return texture\n}\n\n/**********************************************************************************/\n/* */\n/* Create Framebuffer */\n/* */\n/**********************************************************************************/\n\nconst FRAMEBUFFER_ATTACHMENT_MAP = {\n color: 'COLOR_ATTACHMENT0',\n depth: 'DEPTH_ATTACHMENT',\n stencil: 'STENCIL_ATTACHMENT',\n depthStencil: 'DEPTH_STENCIL_ATTACHMENT',\n} as const\n\nclass FramebufferError extends Error {\n constructor(gl: GL, status: number) {\n let errorMessage = `Framebuffer '${name}' not complete. Status: `\n switch (status) {\n case gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT:\n errorMessage += 'FRAMEBUFFER_INCOMPLETE_ATTACHMENT'\n break\n case gl.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:\n errorMessage += 'FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT'\n break\n case gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS:\n errorMessage += 'FRAMEBUFFER_INCOMPLETE_DIMENSIONS'\n break\n case gl.FRAMEBUFFER_UNSUPPORTED:\n errorMessage += 'FRAMEBUFFER_UNSUPPORTED'\n break\n default:\n errorMessage += `Unknown (${status})`\n }\n super(errorMessage)\n }\n}\n\nexport function createFramebuffer(\n gl: GL,\n { attachment, texture, ...options }: FramebufferDefinition,\n) {\n // Create texture for the framebuffer\n texture ??= createTexture(gl, options)\n\n // Create framebuffer\n const framebuffer = assertedNotNullish(\n gl.createFramebuffer(),\n `Failed to create framebuffer: ${name}`,\n )\n\n gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer)\n\n gl.framebufferTexture2D(\n gl.FRAMEBUFFER,\n // Determine attachment point based on attachment kind\n gl[FRAMEBUFFER_ATTACHMENT_MAP[attachment]],\n gl.TEXTURE_2D,\n texture,\n 0,\n )\n\n // Check framebuffer completeness\n const status = gl.checkFramebufferStatus(gl.FRAMEBUFFER)\n if (status !== gl.FRAMEBUFFER_COMPLETE) {\n throw new FramebufferError(gl, status)\n }\n\n return {\n texture,\n framebuffer,\n }\n}\n\n/**********************************************************************************/\n/* */\n/* Create Upsert */\n/* */\n/**********************************************************************************/\n\ntype UpsertMapKind<T, U> = Map<T, U> | (T extends WeakKey ? WeakMap<T, U> : never)\n\nexport function createUpsertMap<T extends UpsertMapKind<any, any> = Map<any, any>>(\n constructor?: new () => T,\n) {\n const map = new (constructor ?? Map)() as T\n return Object.assign(map, {\n getOrInsert(\n key: T extends UpsertMapKind<infer U, any> ? U : never,\n value: T extends UpsertMapKind<any, infer U> ? () => U : never,\n ) {\n let result = map.get(key)\n if (result) {\n return result\n }\n result = value()\n map.set(key, result)\n return result\n },\n })\n}\n","export function forEach<T extends Record<string, any>>(\n value: T,\n callback: (value: T[keyof T], key: keyof T, index: number) => void,\n) {\n let index = 0\n for (const key in value) {\n callback(value[key], key, index)\n index++\n }\n for (const key of Object.getOwnPropertySymbols(value)) {\n callback(value[key as keyof T], key as keyof T, index)\n index++\n }\n}\n\nexport function map<T extends Record<string, any>, TReturn>(\n value: T,\n callback: (value: T[keyof T], key: keyof T, index: number) => TReturn,\n): { [TKey in keyof T]: TReturn } {\n const result = {} as { [TKey in keyof T]: TReturn }\n\n forEach(value, (value, key, index) => {\n result[key] = callback(value, key, index)\n })\n\n return result\n}\n","import { getInstancedArrays, getVertexArrayObject } from './features'\nimport type {\n AttributeMethods,\n AttributeSchema,\n AttributeView,\n BufferSchema,\n BufferView,\n GL,\n UniformView as InferUniformView,\n InterleavedAttributeMethods,\n InterleavedAttributeSchema,\n InterleavedAttributeView,\n UniformSchema,\n View,\n ViewOptions,\n ViewSchema,\n} from './types'\nimport {\n assertedNotNullish,\n createUpsertMap,\n isMatKind,\n isSamplerKind,\n kindToSize,\n kindToUniformFnName,\n} from './utils'\nexport * from './types'\nimport * as ObjectUtils from \"./utils/object\"\n\n/**********************************************************************************/\n/* */\n/* To ID */\n/* */\n/**********************************************************************************/\n\nlet index = 0\nconst PREFIX = 'VIEW_GL_ALIAS'\nconst IS_FIREFOX = navigator.userAgent.toLowerCase().indexOf('firefox') >= 0\n\n// NOTE: using symbol as key for WeakMap is currently broken in firefox\n// see https://bugzilla.mozilla.org/show_bug.cgi?id=1710433\n// fallback to Map will currently cause a memory leak.\nconst SYMBOL_MAP = createUpsertMap(IS_FIREFOX ? Map<symbol, string> : WeakMap<symbol, string>)\n\nexport function toID(key: string | number | symbol) {\n if (typeof key === 'string') {\n return key\n }\n if (typeof key === 'symbol') {\n return SYMBOL_MAP.getOrInsert(key, () => `${PREFIX}_${index++}`)\n }\n return key.toString()\n}\n\n/**********************************************************************************/\n/* */\n/* View */\n/* */\n/**********************************************************************************/\n\nexport function view<TSchema extends ViewSchema>(\n gl: GL,\n program: WebGLProgram,\n schema: TSchema,\n options?: ViewOptions,\n): View<TSchema> {\n return {\n uniforms: !schema.uniforms ? undefined : uniformView(gl, program, schema.uniforms),\n attributes: !schema.attributes\n ? undefined\n : attributeView(gl, program, schema.attributes, options),\n interleavedAttributes: !schema.interleavedAttributes\n ? undefined\n : interleavedAttributeView(gl, program, schema.interleavedAttributes, options),\n buffers: !schema.buffers ? undefined : bufferView(gl, schema.buffers),\n } as View<TSchema>\n}\n\n/**********************************************************************************/\n/* */\n/* Uniform View */\n/* */\n/**********************************************************************************/\n\nexport function uniformView<T extends UniformSchema>(\n gl: GL,\n program: WebGLProgram,\n schema: T,\n): InferUniformView<T> {\n return ObjectUtils.map(schema, ({ kind, size }, key) => {\n const name = toID(key)\n\n const location = gl.getUniformLocation(program, name)\n\n if (isSamplerKind(kind)) {\n return {\n set(arg: number) {\n gl.uniform1i(location, arg)\n },\n }\n }\n\n const fnName = `uniform${kindToUniformFnName(kind)}${size ? 'v' : ''}`\n\n // @ts-ignore FIX WEBGL/WEBGL2 TYPES\n const fn = gl[fnName].bind(gl)\n\n if (isMatKind(kind)) {\n return {\n set(...args: any[]) {\n fn(location, false, args[0])\n },\n }\n }\n\n return {\n set(...args: any[]) {\n fn(location, ...args)\n },\n }\n })\n}\n\n/**********************************************************************************/\n/* */\n/* Attribute View */\n/* */\n/**********************************************************************************/\n\n// Shared attribute helper functions\n// between attributeView and interleavedAttributeView\nfunction handleAttribute(\n gl: GL,\n location: number,\n size: number,\n stride: number,\n offset: number,\n type: 'FLOAT' | 'INT',\n instanced?: boolean,\n) {\n gl.enableVertexAttribArray(location)\n gl.vertexAttribPointer(location, size, gl[type], false, stride, offset)\n\n if (instanced) {\n // Get instanced-arrays-feature: extension if webgl, gl if webgl2\n assertedNotNullish(getInstancedArrays(gl)).vertexAttribDivisor(location, 1)\n }\n}\n\nexport function attributeView<T extends AttributeSchema>(\n gl: GL,\n program: WebGLProgram,\n schema: T,\n { signal }: ViewOptions = {},\n): AttributeView<T> {\n const attributes = ObjectUtils.map(\n schema,\n (\n { kind, instanced, buffer = assertedNotNullish(gl.createBuffer()) },\n key,\n ): AttributeMethods => {\n const name = toID(key)\n\n const location = gl.getAttribLocation(program, name)\n if (location < 0) {\n throw new Error(`Attribute '${name}' not found`)\n }\n\n const size = kindToSize(kind)\n const type = kind.startsWith('i') ? 'INT' : 'FLOAT'\n\n return {\n buffer,\n bind() {\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer)\n handleAttribute(gl, location, size, 0, 0, type, instanced)\n },\n dispose() {\n gl.deleteBuffer(buffer)\n },\n set(data, usage = 'STATIC_DRAW') {\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer)\n gl.bufferData(gl.ARRAY_BUFFER, data, gl[usage])\n return this\n },\n }\n },\n )\n\n signal?.addEventListener('abort', function dispose() {\n ObjectUtils.forEach(attributes, value => value.dispose())\n })\n\n return attributes\n}\n\n/**********************************************************************************/\n/* */\n/* Interleaved Attribute View */\n/* */\n/**********************************************************************************/\n\nexport function interleavedAttributeView<T extends InterleavedAttributeSchema>(\n gl: GL,\n program: WebGLProgram,\n schema: T,\n { signal }: ViewOptions = {},\n): InterleavedAttributeView<T> {\n // Initialize interleaved attributes\n const interleavedAttributes = ObjectUtils.map(schema, ({ layout, instanced }) => {\n // Increment number to keep track of offset\n let index = 0\n\n // Calculate layout information\n const handles = layout.map(layout => {\n const name = toID(layout.key)\n\n const location = gl.getAttribLocation(program, name)\n\n if (location < 0) {\n throw new Error(`Attribute '${name}' not found`)\n }\n\n const size = kindToSize(layout.kind)\n const offset = index\n const type = layout.kind.startsWith('i') ? 'INT' : 'FLOAT'\n index += size * 4\n\n return () => handleAttribute(gl, location, size, stride, offset, type, instanced)\n })\n\n // Set stride to final index\n const stride = index\n\n // Create a buffer\n const buffer = assertedNotNullish(gl.createBuffer())\n\n // Create VAO to cache attribute state\n let vao: { unbind(): void; bind(): void; dispose(): void } | undefined = undefined\n\n // Get VAO-feature: extension if webgl1, gl if webgl2\n const feature = getVertexArrayObject(gl)\n if (feature) {\n const vertexArray = feature.createVertexArray()\n feature.bindVertexArray(vertexArray)\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer)\n for (const handle of handles) {\n handle()\n }\n feature.bindVertexArray(null)\n vao = {\n unbind() {\n feature.bindVertexArray(null)\n },\n bind() {\n feature.bindVertexArray(vertexArray)\n },\n dispose() {\n feature.deleteVertexArray(vertexArray)\n },\n }\n }\n\n return {\n bind() {\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer)\n if (vao) {\n vao.bind()\n } else {\n // Fallback: manual attribute setup\n for (const handle of handles) {\n handle()\n }\n }\n },\n unbind() {\n if (vao) {\n vao.unbind()\n }\n },\n dispose() {\n gl.deleteBuffer(buffer)\n if (vao) {\n vao.dispose()\n }\n },\n set(value, usage = 'STATIC_DRAW') {\n if (vao) {\n vao.bind()\n } else {\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer)\n }\n gl.bufferData(gl.ARRAY_BUFFER, value, gl[usage])\n if (vao) {\n vao.unbind()\n }\n },\n } satisfies InterleavedAttributeMethods\n })\n\n signal?.addEventListener('abort', function dispose() {\n ObjectUtils.forEach(interleavedAttributes, value => value.dispose())\n })\n\n return interleavedAttributes\n}\n\n/**********************************************************************************/\n/* */\n/* Buffer View */\n/* */\n/**********************************************************************************/\n\nexport function bufferView<T extends BufferSchema>(\n gl: GL,\n schema: T,\n { signal }: ViewOptions = {},\n): BufferView<T> {\n // Initialize buffers\n const buffers = ObjectUtils.map(schema, ({ target = 'ARRAY_BUFFER', usage = 'STATIC_DRAW' }) => {\n const buffer = assertedNotNullish(gl.createBuffer())\n return {\n bind() {\n gl.bindBuffer(gl[target], buffer)\n },\n dispose() {\n gl.deleteBuffer(buffer)\n },\n set(data: Float32Array) {\n gl.bindBuffer(gl[target], buffer)\n gl.bufferData(gl[target], data, gl[usage])\n },\n }\n })\n\n signal?.addEventListener('abort', function dispose() {\n ObjectUtils.forEach(buffers, value => value.dispose())\n })\n\n return buffers\n}\n"],"mappings":"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","names":["map","index","value","name","index","layout"]}
1
+ {"version":3,"sources":["../src/gl.ts","../src/utils/index.ts","../src/utils/object.ts","../src/index.ts"],"sourcesContent":["import { RemoveSuffix } from './type-utils'\nimport { GL } from './types'\n\nexport function createShader(gl: GL, type: number, source: string): WebGLShader {\n const shader = gl.createShader(type)\n if (!shader) throw new Error('Failed to create shader')\n\n gl.shaderSource(shader, source)\n gl.compileShader(shader)\n\n if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n const info = gl.getShaderInfoLog(shader)\n gl.deleteShader(shader)\n throw new Error(\n `Failed to compile ${type === gl.VERTEX_SHADER ? 'vertex' : 'fragment'} shader: ${info}`,\n )\n }\n\n return shader\n}\n\nexport function createProgram(gl: GL, vertexSource: string, fragmentSource: string): WebGLProgram {\n const program = gl.createProgram()\n if (!program) throw new Error('Failed to create WebGL program')\n\n const vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexSource)\n const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentSource)\n\n gl.attachShader(program, vertexShader)\n gl.attachShader(program, fragmentShader)\n gl.linkProgram(program)\n\n if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n const info = gl.getProgramInfoLog(program)\n gl.deleteProgram(program)\n gl.deleteShader(vertexShader)\n gl.deleteShader(fragmentShader)\n throw new Error(`Failed to link program: ${info}`)\n }\n\n // Clean up shaders after linking\n gl.deleteShader(vertexShader)\n gl.deleteShader(fragmentShader)\n\n return program\n}\n\nconst INSTANCED_ARRAYS_WRAPPER_MAP = new WeakMap<\n GL,\n RemoveSuffix<\n Pick<\n ANGLE_instanced_arrays,\n 'drawArraysInstancedANGLE' | 'drawElementsInstancedANGLE' | 'vertexAttribDivisorANGLE'\n >,\n 'ANGLE'\n > | null\n>()\nexport function getInstancedArrays(gl: GL) {\n if (gl instanceof WebGL2RenderingContext) return gl\n\n const cached = INSTANCED_ARRAYS_WRAPPER_MAP.get(gl)\n if (cached) return cached\n\n const ext = gl.getExtension('ANGLE_instanced_arrays')\n if (!ext) return undefined\n\n const wrapper = {\n drawArraysInstanced: ext.drawArraysInstancedANGLE.bind(ext),\n drawElementsInstanced: ext.drawElementsInstancedANGLE.bind(ext),\n vertexAttribDivisor: ext.vertexAttribDivisorANGLE.bind(ext),\n }\n INSTANCED_ARRAYS_WRAPPER_MAP.set(gl, wrapper)\n\n return wrapper\n}\n\nconst VERTEX_ARRAY_OBJECT_WRAPPER_MAP = new WeakMap<\n GL,\n RemoveSuffix<\n Pick<\n OES_vertex_array_object,\n 'bindVertexArrayOES' | 'createVertexArrayOES' | 'deleteVertexArrayOES'\n >,\n 'OES'\n > | null\n>()\nexport function getVertexArrayObject(gl: GL) {\n if (gl instanceof WebGL2RenderingContext) return gl\n\n const cached = VERTEX_ARRAY_OBJECT_WRAPPER_MAP.get(gl)\n if (cached) return cached\n\n const ext = gl.getExtension('OES_vertex_array_object')\n if (!ext) return null\n\n const wrapper = {\n bindVertexArray: ext.bindVertexArrayOES.bind(ext),\n createVertexArray: ext.createVertexArrayOES.bind(ext),\n deleteVertexArray: ext.deleteVertexArrayOES.bind(ext),\n }\n VERTEX_ARRAY_OBJECT_WRAPPER_MAP.set(gl, wrapper)\n\n return wrapper\n}\n","import type {\n AttributeKind,\n FramebufferDefinition,\n GL,\n KIND_TO_SIZE_MAP,\n KIND_TO_UNIFORM_FN_NAME_MAP,\n TextureDefinition,\n UniformKind,\n} from '../types'\n\nexport function assertedNotNullish<T>(value: T, message?: string): NonNullable<T> {\n if (value === undefined || value === null) throw new Error(message)\n return value\n}\n\n/**********************************************************************************/\n/* */\n/* Kind To Uniform Name */\n/* */\n/**********************************************************************************/\n\nexport const kindToUniformFnName = <T extends UniformKind>(\n kind: T,\n): KIND_TO_UNIFORM_FN_NAME_MAP[T] => {\n switch (kind[0]) {\n // mat\n case 'm':\n return ('Matrix' + kind.slice(3) + 'fv') as KIND_TO_UNIFORM_FN_NAME_MAP[T]\n // sampler/booleans/integer\n case 's':\n case 'b':\n case 'i':\n return ((kind.match(/\\d/)?.[0] ?? '1') + 'i') as KIND_TO_UNIFORM_FN_NAME_MAP[T]\n // unsigned integers\n case 'u':\n return ((kind[4] || '1') + 'ui') as KIND_TO_UNIFORM_FN_NAME_MAP[T]\n // vec\n case 'v':\n return (kind[3] + 'f') as KIND_TO_UNIFORM_FN_NAME_MAP[T]\n default:\n switch (kind) {\n case 'float':\n return '1f' as KIND_TO_UNIFORM_FN_NAME_MAP[T]\n case 'uint':\n return '1ui' as KIND_TO_UNIFORM_FN_NAME_MAP[T]\n default:\n return '1i' as KIND_TO_UNIFORM_FN_NAME_MAP[T]\n }\n }\n}\n\n/**********************************************************************************/\n/* */\n/* Kind To Size */\n/* */\n/**********************************************************************************/\n\nexport const kindToSize = <T extends UniformKind>(kind: T): KIND_TO_SIZE_MAP[T] => {\n switch (kind[0]) {\n case 'm':\n const [a, b] = kind.match(/\\d+/g)!.map(Number) as [number, number?]\n return (a * (b ?? a)) as KIND_TO_SIZE_MAP[T]\n case 'v':\n case 'i':\n case 'b':\n case 'u':\n const match = kind.match(/\\d/) as [string] | undefined\n return (match ? +match[0] : 1) as KIND_TO_SIZE_MAP[T]\n default:\n return 1 as KIND_TO_SIZE_MAP[T]\n }\n}\n\n/**********************************************************************************/\n/* */\n/* Guards */\n/* */\n/**********************************************************************************/\n\nexport const isMatKind = <\n T extends UniformKind | AttributeKind,\n TPrefix extends string,\n TPostfix extends string,\n>(\n kind: T,\n): kind is T & `${TPrefix}mat${TPostfix}` => kind.includes('mat')\n\nexport const isSamplerKind = <TPrefix extends string, TPostfix extends string>(\n kind: UniformKind,\n): kind is UniformKind & `${TPrefix}sampler${TPostfix}` => kind.includes('sampler')\n\nexport const isVecKind = <TPrefix extends string, TPostfix extends string>(\n kind: UniformKind,\n): kind is UniformKind & `${TPrefix}vec${TPostfix}` => kind.includes('vec')\n\n/**********************************************************************************/\n/* */\n/* Create Texture */\n/* */\n/**********************************************************************************/\n\nexport function createTexture(\n gl: GL,\n {\n target = 'TEXTURE_2D',\n internalFormat = 'RGBA',\n format = 'RGBA',\n type = 'UNSIGNED_BYTE',\n minFilter = 'NEAREST',\n magFilter = 'NEAREST',\n wrapS = 'CLAMP_TO_EDGE',\n wrapT = 'CLAMP_TO_EDGE',\n width,\n height,\n }: TextureDefinition,\n data?: ArrayBufferView | null,\n): WebGLTexture {\n const texture = gl.createTexture()\n\n function getTextureConstant(name: string) {\n if (!(name in gl)) {\n throw new Error(`Attempted to create webgl2-only texture (${name}) in webgl1`)\n }\n return gl[name as keyof typeof gl] as any\n }\n\n gl.bindTexture(gl[target], texture)\n gl.texImage2D(\n gl[target],\n 0,\n getTextureConstant(internalFormat),\n width,\n height,\n 0,\n getTextureConstant(format),\n getTextureConstant(type),\n data ?? null,\n )\n\n console.log(minFilter)\n // Set texture parameters\n gl.texParameteri(gl[target], gl.TEXTURE_MIN_FILTER, gl[minFilter])\n gl.texParameteri(gl[target], gl.TEXTURE_MAG_FILTER, gl[magFilter])\n gl.texParameteri(gl[target], gl.TEXTURE_WRAP_S, gl[wrapS])\n gl.texParameteri(gl[target], gl.TEXTURE_WRAP_T, gl[wrapT])\n\n return texture\n}\n\n/**********************************************************************************/\n/* */\n/* Create Framebuffer */\n/* */\n/**********************************************************************************/\n\nconst FRAMEBUFFER_ATTACHMENT_MAP = {\n color: 'COLOR_ATTACHMENT0',\n depth: 'DEPTH_ATTACHMENT',\n stencil: 'STENCIL_ATTACHMENT',\n depthStencil: 'DEPTH_STENCIL_ATTACHMENT',\n} as const\n\nclass FramebufferError extends Error {\n constructor(gl: GL, status: number) {\n let errorMessage = `Framebuffer '${name}' not complete. Status: `\n switch (status) {\n case gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT:\n errorMessage += 'FRAMEBUFFER_INCOMPLETE_ATTACHMENT'\n break\n case gl.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:\n errorMessage += 'FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT'\n break\n case gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS:\n errorMessage += 'FRAMEBUFFER_INCOMPLETE_DIMENSIONS'\n break\n case gl.FRAMEBUFFER_UNSUPPORTED:\n errorMessage += 'FRAMEBUFFER_UNSUPPORTED'\n break\n default:\n errorMessage += `Unknown (${status})`\n }\n super(errorMessage)\n }\n}\n\nexport function createFramebuffer(\n gl: GL,\n { attachment, texture, ...options }: FramebufferDefinition,\n) {\n // Create texture for the framebuffer\n texture ??= createTexture(gl, options)\n\n // Create framebuffer\n const framebuffer = assertedNotNullish(\n gl.createFramebuffer(),\n `Failed to create framebuffer: ${name}`,\n )\n\n gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer)\n\n gl.framebufferTexture2D(\n gl.FRAMEBUFFER,\n // Determine attachment point based on attachment kind\n gl[FRAMEBUFFER_ATTACHMENT_MAP[attachment]],\n gl.TEXTURE_2D,\n texture,\n 0,\n )\n\n // Check framebuffer completeness\n const status = gl.checkFramebufferStatus(gl.FRAMEBUFFER)\n if (status !== gl.FRAMEBUFFER_COMPLETE) {\n throw new FramebufferError(gl, status)\n }\n\n return {\n texture,\n framebuffer,\n }\n}\n\n/**********************************************************************************/\n/* */\n/* Create Upsert */\n/* */\n/**********************************************************************************/\n\ntype UpsertMapKind<T, U> = Map<T, U> | (T extends WeakKey ? WeakMap<T, U> : never)\n\nexport function createUpsertMap<T extends UpsertMapKind<any, any> = Map<any, any>>(\n constructor?: new () => T,\n) {\n const map = new (constructor ?? Map)() as T\n return Object.assign(map, {\n getOrInsert(\n key: T extends UpsertMapKind<infer U, any> ? U : never,\n value: T extends UpsertMapKind<any, infer U> ? () => U : never,\n ) {\n let result = map.get(key)\n if (result) {\n return result\n }\n result = value()\n map.set(key, result)\n return result\n },\n })\n}\n","export function forEach<T extends Record<string, any>>(\n value: T,\n callback: (value: T[keyof T], key: keyof T, index: number) => void,\n) {\n let index = 0\n for (const key in value) {\n callback(value[key], key, index)\n index++\n }\n for (const key of Object.getOwnPropertySymbols(value)) {\n callback(value[key as keyof T], key as keyof T, index)\n index++\n }\n}\n\nexport function map<T extends Record<string, any>, TReturn>(\n value: T,\n callback: (value: T[keyof T], key: keyof T, index: number) => TReturn,\n): { [TKey in keyof T]: TReturn } {\n const result = {} as { [TKey in keyof T]: TReturn }\n\n forEach(value, (value, key, index) => {\n result[key] = callback(value, key, index)\n })\n\n return result\n}\n","import { getInstancedArrays, getVertexArrayObject } from './gl'\nimport type {\n AttributeMethods,\n AttributeSchema,\n AttributeView,\n BufferSchema,\n BufferView,\n GL,\n UniformView as InferUniformView,\n InterleavedAttributeMethods,\n InterleavedAttributeSchema,\n InterleavedAttributeView,\n UniformSchema,\n View,\n ViewOptions,\n ViewSchema,\n} from './types'\nimport {\n assertedNotNullish,\n createUpsertMap,\n isMatKind,\n isSamplerKind,\n kindToSize,\n kindToUniformFnName,\n} from './utils'\nexport * from './types'\nimport * as ObjectUtils from './utils/object'\n\n/**********************************************************************************/\n/* */\n/* To ID */\n/* */\n/**********************************************************************************/\n\nlet index = 0\nconst PREFIX = 'VIEW_GL_ALIAS'\nconst IS_FIREFOX = navigator.userAgent.toLowerCase().indexOf('firefox') >= 0\n\n// NOTE: using symbol as key for WeakMap is currently broken in firefox\n// see https://bugzilla.mozilla.org/show_bug.cgi?id=1710433\n// fallback to Map will currently cause a memory leak.\nconst SYMBOL_MAP = createUpsertMap(IS_FIREFOX ? Map<symbol, string> : WeakMap<symbol, string>)\n\nexport function toID(key: string | number | symbol) {\n if (typeof key === 'string') {\n return key\n }\n if (typeof key === 'symbol') {\n return SYMBOL_MAP.getOrInsert(key, () => `${PREFIX}_${index++}`)\n }\n return key.toString()\n}\n\n/**********************************************************************************/\n/* */\n/* View */\n/* */\n/**********************************************************************************/\n\nexport function view<TSchema extends ViewSchema>(\n gl: GL,\n program: WebGLProgram,\n schema: TSchema,\n options?: ViewOptions,\n): View<TSchema> {\n return {\n uniforms: !schema.uniforms ? undefined : uniformView(gl, program, schema.uniforms),\n attributes: !schema.attributes\n ? undefined\n : attributeView(gl, program, schema.attributes, options),\n interleavedAttributes: !schema.interleavedAttributes\n ? undefined\n : interleavedAttributeView(gl, program, schema.interleavedAttributes, options),\n buffers: !schema.buffers ? undefined : bufferView(gl, schema.buffers),\n } as View<TSchema>\n}\n\n/**********************************************************************************/\n/* */\n/* Uniform View */\n/* */\n/**********************************************************************************/\n\nexport function uniformView<T extends UniformSchema>(\n gl: GL,\n program: WebGLProgram,\n schema: T,\n): InferUniformView<T> {\n return ObjectUtils.map(schema, ({ kind, size }, key) => {\n const name = toID(key)\n\n const location = gl.getUniformLocation(program, name)\n\n if (isSamplerKind(kind)) {\n return {\n set(arg: number) {\n gl.uniform1i(location, arg)\n },\n }\n }\n\n const fnName = `uniform${kindToUniformFnName(kind)}${size ? 'v' : ''}`\n\n // @ts-ignore FIX WEBGL/WEBGL2 TYPES\n const fn = gl[fnName].bind(gl)\n\n if (isMatKind(kind)) {\n return {\n set(...args: any[]) {\n fn(location, false, args[0])\n },\n }\n }\n\n return {\n set(...args: any[]) {\n fn(location, ...args)\n },\n }\n })\n}\n\n/**********************************************************************************/\n/* */\n/* Attribute View */\n/* */\n/**********************************************************************************/\n\n// Shared attribute helper functions\n// between attributeView and interleavedAttributeView\nfunction handleAttribute(\n gl: GL,\n location: number,\n size: number,\n stride: number,\n offset: number,\n type: 'FLOAT' | 'INT',\n instanced?: boolean,\n) {\n gl.enableVertexAttribArray(location)\n gl.vertexAttribPointer(location, size, gl[type], false, stride, offset)\n\n if (instanced) {\n // Get instanced-arrays-feature: extension if webgl, gl if webgl2\n assertedNotNullish(getInstancedArrays(gl)).vertexAttribDivisor(location, 1)\n }\n}\n\nexport function attributeView<T extends AttributeSchema>(\n gl: GL,\n program: WebGLProgram,\n schema: T,\n { signal }: ViewOptions = {},\n): AttributeView<T> {\n const attributes = ObjectUtils.map(\n schema,\n (\n { kind, instanced, buffer = assertedNotNullish(gl.createBuffer()) },\n key,\n ): AttributeMethods => {\n const name = toID(key)\n\n const location = gl.getAttribLocation(program, name)\n if (location < 0) {\n throw new Error(`Attribute '${name}' not found`)\n }\n\n const size = kindToSize(kind)\n const type = kind.startsWith('i') ? 'INT' : 'FLOAT'\n\n return {\n buffer,\n bind() {\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer)\n handleAttribute(gl, location, size, 0, 0, type, instanced)\n },\n dispose() {\n gl.deleteBuffer(buffer)\n },\n set(data, usage = 'STATIC_DRAW') {\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer)\n gl.bufferData(gl.ARRAY_BUFFER, data, gl[usage])\n return this\n },\n }\n },\n )\n\n signal?.addEventListener('abort', function dispose() {\n ObjectUtils.forEach(attributes, value => value.dispose())\n })\n\n return attributes\n}\n\n/**********************************************************************************/\n/* */\n/* Interleaved Attribute View */\n/* */\n/**********************************************************************************/\n\nexport function interleavedAttributeView<T extends InterleavedAttributeSchema>(\n gl: GL,\n program: WebGLProgram,\n schema: T,\n { signal }: ViewOptions = {},\n): InterleavedAttributeView<T> {\n // Initialize interleaved attributes\n const interleavedAttributes = ObjectUtils.map(schema, ({ layout, instanced }) => {\n // Increment number to keep track of offset\n let index = 0\n\n // Calculate layout information\n const handles = layout.map(layout => {\n const name = toID(layout.key)\n\n const location = gl.getAttribLocation(program, name)\n\n if (location < 0) {\n throw new Error(`Attribute '${name}' not found`)\n }\n\n const size = kindToSize(layout.kind)\n const offset = index\n const type = layout.kind.startsWith('i') ? 'INT' : 'FLOAT'\n index += size * 4\n\n return () => handleAttribute(gl, location, size, stride, offset, type, instanced)\n })\n\n // Set stride to final index\n const stride = index\n\n // Create a buffer\n const buffer = assertedNotNullish(gl.createBuffer())\n\n // Create VAO to cache attribute state\n let vao: { unbind(): void; bind(): void; dispose(): void } | undefined = undefined\n\n // Get VAO-feature: extension if webgl1, gl if webgl2\n const feature = getVertexArrayObject(gl)\n if (feature) {\n const vertexArray = feature.createVertexArray()\n feature.bindVertexArray(vertexArray)\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer)\n for (const handle of handles) {\n handle()\n }\n feature.bindVertexArray(null)\n vao = {\n unbind() {\n feature.bindVertexArray(null)\n },\n bind() {\n feature.bindVertexArray(vertexArray)\n },\n dispose() {\n feature.deleteVertexArray(vertexArray)\n },\n }\n }\n\n return {\n bind() {\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer)\n if (vao) {\n vao.bind()\n } else {\n // Fallback: manual attribute setup\n for (const handle of handles) {\n handle()\n }\n }\n },\n unbind() {\n if (vao) {\n vao.unbind()\n }\n },\n dispose() {\n gl.deleteBuffer(buffer)\n if (vao) {\n vao.dispose()\n }\n },\n set(value, usage = 'STATIC_DRAW') {\n if (vao) {\n vao.bind()\n } else {\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer)\n }\n gl.bufferData(gl.ARRAY_BUFFER, value, gl[usage])\n if (vao) {\n vao.unbind()\n }\n },\n } satisfies InterleavedAttributeMethods\n })\n\n signal?.addEventListener('abort', function dispose() {\n ObjectUtils.forEach(interleavedAttributes, value => value.dispose())\n })\n\n return interleavedAttributes\n}\n\n/**********************************************************************************/\n/* */\n/* Buffer View */\n/* */\n/**********************************************************************************/\n\nexport function bufferView<T extends BufferSchema>(\n gl: GL,\n schema: T,\n { signal }: ViewOptions = {},\n): BufferView<T> {\n // Initialize buffers\n const buffers = ObjectUtils.map(schema, ({ target = 'ARRAY_BUFFER', usage = 'STATIC_DRAW' }) => {\n const buffer = assertedNotNullish(gl.createBuffer())\n return {\n bind() {\n gl.bindBuffer(gl[target], buffer)\n },\n dispose() {\n gl.deleteBuffer(buffer)\n },\n set(data: Float32Array) {\n gl.bindBuffer(gl[target], buffer)\n gl.bufferData(gl[target], data, gl[usage])\n },\n }\n })\n\n signal?.addEventListener('abort', function dispose() {\n ObjectUtils.forEach(buffers, value => value.dispose())\n })\n\n return buffers\n}\n"],"mappings":"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","names":["map","index","value","name","index","layout"]}
package/dist/tag.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { Z as GLSLSlot, _ as GLSL, a0 as UniformTokenFn, a2 as AttributeTokenFn, a1 as AttributeToken, u as AttributeKind, v as AttributeDefinition, a3 as InterleaveToken, X as ViewSchemaPartial, a8 as CompileResult, a9 as Prettify, a4 as GLSLToSchema, G as GL } from './types-DaV9McmR.mjs';
1
+ import { _ as GLSLSlot, $ as GLSL, a1 as UniformTokenFn, a3 as AttributeTokenFn, a2 as AttributeToken, u as AttributeKind, v as AttributeDefinition, a4 as InterleaveToken, Y as ViewSchemaPartial, a9 as CompileResult, aa as Prettify, a5 as GLSLToSchema, G as GL } from './types-CHXzeNxF.mjs';
2
2
 
3
3
  declare function glsl<TSlot extends GLSLSlot, TSlots extends TSlot[]>(template: TemplateStringsArray, ...slots: [...TSlots]): GLSL<TSlots>;
4
4
  declare const uniform: {
package/dist/tag.mjs CHANGED
@@ -1,4 +1,37 @@
1
- // src/features.ts
1
+ // src/gl.ts
2
+ function createShader(gl, type, source) {
3
+ const shader = gl.createShader(type);
4
+ if (!shader) throw new Error("Failed to create shader");
5
+ gl.shaderSource(shader, source);
6
+ gl.compileShader(shader);
7
+ if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
8
+ const info = gl.getShaderInfoLog(shader);
9
+ gl.deleteShader(shader);
10
+ throw new Error(
11
+ `Failed to compile ${type === gl.VERTEX_SHADER ? "vertex" : "fragment"} shader: ${info}`
12
+ );
13
+ }
14
+ return shader;
15
+ }
16
+ function createProgram(gl, vertexSource, fragmentSource) {
17
+ const program = gl.createProgram();
18
+ if (!program) throw new Error("Failed to create WebGL program");
19
+ const vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexSource);
20
+ const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentSource);
21
+ gl.attachShader(program, vertexShader);
22
+ gl.attachShader(program, fragmentShader);
23
+ gl.linkProgram(program);
24
+ if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
25
+ const info = gl.getProgramInfoLog(program);
26
+ gl.deleteProgram(program);
27
+ gl.deleteShader(vertexShader);
28
+ gl.deleteShader(fragmentShader);
29
+ throw new Error(`Failed to link program: ${info}`);
30
+ }
31
+ gl.deleteShader(vertexShader);
32
+ gl.deleteShader(fragmentShader);
33
+ return program;
34
+ }
2
35
  var INSTANCED_ARRAYS_WRAPPER_MAP = /* @__PURE__ */ new WeakMap();
3
36
  function getInstancedArrays(gl) {
4
37
  if (gl instanceof WebGL2RenderingContext) return gl;
@@ -304,41 +337,6 @@ function bufferView(gl, schema, { signal } = {}) {
304
337
  return buffers;
305
338
  }
306
339
 
307
- // src/gl.ts
308
- function createShader(gl, type, source) {
309
- const shader = gl.createShader(type);
310
- if (!shader) throw new Error("Failed to create shader");
311
- gl.shaderSource(shader, source);
312
- gl.compileShader(shader);
313
- if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
314
- const info = gl.getShaderInfoLog(shader);
315
- gl.deleteShader(shader);
316
- throw new Error(
317
- `Failed to compile ${type === gl.VERTEX_SHADER ? "vertex" : "fragment"} shader: ${info}`
318
- );
319
- }
320
- return shader;
321
- }
322
- function createProgram(gl, vertexSource, fragmentSource) {
323
- const program = gl.createProgram();
324
- if (!program) throw new Error("Failed to create WebGL program");
325
- const vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexSource);
326
- const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentSource);
327
- gl.attachShader(program, vertexShader);
328
- gl.attachShader(program, fragmentShader);
329
- gl.linkProgram(program);
330
- if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
331
- const info = gl.getProgramInfoLog(program);
332
- gl.deleteProgram(program);
333
- gl.deleteShader(vertexShader);
334
- gl.deleteShader(fragmentShader);
335
- throw new Error(`Failed to link program: ${info}`);
336
- }
337
- gl.deleteShader(vertexShader);
338
- gl.deleteShader(fragmentShader);
339
- return program;
340
- }
341
-
342
340
  // src/tag.ts
343
341
  function glsl(template, ...slots) {
344
342
  return { template, slots, type: "glsl" };
package/dist/tag.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/features.ts","../src/utils/index.ts","../src/utils/object.ts","../src/index.ts","../src/gl.ts","../src/tag.ts"],"sourcesContent":["import { RemoveSuffix } from './type-utils'\nimport type { GL } from './types'\n\nconst INSTANCED_ARRAYS_WRAPPER_MAP = new WeakMap<\n GL,\n RemoveSuffix<\n Pick<\n ANGLE_instanced_arrays,\n 'drawArraysInstancedANGLE' | 'drawElementsInstancedANGLE' | 'vertexAttribDivisorANGLE'\n >,\n 'ANGLE'\n > | null\n>()\nexport function getInstancedArrays(gl: GL) {\n if (gl instanceof WebGL2RenderingContext) return gl\n\n const cached = INSTANCED_ARRAYS_WRAPPER_MAP.get(gl)\n if (cached) return cached\n\n const ext = gl.getExtension('ANGLE_instanced_arrays')\n if (!ext) return undefined\n\n const wrapper = {\n drawArraysInstanced: ext.drawArraysInstancedANGLE.bind(ext),\n drawElementsInstanced: ext.drawElementsInstancedANGLE.bind(ext),\n vertexAttribDivisor: ext.vertexAttribDivisorANGLE.bind(ext),\n }\n INSTANCED_ARRAYS_WRAPPER_MAP.set(gl, wrapper)\n\n return wrapper\n}\n\nconst VERTEX_ARRAY_OBJECT_WRAPPER_MAP = new WeakMap<\n GL,\n RemoveSuffix<\n Pick<\n OES_vertex_array_object,\n 'bindVertexArrayOES' | 'createVertexArrayOES' | 'deleteVertexArrayOES'\n >,\n 'OES'\n > | null\n>()\nexport function getVertexArrayObject(gl: GL) {\n if (gl instanceof WebGL2RenderingContext) return gl\n\n const cached = VERTEX_ARRAY_OBJECT_WRAPPER_MAP.get(gl)\n if (cached) return cached\n\n const ext = gl.getExtension('OES_vertex_array_object')\n if (!ext) return null\n\n const wrapper = {\n bindVertexArray: ext.bindVertexArrayOES.bind(ext),\n createVertexArray: ext.createVertexArrayOES.bind(ext),\n deleteVertexArray: ext.deleteVertexArrayOES.bind(ext),\n }\n VERTEX_ARRAY_OBJECT_WRAPPER_MAP.set(gl, wrapper)\n\n return wrapper\n}\n","import type {\n AttributeKind,\n FramebufferDefinition,\n GL,\n KIND_TO_SIZE_MAP,\n KIND_TO_UNIFORM_FN_NAME_MAP,\n TextureDefinition,\n UniformKind,\n} from '../types'\n\nexport function assertedNotNullish<T>(value: T, message?: string): NonNullable<T> {\n if (value === undefined || value === null) throw new Error(message)\n return value\n}\n\n/**********************************************************************************/\n/* */\n/* Kind To Uniform Name */\n/* */\n/**********************************************************************************/\n\nexport const kindToUniformFnName = <T extends UniformKind>(\n kind: T,\n): KIND_TO_UNIFORM_FN_NAME_MAP[T] => {\n switch (kind[0]) {\n // mat\n case 'm':\n return ('Matrix' + kind.slice(3) + 'fv') as KIND_TO_UNIFORM_FN_NAME_MAP[T]\n // sampler/booleans/integer\n case 's':\n case 'b':\n case 'i':\n return ((kind.match(/\\d/)?.[0] ?? '1') + 'i') as KIND_TO_UNIFORM_FN_NAME_MAP[T]\n // unsigned integers\n case 'u':\n return ((kind[4] || '1') + 'ui') as KIND_TO_UNIFORM_FN_NAME_MAP[T]\n // vec\n case 'v':\n return (kind[3] + 'f') as KIND_TO_UNIFORM_FN_NAME_MAP[T]\n default:\n switch (kind) {\n case 'float':\n return '1f' as KIND_TO_UNIFORM_FN_NAME_MAP[T]\n case 'uint':\n return '1ui' as KIND_TO_UNIFORM_FN_NAME_MAP[T]\n default:\n return '1i' as KIND_TO_UNIFORM_FN_NAME_MAP[T]\n }\n }\n}\n\n/**********************************************************************************/\n/* */\n/* Kind To Size */\n/* */\n/**********************************************************************************/\n\nexport const kindToSize = <T extends UniformKind>(kind: T): KIND_TO_SIZE_MAP[T] => {\n switch (kind[0]) {\n case 'm':\n const [a, b] = kind.match(/\\d+/g)!.map(Number) as [number, number?]\n return (a * (b ?? a)) as KIND_TO_SIZE_MAP[T]\n case 'v':\n case 'i':\n case 'b':\n case 'u':\n const match = kind.match(/\\d/) as [string] | undefined\n return (match ? +match[0] : 1) as KIND_TO_SIZE_MAP[T]\n default:\n return 1 as KIND_TO_SIZE_MAP[T]\n }\n}\n\n/**********************************************************************************/\n/* */\n/* Guards */\n/* */\n/**********************************************************************************/\n\nexport const isMatKind = <\n T extends UniformKind | AttributeKind,\n TPrefix extends string,\n TPostfix extends string,\n>(\n kind: T,\n): kind is T & `${TPrefix}mat${TPostfix}` => kind.includes('mat')\n\nexport const isSamplerKind = <TPrefix extends string, TPostfix extends string>(\n kind: UniformKind,\n): kind is UniformKind & `${TPrefix}sampler${TPostfix}` => kind.includes('sampler')\n\nexport const isVecKind = <TPrefix extends string, TPostfix extends string>(\n kind: UniformKind,\n): kind is UniformKind & `${TPrefix}vec${TPostfix}` => kind.includes('vec')\n\n/**********************************************************************************/\n/* */\n/* Create Texture */\n/* */\n/**********************************************************************************/\n\nexport function createTexture(\n gl: GL,\n {\n target = 'TEXTURE_2D',\n internalFormat = 'RGBA',\n format = 'RGBA',\n type = 'UNSIGNED_BYTE',\n minFilter = 'NEAREST',\n magFilter = 'NEAREST',\n wrapS = 'CLAMP_TO_EDGE',\n wrapT = 'CLAMP_TO_EDGE',\n width,\n height,\n }: TextureDefinition,\n data?: ArrayBufferView | null,\n): WebGLTexture {\n const texture = gl.createTexture()\n\n function getTextureConstant(name: string) {\n if (!(name in gl)) {\n throw new Error(`Attempted to create webgl2-only texture (${name}) in webgl1`)\n }\n return gl[name as keyof typeof gl] as any\n }\n\n gl.bindTexture(gl[target], texture)\n gl.texImage2D(\n gl[target],\n 0,\n getTextureConstant(internalFormat),\n width,\n height,\n 0,\n getTextureConstant(format),\n getTextureConstant(type),\n data ?? null,\n )\n\n console.log(minFilter)\n // Set texture parameters\n gl.texParameteri(gl[target], gl.TEXTURE_MIN_FILTER, gl[minFilter])\n gl.texParameteri(gl[target], gl.TEXTURE_MAG_FILTER, gl[magFilter])\n gl.texParameteri(gl[target], gl.TEXTURE_WRAP_S, gl[wrapS])\n gl.texParameteri(gl[target], gl.TEXTURE_WRAP_T, gl[wrapT])\n\n return texture\n}\n\n/**********************************************************************************/\n/* */\n/* Create Framebuffer */\n/* */\n/**********************************************************************************/\n\nconst FRAMEBUFFER_ATTACHMENT_MAP = {\n color: 'COLOR_ATTACHMENT0',\n depth: 'DEPTH_ATTACHMENT',\n stencil: 'STENCIL_ATTACHMENT',\n depthStencil: 'DEPTH_STENCIL_ATTACHMENT',\n} as const\n\nclass FramebufferError extends Error {\n constructor(gl: GL, status: number) {\n let errorMessage = `Framebuffer '${name}' not complete. Status: `\n switch (status) {\n case gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT:\n errorMessage += 'FRAMEBUFFER_INCOMPLETE_ATTACHMENT'\n break\n case gl.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:\n errorMessage += 'FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT'\n break\n case gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS:\n errorMessage += 'FRAMEBUFFER_INCOMPLETE_DIMENSIONS'\n break\n case gl.FRAMEBUFFER_UNSUPPORTED:\n errorMessage += 'FRAMEBUFFER_UNSUPPORTED'\n break\n default:\n errorMessage += `Unknown (${status})`\n }\n super(errorMessage)\n }\n}\n\nexport function createFramebuffer(\n gl: GL,\n { attachment, texture, ...options }: FramebufferDefinition,\n) {\n // Create texture for the framebuffer\n texture ??= createTexture(gl, options)\n\n // Create framebuffer\n const framebuffer = assertedNotNullish(\n gl.createFramebuffer(),\n `Failed to create framebuffer: ${name}`,\n )\n\n gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer)\n\n gl.framebufferTexture2D(\n gl.FRAMEBUFFER,\n // Determine attachment point based on attachment kind\n gl[FRAMEBUFFER_ATTACHMENT_MAP[attachment]],\n gl.TEXTURE_2D,\n texture,\n 0,\n )\n\n // Check framebuffer completeness\n const status = gl.checkFramebufferStatus(gl.FRAMEBUFFER)\n if (status !== gl.FRAMEBUFFER_COMPLETE) {\n throw new FramebufferError(gl, status)\n }\n\n return {\n texture,\n framebuffer,\n }\n}\n\n/**********************************************************************************/\n/* */\n/* Create Upsert */\n/* */\n/**********************************************************************************/\n\ntype UpsertMapKind<T, U> = Map<T, U> | (T extends WeakKey ? WeakMap<T, U> : never)\n\nexport function createUpsertMap<T extends UpsertMapKind<any, any> = Map<any, any>>(\n constructor?: new () => T,\n) {\n const map = new (constructor ?? Map)() as T\n return Object.assign(map, {\n getOrInsert(\n key: T extends UpsertMapKind<infer U, any> ? U : never,\n value: T extends UpsertMapKind<any, infer U> ? () => U : never,\n ) {\n let result = map.get(key)\n if (result) {\n return result\n }\n result = value()\n map.set(key, result)\n return result\n },\n })\n}\n","export function forEach<T extends Record<string, any>>(\n value: T,\n callback: (value: T[keyof T], key: keyof T, index: number) => void,\n) {\n let index = 0\n for (const key in value) {\n callback(value[key], key, index)\n index++\n }\n for (const key of Object.getOwnPropertySymbols(value)) {\n callback(value[key as keyof T], key as keyof T, index)\n index++\n }\n}\n\nexport function map<T extends Record<string, any>, TReturn>(\n value: T,\n callback: (value: T[keyof T], key: keyof T, index: number) => TReturn,\n): { [TKey in keyof T]: TReturn } {\n const result = {} as { [TKey in keyof T]: TReturn }\n\n forEach(value, (value, key, index) => {\n result[key] = callback(value, key, index)\n })\n\n return result\n}\n","import { getInstancedArrays, getVertexArrayObject } from './features'\nimport type {\n AttributeMethods,\n AttributeSchema,\n AttributeView,\n BufferSchema,\n BufferView,\n GL,\n UniformView as InferUniformView,\n InterleavedAttributeMethods,\n InterleavedAttributeSchema,\n InterleavedAttributeView,\n UniformSchema,\n View,\n ViewOptions,\n ViewSchema,\n} from './types'\nimport {\n assertedNotNullish,\n createUpsertMap,\n isMatKind,\n isSamplerKind,\n kindToSize,\n kindToUniformFnName,\n} from './utils'\nexport * from './types'\nimport * as ObjectUtils from \"./utils/object\"\n\n/**********************************************************************************/\n/* */\n/* To ID */\n/* */\n/**********************************************************************************/\n\nlet index = 0\nconst PREFIX = 'VIEW_GL_ALIAS'\nconst IS_FIREFOX = navigator.userAgent.toLowerCase().indexOf('firefox') >= 0\n\n// NOTE: using symbol as key for WeakMap is currently broken in firefox\n// see https://bugzilla.mozilla.org/show_bug.cgi?id=1710433\n// fallback to Map will currently cause a memory leak.\nconst SYMBOL_MAP = createUpsertMap(IS_FIREFOX ? Map<symbol, string> : WeakMap<symbol, string>)\n\nexport function toID(key: string | number | symbol) {\n if (typeof key === 'string') {\n return key\n }\n if (typeof key === 'symbol') {\n return SYMBOL_MAP.getOrInsert(key, () => `${PREFIX}_${index++}`)\n }\n return key.toString()\n}\n\n/**********************************************************************************/\n/* */\n/* View */\n/* */\n/**********************************************************************************/\n\nexport function view<TSchema extends ViewSchema>(\n gl: GL,\n program: WebGLProgram,\n schema: TSchema,\n options?: ViewOptions,\n): View<TSchema> {\n return {\n uniforms: !schema.uniforms ? undefined : uniformView(gl, program, schema.uniforms),\n attributes: !schema.attributes\n ? undefined\n : attributeView(gl, program, schema.attributes, options),\n interleavedAttributes: !schema.interleavedAttributes\n ? undefined\n : interleavedAttributeView(gl, program, schema.interleavedAttributes, options),\n buffers: !schema.buffers ? undefined : bufferView(gl, schema.buffers),\n } as View<TSchema>\n}\n\n/**********************************************************************************/\n/* */\n/* Uniform View */\n/* */\n/**********************************************************************************/\n\nexport function uniformView<T extends UniformSchema>(\n gl: GL,\n program: WebGLProgram,\n schema: T,\n): InferUniformView<T> {\n return ObjectUtils.map(schema, ({ kind, size }, key) => {\n const name = toID(key)\n\n const location = gl.getUniformLocation(program, name)\n\n if (isSamplerKind(kind)) {\n return {\n set(arg: number) {\n gl.uniform1i(location, arg)\n },\n }\n }\n\n const fnName = `uniform${kindToUniformFnName(kind)}${size ? 'v' : ''}`\n\n // @ts-ignore FIX WEBGL/WEBGL2 TYPES\n const fn = gl[fnName].bind(gl)\n\n if (isMatKind(kind)) {\n return {\n set(...args: any[]) {\n fn(location, false, args[0])\n },\n }\n }\n\n return {\n set(...args: any[]) {\n fn(location, ...args)\n },\n }\n })\n}\n\n/**********************************************************************************/\n/* */\n/* Attribute View */\n/* */\n/**********************************************************************************/\n\n// Shared attribute helper functions\n// between attributeView and interleavedAttributeView\nfunction handleAttribute(\n gl: GL,\n location: number,\n size: number,\n stride: number,\n offset: number,\n type: 'FLOAT' | 'INT',\n instanced?: boolean,\n) {\n gl.enableVertexAttribArray(location)\n gl.vertexAttribPointer(location, size, gl[type], false, stride, offset)\n\n if (instanced) {\n // Get instanced-arrays-feature: extension if webgl, gl if webgl2\n assertedNotNullish(getInstancedArrays(gl)).vertexAttribDivisor(location, 1)\n }\n}\n\nexport function attributeView<T extends AttributeSchema>(\n gl: GL,\n program: WebGLProgram,\n schema: T,\n { signal }: ViewOptions = {},\n): AttributeView<T> {\n const attributes = ObjectUtils.map(\n schema,\n (\n { kind, instanced, buffer = assertedNotNullish(gl.createBuffer()) },\n key,\n ): AttributeMethods => {\n const name = toID(key)\n\n const location = gl.getAttribLocation(program, name)\n if (location < 0) {\n throw new Error(`Attribute '${name}' not found`)\n }\n\n const size = kindToSize(kind)\n const type = kind.startsWith('i') ? 'INT' : 'FLOAT'\n\n return {\n buffer,\n bind() {\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer)\n handleAttribute(gl, location, size, 0, 0, type, instanced)\n },\n dispose() {\n gl.deleteBuffer(buffer)\n },\n set(data, usage = 'STATIC_DRAW') {\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer)\n gl.bufferData(gl.ARRAY_BUFFER, data, gl[usage])\n return this\n },\n }\n },\n )\n\n signal?.addEventListener('abort', function dispose() {\n ObjectUtils.forEach(attributes, value => value.dispose())\n })\n\n return attributes\n}\n\n/**********************************************************************************/\n/* */\n/* Interleaved Attribute View */\n/* */\n/**********************************************************************************/\n\nexport function interleavedAttributeView<T extends InterleavedAttributeSchema>(\n gl: GL,\n program: WebGLProgram,\n schema: T,\n { signal }: ViewOptions = {},\n): InterleavedAttributeView<T> {\n // Initialize interleaved attributes\n const interleavedAttributes = ObjectUtils.map(schema, ({ layout, instanced }) => {\n // Increment number to keep track of offset\n let index = 0\n\n // Calculate layout information\n const handles = layout.map(layout => {\n const name = toID(layout.key)\n\n const location = gl.getAttribLocation(program, name)\n\n if (location < 0) {\n throw new Error(`Attribute '${name}' not found`)\n }\n\n const size = kindToSize(layout.kind)\n const offset = index\n const type = layout.kind.startsWith('i') ? 'INT' : 'FLOAT'\n index += size * 4\n\n return () => handleAttribute(gl, location, size, stride, offset, type, instanced)\n })\n\n // Set stride to final index\n const stride = index\n\n // Create a buffer\n const buffer = assertedNotNullish(gl.createBuffer())\n\n // Create VAO to cache attribute state\n let vao: { unbind(): void; bind(): void; dispose(): void } | undefined = undefined\n\n // Get VAO-feature: extension if webgl1, gl if webgl2\n const feature = getVertexArrayObject(gl)\n if (feature) {\n const vertexArray = feature.createVertexArray()\n feature.bindVertexArray(vertexArray)\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer)\n for (const handle of handles) {\n handle()\n }\n feature.bindVertexArray(null)\n vao = {\n unbind() {\n feature.bindVertexArray(null)\n },\n bind() {\n feature.bindVertexArray(vertexArray)\n },\n dispose() {\n feature.deleteVertexArray(vertexArray)\n },\n }\n }\n\n return {\n bind() {\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer)\n if (vao) {\n vao.bind()\n } else {\n // Fallback: manual attribute setup\n for (const handle of handles) {\n handle()\n }\n }\n },\n unbind() {\n if (vao) {\n vao.unbind()\n }\n },\n dispose() {\n gl.deleteBuffer(buffer)\n if (vao) {\n vao.dispose()\n }\n },\n set(value, usage = 'STATIC_DRAW') {\n if (vao) {\n vao.bind()\n } else {\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer)\n }\n gl.bufferData(gl.ARRAY_BUFFER, value, gl[usage])\n if (vao) {\n vao.unbind()\n }\n },\n } satisfies InterleavedAttributeMethods\n })\n\n signal?.addEventListener('abort', function dispose() {\n ObjectUtils.forEach(interleavedAttributes, value => value.dispose())\n })\n\n return interleavedAttributes\n}\n\n/**********************************************************************************/\n/* */\n/* Buffer View */\n/* */\n/**********************************************************************************/\n\nexport function bufferView<T extends BufferSchema>(\n gl: GL,\n schema: T,\n { signal }: ViewOptions = {},\n): BufferView<T> {\n // Initialize buffers\n const buffers = ObjectUtils.map(schema, ({ target = 'ARRAY_BUFFER', usage = 'STATIC_DRAW' }) => {\n const buffer = assertedNotNullish(gl.createBuffer())\n return {\n bind() {\n gl.bindBuffer(gl[target], buffer)\n },\n dispose() {\n gl.deleteBuffer(buffer)\n },\n set(data: Float32Array) {\n gl.bindBuffer(gl[target], buffer)\n gl.bufferData(gl[target], data, gl[usage])\n },\n }\n })\n\n signal?.addEventListener('abort', function dispose() {\n ObjectUtils.forEach(buffers, value => value.dispose())\n })\n\n return buffers\n}\n","import { GL } from \"./types\"\n\nexport function createShader(gl: GL, type: number, source: string): WebGLShader {\n const shader = gl.createShader(type)\n if (!shader) throw new Error('Failed to create shader')\n\n gl.shaderSource(shader, source)\n gl.compileShader(shader)\n\n if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n const info = gl.getShaderInfoLog(shader)\n gl.deleteShader(shader)\n throw new Error(\n `Failed to compile ${type === gl.VERTEX_SHADER ? 'vertex' : 'fragment'} shader: ${info}`,\n )\n }\n\n return shader\n}\n\nexport function createProgram(gl: GL, vertexSource: string, fragmentSource: string): WebGLProgram {\n const program = gl.createProgram()\n if (!program) throw new Error('Failed to create WebGL program')\n\n const vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexSource)\n const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentSource)\n\n gl.attachShader(program, vertexShader)\n gl.attachShader(program, fragmentShader)\n gl.linkProgram(program)\n\n if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n const info = gl.getProgramInfoLog(program)\n gl.deleteProgram(program)\n gl.deleteShader(vertexShader)\n gl.deleteShader(fragmentShader)\n throw new Error(`Failed to link program: ${info}`)\n }\n\n // Clean up shaders after linking\n gl.deleteShader(vertexShader)\n gl.deleteShader(fragmentShader)\n\n return program\n}","import { toID, view } from '.'\nimport { createProgram } from './gl'\nimport type { Prettify } from './type-utils'\nimport type {\n AttributeDefinition,\n AttributeKind,\n AttributeTokenFn as AttributeTagMethod,\n AttributeToken,\n CompileResult,\n GL,\n GLSL,\n GLSLSlot,\n GLSLToSchema,\n InterleaveToken,\n UniformDefinition,\n UniformKind,\n UniformTokenFn as UniformTagMethod,\n ViewSchema,\n ViewSchemaPartial,\n} from './types'\nimport { createUpsertMap } from './utils'\n\nexport function glsl<TSlot extends GLSLSlot, TSlots extends TSlot[]>(\n template: TemplateStringsArray,\n ...slots: [...TSlots]\n): GLSL<TSlots> {\n return { template, slots, type: 'glsl' }\n}\n\nexport const uniform = new Proxy(\n {} as {\n [TKey in UniformKind]: UniformTagMethod<TKey>\n },\n {\n get(target, property) {\n // @ts-expect-error\n if (typeof property === 'symbol') return target[property]\n return (key: string, options?: Omit<UniformDefinition, 'kind'>) => ({\n type: 'uniform',\n key,\n kind: property,\n ...options,\n })\n },\n },\n)\n\nexport const attribute = new Proxy(\n {} as {\n [TKey in AttributeKind]: AttributeTagMethod<TKey>\n },\n {\n get(target, property) {\n // @ts-expect-error\n if (typeof property === 'symbol') return target[property]\n return (key: string, options?: Omit<AttributeDefinition, 'kind'>) => ({\n type: 'attribute',\n key,\n kind: property,\n ...options,\n })\n },\n },\n)\n\nexport function interleave<\n const TKey extends string | symbol,\n const TLayout extends Array<AttributeToken<string | symbol, AttributeKind, undefined>>,\n const TOptions extends Omit<AttributeDefinition, 'kind'>,\n>(key: TKey, layout: TLayout, instanced: TOptions): InterleaveToken<TKey, TLayout, TOptions>\nexport function interleave<\n const TKey extends string | symbol,\n const TLayout extends Array<AttributeToken<string | symbol, AttributeKind, undefined>>,\n>(key: TKey, layout: TLayout): InterleaveToken<TKey, TLayout, { instanced: false }>\nexport function interleave<\n const TKey extends string | symbol,\n const TLayout extends Array<AttributeToken<string | symbol, AttributeKind, undefined>>,\n const TOptions extends Omit<AttributeDefinition, 'kind'>,\n>(key: TKey, layout: TLayout, { instanced, buffer }: Partial<TOptions> = {}) {\n return {\n type: 'interleavedAttribute',\n key,\n // remove instanced- and type-property\n layout: layout.map(({ key, kind }) => ({\n key,\n kind,\n })),\n instanced: !!instanced,\n buffer,\n } as unknown as InterleaveToken<TKey, TLayout, TOptions>\n}\n\n/**********************************************************************************/\n/* */\n/* Compile */\n/* */\n/**********************************************************************************/\n\nexport interface CompileOptions<TSchema extends ViewSchemaPartial> {\n schema?: TSchema\n webgl2?: boolean\n}\n\nexport function compile<\n TVertex extends GLSL,\n TFragment extends GLSL,\n TSchema extends ViewSchemaPartial,\n>(\n gl: WebGLRenderingContext,\n vertex: TVertex,\n fragment: TFragment,\n options?: CompileOptions<TSchema> | undefined,\n) {\n const _vertex = resolveGLSLTag(vertex, options) as { template: string; schema: ViewSchema }\n const _fragment = resolveGLSLTag(fragment, options) as { template: string; schema: ViewSchema }\n\n const schema = {\n uniforms: {\n ..._vertex.schema.uniforms,\n ..._fragment.schema.uniforms,\n },\n attributes: {\n ..._vertex.schema.attributes,\n ..._fragment.schema.attributes,\n },\n interleavedAttributes: {\n ..._vertex.schema.interleavedAttributes,\n ..._fragment.schema.interleavedAttributes,\n },\n }\n\n // Deep merge options.schema with generated schema\n for (const kind in options?.schema) {\n const schemaKind = schema[kind as keyof typeof schema]\n const configSchemaKind = options?.schema[kind]\n\n for (const key in configSchemaKind) {\n schemaKind[key] = {\n ...schemaKind[key],\n ...configSchemaKind[key],\n }\n }\n }\n\n try {\n const program = createProgram(gl, _vertex.template, _fragment.template)\n\n return {\n program,\n schema,\n view: view(gl, program, schema),\n vertex: _vertex.template,\n fragment: _fragment.template,\n } as unknown as Prettify<CompileResult<TVertex, TFragment, TSchema>>\n } catch (error) {\n console.error('Error while creating WebGLProgram - vertex\\n\\n', _vertex.template)\n console.error('Error while creating WebGLProgram - fragment\\n\\n', _fragment.template)\n\n throw error\n }\n}\n\nfunction resolveGLSLTag<TTag extends GLSL>(tag: TTag, options?: { webgl2?: boolean }) {\n return {\n template: compile.toString(tag, options),\n schema: compile.toSchema(tag),\n }\n}\n\ncompile.toSchema = function <TTag extends GLSL>(tag: TTag) {\n const result = {\n uniforms: {},\n attributes: {},\n interleavedAttributes: {},\n }\n\n tag.slots.forEach(function handleSlot(slot: GLSLSlot) {\n if (typeof slot !== 'object') {\n return\n }\n\n if (Array.isArray(slot)) {\n slot.forEach(handleSlot)\n return\n }\n\n if (slot.type === 'glsl') {\n const { uniforms, attributes, interleavedAttributes } = compile.toSchema(slot)\n\n result.uniforms = {\n ...result.uniforms,\n ...uniforms,\n }\n result.attributes = {\n ...result.attributes,\n ...attributes,\n }\n result.interleavedAttributes = {\n ...result.interleavedAttributes,\n ...interleavedAttributes,\n }\n\n return\n }\n\n const { key: name, type, ...rest } = slot\n\n // @ts-expect-error\n result[`${type}s`][name] = rest\n })\n\n return result as unknown as Prettify<GLSLToSchema<TTag>>\n}\n\ncompile.toString = function <TTag extends GLSL>(\n { template: [initial, ...rest], slots }: TTag,\n config?: { webgl2?: boolean },\n) {\n const v300 = config?.webgl2 ?? !!initial?.startsWith('#version 300 es')\n\n let template = initial ?? ''\n\n for (let i = 0; i < rest.length; i++) {\n template += `${resolveGlslSlotToString(slots[i]!, v300)}${rest[i]}`\n }\n\n return template\n}\n\nfunction resolveGlslSlotToString(slot: GLSLSlot, v300: boolean): string {\n if (typeof slot !== 'object') {\n return toID(slot)\n }\n\n if (Array.isArray(slot)) {\n return slot.map(slot => resolveGlslSlotToString(slot, v300)).join('')\n }\n\n switch (slot.type) {\n case 'glsl':\n return compile.toString(slot)\n case 'interleavedAttribute':\n return slot.layout.reduce(\n (a, v) =>\n v300 ? `${a}in ${v.kind} ${toID(v.key)};\\n` : `${a}attribute ${v.kind} ${toID(v.key)};\\n`,\n '',\n )\n case 'uniform':\n if ('size' in slot) {\n return `${slot.type} ${slot.kind} ${toID(slot.key)}[${slot.size}];`\n }\n return `${slot.type} ${slot.kind} ${toID(slot.key)};`\n }\n\n if (slot.type === 'attribute') {\n return `${v300 ? 'in' : slot.type} ${slot.kind} ${toID(slot.key)};`\n }\n\n throw new Error(`Unexpected slot: ${JSON.stringify(slot)}`)\n}\n\nconst QUAD_FLOAT_ARRAY = new Float32Array([-1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1])\nconst QUAD_BUFFER_MAP = createUpsertMap(WeakMap<GL, WebGLBuffer>)\n\ncompile.toQuad = function <TFragment extends GLSL, TSchema extends ViewSchemaPartial>(\n gl: GL,\n fragment: TFragment,\n options?: CompileOptions<TSchema>,\n) {\n const buffer = QUAD_BUFFER_MAP.getOrInsert(gl, gl.createBuffer.bind(gl))\n\n const webgl2 = options?.webgl2 ?? fragment.template[0]?.startsWith('#version 300 es')\n\n const vertex = webgl2\n ? glsl`#version 300 es\nprecision mediump float;\n\n${attribute.vec2('a_quad', { buffer })}\n\nout vec2 v_uv;\n\nvoid main() {\n v_uv = a_quad;\n gl_Position = vec4(v_uv, 0.0, 1.0);\n}`\n : glsl`precision mediump float;\n\n${attribute.vec2('a_quad', { buffer })}\n\nvarying vec2 v_uv;\n\nvoid main() {\n v_uv = a_quad;\n gl_Position = vec4(v_uv, 0.0, 1.0);\n}`\n\n const result = compile(gl, vertex, fragment, options)\n\n // @ts-expect-error\n result.view.attributes.a_quad.set(QUAD_FLOAT_ARRAY)\n\n return result\n}\n"],"mappings":"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","names":["map","index","value","name","index","layout","key","name","slot"]}
1
+ {"version":3,"sources":["../src/gl.ts","../src/utils/index.ts","../src/utils/object.ts","../src/index.ts","../src/tag.ts"],"sourcesContent":["import { RemoveSuffix } from './type-utils'\nimport { GL } from './types'\n\nexport function createShader(gl: GL, type: number, source: string): WebGLShader {\n const shader = gl.createShader(type)\n if (!shader) throw new Error('Failed to create shader')\n\n gl.shaderSource(shader, source)\n gl.compileShader(shader)\n\n if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n const info = gl.getShaderInfoLog(shader)\n gl.deleteShader(shader)\n throw new Error(\n `Failed to compile ${type === gl.VERTEX_SHADER ? 'vertex' : 'fragment'} shader: ${info}`,\n )\n }\n\n return shader\n}\n\nexport function createProgram(gl: GL, vertexSource: string, fragmentSource: string): WebGLProgram {\n const program = gl.createProgram()\n if (!program) throw new Error('Failed to create WebGL program')\n\n const vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexSource)\n const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentSource)\n\n gl.attachShader(program, vertexShader)\n gl.attachShader(program, fragmentShader)\n gl.linkProgram(program)\n\n if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n const info = gl.getProgramInfoLog(program)\n gl.deleteProgram(program)\n gl.deleteShader(vertexShader)\n gl.deleteShader(fragmentShader)\n throw new Error(`Failed to link program: ${info}`)\n }\n\n // Clean up shaders after linking\n gl.deleteShader(vertexShader)\n gl.deleteShader(fragmentShader)\n\n return program\n}\n\nconst INSTANCED_ARRAYS_WRAPPER_MAP = new WeakMap<\n GL,\n RemoveSuffix<\n Pick<\n ANGLE_instanced_arrays,\n 'drawArraysInstancedANGLE' | 'drawElementsInstancedANGLE' | 'vertexAttribDivisorANGLE'\n >,\n 'ANGLE'\n > | null\n>()\nexport function getInstancedArrays(gl: GL) {\n if (gl instanceof WebGL2RenderingContext) return gl\n\n const cached = INSTANCED_ARRAYS_WRAPPER_MAP.get(gl)\n if (cached) return cached\n\n const ext = gl.getExtension('ANGLE_instanced_arrays')\n if (!ext) return undefined\n\n const wrapper = {\n drawArraysInstanced: ext.drawArraysInstancedANGLE.bind(ext),\n drawElementsInstanced: ext.drawElementsInstancedANGLE.bind(ext),\n vertexAttribDivisor: ext.vertexAttribDivisorANGLE.bind(ext),\n }\n INSTANCED_ARRAYS_WRAPPER_MAP.set(gl, wrapper)\n\n return wrapper\n}\n\nconst VERTEX_ARRAY_OBJECT_WRAPPER_MAP = new WeakMap<\n GL,\n RemoveSuffix<\n Pick<\n OES_vertex_array_object,\n 'bindVertexArrayOES' | 'createVertexArrayOES' | 'deleteVertexArrayOES'\n >,\n 'OES'\n > | null\n>()\nexport function getVertexArrayObject(gl: GL) {\n if (gl instanceof WebGL2RenderingContext) return gl\n\n const cached = VERTEX_ARRAY_OBJECT_WRAPPER_MAP.get(gl)\n if (cached) return cached\n\n const ext = gl.getExtension('OES_vertex_array_object')\n if (!ext) return null\n\n const wrapper = {\n bindVertexArray: ext.bindVertexArrayOES.bind(ext),\n createVertexArray: ext.createVertexArrayOES.bind(ext),\n deleteVertexArray: ext.deleteVertexArrayOES.bind(ext),\n }\n VERTEX_ARRAY_OBJECT_WRAPPER_MAP.set(gl, wrapper)\n\n return wrapper\n}\n","import type {\n AttributeKind,\n FramebufferDefinition,\n GL,\n KIND_TO_SIZE_MAP,\n KIND_TO_UNIFORM_FN_NAME_MAP,\n TextureDefinition,\n UniformKind,\n} from '../types'\n\nexport function assertedNotNullish<T>(value: T, message?: string): NonNullable<T> {\n if (value === undefined || value === null) throw new Error(message)\n return value\n}\n\n/**********************************************************************************/\n/* */\n/* Kind To Uniform Name */\n/* */\n/**********************************************************************************/\n\nexport const kindToUniformFnName = <T extends UniformKind>(\n kind: T,\n): KIND_TO_UNIFORM_FN_NAME_MAP[T] => {\n switch (kind[0]) {\n // mat\n case 'm':\n return ('Matrix' + kind.slice(3) + 'fv') as KIND_TO_UNIFORM_FN_NAME_MAP[T]\n // sampler/booleans/integer\n case 's':\n case 'b':\n case 'i':\n return ((kind.match(/\\d/)?.[0] ?? '1') + 'i') as KIND_TO_UNIFORM_FN_NAME_MAP[T]\n // unsigned integers\n case 'u':\n return ((kind[4] || '1') + 'ui') as KIND_TO_UNIFORM_FN_NAME_MAP[T]\n // vec\n case 'v':\n return (kind[3] + 'f') as KIND_TO_UNIFORM_FN_NAME_MAP[T]\n default:\n switch (kind) {\n case 'float':\n return '1f' as KIND_TO_UNIFORM_FN_NAME_MAP[T]\n case 'uint':\n return '1ui' as KIND_TO_UNIFORM_FN_NAME_MAP[T]\n default:\n return '1i' as KIND_TO_UNIFORM_FN_NAME_MAP[T]\n }\n }\n}\n\n/**********************************************************************************/\n/* */\n/* Kind To Size */\n/* */\n/**********************************************************************************/\n\nexport const kindToSize = <T extends UniformKind>(kind: T): KIND_TO_SIZE_MAP[T] => {\n switch (kind[0]) {\n case 'm':\n const [a, b] = kind.match(/\\d+/g)!.map(Number) as [number, number?]\n return (a * (b ?? a)) as KIND_TO_SIZE_MAP[T]\n case 'v':\n case 'i':\n case 'b':\n case 'u':\n const match = kind.match(/\\d/) as [string] | undefined\n return (match ? +match[0] : 1) as KIND_TO_SIZE_MAP[T]\n default:\n return 1 as KIND_TO_SIZE_MAP[T]\n }\n}\n\n/**********************************************************************************/\n/* */\n/* Guards */\n/* */\n/**********************************************************************************/\n\nexport const isMatKind = <\n T extends UniformKind | AttributeKind,\n TPrefix extends string,\n TPostfix extends string,\n>(\n kind: T,\n): kind is T & `${TPrefix}mat${TPostfix}` => kind.includes('mat')\n\nexport const isSamplerKind = <TPrefix extends string, TPostfix extends string>(\n kind: UniformKind,\n): kind is UniformKind & `${TPrefix}sampler${TPostfix}` => kind.includes('sampler')\n\nexport const isVecKind = <TPrefix extends string, TPostfix extends string>(\n kind: UniformKind,\n): kind is UniformKind & `${TPrefix}vec${TPostfix}` => kind.includes('vec')\n\n/**********************************************************************************/\n/* */\n/* Create Texture */\n/* */\n/**********************************************************************************/\n\nexport function createTexture(\n gl: GL,\n {\n target = 'TEXTURE_2D',\n internalFormat = 'RGBA',\n format = 'RGBA',\n type = 'UNSIGNED_BYTE',\n minFilter = 'NEAREST',\n magFilter = 'NEAREST',\n wrapS = 'CLAMP_TO_EDGE',\n wrapT = 'CLAMP_TO_EDGE',\n width,\n height,\n }: TextureDefinition,\n data?: ArrayBufferView | null,\n): WebGLTexture {\n const texture = gl.createTexture()\n\n function getTextureConstant(name: string) {\n if (!(name in gl)) {\n throw new Error(`Attempted to create webgl2-only texture (${name}) in webgl1`)\n }\n return gl[name as keyof typeof gl] as any\n }\n\n gl.bindTexture(gl[target], texture)\n gl.texImage2D(\n gl[target],\n 0,\n getTextureConstant(internalFormat),\n width,\n height,\n 0,\n getTextureConstant(format),\n getTextureConstant(type),\n data ?? null,\n )\n\n console.log(minFilter)\n // Set texture parameters\n gl.texParameteri(gl[target], gl.TEXTURE_MIN_FILTER, gl[minFilter])\n gl.texParameteri(gl[target], gl.TEXTURE_MAG_FILTER, gl[magFilter])\n gl.texParameteri(gl[target], gl.TEXTURE_WRAP_S, gl[wrapS])\n gl.texParameteri(gl[target], gl.TEXTURE_WRAP_T, gl[wrapT])\n\n return texture\n}\n\n/**********************************************************************************/\n/* */\n/* Create Framebuffer */\n/* */\n/**********************************************************************************/\n\nconst FRAMEBUFFER_ATTACHMENT_MAP = {\n color: 'COLOR_ATTACHMENT0',\n depth: 'DEPTH_ATTACHMENT',\n stencil: 'STENCIL_ATTACHMENT',\n depthStencil: 'DEPTH_STENCIL_ATTACHMENT',\n} as const\n\nclass FramebufferError extends Error {\n constructor(gl: GL, status: number) {\n let errorMessage = `Framebuffer '${name}' not complete. Status: `\n switch (status) {\n case gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT:\n errorMessage += 'FRAMEBUFFER_INCOMPLETE_ATTACHMENT'\n break\n case gl.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:\n errorMessage += 'FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT'\n break\n case gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS:\n errorMessage += 'FRAMEBUFFER_INCOMPLETE_DIMENSIONS'\n break\n case gl.FRAMEBUFFER_UNSUPPORTED:\n errorMessage += 'FRAMEBUFFER_UNSUPPORTED'\n break\n default:\n errorMessage += `Unknown (${status})`\n }\n super(errorMessage)\n }\n}\n\nexport function createFramebuffer(\n gl: GL,\n { attachment, texture, ...options }: FramebufferDefinition,\n) {\n // Create texture for the framebuffer\n texture ??= createTexture(gl, options)\n\n // Create framebuffer\n const framebuffer = assertedNotNullish(\n gl.createFramebuffer(),\n `Failed to create framebuffer: ${name}`,\n )\n\n gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer)\n\n gl.framebufferTexture2D(\n gl.FRAMEBUFFER,\n // Determine attachment point based on attachment kind\n gl[FRAMEBUFFER_ATTACHMENT_MAP[attachment]],\n gl.TEXTURE_2D,\n texture,\n 0,\n )\n\n // Check framebuffer completeness\n const status = gl.checkFramebufferStatus(gl.FRAMEBUFFER)\n if (status !== gl.FRAMEBUFFER_COMPLETE) {\n throw new FramebufferError(gl, status)\n }\n\n return {\n texture,\n framebuffer,\n }\n}\n\n/**********************************************************************************/\n/* */\n/* Create Upsert */\n/* */\n/**********************************************************************************/\n\ntype UpsertMapKind<T, U> = Map<T, U> | (T extends WeakKey ? WeakMap<T, U> : never)\n\nexport function createUpsertMap<T extends UpsertMapKind<any, any> = Map<any, any>>(\n constructor?: new () => T,\n) {\n const map = new (constructor ?? Map)() as T\n return Object.assign(map, {\n getOrInsert(\n key: T extends UpsertMapKind<infer U, any> ? U : never,\n value: T extends UpsertMapKind<any, infer U> ? () => U : never,\n ) {\n let result = map.get(key)\n if (result) {\n return result\n }\n result = value()\n map.set(key, result)\n return result\n },\n })\n}\n","export function forEach<T extends Record<string, any>>(\n value: T,\n callback: (value: T[keyof T], key: keyof T, index: number) => void,\n) {\n let index = 0\n for (const key in value) {\n callback(value[key], key, index)\n index++\n }\n for (const key of Object.getOwnPropertySymbols(value)) {\n callback(value[key as keyof T], key as keyof T, index)\n index++\n }\n}\n\nexport function map<T extends Record<string, any>, TReturn>(\n value: T,\n callback: (value: T[keyof T], key: keyof T, index: number) => TReturn,\n): { [TKey in keyof T]: TReturn } {\n const result = {} as { [TKey in keyof T]: TReturn }\n\n forEach(value, (value, key, index) => {\n result[key] = callback(value, key, index)\n })\n\n return result\n}\n","import { getInstancedArrays, getVertexArrayObject } from './gl'\nimport type {\n AttributeMethods,\n AttributeSchema,\n AttributeView,\n BufferSchema,\n BufferView,\n GL,\n UniformView as InferUniformView,\n InterleavedAttributeMethods,\n InterleavedAttributeSchema,\n InterleavedAttributeView,\n UniformSchema,\n View,\n ViewOptions,\n ViewSchema,\n} from './types'\nimport {\n assertedNotNullish,\n createUpsertMap,\n isMatKind,\n isSamplerKind,\n kindToSize,\n kindToUniformFnName,\n} from './utils'\nexport * from './types'\nimport * as ObjectUtils from './utils/object'\n\n/**********************************************************************************/\n/* */\n/* To ID */\n/* */\n/**********************************************************************************/\n\nlet index = 0\nconst PREFIX = 'VIEW_GL_ALIAS'\nconst IS_FIREFOX = navigator.userAgent.toLowerCase().indexOf('firefox') >= 0\n\n// NOTE: using symbol as key for WeakMap is currently broken in firefox\n// see https://bugzilla.mozilla.org/show_bug.cgi?id=1710433\n// fallback to Map will currently cause a memory leak.\nconst SYMBOL_MAP = createUpsertMap(IS_FIREFOX ? Map<symbol, string> : WeakMap<symbol, string>)\n\nexport function toID(key: string | number | symbol) {\n if (typeof key === 'string') {\n return key\n }\n if (typeof key === 'symbol') {\n return SYMBOL_MAP.getOrInsert(key, () => `${PREFIX}_${index++}`)\n }\n return key.toString()\n}\n\n/**********************************************************************************/\n/* */\n/* View */\n/* */\n/**********************************************************************************/\n\nexport function view<TSchema extends ViewSchema>(\n gl: GL,\n program: WebGLProgram,\n schema: TSchema,\n options?: ViewOptions,\n): View<TSchema> {\n return {\n uniforms: !schema.uniforms ? undefined : uniformView(gl, program, schema.uniforms),\n attributes: !schema.attributes\n ? undefined\n : attributeView(gl, program, schema.attributes, options),\n interleavedAttributes: !schema.interleavedAttributes\n ? undefined\n : interleavedAttributeView(gl, program, schema.interleavedAttributes, options),\n buffers: !schema.buffers ? undefined : bufferView(gl, schema.buffers),\n } as View<TSchema>\n}\n\n/**********************************************************************************/\n/* */\n/* Uniform View */\n/* */\n/**********************************************************************************/\n\nexport function uniformView<T extends UniformSchema>(\n gl: GL,\n program: WebGLProgram,\n schema: T,\n): InferUniformView<T> {\n return ObjectUtils.map(schema, ({ kind, size }, key) => {\n const name = toID(key)\n\n const location = gl.getUniformLocation(program, name)\n\n if (isSamplerKind(kind)) {\n return {\n set(arg: number) {\n gl.uniform1i(location, arg)\n },\n }\n }\n\n const fnName = `uniform${kindToUniformFnName(kind)}${size ? 'v' : ''}`\n\n // @ts-ignore FIX WEBGL/WEBGL2 TYPES\n const fn = gl[fnName].bind(gl)\n\n if (isMatKind(kind)) {\n return {\n set(...args: any[]) {\n fn(location, false, args[0])\n },\n }\n }\n\n return {\n set(...args: any[]) {\n fn(location, ...args)\n },\n }\n })\n}\n\n/**********************************************************************************/\n/* */\n/* Attribute View */\n/* */\n/**********************************************************************************/\n\n// Shared attribute helper functions\n// between attributeView and interleavedAttributeView\nfunction handleAttribute(\n gl: GL,\n location: number,\n size: number,\n stride: number,\n offset: number,\n type: 'FLOAT' | 'INT',\n instanced?: boolean,\n) {\n gl.enableVertexAttribArray(location)\n gl.vertexAttribPointer(location, size, gl[type], false, stride, offset)\n\n if (instanced) {\n // Get instanced-arrays-feature: extension if webgl, gl if webgl2\n assertedNotNullish(getInstancedArrays(gl)).vertexAttribDivisor(location, 1)\n }\n}\n\nexport function attributeView<T extends AttributeSchema>(\n gl: GL,\n program: WebGLProgram,\n schema: T,\n { signal }: ViewOptions = {},\n): AttributeView<T> {\n const attributes = ObjectUtils.map(\n schema,\n (\n { kind, instanced, buffer = assertedNotNullish(gl.createBuffer()) },\n key,\n ): AttributeMethods => {\n const name = toID(key)\n\n const location = gl.getAttribLocation(program, name)\n if (location < 0) {\n throw new Error(`Attribute '${name}' not found`)\n }\n\n const size = kindToSize(kind)\n const type = kind.startsWith('i') ? 'INT' : 'FLOAT'\n\n return {\n buffer,\n bind() {\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer)\n handleAttribute(gl, location, size, 0, 0, type, instanced)\n },\n dispose() {\n gl.deleteBuffer(buffer)\n },\n set(data, usage = 'STATIC_DRAW') {\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer)\n gl.bufferData(gl.ARRAY_BUFFER, data, gl[usage])\n return this\n },\n }\n },\n )\n\n signal?.addEventListener('abort', function dispose() {\n ObjectUtils.forEach(attributes, value => value.dispose())\n })\n\n return attributes\n}\n\n/**********************************************************************************/\n/* */\n/* Interleaved Attribute View */\n/* */\n/**********************************************************************************/\n\nexport function interleavedAttributeView<T extends InterleavedAttributeSchema>(\n gl: GL,\n program: WebGLProgram,\n schema: T,\n { signal }: ViewOptions = {},\n): InterleavedAttributeView<T> {\n // Initialize interleaved attributes\n const interleavedAttributes = ObjectUtils.map(schema, ({ layout, instanced }) => {\n // Increment number to keep track of offset\n let index = 0\n\n // Calculate layout information\n const handles = layout.map(layout => {\n const name = toID(layout.key)\n\n const location = gl.getAttribLocation(program, name)\n\n if (location < 0) {\n throw new Error(`Attribute '${name}' not found`)\n }\n\n const size = kindToSize(layout.kind)\n const offset = index\n const type = layout.kind.startsWith('i') ? 'INT' : 'FLOAT'\n index += size * 4\n\n return () => handleAttribute(gl, location, size, stride, offset, type, instanced)\n })\n\n // Set stride to final index\n const stride = index\n\n // Create a buffer\n const buffer = assertedNotNullish(gl.createBuffer())\n\n // Create VAO to cache attribute state\n let vao: { unbind(): void; bind(): void; dispose(): void } | undefined = undefined\n\n // Get VAO-feature: extension if webgl1, gl if webgl2\n const feature = getVertexArrayObject(gl)\n if (feature) {\n const vertexArray = feature.createVertexArray()\n feature.bindVertexArray(vertexArray)\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer)\n for (const handle of handles) {\n handle()\n }\n feature.bindVertexArray(null)\n vao = {\n unbind() {\n feature.bindVertexArray(null)\n },\n bind() {\n feature.bindVertexArray(vertexArray)\n },\n dispose() {\n feature.deleteVertexArray(vertexArray)\n },\n }\n }\n\n return {\n bind() {\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer)\n if (vao) {\n vao.bind()\n } else {\n // Fallback: manual attribute setup\n for (const handle of handles) {\n handle()\n }\n }\n },\n unbind() {\n if (vao) {\n vao.unbind()\n }\n },\n dispose() {\n gl.deleteBuffer(buffer)\n if (vao) {\n vao.dispose()\n }\n },\n set(value, usage = 'STATIC_DRAW') {\n if (vao) {\n vao.bind()\n } else {\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer)\n }\n gl.bufferData(gl.ARRAY_BUFFER, value, gl[usage])\n if (vao) {\n vao.unbind()\n }\n },\n } satisfies InterleavedAttributeMethods\n })\n\n signal?.addEventListener('abort', function dispose() {\n ObjectUtils.forEach(interleavedAttributes, value => value.dispose())\n })\n\n return interleavedAttributes\n}\n\n/**********************************************************************************/\n/* */\n/* Buffer View */\n/* */\n/**********************************************************************************/\n\nexport function bufferView<T extends BufferSchema>(\n gl: GL,\n schema: T,\n { signal }: ViewOptions = {},\n): BufferView<T> {\n // Initialize buffers\n const buffers = ObjectUtils.map(schema, ({ target = 'ARRAY_BUFFER', usage = 'STATIC_DRAW' }) => {\n const buffer = assertedNotNullish(gl.createBuffer())\n return {\n bind() {\n gl.bindBuffer(gl[target], buffer)\n },\n dispose() {\n gl.deleteBuffer(buffer)\n },\n set(data: Float32Array) {\n gl.bindBuffer(gl[target], buffer)\n gl.bufferData(gl[target], data, gl[usage])\n },\n }\n })\n\n signal?.addEventListener('abort', function dispose() {\n ObjectUtils.forEach(buffers, value => value.dispose())\n })\n\n return buffers\n}\n","import { toID, view } from '.'\nimport { createProgram } from './gl'\nimport type { Prettify } from './type-utils'\nimport type {\n AttributeDefinition,\n AttributeKind,\n AttributeTokenFn as AttributeTagMethod,\n AttributeToken,\n CompileResult,\n GL,\n GLSL,\n GLSLSlot,\n GLSLToSchema,\n InterleaveToken,\n UniformDefinition,\n UniformKind,\n UniformTokenFn as UniformTagMethod,\n ViewSchema,\n ViewSchemaPartial,\n} from './types'\nimport { createUpsertMap } from './utils'\n\nexport function glsl<TSlot extends GLSLSlot, TSlots extends TSlot[]>(\n template: TemplateStringsArray,\n ...slots: [...TSlots]\n): GLSL<TSlots> {\n return { template, slots, type: 'glsl' }\n}\n\nexport const uniform = new Proxy(\n {} as {\n [TKey in UniformKind]: UniformTagMethod<TKey>\n },\n {\n get(target, property) {\n // @ts-expect-error\n if (typeof property === 'symbol') return target[property]\n return (key: string, options?: Omit<UniformDefinition, 'kind'>) => ({\n type: 'uniform',\n key,\n kind: property,\n ...options,\n })\n },\n },\n)\n\nexport const attribute = new Proxy(\n {} as {\n [TKey in AttributeKind]: AttributeTagMethod<TKey>\n },\n {\n get(target, property) {\n // @ts-expect-error\n if (typeof property === 'symbol') return target[property]\n return (key: string, options?: Omit<AttributeDefinition, 'kind'>) => ({\n type: 'attribute',\n key,\n kind: property,\n ...options,\n })\n },\n },\n)\n\nexport function interleave<\n const TKey extends string | symbol,\n const TLayout extends Array<AttributeToken<string | symbol, AttributeKind, undefined>>,\n const TOptions extends Omit<AttributeDefinition, 'kind'>,\n>(key: TKey, layout: TLayout, instanced: TOptions): InterleaveToken<TKey, TLayout, TOptions>\nexport function interleave<\n const TKey extends string | symbol,\n const TLayout extends Array<AttributeToken<string | symbol, AttributeKind, undefined>>,\n>(key: TKey, layout: TLayout): InterleaveToken<TKey, TLayout, { instanced: false }>\nexport function interleave<\n const TKey extends string | symbol,\n const TLayout extends Array<AttributeToken<string | symbol, AttributeKind, undefined>>,\n const TOptions extends Omit<AttributeDefinition, 'kind'>,\n>(key: TKey, layout: TLayout, { instanced, buffer }: Partial<TOptions> = {}) {\n return {\n type: 'interleavedAttribute',\n key,\n // remove instanced- and type-property\n layout: layout.map(({ key, kind }) => ({\n key,\n kind,\n })),\n instanced: !!instanced,\n buffer,\n } as unknown as InterleaveToken<TKey, TLayout, TOptions>\n}\n\n/**********************************************************************************/\n/* */\n/* Compile */\n/* */\n/**********************************************************************************/\n\nexport interface CompileOptions<TSchema extends ViewSchemaPartial> {\n schema?: TSchema\n webgl2?: boolean\n}\n\nexport function compile<\n TVertex extends GLSL,\n TFragment extends GLSL,\n TSchema extends ViewSchemaPartial,\n>(\n gl: WebGLRenderingContext,\n vertex: TVertex,\n fragment: TFragment,\n options?: CompileOptions<TSchema> | undefined,\n) {\n const _vertex = resolveGLSLTag(vertex, options) as { template: string; schema: ViewSchema }\n const _fragment = resolveGLSLTag(fragment, options) as { template: string; schema: ViewSchema }\n\n const schema = {\n uniforms: {\n ..._vertex.schema.uniforms,\n ..._fragment.schema.uniforms,\n },\n attributes: {\n ..._vertex.schema.attributes,\n ..._fragment.schema.attributes,\n },\n interleavedAttributes: {\n ..._vertex.schema.interleavedAttributes,\n ..._fragment.schema.interleavedAttributes,\n },\n }\n\n // Deep merge options.schema with generated schema\n for (const kind in options?.schema) {\n const schemaKind = schema[kind as keyof typeof schema]\n const configSchemaKind = options?.schema[kind]\n\n for (const key in configSchemaKind) {\n schemaKind[key] = {\n ...schemaKind[key],\n ...configSchemaKind[key],\n }\n }\n }\n\n try {\n const program = createProgram(gl, _vertex.template, _fragment.template)\n\n return {\n program,\n schema,\n view: view(gl, program, schema),\n vertex: _vertex.template,\n fragment: _fragment.template,\n } as unknown as Prettify<CompileResult<TVertex, TFragment, TSchema>>\n } catch (error) {\n console.error('Error while creating WebGLProgram - vertex\\n\\n', _vertex.template)\n console.error('Error while creating WebGLProgram - fragment\\n\\n', _fragment.template)\n\n throw error\n }\n}\n\nfunction resolveGLSLTag<TTag extends GLSL>(tag: TTag, options?: { webgl2?: boolean }) {\n return {\n template: compile.toString(tag, options),\n schema: compile.toSchema(tag),\n }\n}\n\ncompile.toSchema = function <TTag extends GLSL>(tag: TTag) {\n const result = {\n uniforms: {},\n attributes: {},\n interleavedAttributes: {},\n }\n\n tag.slots.forEach(function handleSlot(slot: GLSLSlot) {\n if (typeof slot !== 'object') {\n return\n }\n\n if (Array.isArray(slot)) {\n slot.forEach(handleSlot)\n return\n }\n\n if (slot.type === 'glsl') {\n const { uniforms, attributes, interleavedAttributes } = compile.toSchema(slot)\n\n result.uniforms = {\n ...result.uniforms,\n ...uniforms,\n }\n result.attributes = {\n ...result.attributes,\n ...attributes,\n }\n result.interleavedAttributes = {\n ...result.interleavedAttributes,\n ...interleavedAttributes,\n }\n\n return\n }\n\n const { key: name, type, ...rest } = slot\n\n // @ts-expect-error\n result[`${type}s`][name] = rest\n })\n\n return result as unknown as Prettify<GLSLToSchema<TTag>>\n}\n\ncompile.toString = function <TTag extends GLSL>(\n { template: [initial, ...rest], slots }: TTag,\n config?: { webgl2?: boolean },\n) {\n const v300 = config?.webgl2 ?? !!initial?.startsWith('#version 300 es')\n\n let template = initial ?? ''\n\n for (let i = 0; i < rest.length; i++) {\n template += `${resolveGlslSlotToString(slots[i]!, v300)}${rest[i]}`\n }\n\n return template\n}\n\nfunction resolveGlslSlotToString(slot: GLSLSlot, v300: boolean): string {\n if (typeof slot !== 'object') {\n return toID(slot)\n }\n\n if (Array.isArray(slot)) {\n return slot.map(slot => resolveGlslSlotToString(slot, v300)).join('')\n }\n\n switch (slot.type) {\n case 'glsl':\n return compile.toString(slot)\n case 'interleavedAttribute':\n return slot.layout.reduce(\n (a, v) =>\n v300 ? `${a}in ${v.kind} ${toID(v.key)};\\n` : `${a}attribute ${v.kind} ${toID(v.key)};\\n`,\n '',\n )\n case 'uniform':\n if ('size' in slot) {\n return `${slot.type} ${slot.kind} ${toID(slot.key)}[${slot.size}];`\n }\n return `${slot.type} ${slot.kind} ${toID(slot.key)};`\n }\n\n if (slot.type === 'attribute') {\n return `${v300 ? 'in' : slot.type} ${slot.kind} ${toID(slot.key)};`\n }\n\n throw new Error(`Unexpected slot: ${JSON.stringify(slot)}`)\n}\n\nconst QUAD_FLOAT_ARRAY = new Float32Array([-1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1])\nconst QUAD_BUFFER_MAP = createUpsertMap(WeakMap<GL, WebGLBuffer>)\n\ncompile.toQuad = function <TFragment extends GLSL, TSchema extends ViewSchemaPartial>(\n gl: GL,\n fragment: TFragment,\n options?: CompileOptions<TSchema>,\n) {\n const buffer = QUAD_BUFFER_MAP.getOrInsert(gl, gl.createBuffer.bind(gl))\n\n const webgl2 = options?.webgl2 ?? fragment.template[0]?.startsWith('#version 300 es')\n\n const vertex = webgl2\n ? glsl`#version 300 es\nprecision mediump float;\n\n${attribute.vec2('a_quad', { buffer })}\n\nout vec2 v_uv;\n\nvoid main() {\n v_uv = a_quad;\n gl_Position = vec4(v_uv, 0.0, 1.0);\n}`\n : glsl`precision mediump float;\n\n${attribute.vec2('a_quad', { buffer })}\n\nvarying vec2 v_uv;\n\nvoid main() {\n v_uv = a_quad;\n gl_Position = vec4(v_uv, 0.0, 1.0);\n}`\n\n const result = compile(gl, vertex, fragment, options)\n\n // @ts-expect-error\n result.view.attributes.a_quad.set(QUAD_FLOAT_ARRAY)\n\n return result\n}\n"],"mappings":"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","names":["map","index","value","name","index","layout","key","name","slot"]}
@@ -1,6 +1,9 @@
1
1
  type Prettify<T> = {
2
2
  [K in keyof T]: T[K];
3
3
  } & {};
4
+ type RemoveSuffix<T, S extends string> = {
5
+ [K in keyof T as K extends `${infer Prefix}${S}` ? Prefix : K]: T[K];
6
+ };
4
7
  type DeepMerge<A extends readonly [...any]> = A extends [infer L, ...infer R] ? DeepMergeTwo<L, DeepMerge<R>> : unknown;
5
8
  type DeepMergeTwo<TBase, TOverride> = {
6
9
  [K in keyof TBase | keyof TOverride]: K extends keyof TOverride ? K extends keyof TBase ? ShallowMerge<[TBase[K], TOverride[K]]> : TOverride[K] : K extends keyof TBase ? TBase[K] : never;
@@ -481,4 +484,4 @@ type CompileResult<TVertex extends GLSL, TFragment extends GLSL, TOverrideSchema
481
484
  fragment: string;
482
485
  } : never;
483
486
 
484
- export type { UniformToken as $, AttributeSchema as A, BufferSchema as B, BufferDefinition as C, BufferMethods as D, Framebuffer as E, FramebufferDefinition as F, GL as G, TextureTarget as H, InterleavedAttributeSchema as I, TextureSchema as J, KIND_TO_UNIFORM_FN_NAME_MAP as K, TextureMethods as L, TextureView as M, TextureParameterName as N, TextureParameterValue as O, TextureParameters as P, InternalFormat as Q, Format as R, PixelType as S, TextureDefinition as T, UniformSchema as U, ViewSchema as V, TexImage2DOptions as W, ViewSchemaPartial as X, GLSLResult as Y, GLSLSlot as Z, GLSL as _, ViewOptions as a, UniformTokenFn as a0, AttributeToken as a1, AttributeTokenFn as a2, InterleaveToken as a3, GLSLToSchema as a4, GLSLToView as a5, GLSLSlotsToSchema as a6, MergeGLSLSchema as a7, CompileResult as a8, Prettify as a9, View as b, UniformView as c, AttributeView as d, InterleavedAttributeView as e, BufferView as f, GLTarget as g, GLUsage as h, GLTextureTarget as i, GLTextureFormat as j, GLTextureType as k, GLTextureFilter as l, GLTextureWrap as m, KIND_TO_SIZE_MAP as n, UniformFnName as o, UniformKind as p, UniformDefinition as q, UniformSchemaPartial as r, UniformMethods as s, AttributeShortHand as t, AttributeKind as u, AttributeDefinition as v, AttributeMethods as w, InterleavedAttributeLayout as x, InterleavedAttributeDefinition as y, InterleavedAttributeMethods as z };
487
+ export type { GLSL as $, AttributeSchema as A, BufferSchema as B, BufferDefinition as C, BufferMethods as D, Framebuffer as E, FramebufferDefinition as F, GL as G, TextureTarget as H, InterleavedAttributeSchema as I, TextureSchema as J, KIND_TO_UNIFORM_FN_NAME_MAP as K, TextureMethods as L, TextureView as M, TextureParameterName as N, TextureParameterValue as O, TextureParameters as P, InternalFormat as Q, RemoveSuffix as R, Format as S, TextureDefinition as T, UniformSchema as U, ViewSchema as V, PixelType as W, TexImage2DOptions as X, ViewSchemaPartial as Y, GLSLResult as Z, GLSLSlot as _, ViewOptions as a, UniformToken as a0, UniformTokenFn as a1, AttributeToken as a2, AttributeTokenFn as a3, InterleaveToken as a4, GLSLToSchema as a5, GLSLToView as a6, GLSLSlotsToSchema as a7, MergeGLSLSchema as a8, CompileResult as a9, Prettify as aa, View as b, UniformView as c, AttributeView as d, InterleavedAttributeView as e, BufferView as f, GLTarget as g, GLUsage as h, GLTextureTarget as i, GLTextureFormat as j, GLTextureType as k, GLTextureFilter as l, GLTextureWrap as m, KIND_TO_SIZE_MAP as n, UniformFnName as o, UniformKind as p, UniformDefinition as q, UniformSchemaPartial as r, UniformMethods as s, AttributeShortHand as t, AttributeKind as u, AttributeDefinition as v, AttributeMethods as w, InterleavedAttributeLayout as x, InterleavedAttributeDefinition as y, InterleavedAttributeMethods as z };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bigmistqke/view.gl",
3
- "version": "0.1.10",
3
+ "version": "0.1.11",
4
4
  "description": "👀 Utilities for managing WebGL resources.",
5
5
  "exports": {
6
6
  ".": {
package/src/gl.ts CHANGED
@@ -1,4 +1,5 @@
1
- import { GL } from "./types"
1
+ import { RemoveSuffix } from './type-utils'
2
+ import { GL } from './types'
2
3
 
3
4
  export function createShader(gl: GL, type: number, source: string): WebGLShader {
4
5
  const shader = gl.createShader(type)
@@ -42,4 +43,62 @@ export function createProgram(gl: GL, vertexSource: string, fragmentSource: stri
42
43
  gl.deleteShader(fragmentShader)
43
44
 
44
45
  return program
45
- }
46
+ }
47
+
48
+ const INSTANCED_ARRAYS_WRAPPER_MAP = new WeakMap<
49
+ GL,
50
+ RemoveSuffix<
51
+ Pick<
52
+ ANGLE_instanced_arrays,
53
+ 'drawArraysInstancedANGLE' | 'drawElementsInstancedANGLE' | 'vertexAttribDivisorANGLE'
54
+ >,
55
+ 'ANGLE'
56
+ > | null
57
+ >()
58
+ export function getInstancedArrays(gl: GL) {
59
+ if (gl instanceof WebGL2RenderingContext) return gl
60
+
61
+ const cached = INSTANCED_ARRAYS_WRAPPER_MAP.get(gl)
62
+ if (cached) return cached
63
+
64
+ const ext = gl.getExtension('ANGLE_instanced_arrays')
65
+ if (!ext) return undefined
66
+
67
+ const wrapper = {
68
+ drawArraysInstanced: ext.drawArraysInstancedANGLE.bind(ext),
69
+ drawElementsInstanced: ext.drawElementsInstancedANGLE.bind(ext),
70
+ vertexAttribDivisor: ext.vertexAttribDivisorANGLE.bind(ext),
71
+ }
72
+ INSTANCED_ARRAYS_WRAPPER_MAP.set(gl, wrapper)
73
+
74
+ return wrapper
75
+ }
76
+
77
+ const VERTEX_ARRAY_OBJECT_WRAPPER_MAP = new WeakMap<
78
+ GL,
79
+ RemoveSuffix<
80
+ Pick<
81
+ OES_vertex_array_object,
82
+ 'bindVertexArrayOES' | 'createVertexArrayOES' | 'deleteVertexArrayOES'
83
+ >,
84
+ 'OES'
85
+ > | null
86
+ >()
87
+ export function getVertexArrayObject(gl: GL) {
88
+ if (gl instanceof WebGL2RenderingContext) return gl
89
+
90
+ const cached = VERTEX_ARRAY_OBJECT_WRAPPER_MAP.get(gl)
91
+ if (cached) return cached
92
+
93
+ const ext = gl.getExtension('OES_vertex_array_object')
94
+ if (!ext) return null
95
+
96
+ const wrapper = {
97
+ bindVertexArray: ext.bindVertexArrayOES.bind(ext),
98
+ createVertexArray: ext.createVertexArrayOES.bind(ext),
99
+ deleteVertexArray: ext.deleteVertexArrayOES.bind(ext),
100
+ }
101
+ VERTEX_ARRAY_OBJECT_WRAPPER_MAP.set(gl, wrapper)
102
+
103
+ return wrapper
104
+ }
package/src/index.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { getInstancedArrays, getVertexArrayObject } from './features'
1
+ import { getInstancedArrays, getVertexArrayObject } from './gl'
2
2
  import type {
3
3
  AttributeMethods,
4
4
  AttributeSchema,
@@ -24,7 +24,7 @@ import {
24
24
  kindToUniformFnName,
25
25
  } from './utils'
26
26
  export * from './types'
27
- import * as ObjectUtils from "./utils/object"
27
+ import * as ObjectUtils from './utils/object'
28
28
 
29
29
  /**********************************************************************************/
30
30
  /* */
package/src/features.ts DELETED
@@ -1,60 +0,0 @@
1
- import { RemoveSuffix } from './type-utils'
2
- import type { GL } from './types'
3
-
4
- const INSTANCED_ARRAYS_WRAPPER_MAP = new WeakMap<
5
- GL,
6
- RemoveSuffix<
7
- Pick<
8
- ANGLE_instanced_arrays,
9
- 'drawArraysInstancedANGLE' | 'drawElementsInstancedANGLE' | 'vertexAttribDivisorANGLE'
10
- >,
11
- 'ANGLE'
12
- > | null
13
- >()
14
- export function getInstancedArrays(gl: GL) {
15
- if (gl instanceof WebGL2RenderingContext) return gl
16
-
17
- const cached = INSTANCED_ARRAYS_WRAPPER_MAP.get(gl)
18
- if (cached) return cached
19
-
20
- const ext = gl.getExtension('ANGLE_instanced_arrays')
21
- if (!ext) return undefined
22
-
23
- const wrapper = {
24
- drawArraysInstanced: ext.drawArraysInstancedANGLE.bind(ext),
25
- drawElementsInstanced: ext.drawElementsInstancedANGLE.bind(ext),
26
- vertexAttribDivisor: ext.vertexAttribDivisorANGLE.bind(ext),
27
- }
28
- INSTANCED_ARRAYS_WRAPPER_MAP.set(gl, wrapper)
29
-
30
- return wrapper
31
- }
32
-
33
- const VERTEX_ARRAY_OBJECT_WRAPPER_MAP = new WeakMap<
34
- GL,
35
- RemoveSuffix<
36
- Pick<
37
- OES_vertex_array_object,
38
- 'bindVertexArrayOES' | 'createVertexArrayOES' | 'deleteVertexArrayOES'
39
- >,
40
- 'OES'
41
- > | null
42
- >()
43
- export function getVertexArrayObject(gl: GL) {
44
- if (gl instanceof WebGL2RenderingContext) return gl
45
-
46
- const cached = VERTEX_ARRAY_OBJECT_WRAPPER_MAP.get(gl)
47
- if (cached) return cached
48
-
49
- const ext = gl.getExtension('OES_vertex_array_object')
50
- if (!ext) return null
51
-
52
- const wrapper = {
53
- bindVertexArray: ext.bindVertexArrayOES.bind(ext),
54
- createVertexArray: ext.createVertexArrayOES.bind(ext),
55
- deleteVertexArray: ext.deleteVertexArrayOES.bind(ext),
56
- }
57
- VERTEX_ARRAY_OBJECT_WRAPPER_MAP.set(gl, wrapper)
58
-
59
- return wrapper
60
- }