melonjs 10.7.1 → 10.8.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.
- package/dist/melonjs.js +1131 -652
- package/dist/melonjs.min.js +4 -4
- package/dist/melonjs.module.d.ts +1038 -198
- package/dist/melonjs.module.js +1234 -763
- package/package.json +7 -7
- package/src/camera/camera2d.js +1 -1
- package/src/entity/entity.js +6 -7
- package/src/geometries/ellipse.js +10 -11
- package/src/geometries/line.js +3 -3
- package/src/geometries/path2d.js +319 -0
- package/src/geometries/poly.js +11 -11
- package/src/geometries/rectangle.js +15 -15
- package/src/geometries/roundrect.js +67 -0
- package/src/index.js +5 -1
- package/src/input/pointerevent.js +1 -1
- package/src/lang/deprecated.js +1 -1
- package/src/level/tiled/TMXLayer.js +1 -1
- package/src/level/tiled/TMXObject.js +9 -12
- package/src/level/tiled/TMXTileMap.js +23 -4
- package/src/level/tiled/renderer/TMXHexagonalRenderer.js +1 -1
- package/src/level/tiled/renderer/TMXIsometricRenderer.js +1 -1
- package/src/level/tiled/renderer/TMXOrthogonalRenderer.js +1 -1
- package/src/level/tiled/renderer/TMXRenderer.js +1 -1
- package/src/level/tiled/renderer/TMXStaggeredRenderer.js +1 -1
- package/src/loader/loader.js +4 -4
- package/src/loader/loadingscreen.js +1 -1
- package/src/math/color.js +1 -1
- package/src/math/matrix2.js +1 -1
- package/src/math/matrix3.js +1 -1
- package/src/math/observable_vector2.js +1 -1
- package/src/math/observable_vector3.js +1 -1
- package/src/math/vector2.js +1 -1
- package/src/math/vector3.js +1 -1
- package/src/particles/emitter.js +23 -14
- package/src/particles/particle.js +3 -2
- package/src/physics/body.js +67 -51
- package/src/physics/bounds.js +8 -9
- package/src/physics/world.js +1 -1
- package/src/renderable/collectable.js +9 -2
- package/src/renderable/colorlayer.js +1 -1
- package/src/renderable/container.js +1 -1
- package/src/renderable/imagelayer.js +1 -1
- package/src/renderable/renderable.js +1 -1
- package/src/renderable/sprite.js +2 -3
- package/src/renderable/trigger.js +10 -4
- package/src/state/stage.js +1 -1
- package/src/state/state.js +1 -1
- package/src/system/device.js +10 -8
- package/src/system/pooling.js +156 -149
- package/src/text/bitmaptext.js +1 -1
- package/src/text/text.js +1 -1
- package/src/video/canvas/canvas_renderer.js +89 -34
- package/src/video/renderer.js +26 -14
- package/src/video/texture.js +1 -1
- package/src/video/webgl/glshader.js +29 -193
- package/src/video/webgl/utils/attributes.js +16 -0
- package/src/video/webgl/utils/precision.js +11 -0
- package/src/video/webgl/utils/program.js +58 -0
- package/src/video/webgl/utils/string.js +16 -0
- package/src/video/webgl/utils/uniforms.js +87 -0
- package/src/video/webgl/webgl_compositor.js +1 -14
- package/src/video/webgl/webgl_renderer.js +123 -181
|
@@ -189,7 +189,7 @@ class CanvasRenderer extends Renderer {
|
|
|
189
189
|
* @param {number} height The rectangle's height.
|
|
190
190
|
*/
|
|
191
191
|
clearRect(x, y, width, height) {
|
|
192
|
-
this.
|
|
192
|
+
this.getContext().clearRect(x, y, width, height);
|
|
193
193
|
}
|
|
194
194
|
|
|
195
195
|
/**
|
|
@@ -208,7 +208,7 @@ class CanvasRenderer extends Renderer {
|
|
|
208
208
|
* var basic = renderer.createPattern(image, "no-repeat");
|
|
209
209
|
*/
|
|
210
210
|
createPattern(image, repeat) {
|
|
211
|
-
return this.
|
|
211
|
+
return this.getContext().createPattern(image, repeat);
|
|
212
212
|
}
|
|
213
213
|
|
|
214
214
|
/**
|
|
@@ -234,10 +234,11 @@ class CanvasRenderer extends Renderer {
|
|
|
234
234
|
* renderer.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);
|
|
235
235
|
*/
|
|
236
236
|
drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh) {
|
|
237
|
-
if (this.
|
|
237
|
+
if (this.getGlobalAlpha() < 1 / 255) {
|
|
238
238
|
// Fast path: don't draw fully transparent
|
|
239
239
|
return;
|
|
240
240
|
}
|
|
241
|
+
var context = this.getContext();
|
|
241
242
|
|
|
242
243
|
if (typeof sw === "undefined") {
|
|
243
244
|
sw = dw = image.width;
|
|
@@ -271,7 +272,7 @@ class CanvasRenderer extends Renderer {
|
|
|
271
272
|
// get a tinted version of this image from the texture cache
|
|
272
273
|
source = this.cache.tint(image, this.currentTint.toRGB());
|
|
273
274
|
}
|
|
274
|
-
|
|
275
|
+
context.drawImage(source, sx, sy, sw, sh, dx, dy, dw, dh);
|
|
275
276
|
}
|
|
276
277
|
|
|
277
278
|
/**
|
|
@@ -287,14 +288,15 @@ class CanvasRenderer extends Renderer {
|
|
|
287
288
|
* @see CanvasRenderer#createPattern
|
|
288
289
|
*/
|
|
289
290
|
drawPattern(pattern, x, y, width, height) {
|
|
290
|
-
if (this.
|
|
291
|
+
if (this.getGlobalAlpha() < 1 / 255) {
|
|
291
292
|
// Fast path: don't draw fully transparent
|
|
292
293
|
return;
|
|
293
294
|
}
|
|
294
|
-
var
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
295
|
+
var context = this.getContext();
|
|
296
|
+
var fillStyle = context.fillStyle;
|
|
297
|
+
context.fillStyle = pattern;
|
|
298
|
+
context.fillRect(x, y, width, height);
|
|
299
|
+
context.fillStyle = fillStyle;
|
|
298
300
|
}
|
|
299
301
|
|
|
300
302
|
/**
|
|
@@ -311,12 +313,12 @@ class CanvasRenderer extends Renderer {
|
|
|
311
313
|
* @param {boolean} [fill=false] also fill the shape with the current color if true
|
|
312
314
|
*/
|
|
313
315
|
strokeArc(x, y, radius, start, end, antiClockwise, fill = false) {
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
if (context.globalAlpha < 1 / 255) {
|
|
316
|
+
if (this.getGlobalAlpha() < 1 / 255) {
|
|
317
317
|
// Fast path: don't draw fully transparent
|
|
318
318
|
return;
|
|
319
319
|
}
|
|
320
|
+
var context = this.getContext();
|
|
321
|
+
|
|
320
322
|
context.translate(x, y);
|
|
321
323
|
context.beginPath();
|
|
322
324
|
context.arc(0, 0, radius, start, end, antiClockwise || false);
|
|
@@ -352,12 +354,11 @@ class CanvasRenderer extends Renderer {
|
|
|
352
354
|
* @param {boolean} [fill=false] also fill the shape with the current color if true
|
|
353
355
|
*/
|
|
354
356
|
strokeEllipse(x, y, w, h, fill = false) {
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
if (context.globalAlpha < 1 / 255) {
|
|
357
|
+
if (this.getGlobalAlpha() < 1 / 255) {
|
|
358
358
|
// Fast path: don't draw fully transparent
|
|
359
359
|
return;
|
|
360
360
|
}
|
|
361
|
+
var context = this.getContext();
|
|
361
362
|
|
|
362
363
|
var hw = w,
|
|
363
364
|
hh = h,
|
|
@@ -408,9 +409,7 @@ class CanvasRenderer extends Renderer {
|
|
|
408
409
|
* @param {number} endY the end y coordinate
|
|
409
410
|
*/
|
|
410
411
|
strokeLine(startX, startY, endX, endY) {
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
if (context < 1 / 255) {
|
|
412
|
+
if (this.getGlobalAlpha() < 1 / 255) {
|
|
414
413
|
// Fast path: don't draw fully transparent
|
|
415
414
|
return;
|
|
416
415
|
}
|
|
@@ -444,12 +443,11 @@ class CanvasRenderer extends Renderer {
|
|
|
444
443
|
* @param {boolean} [fill=false] also fill the shape with the current color if true
|
|
445
444
|
*/
|
|
446
445
|
strokePolygon(poly, fill = false) {
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
if (context.globalAlpha < 1 / 255) {
|
|
446
|
+
if (this.getGlobalAlpha() < 1 / 255) {
|
|
450
447
|
// Fast path: don't draw fully transparent
|
|
451
448
|
return;
|
|
452
449
|
}
|
|
450
|
+
var context = this.getContext();
|
|
453
451
|
|
|
454
452
|
this.translate(poly.pos.x, poly.pos.y);
|
|
455
453
|
context.beginPath();
|
|
@@ -488,15 +486,13 @@ class CanvasRenderer extends Renderer {
|
|
|
488
486
|
* @param {boolean} [fill=false] also fill the shape with the current color if true
|
|
489
487
|
*/
|
|
490
488
|
strokeRect(x, y, width, height, fill = false) {
|
|
491
|
-
if (
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
if (this.backBufferContext2D.globalAlpha < 1 / 255) {
|
|
495
|
-
// Fast path: don't draw fully transparent
|
|
496
|
-
return;
|
|
497
|
-
}
|
|
498
|
-
this.backBufferContext2D.strokeRect(x, y, width, height);
|
|
489
|
+
if (this.getGlobalAlpha() < 1 / 255) {
|
|
490
|
+
// Fast path: don't draw fully transparent
|
|
491
|
+
return;
|
|
499
492
|
}
|
|
493
|
+
var context = this.getContext();
|
|
494
|
+
|
|
495
|
+
context[fill === true ? "fillRect" : "strokeRect"](x, y, width, height);
|
|
500
496
|
}
|
|
501
497
|
|
|
502
498
|
/**
|
|
@@ -510,11 +506,59 @@ class CanvasRenderer extends Renderer {
|
|
|
510
506
|
* @param {number} height
|
|
511
507
|
*/
|
|
512
508
|
fillRect(x, y, width, height) {
|
|
513
|
-
|
|
509
|
+
this.strokeRect(x, y, width, height, true);
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
/**
|
|
513
|
+
* Stroke a rounded rectangle at the specified coordinates
|
|
514
|
+
* @name strokeRoundRect
|
|
515
|
+
* @memberof CanvasRenderer.prototype
|
|
516
|
+
* @function
|
|
517
|
+
* @param {number} x
|
|
518
|
+
* @param {number} y
|
|
519
|
+
* @param {number} width
|
|
520
|
+
* @param {number} height
|
|
521
|
+
* @param {number} radius
|
|
522
|
+
* @param {boolean} [fill=false] also fill the shape with the current color if true
|
|
523
|
+
*/
|
|
524
|
+
strokeRoundRect(x, y, width, height, radius, fill = false) {
|
|
525
|
+
if (this.getGlobalAlpha() < 1 / 255) {
|
|
514
526
|
// Fast path: don't draw fully transparent
|
|
515
527
|
return;
|
|
516
528
|
}
|
|
517
|
-
this.
|
|
529
|
+
var context = this.getContext();
|
|
530
|
+
|
|
531
|
+
context.beginPath();
|
|
532
|
+
if (typeof context.roundRect === "function") {
|
|
533
|
+
//https://developer.chrome.com/blog/canvas2d/#round-rect
|
|
534
|
+
context.roundRect(x, y, width, height, radius);
|
|
535
|
+
} else {
|
|
536
|
+
context.moveTo(x + radius, y);
|
|
537
|
+
context.lineTo(x + width - radius, y);
|
|
538
|
+
context.arcTo(x + width, y, x + width, y + radius, radius);
|
|
539
|
+
context.lineTo(x + width, y + height - radius);
|
|
540
|
+
context.arcTo(x + width, y + height, x + width - radius, y + height, radius);
|
|
541
|
+
context.lineTo(x + radius, y + height);
|
|
542
|
+
context.arcTo(x, y + height, x, y + height - radius, radius);
|
|
543
|
+
context.lineTo(x, y + radius);
|
|
544
|
+
context.arcTo(x, y, x + radius, y, radius);
|
|
545
|
+
}
|
|
546
|
+
context[fill === true ? "fill" : "stroke"]();
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
/**
|
|
550
|
+
* Draw a rounded filled rectangle at the specified coordinates
|
|
551
|
+
* @name fillRoundRect
|
|
552
|
+
* @memberof CanvasRenderer.prototype
|
|
553
|
+
* @function
|
|
554
|
+
* @param {number} x
|
|
555
|
+
* @param {number} y
|
|
556
|
+
* @param {number} width
|
|
557
|
+
* @param {number} height
|
|
558
|
+
* @param {number} radius
|
|
559
|
+
*/
|
|
560
|
+
fillRoundRect(x, y, width, height, radius) {
|
|
561
|
+
this.strokeRoundRect(x, y, width, height, radius, true);
|
|
518
562
|
}
|
|
519
563
|
|
|
520
564
|
|
|
@@ -556,7 +600,7 @@ class CanvasRenderer extends Renderer {
|
|
|
556
600
|
*/
|
|
557
601
|
restore() {
|
|
558
602
|
this.backBufferContext2D.restore();
|
|
559
|
-
this.currentColor.glArray[3] = this.
|
|
603
|
+
this.currentColor.glArray[3] = this.getGlobalAlpha();
|
|
560
604
|
this.currentScissor[0] = 0;
|
|
561
605
|
this.currentScissor[1] = 0;
|
|
562
606
|
this.currentScissor[2] = this.backBufferCanvas.width;
|
|
@@ -604,7 +648,7 @@ class CanvasRenderer extends Renderer {
|
|
|
604
648
|
}
|
|
605
649
|
|
|
606
650
|
/**
|
|
607
|
-
* Set the global alpha
|
|
651
|
+
* Set the global alpha
|
|
608
652
|
* @name setGlobalAlpha
|
|
609
653
|
* @memberof CanvasRenderer.prototype
|
|
610
654
|
* @function
|
|
@@ -614,6 +658,17 @@ class CanvasRenderer extends Renderer {
|
|
|
614
658
|
this.backBufferContext2D.globalAlpha = this.currentColor.glArray[3] = alpha;
|
|
615
659
|
}
|
|
616
660
|
|
|
661
|
+
/**
|
|
662
|
+
* Return the global alpha
|
|
663
|
+
* @name getGlobalAlpha
|
|
664
|
+
* @memberof CanvasRenderer.prototype
|
|
665
|
+
* @function
|
|
666
|
+
* @returns {number} global alpha value
|
|
667
|
+
*/
|
|
668
|
+
getGlobalAlpha() {
|
|
669
|
+
return this.backBufferContext2D.globalAlpha;
|
|
670
|
+
}
|
|
671
|
+
|
|
617
672
|
/**
|
|
618
673
|
* Set the line width on the context
|
|
619
674
|
* @name setLineWidth
|
|
@@ -723,7 +778,7 @@ class CanvasRenderer extends Renderer {
|
|
|
723
778
|
* @param {Rect|Polygon|Line|Ellipse} [mask] the shape defining the mask to be applied
|
|
724
779
|
*/
|
|
725
780
|
setMask(mask) {
|
|
726
|
-
var context = this.
|
|
781
|
+
var context = this.getContext();
|
|
727
782
|
var _x = mask.pos.x, _y = mask.pos.y;
|
|
728
783
|
|
|
729
784
|
context.save();
|
package/src/video/renderer.js
CHANGED
|
@@ -5,10 +5,12 @@ import * as event from "./../system/event.js";
|
|
|
5
5
|
import device from "./../system/device.js";
|
|
6
6
|
import { setPrefixed } from "./../utils/agent.js";
|
|
7
7
|
import Rect from "./../geometries/rectangle.js";
|
|
8
|
+
import RoundRect from "./../geometries/roundrect.js";
|
|
8
9
|
import Ellipse from "./../geometries/ellipse.js";
|
|
9
10
|
import Polygon from "./../geometries/poly.js";
|
|
10
11
|
import Line from "./../geometries/line.js";
|
|
11
12
|
import Bounds from "./../physics/bounds.js";
|
|
13
|
+
import Path2D from "./../geometries/path2d.js";
|
|
12
14
|
|
|
13
15
|
/**
|
|
14
16
|
* @classdesc
|
|
@@ -43,12 +45,20 @@ class Renderer {
|
|
|
43
45
|
/**
|
|
44
46
|
* true if the current rendering context is valid
|
|
45
47
|
* @name isContextValid
|
|
46
|
-
* @memberof Renderer
|
|
48
|
+
* @memberof Renderer#
|
|
47
49
|
* @default true
|
|
48
50
|
* type {boolean}
|
|
49
51
|
*/
|
|
50
52
|
this.isContextValid = true;
|
|
51
53
|
|
|
54
|
+
/**
|
|
55
|
+
* The Path2D instance used by the renderer to draw primitives
|
|
56
|
+
* @name path2D
|
|
57
|
+
* @type {Path2D}
|
|
58
|
+
* @memberof Renderer#
|
|
59
|
+
*/
|
|
60
|
+
this.path2D = new Path2D();
|
|
61
|
+
|
|
52
62
|
/**
|
|
53
63
|
* @ignore
|
|
54
64
|
*/
|
|
@@ -331,11 +341,13 @@ class Renderer {
|
|
|
331
341
|
* @name stroke
|
|
332
342
|
* @memberof Renderer.prototype
|
|
333
343
|
* @function
|
|
334
|
-
* @param {Rect|Polygon|Line|Ellipse} shape a shape object to stroke
|
|
344
|
+
* @param {Rect|RoundRect|Polygon|Line|Ellipse} shape a shape object to stroke
|
|
335
345
|
* @param {boolean} [fill=false] fill the shape with the current color if true
|
|
336
346
|
*/
|
|
337
347
|
stroke(shape, fill) {
|
|
338
|
-
if (shape instanceof
|
|
348
|
+
if (shape instanceof RoundRect) {
|
|
349
|
+
this.strokeRoundRect(shape.left, shape.top, shape.width, shape.height, shape.radius, fill);
|
|
350
|
+
} else if (shape instanceof Rect || shape instanceof Bounds) {
|
|
339
351
|
this.strokeRect(shape.left, shape.top, shape.width, shape.height, fill);
|
|
340
352
|
} else if (shape instanceof Line || shape instanceof Polygon) {
|
|
341
353
|
this.strokePolygon(shape, fill);
|
|
@@ -350,6 +362,17 @@ class Renderer {
|
|
|
350
362
|
}
|
|
351
363
|
}
|
|
352
364
|
|
|
365
|
+
/**
|
|
366
|
+
* fill the given shape
|
|
367
|
+
* @name fill
|
|
368
|
+
* @memberof Renderer.prototype
|
|
369
|
+
* @function
|
|
370
|
+
* @param {Rect|Polygon|Line|Ellipse} shape a shape object to fill
|
|
371
|
+
*/
|
|
372
|
+
fill(shape) {
|
|
373
|
+
this.stroke(shape, true);
|
|
374
|
+
}
|
|
375
|
+
|
|
353
376
|
/**
|
|
354
377
|
* tint the given image or canvas using the given color
|
|
355
378
|
* @name tint
|
|
@@ -379,17 +402,6 @@ class Renderer {
|
|
|
379
402
|
return canvas;
|
|
380
403
|
}
|
|
381
404
|
|
|
382
|
-
/**
|
|
383
|
-
* fill the given shape
|
|
384
|
-
* @name fill
|
|
385
|
-
* @memberof Renderer.prototype
|
|
386
|
-
* @function
|
|
387
|
-
* @param {Rect|Polygon|Line|Ellipse} shape a shape object to fill
|
|
388
|
-
*/
|
|
389
|
-
fill(shape) {
|
|
390
|
-
this.stroke(shape, true);
|
|
391
|
-
}
|
|
392
|
-
|
|
393
405
|
/**
|
|
394
406
|
* A mask limits rendering elements to the shape and position of the given mask object.
|
|
395
407
|
* So, if the renderable is larger than the mask, only the intersecting part of the renderable will be visible.
|
package/src/video/texture.js
CHANGED
|
@@ -3,7 +3,7 @@ import WebGLRenderer from "./webgl/webgl_renderer.js";
|
|
|
3
3
|
import TextureCache from "./texture_cache.js";
|
|
4
4
|
import Sprite from "./../renderable/sprite.js";
|
|
5
5
|
import { renderer } from "./video.js";
|
|
6
|
-
import
|
|
6
|
+
import pool from "./../system/pooling.js";
|
|
7
7
|
import loader from "./../loader/loader.js";
|
|
8
8
|
import { ETA } from "./../math/math.js";
|
|
9
9
|
|
|
@@ -1,198 +1,10 @@
|
|
|
1
1
|
import * as event from "./../../system/event.js";
|
|
2
2
|
import device from "./../../system/device.js";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
var uniforms = {},
|
|
9
|
-
uniRx = /uniform\s+(\w+)\s+(\w+)/g,
|
|
10
|
-
uniformsData = {},
|
|
11
|
-
descriptor = {},
|
|
12
|
-
locations = {},
|
|
13
|
-
match;
|
|
14
|
-
|
|
15
|
-
// Detect all uniform names and types
|
|
16
|
-
[ shader.vertex, shader.fragment ].forEach(function (shader) {
|
|
17
|
-
while ((match = uniRx.exec(shader))) {
|
|
18
|
-
uniformsData[match[2]] = match[1];
|
|
19
|
-
}
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
// Get uniform references
|
|
23
|
-
Object.keys(uniformsData).forEach(function (name) {
|
|
24
|
-
var type = uniformsData[name];
|
|
25
|
-
locations[name] = gl.getUniformLocation(shader.program, name);
|
|
26
|
-
|
|
27
|
-
descriptor[name] = {
|
|
28
|
-
"get" : (function (name) {
|
|
29
|
-
/**
|
|
30
|
-
* A getter for the uniform location
|
|
31
|
-
* @ignore
|
|
32
|
-
*/
|
|
33
|
-
return function () {
|
|
34
|
-
return locations[name];
|
|
35
|
-
};
|
|
36
|
-
})(name),
|
|
37
|
-
"set" : (function (name, type, fn) {
|
|
38
|
-
if (type.indexOf("mat") === 0) {
|
|
39
|
-
/**
|
|
40
|
-
* A generic setter for uniform matrices
|
|
41
|
-
* @ignore
|
|
42
|
-
*/
|
|
43
|
-
return function (val) {
|
|
44
|
-
gl[fn](locations[name], false, val);
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
else {
|
|
48
|
-
/**
|
|
49
|
-
* A generic setter for uniform vectors
|
|
50
|
-
* @ignore
|
|
51
|
-
*/
|
|
52
|
-
return function (val) {
|
|
53
|
-
var fnv = fn;
|
|
54
|
-
if (val.length && fn.substr(-1) !== "v") {
|
|
55
|
-
fnv += "v";
|
|
56
|
-
}
|
|
57
|
-
gl[fnv](locations[name], val);
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
|
-
})(name, type, "uniform" + fnHash[type])
|
|
61
|
-
};
|
|
62
|
-
});
|
|
63
|
-
Object.defineProperties(uniforms, descriptor);
|
|
64
|
-
|
|
65
|
-
return uniforms;
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* @ignore
|
|
70
|
-
*/
|
|
71
|
-
function extractAttributes(gl, shader) {
|
|
72
|
-
var attributes = {},
|
|
73
|
-
attrRx = /attribute\s+\w+\s+(\w+)/g,
|
|
74
|
-
match,
|
|
75
|
-
i = 0;
|
|
76
|
-
|
|
77
|
-
// Detect all attribute names
|
|
78
|
-
while ((match = attrRx.exec(shader.vertex))) {
|
|
79
|
-
attributes[match[1]] = i++;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
return attributes;
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* @ignore
|
|
87
|
-
*/
|
|
88
|
-
function compileShader(gl, type, source) {
|
|
89
|
-
var shader = gl.createShader(type);
|
|
90
|
-
gl.shaderSource(shader, source);
|
|
91
|
-
gl.compileShader(shader);
|
|
92
|
-
|
|
93
|
-
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
|
|
94
|
-
throw new Error(gl.getShaderInfoLog(shader));
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
return shader;
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* Compile GLSL into a shader object
|
|
102
|
-
* @ignore
|
|
103
|
-
*/
|
|
104
|
-
function compileProgram(gl, vertex, fragment, attributes) {
|
|
105
|
-
var vertShader = compileShader(gl, gl.VERTEX_SHADER, vertex);
|
|
106
|
-
var fragShader = compileShader(gl, gl.FRAGMENT_SHADER, fragment);
|
|
107
|
-
|
|
108
|
-
var program = gl.createProgram();
|
|
109
|
-
|
|
110
|
-
gl.attachShader(program, vertShader);
|
|
111
|
-
gl.attachShader(program, fragShader);
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
// force vertex attributes to use location 0 as starting location to prevent
|
|
115
|
-
// browser to do complicated emulation when running on desktop OpenGL (e.g. on macOS)
|
|
116
|
-
for (var location in attributes) {
|
|
117
|
-
gl.bindAttribLocation(program, attributes[location], location);
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
gl.linkProgram(program);
|
|
121
|
-
|
|
122
|
-
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
|
|
123
|
-
var error_msg =
|
|
124
|
-
"Error initializing Shader " + this + "\n" +
|
|
125
|
-
"gl.VALIDATE_STATUS: " + gl.getProgramParameter(program, gl.VALIDATE_STATUS) + "\n" +
|
|
126
|
-
"gl.getError()" + gl.getError() + "\n" +
|
|
127
|
-
"gl.getProgramInfoLog()" + gl.getProgramInfoLog(program);
|
|
128
|
-
// house cleaning
|
|
129
|
-
gl.deleteProgram(program);
|
|
130
|
-
program = null;
|
|
131
|
-
// throw the exception
|
|
132
|
-
throw new Error(error_msg);
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
gl.useProgram(program);
|
|
136
|
-
|
|
137
|
-
// clean-up
|
|
138
|
-
gl.deleteShader(vertShader);
|
|
139
|
-
gl.deleteShader(fragShader);
|
|
140
|
-
|
|
141
|
-
return program;
|
|
142
|
-
};
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* Hash map of GLSL data types to WebGL Uniform methods
|
|
147
|
-
* @ignore
|
|
148
|
-
*/
|
|
149
|
-
var fnHash = {
|
|
150
|
-
"bool" : "1i",
|
|
151
|
-
"int" : "1i",
|
|
152
|
-
"float" : "1f",
|
|
153
|
-
"vec2" : "2fv",
|
|
154
|
-
"vec3" : "3fv",
|
|
155
|
-
"vec4" : "4fv",
|
|
156
|
-
"bvec2" : "2iv",
|
|
157
|
-
"bvec3" : "3iv",
|
|
158
|
-
"bvec4" : "4iv",
|
|
159
|
-
"ivec2" : "2iv",
|
|
160
|
-
"ivec3" : "3iv",
|
|
161
|
-
"ivec4" : "4iv",
|
|
162
|
-
"mat2" : "Matrix2fv",
|
|
163
|
-
"mat3" : "Matrix3fv",
|
|
164
|
-
"mat4" : "Matrix4fv",
|
|
165
|
-
"sampler2D" : "1i"
|
|
166
|
-
};
|
|
167
|
-
|
|
168
|
-
/**
|
|
169
|
-
* set precision for the fiven shader source
|
|
170
|
-
* won't do anything if the precision is already specified
|
|
171
|
-
* @ignore
|
|
172
|
-
*/
|
|
173
|
-
function setPrecision(src, precision) {
|
|
174
|
-
if (src.substring(0, 9) !== "precision") {
|
|
175
|
-
return "precision " + precision + " float;" + src;
|
|
176
|
-
}
|
|
177
|
-
return src;
|
|
178
|
-
};
|
|
179
|
-
|
|
180
|
-
/**
|
|
181
|
-
* clean the given source from space, comments, etc...
|
|
182
|
-
* @ignore
|
|
183
|
-
*/
|
|
184
|
-
function minify(src) {
|
|
185
|
-
// remove comments
|
|
186
|
-
src = src.replace(/\/\*[\s\S]*?\*\/|([^\\:]|^)\/\/.*$/gm, "$1");
|
|
187
|
-
// Remove leading and trailing whitespace from lines
|
|
188
|
-
src = src.replace(/(\\n\s+)|(\s+\\n)/g, "");
|
|
189
|
-
// Remove line breaks
|
|
190
|
-
src = src.replace(/(\\r|\\n)+/g, "");
|
|
191
|
-
// Remove unnecessary whitespace
|
|
192
|
-
src = src.replace(/\s*([;,[\](){}\\\/\-+*|^&!=<>?~%])\s*/g, "$1");
|
|
193
|
-
|
|
194
|
-
return src;
|
|
195
|
-
};
|
|
3
|
+
import { extractUniforms } from "./utils/uniforms.js";
|
|
4
|
+
import { extractAttributes } from "./utils/attributes.js";
|
|
5
|
+
import { compileProgram } from "./utils/program.js";
|
|
6
|
+
import { setPrecision } from "./utils/precision.js";
|
|
7
|
+
import { minify } from "./utils/string.js";
|
|
196
8
|
|
|
197
9
|
/**
|
|
198
10
|
* @classdesc
|
|
@@ -337,6 +149,30 @@ class GLShader {
|
|
|
337
149
|
}
|
|
338
150
|
}
|
|
339
151
|
|
|
152
|
+
/**
|
|
153
|
+
* activate the given vertex attribute for this shader
|
|
154
|
+
* @name setVertexAttributes
|
|
155
|
+
* @memberof GLShader
|
|
156
|
+
* @function
|
|
157
|
+
* @param {WebGLRenderingContext} gl the current WebGL rendering context
|
|
158
|
+
* @param {object[]} attributes an array of vertex attributes
|
|
159
|
+
* @param {number} vertexByteSize the size of a single vertex in bytes
|
|
160
|
+
*/
|
|
161
|
+
setVertexAttributes(gl, attributes, vertexByteSize) {
|
|
162
|
+
// set the vertex attributes
|
|
163
|
+
for (var index = 0; index < attributes.length; ++index) {
|
|
164
|
+
var element = attributes[index];
|
|
165
|
+
var location = this.getAttribLocation(element.name);
|
|
166
|
+
|
|
167
|
+
if (location !== -1) {
|
|
168
|
+
gl.enableVertexAttribArray(location);
|
|
169
|
+
gl.vertexAttribPointer(location, element.size, element.type, element.normalized, vertexByteSize, element.offset);
|
|
170
|
+
} else {
|
|
171
|
+
gl.disableVertexAttribArray(index);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
340
176
|
/**
|
|
341
177
|
* destroy this shader objects resources (program, attributes, uniforms)
|
|
342
178
|
* @name destroy
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @ignore
|
|
3
|
+
*/
|
|
4
|
+
export function extractAttributes(gl, shader) {
|
|
5
|
+
var attributes = {},
|
|
6
|
+
attrRx = /attribute\s+\w+\s+(\w+)/g,
|
|
7
|
+
match,
|
|
8
|
+
i = 0;
|
|
9
|
+
|
|
10
|
+
// Detect all attribute names
|
|
11
|
+
while ((match = attrRx.exec(shader.vertex))) {
|
|
12
|
+
attributes[match[1]] = i++;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
return attributes;
|
|
16
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* set precision for the fiven shader source
|
|
3
|
+
* won't do anything if the precision is already specified
|
|
4
|
+
* @ignore
|
|
5
|
+
*/
|
|
6
|
+
export function setPrecision(src, precision) {
|
|
7
|
+
if (src.substring(0, 9) !== "precision") {
|
|
8
|
+
return "precision " + precision + " float;" + src;
|
|
9
|
+
}
|
|
10
|
+
return src;
|
|
11
|
+
};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @ignore
|
|
3
|
+
*/
|
|
4
|
+
function compileShader(gl, type, source) {
|
|
5
|
+
var shader = gl.createShader(type);
|
|
6
|
+
gl.shaderSource(shader, source);
|
|
7
|
+
gl.compileShader(shader);
|
|
8
|
+
|
|
9
|
+
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
|
|
10
|
+
throw new Error(gl.getShaderInfoLog(shader));
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
return shader;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Compile GLSL into a shader object
|
|
18
|
+
* @ignore
|
|
19
|
+
*/
|
|
20
|
+
export function compileProgram(gl, vertex, fragment, attributes) {
|
|
21
|
+
var vertShader = compileShader(gl, gl.VERTEX_SHADER, vertex);
|
|
22
|
+
var fragShader = compileShader(gl, gl.FRAGMENT_SHADER, fragment);
|
|
23
|
+
|
|
24
|
+
var program = gl.createProgram();
|
|
25
|
+
|
|
26
|
+
gl.attachShader(program, vertShader);
|
|
27
|
+
gl.attachShader(program, fragShader);
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
// force vertex attributes to use location 0 as starting location to prevent
|
|
31
|
+
// browser to do complicated emulation when running on desktop OpenGL (e.g. on macOS)
|
|
32
|
+
for (var location in attributes) {
|
|
33
|
+
gl.bindAttribLocation(program, attributes[location], location);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
gl.linkProgram(program);
|
|
37
|
+
|
|
38
|
+
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
|
|
39
|
+
var error_msg =
|
|
40
|
+
"Error initializing Shader " + this + "\n" +
|
|
41
|
+
"gl.VALIDATE_STATUS: " + gl.getProgramParameter(program, gl.VALIDATE_STATUS) + "\n" +
|
|
42
|
+
"gl.getError()" + gl.getError() + "\n" +
|
|
43
|
+
"gl.getProgramInfoLog()" + gl.getProgramInfoLog(program);
|
|
44
|
+
// house cleaning
|
|
45
|
+
gl.deleteProgram(program);
|
|
46
|
+
program = null;
|
|
47
|
+
// throw the exception
|
|
48
|
+
throw new Error(error_msg);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
gl.useProgram(program);
|
|
52
|
+
|
|
53
|
+
// clean-up
|
|
54
|
+
gl.deleteShader(vertShader);
|
|
55
|
+
gl.deleteShader(fragShader);
|
|
56
|
+
|
|
57
|
+
return program;
|
|
58
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* clean the given source from space, comments, etc...
|
|
3
|
+
* @ignore
|
|
4
|
+
*/
|
|
5
|
+
export function minify(src) {
|
|
6
|
+
// remove comments
|
|
7
|
+
src = src.replace(/\/\*[\s\S]*?\*\/|([^\\:]|^)\/\/.*$/gm, "$1");
|
|
8
|
+
// Remove leading and trailing whitespace from lines
|
|
9
|
+
src = src.replace(/(\\n\s+)|(\s+\\n)/g, "");
|
|
10
|
+
// Remove line breaks
|
|
11
|
+
src = src.replace(/(\\r|\\n)+/g, "");
|
|
12
|
+
// Remove unnecessary whitespace
|
|
13
|
+
src = src.replace(/\s*([;,[\](){}\\\/\-+*|^&!=<>?~%])\s*/g, "$1");
|
|
14
|
+
|
|
15
|
+
return src;
|
|
16
|
+
};
|