littlejsengine 1.7.21 → 1.8.1

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 (51) hide show
  1. package/README.md +27 -55
  2. package/build/littlejs.d.ts +101 -58
  3. package/build/littlejs.esm.js +497 -419
  4. package/build/littlejs.esm.min.js +1 -1
  5. package/build/littlejs.js +493 -228
  6. package/build/littlejs.min.js +1 -1
  7. package/build/littlejs.release.js +493 -228
  8. package/examples/breakout/game.js +17 -14
  9. package/examples/breakout/gameObjects.js +29 -8
  10. package/examples/breakout/index.html +3 -3
  11. package/examples/breakoutTutorial/README.md +2 -2
  12. package/examples/breakoutTutorial/game.js +4 -4
  13. package/examples/breakoutTutorial/index.html +2 -2
  14. package/examples/electron/game.js +3 -2
  15. package/examples/electron/index.html +2 -2
  16. package/examples/empty/game.js +1 -1
  17. package/examples/favicon.png +0 -0
  18. package/examples/js13k/game.js +20 -15
  19. package/examples/js13k/index.html +14 -14
  20. package/examples/module/game.js +4 -3
  21. package/examples/module/index.html +1 -1
  22. package/examples/particles/index.html +19 -22
  23. package/examples/platformer/game.js +3 -3
  24. package/examples/platformer/gameEffects.js +21 -19
  25. package/examples/platformer/gameLevel.js +6 -6
  26. package/examples/platformer/gameObjects.js +18 -18
  27. package/examples/platformer/gamePlayer.js +4 -3
  28. package/examples/platformer/index.html +6 -6
  29. package/examples/platformer/tiles.png +0 -0
  30. package/examples/platformer/tilesLevel.png +0 -0
  31. package/examples/puzzle/game.js +10 -8
  32. package/examples/puzzle/index.html +2 -2
  33. package/examples/screenshot.jpg +0 -0
  34. package/examples/starter/game.js +32 -21
  35. package/examples/starter/index.html +13 -13
  36. package/examples/starter/tiles.png +0 -0
  37. package/examples/stress/index.html +2 -2
  38. package/examples/typescript/game.js +4 -3
  39. package/examples/typescript/game.ts +4 -3
  40. package/examples/typescript/index.html +1 -1
  41. package/package.json +1 -1
  42. package/src/engine.js +59 -52
  43. package/src/engineDraw.js +137 -38
  44. package/src/engineExport.js +4 -191
  45. package/src/engineMedals.js +13 -45
  46. package/src/engineObject.js +12 -13
  47. package/src/engineParticles.js +17 -17
  48. package/src/engineSettings.js +195 -2
  49. package/src/engineTileLayer.js +23 -22
  50. package/src/engineUtilities.js +6 -6
  51. package/src/engineWebGL.js +31 -32
@@ -13,7 +13,7 @@
13
13
  * let particleEmiter = new ParticleEmitter
14
14
  * (
15
15
  * pos, 0, 1, 0, 500, PI, // pos, angle, emitSize, emitTime, emitRate, emiteCone
16
- * 0, vec2(16), // tileIndex, tileSize
16
+ * tile(0, 16), // tileInfo
17
17
  * new Color(1,1,1), new Color(0,0,0), // colorStartA, colorStartB
18
18
  * new Color(1,1,1,0), new Color(0,0,0,0), // colorEndA, colorEndB
19
19
  * 2, .2, .2, .1, .05, // particleTime, sizeStart, sizeEnd, particleSpeed, particleAngleSpeed
@@ -30,8 +30,7 @@ class ParticleEmitter extends EngineObject
30
30
  * @param {Number} [emitTime=0] - How long to stay alive (0 is forever)
31
31
  * @param {Number} [emitRate=100] - How many particles per second to spawn, does not emit if 0
32
32
  * @param {Number} [emitConeAngle=PI] - Local angle to apply velocity to particles from emitter
33
- * @param {Number} [tileIndex=-1] - Index into tile sheet, if <0 no texture is applied
34
- * @param {Vector2} [tileSize=tileSizeDefault] - Tile size for particles
33
+ * @param {TileInfo} [tileInfo] - Tile info to render particles (undefined is untextured)
35
34
  * @param {Color} [colorStartA=Color()] - Color at start of life 1, randomized between start colors
36
35
  * @param {Color} [colorStartB=Color()] - Color at start of life 2, randomized between start colors
37
36
  * @param {Color} [colorEndA=Color(1,1,1,0)] - Color at end of life 1, randomized between end colors
@@ -61,8 +60,7 @@ class ParticleEmitter extends EngineObject
61
60
  emitTime = 0,
62
61
  emitRate = 100,
63
62
  emitConeAngle = PI,
64
- tileIndex = -1,
65
- tileSize = tileSizeDefault,
63
+ tileInfo,
66
64
  colorStartA = new Color,
67
65
  colorStartB = new Color,
68
66
  colorEndA = new Color(1,1,1,0),
@@ -85,7 +83,7 @@ class ParticleEmitter extends EngineObject
85
83
  localSpace
86
84
  )
87
85
  {
88
- super(pos, vec2(), tileIndex, tileSize, angle, undefined, renderOrder);
86
+ super(pos, vec2(), tileInfo, angle, undefined, renderOrder);
89
87
 
90
88
  // emitter settings
91
89
  /** @property {Number} - World space size of the emitter (float for circle diameter, vec2 for rect) */
@@ -184,7 +182,7 @@ class ParticleEmitter extends EngineObject
184
182
  angle += this.angle;
185
183
  }
186
184
 
187
- const particle = new Particle(pos, this.tileIndex, this.tileSize, angle);
185
+ const particle = new Particle(pos, this.tileInfo, this.tileSize, angle);
188
186
 
189
187
  // randomness scales each paremeter by a percentage
190
188
  const randomness = this.randomness;
@@ -244,12 +242,11 @@ class Particle extends EngineObject
244
242
  /**
245
243
  * Create a particle with the given settings
246
244
  * @param {Vector2} position - World space position of the particle
247
- * @param {Number} [tileIndex=-1] - Tile to use to render, untextured if -1
248
- * @param {Vector2} [tileSize=tileSizeDefault] - Size of tile in source pixels
245
+ * @param {TileInfo} [tileInfo] - Tile info to render particles (undefined is untextured)
249
246
  * @param {Number} [angle=0] - Angle to rotate the particle
250
247
  */
251
- constructor(pos, tileIndex, tileSize, angle)
252
- { super(pos, vec2(), tileIndex, tileSize, angle); }
248
+ constructor(pos, tileInfo, angle)
249
+ { super(pos, vec2(), tileInfo, angle); }
253
250
 
254
251
  /** Render the particle, automatically called each frame, sorted by renderOrder */
255
252
  render()
@@ -283,14 +280,17 @@ class Particle extends EngineObject
283
280
  if (this.localSpaceEmitter)
284
281
  velocity = velocity.rotate(-this.localSpaceEmitter.angle);
285
282
  const speed = velocity.length();
286
- const direction = velocity.scale(1/speed);
287
- const trailLength = speed * this.trailScale;
288
- size.y = max(size.x, trailLength);
289
- angle = direction.angle();
290
- drawTile(pos.add(direction.multiply(vec2(0,-trailLength/2))), size, this.tileIndex, this.tileSize, color, angle, this.mirror);
283
+ if (speed)
284
+ {
285
+ const direction = velocity.scale(1/speed);
286
+ const trailLength = speed * this.trailScale;
287
+ size.y = max(size.x, trailLength);
288
+ angle = direction.angle();
289
+ drawTile(pos.add(direction.multiply(vec2(0,-trailLength/2))), size, this.tileInfo, color, angle, this.mirror);
290
+ }
291
291
  }
292
292
  else
293
- drawTile(pos, size, this.tileIndex, this.tileSize, color, angle, this.mirror);
293
+ drawTile(pos, size, this.tileInfo, color, angle, this.mirror);
294
294
  this.additive && setBlendMode();
295
295
  debugParticles && debugRect(pos, size, '#f005', 0, angle);
296
296
 
@@ -73,7 +73,7 @@ let glOverlay = 1;
73
73
  * @memberof Settings */
74
74
  let tileSizeDefault = vec2(16);
75
75
 
76
- /** Prevent tile bleeding from neighbors in pixels
76
+ /** How many pixels smaller to draw tiles to prevent bleeding from neighbors
77
77
  * @type {Number}
78
78
  * @default
79
79
  * @memberof Settings */
@@ -247,4 +247,197 @@ let medalDisplayIconSize = 50;
247
247
  * @type {Boolean}
248
248
  * @default 0
249
249
  * @memberof Settings */
250
- let medalsPreventUnlock;
250
+ let medalsPreventUnlock;
251
+
252
+ ///////////////////////////////////////////////////////////////////////////////
253
+ // Setters for global variables
254
+
255
+ /** Set position of camera in world space
256
+ * @param {Vector2} pos
257
+ * @memberof Settings */
258
+ function setCameraPos(pos) { cameraPos = pos; }
259
+
260
+ /** Set scale of camera in world space
261
+ * @param {Number} scale
262
+ * @memberof Settings */
263
+ function setCameraScale(scale) { cameraScale = scale; }
264
+
265
+ /** Set max size of the canvas
266
+ * @param {Vector2} size
267
+ * @memberof Settings */
268
+ function setCanvasMaxSize(size) { canvasMaxSize = size; }
269
+
270
+ /** Set fixed size of the canvas
271
+ * @param {Vector2} size
272
+ * @memberof Settings */
273
+ function setCanvasFixedSize(size) { canvasFixedSize = size; }
274
+
275
+ /** Disables anti aliasing for pixel art if true
276
+ * @param {Boolean} pixelated
277
+ * @memberof Settings */
278
+ function setCanvasPixelated(pixelated) { canvasPixelated = pixelated; }
279
+
280
+ /** Set default font used for text rendering
281
+ * @param {String} font
282
+ * @memberof Settings */
283
+ function setFontDefault(font) { fontDefault = font; }
284
+
285
+ /** Set if webgl rendering is enabled
286
+ * @param {Boolean} enable
287
+ * @memberof Settings */
288
+ function setGlEnable(enable) { glEnable = enable; }
289
+
290
+ /** Set to not composite the WebGL canvas
291
+ * @param {Boolean} overlay
292
+ * @memberof Settings */
293
+ function setGlOverlay(overlay) { glOverlay = overlay; }
294
+
295
+ /** Set default size of tiles in pixels
296
+ * @param {Vector2} size
297
+ * @memberof Settings */
298
+ function setTileSizeDefault(size) { tileSizeDefault = size; }
299
+
300
+ /** Set to prevent tile bleeding from neighbors in pixels
301
+ * @param {Number} scale
302
+ * @memberof Settings */
303
+ function setTileFixBleedScale(scale) { tileFixBleedScale = scale; }
304
+
305
+ /** Set if collisions between objects are enabled
306
+ * @param {Boolean} enable
307
+ * @memberof Settings */
308
+ function setEnablePhysicsSolver(enable) { enablePhysicsSolver = enable; }
309
+
310
+ /** Set default object mass for collison calcuations
311
+ * @param {Number} mass
312
+ * @memberof Settings */
313
+ function setObjectDefaultMass(mass) { objectDefaultMass = mass; }
314
+
315
+ /** Set how much to slow velocity by each frame
316
+ * @param {Number} damping
317
+ * @memberof Settings */
318
+ function setObjectDefaultDamping(damp) { objectDefaultDamping = damp; }
319
+
320
+ /** Set how much to slow angular velocity each frame
321
+ * @param {Number} damping
322
+ * @memberof Settings */
323
+ function setObjectDefaultAngleDamping(damp) { objectDefaultAngleDamping = damp; }
324
+
325
+ /** Set how much to bounce when a collision occur
326
+ * @param {Number} elasticity
327
+ * @memberof Settings */
328
+ function setObjectDefaultElasticity(elasticity) { objectDefaultElasticity = elasticity; }
329
+
330
+ /** Set how much to slow when touching
331
+ * @param {Number} friction
332
+ * @memberof Settings */
333
+ function setObjectDefaultFriction(friction) { objectDefaultFriction = friction; }
334
+
335
+ /** Set max speed to avoid fast objects missing collisions
336
+ * @param {Number} speed
337
+ * @memberof Settings */
338
+ function setObjectMaxSpeed(speed) { objectMaxSpeed = speed; }
339
+
340
+ /** Set how much gravity to apply to objects along the Y axis
341
+ * @param {Number} gravity
342
+ * @memberof Settings */
343
+ function setGravity(g) { gravity = g; }
344
+
345
+ /** Set to scales emit rate of particles
346
+ * @param {Number} scale
347
+ * @memberof Settings */
348
+ function setParticleEmitRateScale(scale) { particleEmitRateScale = scale; }
349
+
350
+ /** Set if gamepads are enabled
351
+ * @param {Boolean} enable
352
+ * @memberof Settings */
353
+ function setGamepadsEnable(enable) { gamepadsEnable = enable; }
354
+
355
+ /** Set if the dpad input is also routed to the left analog stick
356
+ * @param {Boolean} enable
357
+ * @memberof Settings */
358
+ function setGamepadDirectionEmulateStick(enable) { gamepadDirectionEmulateStick = enable; }
359
+
360
+ /** Set if true the WASD keys are also routed to the direction keys
361
+ * @param {Boolean} enable
362
+ * @memberof Settings */
363
+ function setInputWASDEmulateDirection(enable) { inputWASDEmulateDirection = enable; }
364
+
365
+ /** Set if touch gamepad should appear on mobile devices
366
+ * @param {Boolean} enable
367
+ * @memberof Settings */
368
+ function setTouchGamepadEnable(enable) { touchGamepadEnable = enable; }
369
+
370
+ /** Set if touch gamepad should be analog stick or 8 way dpad
371
+ * @param {Boolean} analog
372
+ * @memberof Settings */
373
+ function setTouchGamepadAnalog(analog) { touchGamepadAnalog = analog; }
374
+
375
+ /** Set size of virutal gamepad for touch devices in pixels
376
+ * @param {Number} size
377
+ * @memberof Settings */
378
+ function setTouchGamepadSize(size) { touchGamepadSize = size; }
379
+
380
+ /** Set transparency of touch gamepad overlay
381
+ * @param {Number} alpha
382
+ * @memberof Settings */
383
+ function setTouchGamepadAlpha(alpha) { touchGamepadAlpha = alpha; }
384
+
385
+ /** Set to allow vibration hardware if it exists
386
+ * @param {Boolean} enable
387
+ * @memberof Settings */
388
+ function setVibrateEnable(enable) { vibrateEnable = enable; }
389
+
390
+ /** Set to disable all audio code
391
+ * @param {Boolean} enable
392
+ * @memberof Settings */
393
+ function setSoundEnable(enable) { soundEnable = enable; }
394
+
395
+ /** Set volume scale to apply to all sound, music and speech
396
+ * @param {Number} volume
397
+ * @memberof Settings */
398
+ function setSoundVolume(volume) { soundVolume = volume; }
399
+
400
+ /** Set default range where sound no longer plays
401
+ * @param {Number} range
402
+ * @memberof Settings */
403
+ function setSoundDefaultRange(range) { soundDefaultRange = range; }
404
+
405
+ /** Set default range percent to start tapering off sound
406
+ * @param {Number} taper
407
+ * @memberof Settings */
408
+ function setSoundDefaultTaper(taper) { soundDefaultTaper = taper; }
409
+
410
+ /** Set how long to show medals for in seconds
411
+ * @param {Number} time
412
+ * @memberof Settings */
413
+ function setMedalDisplayTime(time) { medalDisplayTime = time; }
414
+
415
+ /** Set how quickly to slide on/off medals in seconds
416
+ * @param {Number} time
417
+ * @memberof Settings */
418
+ function setMedalDisplaySlideTime(time) { medalDisplaySlideTime = time; }
419
+
420
+ /** Set size of medal display
421
+ * @param {Vector2} size
422
+ * @memberof Settings */
423
+ function setMedalDisplaySize(size) { medalDisplaySize = size; }
424
+
425
+ /** Set size of icon in medal display
426
+ * @param {Number} size
427
+ * @memberof Settings */
428
+ function setMedalDisplayIconSize(size) { medalDisplayIconSize = size; }
429
+
430
+ /** Set to stop medals from being unlockable
431
+ * @param {Boolean} preventUnlock
432
+ * @memberof Settings */
433
+ function setMedalsPreventUnlock(preventUnlock) { medalsPreventUnlock = preventUnlock; }
434
+
435
+ /** Set if watermark with FPS should be shown
436
+ * @param {Boolean} show
437
+ * @memberof Debug */
438
+ function setShowWatermark(show) { showWatermark = show; }
439
+
440
+ /** Set key code used to toggle debug mode, Esc by default
441
+ * @param {Number} key
442
+ * @memberof Debug */
443
+ function setDebugKey(key) { debugKey = key; }
@@ -155,7 +155,7 @@ class TileLayerData
155
155
  }
156
156
 
157
157
  /**
158
- * Tile layer object - cached rendering system for tile layers
158
+ * Tile Layer - cached rendering system for tile layers
159
159
  * - Each Tile layer is rendered to an off screen canvas
160
160
  * - To allow dynamic modifications, layers are rendered using canvas 2d
161
161
  * - Some devices like mobile phones are limited to 4k texture resolution
@@ -171,13 +171,13 @@ class TileLayer extends EngineObject
171
171
  /** Create a tile layer object
172
172
  * @param {Vector2} [position=Vector2()] - World space position
173
173
  * @param {Vector2} [size=tileCollisionSize] - World space size
174
- * @param {Vector2} [tileSize=tileSizeDefault] - Size of tiles in source pixels
174
+ * @param {TileInfo} [tileInfo] - Tile info for layer
175
175
  * @param {Vector2} [scale=Vector2(1,1)] - How much to scale this layer when rendered
176
176
  * @param {Number} [renderOrder=0] - Objects sorted by renderOrder before being rendered
177
177
  */
178
- constructor(pos, size=tileCollisionSize, tileSize=tileSizeDefault, scale=vec2(1), renderOrder=0)
178
+ constructor(pos, size=tileCollisionSize, tileInfo=tile(), scale=vec2(1), renderOrder=0)
179
179
  {
180
- super(pos, size, -1, tileSize, 0, undefined, renderOrder);
180
+ super(pos, size, tileInfo, 0, undefined, renderOrder);
181
181
 
182
182
  /** @property {HTMLCanvasElement} - The canvas used by this tile layer */
183
183
  this.canvas = document.createElement('canvas');
@@ -254,13 +254,13 @@ constructor(pos, size=tileCollisionSize, tileSize=tileSizeDefault, scale=vec2(1)
254
254
  mainCanvas = this.canvas;
255
255
  mainContext = this.context;
256
256
  cameraPos = this.size.scale(.5);
257
- cameraScale = this.tileSize.x;
257
+ cameraScale = this.tileInfo.size.x;
258
258
 
259
259
  if (clear)
260
260
  {
261
261
  // clear and set size
262
- mainCanvas.width = this.size.x * this.tileSize.x;
263
- mainCanvas.height = this.size.y * this.tileSize.y;
262
+ mainCanvas.width = this.size.x * this.tileInfo.size.x;
263
+ mainCanvas.height = this.size.y * this.tileInfo.size.y;
264
264
  }
265
265
 
266
266
  // begin a new render for the tile canvas
@@ -291,7 +291,8 @@ constructor(pos, size=tileCollisionSize, tileSize=tileSizeDefault, scale=vec2(1)
291
291
  if (d.tile != undefined)
292
292
  {
293
293
  ASSERT(mainContext == this.context); // must call redrawStart() before drawing tiles
294
- drawTile(pos, vec2(1), d.tile, this.tileSize, d.color, d.direction*PI/2, d.mirror);
294
+ const tileInfo = tile(d.tile, this.tileInfo.size, this.tileInfo.textureIndex);
295
+ drawTile(pos, vec2(1), tileInfo, d.color, d.direction*PI/2, d.mirror);
295
296
  }
296
297
  }
297
298
 
@@ -313,8 +314,8 @@ constructor(pos, size=tileCollisionSize, tileSize=tileSizeDefault, scale=vec2(1)
313
314
  {
314
315
  const context = this.context;
315
316
  context.save();
316
- pos = pos.subtract(this.pos).multiply(this.tileSize);
317
- size = size.multiply(this.tileSize);
317
+ pos = pos.subtract(this.pos).multiply(this.tileInfo.size);
318
+ size = size.multiply(this.tileInfo.size);
318
319
  context.translate(pos.x, this.canvas.height - pos.y);
319
320
  context.rotate(angle);
320
321
  context.scale(mirror ? -size.x : size.x, size.y);
@@ -325,28 +326,28 @@ constructor(pos, size=tileCollisionSize, tileSize=tileSizeDefault, scale=vec2(1)
325
326
  /** Draw a tile directly onto the layer canvas
326
327
  * @param {Vector2} pos
327
328
  * @param {Vector2} [size=Vector2(1,1)]
328
- * @param {Number} [tileIndex=-1]
329
- * @param {Vector2} [tileSize=tileSizeDefault]
329
+ * @param {TileInfo} [tileInfo]
330
330
  * @param {Color} [color=Color()]
331
331
  * @param {Number} [angle=0]
332
332
  * @param {Boolean} [mirror=0] */
333
- drawTile(pos, size=vec2(1), tileIndex=-1, tileSize=tileSizeDefault, color=new Color, angle, mirror)
333
+ drawTile(pos, size=vec2(1), tileInfo, color=new Color, angle, mirror)
334
334
  {
335
335
  this.drawCanvas2D(pos, size, angle, mirror, (context)=>
336
336
  {
337
- if (tileIndex < 0)
337
+ const textureInfo = tileInfo && tileInfo.getTextureInfo();
338
+ if (textureInfo)
338
339
  {
339
- // untextured
340
- context.fillStyle = color;
341
- context.fillRect(-.5, -.5, 1, 1);
340
+ context.globalAlpha = color.a; // only alpha is supported
341
+ context.drawImage(textureInfo.image,
342
+ tileInfo.pos.x, tileInfo.pos.y,
343
+ tileInfo.size.x, tileInfo.size.y, -.5, -.5, 1, 1);
344
+ context.globalAlpha = 1;
342
345
  }
343
346
  else
344
347
  {
345
- const cols = tileImage.width/tileSize.x;
346
- context.globalAlpha = color.a; // only alpha, no color, is supported in this mode
347
- context.drawImage(tileImage,
348
- (tileIndex%cols)*tileSize.x, (tileIndex/cols|0)*tileSize.y,
349
- tileSize.x, tileSize.y, -.5, -.5, 1, 1);
348
+ // untextured
349
+ context.fillStyle = color;
350
+ context.fillRect(-.5, -.5, 1, 1);
350
351
  }
351
352
  });
352
353
  }
@@ -205,10 +205,10 @@ function randColor(colorA=new Color, colorB=new Color(0,0,0,1), linear)
205
205
  * - Can be used to create a deterministic random number sequence
206
206
  * @example
207
207
  * let r = new RandomGenerator(123); // random number generator with seed 123
208
- * let a = r.rand(); // random value between 0 and 1
209
- * let b = r.randInt(10); // random integer between 0 and 9
208
+ * let a = r.float(); // random value between 0 and 1
209
+ * let b = r.int(10); // random integer between 0 and 9
210
210
  * r.seed = 123; // reset the seed
211
- * let c = r.rand(); // the same value as a
211
+ * let c = r.float(); // the same value as a
212
212
  */
213
213
  class RandomGenerator
214
214
  {
@@ -237,18 +237,18 @@ class RandomGenerator
237
237
  * @param {Number} valueA
238
238
  * @param {Number} [valueB=0]
239
239
  * @return {Number} */
240
- int(valueA, valueB=0) { return Math.floor(this.rand(valueA, valueB)); }
240
+ int(valueA, valueB=0) { return Math.floor(this.float(valueA, valueB)); }
241
241
 
242
242
  /** Randomly returns either -1 or 1 deterministically
243
243
  * @return {Number} */
244
- sign() { return this.randInt(2) * 2 - 1; }
244
+ sign() { return this.int(2) * 2 - 1; }
245
245
  }
246
246
 
247
247
  ///////////////////////////////////////////////////////////////////////////////
248
248
 
249
249
  /**
250
250
  * Create a 2d vector, can take another Vector2 to copy, 2 scalars, or 1 scalar
251
- * @param {Number} [x=0]
251
+ * @param {(Number|Vector2)} [x=0]
252
252
  * @param {Number} [y=0]
253
253
  * @return {Vector2}
254
254
  * @example
@@ -6,6 +6,7 @@
6
6
  * - Can be disabled with glEnable to revert to 2D canvas rendering
7
7
  * - Batches sprite rendering on GPU for incredibly fast performance
8
8
  * - Sprite transform math is done in the shader where possible
9
+ * - Supports shadertoy style post processing shaders
9
10
  * @namespace WebGL
10
11
  */
11
12
 
@@ -21,11 +22,6 @@ let glCanvas;
21
22
  * @memberof WebGL */
22
23
  let glContext;
23
24
 
24
- /** Main tile sheet texture automatically loaded by engine
25
- * @type {WebGLTexture}
26
- * @memberof WebGL */
27
- let glTileTexture;
28
-
29
25
  // WebGL internal variables not exposed to documentation
30
26
  let glActiveTexture, glShader, glArrayBuffer, glPositionData, glColorData, glBatchCount, glBatchAdditive, glAdditive;
31
27
 
@@ -34,32 +30,34 @@ let glActiveTexture, glShader, glArrayBuffer, glPositionData, glColorData, glBat
34
30
  // Initalize WebGL, called automatically by the engine
35
31
  function glInit()
36
32
  {
37
- // create the canvas and tile texture
33
+ // create the canvas and textures
38
34
  glCanvas = document.createElement('canvas');
39
- glContext = glCanvas.getContext('webgl', {antialias: false});
40
- glTileTexture = glCreateTexture(tileImage);
35
+ glContext = glCanvas.getContext('webgl2');
41
36
 
42
37
  // some browsers are much faster without copying the gl buffer so we just overlay it instead
43
38
  glOverlay && document.body.appendChild(glCanvas);
44
39
 
45
40
  // setup vertex and fragment shaders
46
41
  glShader = glCreateProgram(
42
+ '#version 300 es\n' + // specify GLSL ES version
47
43
  'precision highp float;'+ // use highp for better accuracy
48
44
  'uniform mat4 m;'+ // transform matrix
49
- 'attribute vec2 p,t;'+ // position, uv
50
- 'attribute vec4 c,a;'+ // color, additiveColor
51
- 'varying vec4 v,d,e;'+ // return uv, color, additiveColor
45
+ 'in vec2 p,t;'+ // position, uv
46
+ 'in vec4 c,a;'+ // color, additiveColor
47
+ 'out vec4 v,d,e;'+ // return uv, color, additiveColor
52
48
  'void main(){'+ // shader entry point
53
49
  'gl_Position=m*vec4(p,1,1);'+ // transform position
54
50
  'v=vec4(t,p);d=c;e=a;'+ // pass stuff to fragment shader
55
51
  '}' // end of shader
56
52
  ,
57
- 'precision highp float;'+ // use highp for better accuracy
58
- 'varying vec4 v,d,e;'+ // uv, color, additiveColor
59
- 'uniform sampler2D s;'+ // texture
60
- 'void main(){'+ // shader entry point
61
- 'gl_FragColor=texture2D(s,v.xy)*d+e;'+ // modulate texture by color plus additive
62
- '}' // end of shader
53
+ '#version 300 es\n' + // specify GLSL ES version
54
+ 'precision highp float;'+ // use highp for better accuracy
55
+ 'in vec4 v,d,e;'+ // uv, color, additiveColor
56
+ 'uniform sampler2D s;'+ // texture
57
+ 'out vec4 c;'+ // out color
58
+ 'void main(){'+ // shader entry point
59
+ 'c=texture(s,v.xy)*d+e;'+ // modulate texture by color plus additive
60
+ '}' // end of shader
63
61
  );
64
62
 
65
63
  // init buffers
@@ -80,7 +78,7 @@ function glPreRender()
80
78
  // set up the shader
81
79
  glContext.useProgram(glShader);
82
80
  glContext.activeTexture(gl_TEXTURE0);
83
- glContext.bindTexture(gl_TEXTURE_2D, glActiveTexture = glTileTexture);
81
+ glContext.bindTexture(gl_TEXTURE_2D, glActiveTexture = textureInfos[0].glTexture);
84
82
  glContext.bindBuffer(gl_ARRAY_BUFFER, glArrayBuffer);
85
83
  glContext.bufferData(gl_ARRAY_BUFFER, gl_VERTEX_BUFFER_SIZE, gl_DYNAMIC_DRAW);
86
84
  glSetBlendMode();
@@ -115,22 +113,23 @@ function glPreRender()
115
113
  /** Set the WebGl blend mode, normally you should call setBlendMode instead
116
114
  * @param {Boolean} [additive=0]
117
115
  * @memberof WebGL */
118
- function glSetBlendMode(additive)
116
+ function glSetBlendMode(additive=0)
119
117
  {
120
118
  // setup blending
121
119
  glAdditive = additive;
122
120
  }
123
121
 
124
- /** Set the WebGl texture, not normally necessary unless multiple tile sheets are used
122
+ /** Set the WebGl texture, called automatically if using multiple textures
125
123
  * - This may also flush the gl buffer resulting in more draw calls and worse performance
126
- * @param {WebGLTexture} [texture=glTileTexture]
124
+ * @param {WebGLTexture} texture
127
125
  * @memberof WebGL */
128
- function glSetTexture(texture=glTileTexture)
126
+ function glSetTexture(texture)
129
127
  {
130
128
  // must flush cache with the old texture to set a new one
131
- if (texture != glActiveTexture)
132
- glFlush();
129
+ if (texture == glActiveTexture)
130
+ return;
133
131
 
132
+ glFlush();
134
133
  glContext.bindTexture(gl_TEXTURE_2D, glActiveTexture = texture);
135
134
  }
136
135
 
@@ -309,25 +308,28 @@ function glInitPostProcess(shaderCode, includeOverlay)
309
308
  {
310
309
  ASSERT(!glPostShader); // can only have 1 post effects shader
311
310
 
312
- if (!shaderCode) // default shader
313
- shaderCode = 'void mainImage(out vec4 c,vec2 p){c=texture2D(iChannel0,p/iResolution.xy);}';
311
+ if (!shaderCode) // default shader pass through
312
+ shaderCode = 'void mainImage(out vec4 c,vec2 p){c=texture(iChannel0,p/iResolution.xy);}';
314
313
 
315
314
  // create the shader
316
315
  glPostShader = glCreateProgram(
316
+ '#version 300 es\n' + // specify GLSL ES version
317
317
  'precision highp float;'+ // use highp for better accuracy
318
- 'attribute vec2 p;'+ // position
318
+ 'in vec2 p;'+ // position
319
319
  'void main(){'+ // shader entry point
320
320
  'gl_Position=vec4(p,1,1);'+ // set position
321
321
  '}' // end of shader
322
322
  ,
323
+ '#version 300 es\n' + // specify GLSL ES version
323
324
  'precision highp float;'+ // use highp for better accuracy
324
325
  'uniform sampler2D iChannel0;'+ // input texture
325
326
  'uniform vec3 iResolution;'+ // size of output texture
326
327
  'uniform float iTime;'+ // time passed
328
+ 'out vec4 c;'+ // out color
327
329
  '\n' + shaderCode + '\n'+ // insert custom shader code
328
330
  'void main(){'+ // shader entry point
329
- 'mainImage(gl_FragColor,gl_FragCoord.xy);'+ // call post process function
330
- 'gl_FragColor.a=1.;'+ // always use full alpha
331
+ 'mainImage(c,gl_FragCoord.xy);'+ // call post process function
332
+ 'c.a=1.;'+ // always use full alpha
331
333
  '}' // end of shader
332
334
  );
333
335
 
@@ -400,7 +402,6 @@ gl_ONE_MINUS_SRC_ALPHA = 771,
400
402
  gl_BLEND = 3042,
401
403
  gl_TEXTURE_2D = 3553,
402
404
  gl_UNSIGNED_BYTE = 5121,
403
- gl_BYTE = 5120,
404
405
  gl_FLOAT = 5126,
405
406
  gl_RGBA = 6408,
406
407
  gl_NEAREST = 9728,
@@ -412,7 +413,6 @@ gl_TEXTURE_WRAP_T = 10243,
412
413
  gl_COLOR_BUFFER_BIT = 16384,
413
414
  gl_CLAMP_TO_EDGE = 33071,
414
415
  gl_TEXTURE0 = 33984,
415
- gl_TEXTURE1 = 33985,
416
416
  gl_ARRAY_BUFFER = 34962,
417
417
  gl_STATIC_DRAW = 35044,
418
418
  gl_DYNAMIC_DRAW = 35048,
@@ -423,7 +423,6 @@ gl_LINK_STATUS = 35714,
423
423
  gl_UNPACK_FLIP_Y_WEBGL = 37440,
424
424
 
425
425
  // constants for batch rendering
426
- gl_VERTICES_PER_QUAD = 6,
427
426
  gl_INDICIES_PER_VERT = 6,
428
427
  gl_MAX_BATCH = 1e5,
429
428
  gl_VERTEX_BYTE_STRIDE = (4 * 2) * 2 + (4) * 2, // vec2 * 2 + (char * 4) * 2