littlejsengine 1.24.2 → 1.25.0

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.
Files changed (42) hide show
  1. package/CHANGELOG.md +55 -0
  2. package/EDITOR.md +2 -2
  3. package/FAQ.md +6 -0
  4. package/REFERENCE.md +86 -41
  5. package/dist/littlejs.d.ts +600 -323
  6. package/dist/littlejs.esm.js +2412 -1797
  7. package/dist/littlejs.esm.min.js +38 -24
  8. package/dist/littlejs.js +2410 -1797
  9. package/dist/littlejs.min.js +37 -23
  10. package/dist/littlejs.release.js +2393 -1826
  11. package/package.json +1 -1
  12. package/plugins/box2d.js +41 -28
  13. package/plugins/drawUtilities.js +374 -380
  14. package/plugins/gltf.js +331 -55
  15. package/plugins/lightSystem.js +2 -2
  16. package/plugins/math3d.js +1013 -1014
  17. package/plugins/newgrounds.js +1 -4
  18. package/plugins/particleEffects.js +3 -4
  19. package/plugins/pathFinder.js +52 -28
  20. package/plugins/pluginExport.js +2 -0
  21. package/plugins/postProcess.js +196 -65
  22. package/plugins/render3d.js +8 -6
  23. package/plugins/render3dEditor.js +3 -3
  24. package/plugins/render3dExtras.js +31 -10
  25. package/plugins/render3dLevel.js +15 -4
  26. package/plugins/textureSheet.js +15 -7
  27. package/plugins/tweenSystem.js +43 -38
  28. package/plugins/uiSystem.js +25 -20
  29. package/src/engine.js +39 -21
  30. package/src/engineAudio.js +13 -9
  31. package/src/engineBuild.mjs +49 -2
  32. package/src/engineDebug.js +3 -2
  33. package/src/engineDraw.js +20 -18
  34. package/src/engineEditor.js +75 -23
  35. package/src/engineInput.js +10 -10
  36. package/src/engineMath.js +3 -6
  37. package/src/engineObject.js +8 -9
  38. package/src/engineParticles.js +8 -7
  39. package/src/engineRelease.js +17 -10
  40. package/src/engineTileLayer.js +33 -14
  41. package/src/engineUtilities.js +15 -2
  42. package/src/engineWebGL.js +34 -12
@@ -37,13 +37,13 @@
37
37
  * let pos = vec2(2,3);
38
38
  * let particleEmitter = new ParticleEmitter
39
39
  * (
40
- * pos, 0, 1, 0, 500, PI, // pos, angle, emitSize, emitTime, emitRate, emitCone
40
+ * pos, 0, 1, 0, 500, PI, // pos, angle, emitSize, emitTime, emitRate, emitConeAngle
41
41
  * tile(0, 16), // tileInfo
42
42
  * rgb(1,1,1,1), rgb(0,0,0,1), // colorStartA, colorStartB
43
43
  * rgb(1,1,1,0), rgb(0,0,0,0), // colorEndA, colorEndB
44
- * 1, .2, .2, .1, .05, // particleTime, sizeStart, sizeEnd, particleSpeed, particleAngleSpeed
45
- * .99, 1, 1, PI, .05, // damping, angleDamping, gravityScale, particleCone, fadeRate
46
- * .5, true // randomness, collide
44
+ * 1, .2, .2, .1, .05, // particleTime, sizeStart, sizeEnd, speed, angleSpeed
45
+ * .99, 1, 1, PI, .05, // damping, angleDamping, gravityScale, particleConeAngle, fadeRate
46
+ * .5, true // randomness, collideLevel
47
47
  * );
48
48
  */
49
49
  class ParticleEmitter extends EngineObject
@@ -336,7 +336,8 @@ class ParticleEmitter extends EngineObject
336
336
  this.additive && setAdditiveBlendMode(false);
337
337
  }
338
338
 
339
- /** is emitter actively spawning */
339
+ /** is emitter actively spawning
340
+ * @return {boolean} */
340
341
  isActive() { return !this.emitTime || this.getAliveTime() < this.emitTime; }
341
342
 
342
343
  /** Destroy the particle emitter
@@ -548,8 +549,8 @@ class Particle
548
549
  }
549
550
  if (isBlockedY || !isBlockedX)
550
551
  {
551
- // down is the world's gravity, or the emitter's own fall in a world with none
552
- const down = gravity.y || emitter.gravity || 0;
552
+ // down is the way it falls, the world's gravity by its gravityScale and the emitter's own
553
+ const down = gravityY;
553
554
  const wasFalling = this.velocity.y < 0 && down < 0 || this.velocity.y > 0 && down > 0;
554
555
  if (wasFalling)
555
556
  this.groundObject = hitLayer;
@@ -10,18 +10,17 @@
10
10
 
11
11
  'use strict';
12
12
 
13
- let debugWatermark = 0;
13
+ let debugWatermark = false;
14
14
  let debugKey = '';
15
15
  let debugKeysAlways = false;
16
16
  let debugTweakables = false;
17
- let debugClearCount = 0;
18
- const debug = 0;
19
- const debugOverlay = 0;
20
- const debugPhysics = 0;
21
- const debugParticles = 0;
22
- const debugRaycast = 0;
23
- const debugGamepads = 0;
24
- const debugSound = 0;
17
+ const debug = false;
18
+ const debugOverlay = false;
19
+ const debugPhysics = false;
20
+ const debugParticles = false;
21
+ const debugRaycast = false;
22
+ const debugGamepads = false;
23
+ const debugSound = false;
25
24
  const debugPointSize = .5;
26
25
 
27
26
  // debug commands are automatically removed from the final build
@@ -52,6 +51,14 @@ function tweak(){}
52
51
  function tweakButton(){}
53
52
  function tweakDivider(){}
54
53
  function tweakEngineDefaults(){}
54
+ // the 2D editor's edit functions in a release build, which has no editor: there is nothing to edit and nothing
55
+ // changes, and a game that calls them needs no guard; edit3D stays undefined, as it is with no 3D plugins
56
+ const editorEdit2DRelease =
57
+ {
58
+ map: undefined, layer: undefined, hover: undefined, get objects() { return []; }, get selection() { return new Set; },
59
+ paint(){ return false; }, changeObjects(){ return false; }, strokeEnd(){}, strokeCancel(){}, bulk(){},
60
+ undo(){ return false; }, toJSON(){ return ''; },
61
+ };
55
62
  class LevelEditor
56
63
  {
57
64
  constructor()
@@ -61,7 +68,7 @@ class LevelEditor
61
68
  }
62
69
  get isOpen() { return false; }
63
70
  get is3D() { return false; }
64
- get edit2D() { return undefined; }
71
+ get edit2D() { return editorEdit2DRelease; }
65
72
  get edit3D() { return undefined; }
66
73
  open(){} close(){} addKey(){} addButton(){} addTool(){}
67
74
  onTile(){} onRestart(){} onPlayFrom(){} onOpen(){} onClose(){} onUpdate(){} onDraw(){} onPanel(){}
@@ -7,7 +7,7 @@
7
7
  * - TileLayer for rendering, TileCollisionLayer for physics
8
8
  * - Collision callbacks for tile interactions with objects
9
9
  * - Optimized raycast support for tile-based physics
10
- * - Integration with Box2D physics via Box2DTileLayer plugin
10
+ * - Integration with Box2D physics via the Box2dTileLayer plugin
11
11
  * @namespace TileLayers
12
12
  */
13
13
 
@@ -16,6 +16,28 @@
16
16
  ///////////////////////////////////////////////////////////////////////////////
17
17
  // Tile Layer System
18
18
 
19
+ /** A Tiled map as Tiled saves it as JSON, what tileLayersLoad and objectLayersLoad take and tileLayersFromLDtk
20
+ * makes; the fields read are listed, and the rest of the file is kept as it is
21
+ * @typedef {Object} TiledMap
22
+ * @property {number} width - Cells across
23
+ * @property {number} height - Cells up
24
+ * @property {number} [tilewidth] - A tile's width in pixels
25
+ * @property {number} [tileheight] - A tile's height in pixels
26
+ * @property {Array<Object>} layers - Tile layers, object layers and groups of them, bottom first
27
+ * @property {Array<Object>} [tilesets] - The first one's margin, spacing and columns are read
28
+ * @property {number} [nextlayerid]
29
+ * @property {number} [nextobjectid]
30
+ * @property {string} [orientation]
31
+ * @property {string} [renderorder]
32
+ * @property {boolean} [infinite]
33
+ * @property {string} [type]
34
+ * @property {string|number} [version] - A number in files from Tiled before 1.6
35
+ * @property {string} [tiledversion]
36
+ * @property {number} [compressionlevel]
37
+ * @property {string} [backgroundcolor]
38
+ * @property {Array<Object>} [properties]
39
+ * @memberof TileLayers */
40
+
19
41
  /** Keep track of all tile layers with collision
20
42
  * @type {Array<TileCollisionLayer>}
21
43
  * @memberof TileLayers */
@@ -90,7 +112,7 @@ function tileCollisionTest(pos, size=vec2(), callbackObject, solidOnly=true)
90
112
  * @param {Vector2} posEnd
91
113
  * @param {EngineObject|TileCollisionCallback} [callbackObject] - Callback, engine object, or undefined
92
114
  * @param {Vector2} [normal] - Optional normal of the surface hit
93
- * @param {boolean} [solidOnly=true] - Only check solid layers?
115
+ * @param {boolean} [solidOnly] - Only check solid layers?
94
116
  * @return {Vector2|undefined} - where the ray meets the first tile hit, nudged just inside it, or undefined if no hit
95
117
  * @memberof TileLayers */
96
118
  function tileCollisionRaycast(posStart, posEnd, callbackObject, normal, solidOnly=true)
@@ -151,7 +173,7 @@ function tileLayerTileInfo(t, tile)
151
173
  * - An object or image layer keeps its index, with its slot in the returned array left empty
152
174
  * - A hidden layer (visible false) is loaded, its collision included, but not drawn; its render
153
175
  * is a no-op, delete that and call redraw() to show it
154
- * @param {Object} tileMapData - Level data from exported data
176
+ * @param {TiledMap} [tileMapData] - Level data from exported data, a 50 by 50 empty level when left out
155
177
  * @param {TileInfo} [tileInfo] - Default tile info (used for size and texture), tile() by default, none when no image is loaded
156
178
  * @param {number} [renderOrder] - Render order of the top layer
157
179
  * @param {number|string} [collisionLayer] - Layer to use for collision if any, by its index or its name
@@ -165,10 +187,7 @@ function tileLayersLoad(tileMapData, tileInfo=tileLayerDefaultTile(), renderOrde
165
187
  {
166
188
  // default level data if loading failed
167
189
  const s = 50;
168
- tileMapData = {};
169
- tileMapData.height = tileMapData.width = s;
170
- tileMapData.layers = [{}];
171
- tileMapData.layers[0].data = new Array(s*s).fill(0);
190
+ tileMapData = {width: s, height: s, layers: [{data: new Array(s*s).fill(0)}]};
172
191
  }
173
192
 
174
193
  // the editor, in debug builds, keeps the map as the source of its edits and brings back autosaved ones
@@ -310,7 +329,7 @@ const tileLayersLDtkTypes = {Int: 'int', Float: 'float', Bool: 'bool', String: '
310
329
  * - The level editor edits the map this returns, and saves it as a Tiled map
311
330
  * @param {Object} ldtk - The LDtk project, its JSON
312
331
  * @param {number|string} [level] - Which level, by its index or its identifier
313
- * @return {Object} - A Tiled map: width, height, tilewidth, tileheight, tilesets and layers
332
+ * @return {TiledMap} - A Tiled map: width, height, tilewidth, tileheight, tilesets and layers
314
333
  * @example
315
334
  * const map = tileLayersFromLDtk(await fetchJSON('world.ldtk'), 'Level_0');
316
335
  * const layers = tileLayersLoad(map, tile(0, 16), 0, 'Collisions'); // its IntGrid layer is solid
@@ -441,7 +460,7 @@ const objectLayersTypes = new Map;
441
460
  * - Adding a name again replaces it
442
461
  * @param {string} name - The type the objects have in Tiled
443
462
  * @param {Function} make - A class made at each object's position, or a function called with it
444
- * @param {Object} [defaults] - Properties set on each one made, the level editor shows inputs for them
463
+ * @param {Object<string, any>} [defaults] - Properties set on each one made, the level editor shows inputs for them
445
464
  * @param {TileInfo} [tileInfo] - An icon for the level editor
446
465
  * @memberof TileLayers
447
466
  * @example
@@ -462,7 +481,7 @@ function objectLayersAddType(name, make, defaults={}, tileInfo)
462
481
  * - The object's properties in Tiled are set over the type's defaults: numbers, booleans, strings, and colors,
463
482
  * and for a Vector2 default the string x,y
464
483
  * - An object whose type was not added is skipped, with a warning in debug builds
465
- * @param {Object} tileMapData - The same Tiled map given to tileLayersLoad
484
+ * @param {TiledMap} tileMapData - The same Tiled map given to tileLayersLoad
466
485
  * @return {Array<any>} - What each object's type made, a function that made nothing is left out
467
486
  * @memberof TileLayers */
468
487
  function objectLayersLoad(tileMapData)
@@ -556,7 +575,7 @@ class TileLayerData
556
575
  /** Create a tile layer data object, one for each tile in a TileLayer
557
576
  * @param {number} [tile] - The tile to use, from 0 like tile(); undefined is an empty cell that draws nothing
558
577
  * @param {number} [direction] - Integer direction of tile, in 90 degree increments
559
- * @param {boolean} [mirror] - If the tile should be mirrored along the x axis
578
+ * @param {boolean} [mirror] - If the tile is flipped left to right
560
579
  * @param {Color} [color] - Color of the tile */
561
580
  constructor(tile, direction=0, mirror=false, color=new Color)
562
581
  {
@@ -565,7 +584,7 @@ class TileLayerData
565
584
  this.tile = tile;
566
585
  /** @property {number} - Integer direction of tile, in 90 degree increments */
567
586
  this.direction = direction;
568
- /** @property {boolean} - If the tile should be mirrored along the x axis */
587
+ /** @property {boolean} - If the tile is flipped left to right */
569
588
  this.mirror = mirror;
570
589
  /** @property {Color} - Color of the tile */
571
590
  this.color = color.copy();
@@ -641,7 +660,7 @@ class CanvasLayer extends EngineObject
641
660
  * @param {Vector2} [size] - Size in world space
642
661
  * @param {Color} [color] - Color to modulate with
643
662
  * @param {number} [angle] - Angle to rotate by
644
- * @param {boolean} [mirror] - If true image is flipped along the Y axis
663
+ * @param {boolean} [mirror] - If true the image is flipped left to right
645
664
  * @param {Color} [additiveColor] - Additive color to be applied if any
646
665
  * @param {boolean} [screenSpace=drawScreenSpace] - If true the pos and size are in screen space
647
666
  * @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context] - Canvas 2D context to draw to */
@@ -931,7 +950,7 @@ class TileLayer extends CanvasLayer
931
950
  * @param {TileInfo} [tileInfo] - Tile info to use, untextured if undefined
932
951
  * @param {Color} [color=WHITE] - Color to modulate with
933
952
  * @param {number} [angle] - Angle to rotate by
934
- * @param {boolean} [mirror] - Is image flipped along the Y axis?
953
+ * @param {boolean} [mirror] - Is the image flipped left to right?
935
954
  * @param {Color} [additiveColor] - Additive color to be applied if any */
936
955
  drawLayerTile(pos, size=vec2(1), tileInfo, color=WHITE,
937
956
  angle=0, mirror, additiveColor)
@@ -117,18 +117,29 @@ function formatTime(t)
117
117
 
118
118
  /** Fetches a JSON file from a URL and returns the parsed JSON object. Must be used with await!
119
119
  * @param {string} url - URL of JSON file
120
- * @return {Promise<object>}
120
+ * @return {Promise<any>} - The parsed JSON, any shape, as response.json() gives it
121
121
  * @memberof Utilities */
122
122
  async function fetchJSON(url)
123
123
  {
124
124
  const response = await fetch(url);
125
125
  if (!response.ok)
126
126
  throw new Error(`Failed to fetch JSON from ${url}: ${response.status} ${response.statusText}`);
127
- const json = await response.json();
127
+ const text = await response.text();
128
+ let json;
129
+ try { json = JSON.parse(text); }
130
+ catch (e)
131
+ {
132
+ // a dev server answers a mistyped path with its own page, which is no JSON, so the error says which file
133
+ throw new Error(`fetchJSON: ${url} is not JSON` + (loadIsWebPage(text) ?
134
+ ', it is a web page, so the path may be wrong' : ': ' + e.message));
135
+ }
128
136
  editorJSONFetched(url, json); // debug builds remember the file a level came from, to save it by that name
129
137
  return json;
130
138
  }
131
139
 
140
+ // is a file's text a web page, as a dev server sends for a path it does not have
141
+ const loadIsWebPage = (text)=> /^\s*</.test(text);
142
+
132
143
  ///////////////////////////////////////////////////////////////////////////////
133
144
 
134
145
  /** Save a text file to disk
@@ -239,6 +250,8 @@ function readSaveData(saveName, defaultSaveData)
239
250
  {
240
251
  try { loadedData = JSON.parse(data); }
241
252
  catch { LOG('readSaveData: corrupt JSON for', saveName, '— using defaults'); }
253
+ if (!loadedData || typeof loadedData !== 'object' || isArray(loadedData))
254
+ loadedData = {}; // only an object of saved values, never a string spread into its letters
242
255
  }
243
256
  }
244
257
  catch { LOG('readSaveData: localStorage unavailable — using defaults'); }
@@ -46,11 +46,12 @@ let glAntialias = true;
46
46
 
47
47
  // WebGL internal variables not exposed to documentation
48
48
  let glMipmappedTextures = new WeakSet, glMipmapsUntilTarget = new WeakSet, glMipmapsStale = new Set, glPremultipliedTextures = new WeakSet, glShaderPremultiplied, glEnableBeforeLoss = true, glShader, glPolyShader, glPolyMode, glAdditive, glBatchAdditive, glActiveTexture, glArrayBuffer, glGeometryBuffer, glPositionData, glColorData, glBatchCount, glTextureInfos = new Set, glInstancedVAO, glPolyVAO, glFramebuffer, glRenderTarget, glShaderObjects = [], glCustomShader, glBatchShader, glProgramCustom, glTransform, glRenderTargetSaved, glUniformLocations = new WeakMap, glCanBeEnabled = true;
49
+ let glFailedPrograms = new WeakSet; // programs that did not build in a release build, which nothing draws with
49
50
  // ANDed onto every packed color as a draw is queued; the light system's shadow pass sets 0xff000000
50
51
  // to draw everything black with its alpha kept (rgbaInt packs alpha in the top byte)
51
52
  let glColorMask = -1;
52
53
  // ORed onto the additive color of every quad and onto every poly point's color as a draw is queued; the light system's
53
- // emissive pass sets a grey with the mask at 0xff000000, so a draw comes out that grey in its own shape
54
+ // emissive pass sets a gray with the mask at 0xff000000, so a draw comes out that gray in its own shape
54
55
  let glColorAdditive = 0;
55
56
  // a texture drawn into with the canvas's own transform and its size, the light system's lightmap while its pass
56
57
  // runs: a target set and ended inside it, like a tile layer redrawn in a renderLight, goes back to it, not the canvas
@@ -218,6 +219,14 @@ function glInit(rootElement)
218
219
  '}' // end of shader
219
220
  );
220
221
 
222
+ // a device that can not build the engine's own programs draws with Canvas2D, as after a lost context
223
+ if (glFailedPrograms.has(glShader) || glFailedPrograms.has(glPolyShader))
224
+ {
225
+ console.error('LittleJS: WebGL can not draw on this device, using Canvas2D');
226
+ glEnable = glCanBeEnabled = false;
227
+ glCanvas.style.display = 'none';
228
+ }
229
+
221
230
  // init buffers
222
231
  const glInstanceData = new ArrayBuffer(gl_ARRAY_BUFFER_SIZE);
223
232
  glPositionData = new Float32Array(glInstanceData);
@@ -436,7 +445,7 @@ function glSetTextureWrap(texture, wrap=true)
436
445
  /** Compile WebGL shader of the given type, will throw errors if in debug mode
437
446
  * @param {string} source
438
447
  * @param {number} type
439
- * @return {WebGLShader}
448
+ * @return {WebGLShader|undefined} - undefined with no WebGL
440
449
  * @memberof WebGL */
441
450
  function glCompileShader(source, type)
442
451
  {
@@ -456,7 +465,7 @@ function glCompileShader(source, type)
456
465
  /** Create WebGL program with given shaders
457
466
  * @param {string} vsSource
458
467
  * @param {string} fsSource
459
- * @return {WebGLProgram}
468
+ * @return {WebGLProgram|undefined} - undefined with no WebGL
460
469
  * @memberof WebGL */
461
470
  function glCreateProgram(vsSource, fsSource)
462
471
  {
@@ -464,13 +473,23 @@ function glCreateProgram(vsSource, fsSource)
464
473
 
465
474
  // build the program
466
475
  const program = glContext.createProgram();
467
- glContext.attachShader(program, glCompileShader(vsSource, glContext.VERTEX_SHADER));
468
- glContext.attachShader(program, glCompileShader(fsSource, glContext.FRAGMENT_SHADER));
476
+ const vertexShader = glCompileShader(vsSource, glContext.VERTEX_SHADER);
477
+ const fragmentShader = glCompileShader(fsSource, glContext.FRAGMENT_SHADER);
478
+ glContext.attachShader(program, vertexShader);
479
+ glContext.attachShader(program, fragmentShader);
469
480
  glContext.linkProgram(program);
470
481
 
471
- // check for errors
472
- if (debug && !glContext.getProgramParameter(program, glContext.LINK_STATUS))
473
- throw glContext.getProgramInfoLog(program);
482
+ // check for errors in every build, as a driver may refuse what another takes: a debug build throws, a release
483
+ // one says why once and marks the program, which the engine's draws then do without
484
+ if (!glContext.getProgramParameter(program, glContext.LINK_STATUS))
485
+ {
486
+ const log = glContext.getProgramInfoLog(program) + '\n' +
487
+ glContext.getShaderInfoLog(vertexShader) + glContext.getShaderInfoLog(fragmentShader);
488
+ if (debug)
489
+ throw log;
490
+ console.error('LittleJS: a shader failed to build\n' + log);
491
+ glFailedPrograms.add(program);
492
+ }
474
493
  return program;
475
494
  }
476
495
 
@@ -486,7 +505,7 @@ function glUniformLocation(program, name)
486
505
  // color, then the sprite's color and additive color apply as the engine's own fragment shader does
487
506
  function glShaderProgram(shader)
488
507
  {
489
- return shader.program ||= glCreateProgram(gl_VERTEX_SOURCE,
508
+ const program = shader.program ||= glCreateProgram(gl_VERTEX_SOURCE,
490
509
  '#version 300 es\n' +
491
510
  'precision highp float;' +
492
511
  'uniform sampler2D iChannel0;' + // the texture
@@ -497,6 +516,7 @@ function glShaderProgram(shader)
497
516
  '#define localUV l\n' +
498
517
  shader.fragmentCode + '\n' +
499
518
  'void main(){vec4 t;mainImage(t,v);' + gl_FRAGMENT_TINT_SOURCE + '}');
519
+ return glFailedPrograms.has(program) ? glShader : program;
500
520
  }
501
521
 
502
522
  /** Create WebGL texture from an image and init the texture settings
@@ -504,7 +524,7 @@ function glShaderProgram(shader)
504
524
  * @param {HTMLImageElement|HTMLCanvasElement|OffscreenCanvas|ImageBitmap} [image]
505
525
  * @param {boolean|Array<number>} [wrap] - true for REPEAT, false for CLAMP_TO_EDGE, or the WebGL modes across and down
506
526
  * @param {boolean} [pixelated] - Hard edged or smooth, undefined follows tilesPixelated
507
- * @return {WebGLTexture}
527
+ * @return {WebGLTexture|undefined} - undefined with no WebGL
508
528
  * @memberof WebGL */
509
529
  function glCreateTexture(image, wrap=false, pixelated=tilesPixelated)
510
530
  {
@@ -673,6 +693,8 @@ function glFlush()
673
693
  const height = glRenderTarget ? mainCanvasSize.y : glCanvas.height;
674
694
  glContext.uniform3f(uniform('iResolution'), width, height, 1);
675
695
  glContext.uniform1i(uniform('premultipliedTexture'), +premultiplied);
696
+ if (program === glShader)
697
+ glShaderPremultiplied = premultiplied; // a Shader that did not build draws with the engine's
676
698
  }
677
699
  }
678
700
  if (!glPolyMode && !glBatchShader && glShaderPremultiplied !== premultiplied)
@@ -730,8 +752,8 @@ function glSetAntialias(antialias=true)
730
752
  * @param {number} [uv0Y]
731
753
  * @param {number} [uv1X]
732
754
  * @param {number} [uv1Y]
733
- * @param {number} [rgba=-1] - white is -1
734
- * @param {number} [rgbaAdditive=0] - black is 0
755
+ * @param {number} [rgba] - white is -1
756
+ * @param {number} [rgbaAdditive] - black is 0
735
757
  * @memberof WebGL */
736
758
  function glDraw(x, y, sizeX, sizeY, angle=0, uv0X=0, uv0Y=0, uv1X=1, uv1Y=1, rgba=-1, rgbaAdditive=0)
737
759
  {