melonjs 14.5.0 → 15.1.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/LICENSE.md +1 -1
- package/README.md +6 -6
- package/dist/melonjs.mjs/_virtual/_commonjsHelpers.js +1 -1
- package/dist/melonjs.mjs/_virtual/arraymultimap.js +1 -1
- package/dist/melonjs.mjs/_virtual/earcut.js +1 -1
- package/dist/melonjs.mjs/_virtual/howler.js +1 -1
- package/dist/melonjs.mjs/_virtual/index.js +7 -3
- package/dist/melonjs.mjs/_virtual/index2.js +1 -1
- package/dist/melonjs.mjs/_virtual/multimap.js +1 -1
- package/dist/melonjs.mjs/_virtual/setmultimap.js +1 -1
- package/dist/melonjs.mjs/application/application.js +27 -17
- package/dist/melonjs.mjs/application/header.js +6 -5
- package/dist/melonjs.mjs/application/resize.js +20 -20
- package/dist/melonjs.mjs/application/settings.js +1 -1
- package/dist/melonjs.mjs/audio/audio.js +18 -20
- package/dist/melonjs.mjs/camera/camera2d.js +10 -10
- package/dist/melonjs.mjs/const.js +1 -1
- package/dist/melonjs.mjs/entity/entity.js +4 -4
- package/dist/melonjs.mjs/geometries/ellipse.js +6 -6
- package/dist/melonjs.mjs/geometries/line.js +9 -9
- package/dist/melonjs.mjs/geometries/path2d.js +56 -56
- package/dist/melonjs.mjs/geometries/point.js +2 -2
- package/dist/melonjs.mjs/geometries/poly.js +29 -29
- package/dist/melonjs.mjs/geometries/rectangle.js +8 -8
- package/dist/melonjs.mjs/geometries/roundrect.js +6 -6
- package/dist/melonjs.mjs/index.js +8 -6
- package/dist/melonjs.mjs/input/gamepad.js +30 -30
- package/dist/melonjs.mjs/input/input.js +2 -2
- package/dist/melonjs.mjs/input/keyboard.js +15 -15
- package/dist/melonjs.mjs/input/pointer.js +2 -2
- package/dist/melonjs.mjs/input/pointerevent.js +59 -59
- package/dist/melonjs.mjs/lang/console.js +3 -3
- package/dist/melonjs.mjs/lang/deprecated.js +2 -2
- package/dist/melonjs.mjs/level/level.js +9 -9
- package/dist/melonjs.mjs/level/tiled/TMXGroup.js +3 -3
- package/dist/melonjs.mjs/level/tiled/TMXLayer.js +31 -31
- package/dist/melonjs.mjs/level/tiled/TMXObject.js +8 -8
- package/dist/melonjs.mjs/level/tiled/TMXTile.js +8 -8
- package/dist/melonjs.mjs/level/tiled/TMXTileMap.js +19 -19
- package/dist/melonjs.mjs/level/tiled/TMXTileset.js +15 -15
- package/dist/melonjs.mjs/level/tiled/TMXTilesetGroup.js +3 -3
- package/dist/melonjs.mjs/level/tiled/TMXUtils.js +46 -41
- package/dist/melonjs.mjs/level/tiled/constants.js +1 -1
- package/dist/melonjs.mjs/level/tiled/renderer/TMXHexagonalRenderer.js +30 -30
- package/dist/melonjs.mjs/level/tiled/renderer/TMXIsometricRenderer.js +21 -21
- package/dist/melonjs.mjs/level/tiled/renderer/TMXOrthogonalRenderer.js +10 -10
- package/dist/melonjs.mjs/level/tiled/renderer/TMXRenderer.js +2 -2
- package/dist/melonjs.mjs/level/tiled/renderer/TMXStaggeredRenderer.js +6 -6
- package/dist/melonjs.mjs/level/tiled/renderer/autodetect.js +1 -1
- package/dist/melonjs.mjs/loader/cache.js +1 -1
- package/dist/melonjs.mjs/loader/loader.js +7 -7
- package/dist/melonjs.mjs/loader/loadingscreen.js +2 -2
- package/dist/melonjs.mjs/loader/melonjs_logo.png.js +1 -1
- package/dist/melonjs.mjs/loader/parser.js +13 -13
- package/dist/melonjs.mjs/loader/settings.js +3 -3
- package/dist/melonjs.mjs/math/color.js +25 -24
- package/dist/melonjs.mjs/math/math.js +2 -2
- package/dist/melonjs.mjs/math/matrix2.js +22 -22
- package/dist/melonjs.mjs/math/matrix3.js +52 -52
- package/dist/melonjs.mjs/math/observable_vector2.js +12 -12
- package/dist/melonjs.mjs/math/observable_vector3.js +22 -22
- package/dist/melonjs.mjs/math/vector2.js +11 -11
- package/dist/melonjs.mjs/math/vector3.js +21 -21
- package/dist/melonjs.mjs/node_modules/@teppeis/multimaps/dist/esm/arraymultimap.js +45 -0
- package/dist/melonjs.mjs/node_modules/@teppeis/multimaps/dist/esm/multimap.js +130 -0
- package/dist/melonjs.mjs/node_modules/@teppeis/multimaps/dist/src/arraymultimap.js +1 -1
- package/dist/melonjs.mjs/node_modules/@teppeis/multimaps/dist/src/index.js +1 -1
- package/dist/melonjs.mjs/node_modules/@teppeis/multimaps/dist/src/multimap.js +1 -1
- package/dist/melonjs.mjs/node_modules/@teppeis/multimaps/dist/src/setmultimap.js +1 -1
- package/dist/melonjs.mjs/node_modules/earcut/src/earcut.js +1 -1
- package/dist/melonjs.mjs/node_modules/eventemitter3/index.js +2 -2
- package/dist/melonjs.mjs/node_modules/eventemitter3/index2.js +1 -1
- package/dist/melonjs.mjs/node_modules/howler/dist/howler.js +1 -1
- package/dist/melonjs.mjs/particles/emitter.js +5 -5
- package/dist/melonjs.mjs/particles/particle.js +8 -8
- package/dist/melonjs.mjs/particles/settings.js +3 -3
- package/dist/melonjs.mjs/physics/body.js +17 -17
- package/dist/melonjs.mjs/physics/bounds.js +12 -12
- package/dist/melonjs.mjs/physics/collision.js +3 -3
- package/dist/melonjs.mjs/physics/detector.js +14 -14
- package/dist/melonjs.mjs/physics/quadtree.js +19 -19
- package/dist/melonjs.mjs/physics/response.js +1 -1
- package/dist/melonjs.mjs/physics/sat.js +60 -60
- package/dist/melonjs.mjs/physics/world.js +4 -4
- package/dist/melonjs.mjs/plugin/plugin.js +11 -11
- package/dist/melonjs.mjs/renderable/collectable.js +2 -2
- package/dist/melonjs.mjs/renderable/colorlayer.js +1 -1
- package/dist/melonjs.mjs/renderable/container.js +77 -59
- package/dist/melonjs.mjs/renderable/dragndrop.js +5 -5
- package/dist/melonjs.mjs/renderable/imagelayer.js +7 -6
- package/dist/melonjs.mjs/renderable/light2d.js +6 -6
- package/dist/melonjs.mjs/renderable/nineslicesprite.js +12 -12
- package/dist/melonjs.mjs/renderable/renderable.js +35 -13
- package/dist/melonjs.mjs/renderable/sprite.js +25 -25
- package/dist/melonjs.mjs/renderable/trigger.js +11 -9
- package/dist/melonjs.mjs/renderable/ui/uibaseelement.js +97 -27
- package/dist/melonjs.mjs/renderable/ui/uispriteelement.js +25 -25
- package/dist/melonjs.mjs/renderable/ui/uitextbutton.js +83 -65
- package/dist/melonjs.mjs/state/stage.js +7 -7
- package/dist/melonjs.mjs/state/state.js +15 -15
- package/dist/melonjs.mjs/system/device.js +3 -3
- package/dist/melonjs.mjs/system/dom.js +1 -1
- package/dist/melonjs.mjs/system/event.js +2 -2
- package/dist/melonjs.mjs/system/platform.js +1 -1
- package/dist/melonjs.mjs/system/pooling.js +9 -9
- package/dist/melonjs.mjs/system/save.js +6 -6
- package/dist/melonjs.mjs/system/timer.js +16 -12
- package/dist/melonjs.mjs/text/bitmaptext.js +20 -20
- package/dist/melonjs.mjs/text/bitmaptextdata.js +22 -22
- package/dist/melonjs.mjs/text/glyph.js +3 -3
- package/dist/melonjs.mjs/text/text.js +63 -92
- package/dist/melonjs.mjs/text/textmetrics.js +15 -15
- package/dist/melonjs.mjs/text/textstyle.js +4 -6
- package/dist/melonjs.mjs/tweens/easing.js +4 -4
- package/dist/melonjs.mjs/tweens/interpolation.js +8 -8
- package/dist/melonjs.mjs/tweens/tween.js +11 -11
- package/dist/melonjs.mjs/utils/agent.js +6 -6
- package/dist/melonjs.mjs/utils/array.js +4 -4
- package/dist/melonjs.mjs/utils/file.js +1 -1
- package/dist/melonjs.mjs/utils/function.js +5 -5
- package/dist/melonjs.mjs/utils/string.js +3 -3
- package/dist/melonjs.mjs/utils/utils.js +16 -16
- package/dist/melonjs.mjs/video/canvas/canvas_renderer.js +41 -119
- package/dist/melonjs.mjs/video/renderer.js +70 -14
- package/dist/melonjs.mjs/video/texture/atlas.js +39 -45
- package/dist/melonjs.mjs/video/texture/cache.js +9 -10
- package/dist/melonjs.mjs/video/texture/canvas_texture.js +63 -3
- package/dist/melonjs.mjs/video/utils/autodetect.js +1 -1
- package/dist/melonjs.mjs/video/video.js +2 -2
- package/dist/melonjs.mjs/video/webgl/buffer/vertex.js +23 -19
- package/dist/melonjs.mjs/video/webgl/compositors/compositor.js +80 -80
- package/dist/melonjs.mjs/video/webgl/compositors/primitive_compositor.js +77 -0
- package/dist/melonjs.mjs/video/webgl/compositors/quad_compositor.js +252 -0
- package/dist/melonjs.mjs/video/webgl/compositors/webgl_compositor.js +1 -1
- package/dist/melonjs.mjs/video/webgl/glshader.js +7 -7
- package/dist/melonjs.mjs/video/webgl/shaders/primitive.frag.js +1 -1
- package/dist/melonjs.mjs/video/webgl/shaders/primitive.vert.js +2 -2
- package/dist/melonjs.mjs/video/webgl/shaders/quad.frag.js +1 -1
- package/dist/melonjs.mjs/video/webgl/shaders/quad.vert.js +2 -2
- package/dist/melonjs.mjs/video/webgl/utils/attributes.js +2 -2
- package/dist/melonjs.mjs/video/webgl/utils/precision.js +1 -1
- package/dist/melonjs.mjs/video/webgl/utils/program.js +7 -7
- package/dist/melonjs.mjs/video/webgl/utils/string.js +1 -1
- package/dist/melonjs.mjs/video/webgl/utils/uniforms.js +4 -4
- package/dist/melonjs.mjs/video/webgl/webgl_renderer.js +188 -181
- package/dist/melonjs.module.js +25040 -25193
- package/dist/types/application/application.d.ts +11 -8
- package/dist/types/audio/audio.d.ts +3 -3
- package/dist/types/entity/entity.d.ts +1 -1
- package/dist/types/index.d.ts +7 -4
- package/dist/types/input/input.d.ts +1 -1
- package/dist/types/input/keyboard.d.ts +1 -1
- package/dist/types/input/pointerevent.d.ts +6 -6
- package/dist/types/level/level.d.ts +2 -2
- package/dist/types/level/tiled/TMXLayer.d.ts +4 -4
- package/dist/types/level/tiled/TMXTileMap.d.ts +2 -2
- package/dist/types/level/tiled/TMXUtils.d.ts +5 -4
- package/dist/types/loader/loader.d.ts +2 -2
- package/dist/types/loader/settings.d.ts +2 -2
- package/dist/types/particles/emitter.d.ts +1 -1
- package/dist/types/physics/collision.d.ts +1 -1
- package/dist/types/physics/detector.d.ts +1 -1
- package/dist/types/plugin/plugin.d.ts +2 -2
- package/dist/types/renderable/container.d.ts +21 -17
- package/dist/types/renderable/renderable.d.ts +6 -0
- package/dist/types/renderable/sprite.d.ts +11 -11
- package/dist/types/renderable/trigger.d.ts +1 -1
- package/dist/types/renderable/ui/uibaseelement.d.ts +28 -6
- package/dist/types/renderable/ui/uispriteelement.d.ts +12 -14
- package/dist/types/renderable/ui/uitextbutton.d.ts +52 -12
- package/dist/types/state/stage.d.ts +1 -1
- package/dist/types/system/device.d.ts +1 -1
- package/dist/types/system/pooling.d.ts +3 -3
- package/dist/types/system/timer.d.ts +5 -5
- package/dist/types/text/bitmaptext.d.ts +1 -1
- package/dist/types/text/text.d.ts +7 -21
- package/dist/types/text/textstyle.d.ts +1 -1
- package/dist/types/utils/array.d.ts +2 -2
- package/dist/types/video/canvas/canvas_renderer.d.ts +8 -81
- package/dist/types/video/renderer.d.ts +48 -4
- package/dist/types/video/texture/atlas.d.ts +3 -3
- package/dist/types/video/texture/canvas_texture.d.ts +40 -0
- package/dist/types/video/webgl/buffer/vertex.d.ts +3 -3
- package/dist/types/video/webgl/compositors/compositor.d.ts +38 -32
- package/dist/types/video/webgl/compositors/primitive_compositor.d.ts +22 -0
- package/dist/types/video/webgl/compositors/quad_compositor.d.ts +72 -0
- package/dist/types/video/webgl/glshader.d.ts +1 -1
- package/dist/types/video/webgl/webgl_renderer.d.ts +47 -37
- package/package.json +16 -17
- package/src/application/application.js +26 -16
- package/src/application/header.js +5 -4
- package/src/application/resize.js +19 -19
- package/src/audio/audio.js +17 -19
- package/src/camera/camera2d.js +9 -9
- package/src/entity/entity.js +3 -3
- package/src/geometries/ellipse.js +5 -5
- package/src/geometries/line.js +8 -8
- package/src/geometries/path2d.js +55 -55
- package/src/geometries/point.js +1 -1
- package/src/geometries/poly.js +28 -28
- package/src/geometries/rectangle.js +7 -7
- package/src/geometries/roundrect.js +5 -5
- package/src/index.js +9 -4
- package/src/input/gamepad.js +29 -29
- package/src/input/input.js +1 -1
- package/src/input/keyboard.js +14 -14
- package/src/input/pointer.js +1 -1
- package/src/input/pointerevent.js +52 -52
- package/src/lang/console.js +2 -2
- package/src/lang/deprecated.js +1 -1
- package/src/level/level.js +8 -8
- package/src/level/tiled/TMXGroup.js +2 -2
- package/src/level/tiled/TMXLayer.js +30 -30
- package/src/level/tiled/TMXObject.js +7 -7
- package/src/level/tiled/TMXTile.js +7 -7
- package/src/level/tiled/TMXTileMap.js +18 -18
- package/src/level/tiled/TMXTileset.js +14 -14
- package/src/level/tiled/TMXTilesetGroup.js +2 -2
- package/src/level/tiled/TMXUtils.js +45 -40
- package/src/level/tiled/renderer/TMXHexagonalRenderer.js +29 -29
- package/src/level/tiled/renderer/TMXIsometricRenderer.js +20 -20
- package/src/level/tiled/renderer/TMXOrthogonalRenderer.js +9 -9
- package/src/level/tiled/renderer/TMXRenderer.js +1 -1
- package/src/level/tiled/renderer/TMXStaggeredRenderer.js +5 -5
- package/src/loader/loader.js +6 -6
- package/src/loader/loadingscreen.js +1 -1
- package/src/loader/parser.js +12 -12
- package/src/loader/settings.js +2 -2
- package/src/math/color.js +24 -23
- package/src/math/math.js +1 -1
- package/src/math/matrix2.js +21 -21
- package/src/math/matrix3.js +51 -51
- package/src/math/observable_vector2.js +11 -11
- package/src/math/observable_vector3.js +21 -21
- package/src/math/vector2.js +10 -10
- package/src/math/vector3.js +20 -20
- package/src/particles/emitter.js +4 -4
- package/src/particles/particle.js +7 -7
- package/src/particles/settings.js +2 -2
- package/src/physics/body.js +16 -16
- package/src/physics/bounds.js +11 -11
- package/src/physics/collision.js +2 -2
- package/src/physics/detector.js +13 -13
- package/src/physics/quadtree.js +18 -18
- package/src/physics/sat.js +59 -59
- package/src/physics/world.js +3 -3
- package/src/plugin/plugin.js +8 -8
- package/src/polyfill/index.js +0 -2
- package/src/renderable/collectable.js +1 -1
- package/src/renderable/container.js +76 -58
- package/src/renderable/dragndrop.js +4 -4
- package/src/renderable/imagelayer.js +6 -5
- package/src/renderable/light2d.js +5 -5
- package/src/renderable/nineslicesprite.js +11 -11
- package/src/renderable/renderable.js +34 -12
- package/src/renderable/sprite.js +24 -24
- package/src/renderable/trigger.js +10 -8
- package/src/renderable/ui/uibaseelement.js +96 -26
- package/src/renderable/ui/uispriteelement.js +24 -24
- package/src/renderable/ui/uitextbutton.js +85 -67
- package/src/state/stage.js +6 -6
- package/src/state/state.js +14 -14
- package/src/system/device.js +2 -2
- package/src/system/event.js +1 -1
- package/src/system/pooling.js +8 -8
- package/src/system/save.js +5 -5
- package/src/system/timer.js +15 -11
- package/src/text/bitmaptext.js +19 -19
- package/src/text/bitmaptextdata.js +21 -21
- package/src/text/glyph.js +2 -2
- package/src/text/text.js +62 -91
- package/src/text/textmetrics.js +14 -14
- package/src/text/textstyle.js +3 -5
- package/src/tweens/easing.js +3 -3
- package/src/tweens/interpolation.js +7 -7
- package/src/tweens/tween.js +10 -10
- package/src/utils/agent.js +5 -5
- package/src/utils/array.js +3 -3
- package/src/utils/function.js +4 -4
- package/src/utils/string.js +2 -2
- package/src/utils/utils.js +15 -15
- package/src/video/canvas/canvas_renderer.js +39 -117
- package/src/video/renderer.js +68 -12
- package/src/video/texture/atlas.js +38 -44
- package/src/video/texture/cache.js +6 -6
- package/src/video/texture/canvas_texture.js +62 -2
- package/src/video/video.js +1 -1
- package/src/video/webgl/buffer/vertex.js +22 -18
- package/src/video/webgl/compositors/compositor.js +79 -80
- package/src/video/webgl/compositors/primitive_compositor.js +68 -0
- package/src/video/webgl/compositors/{webgl_compositor.js → quad_compositor.js} +52 -109
- package/src/video/webgl/glshader.js +6 -6
- package/src/video/webgl/shaders/primitive.vert +2 -5
- package/src/video/webgl/shaders/quad.vert +3 -1
- package/src/video/webgl/utils/attributes.js +1 -1
- package/src/video/webgl/utils/program.js +6 -6
- package/src/video/webgl/utils/uniforms.js +3 -3
- package/src/video/webgl/webgl_renderer.js +186 -179
- package/dist/melonjs.mjs/_virtual/make-built-in.js +0 -10
- package/dist/melonjs.mjs/_virtual/object-define-property.js +0 -10
- package/dist/melonjs.mjs/_virtual/object-get-own-property-descriptor.js +0 -10
- package/dist/melonjs.mjs/_virtual/object-get-own-property-names.js +0 -10
- package/dist/melonjs.mjs/_virtual/object-get-own-property-symbols.js +0 -10
- package/dist/melonjs.mjs/_virtual/object-property-is-enumerable.js +0 -10
- package/dist/melonjs.mjs/_virtual/shared.js +0 -10
- package/dist/melonjs.mjs/game.js +0 -29
- package/dist/melonjs.mjs/polyfill/console.js +0 -18
- package/dist/melonjs.mjs/polyfill/performance.js +0 -27
- package/dist/melonjs.mjs/polyfill/requestAnimationFrame.js +0 -46
- package/dist/melonjs.mjs/polyfill/roundrect.js +0 -242
- package/dist/melonjs.mjs/renderable/re_container.js +0 -1016
- package/dist/melonjs.mjs/video/utils/resize.js +0 -116
- package/dist/melonjs.mjs/video/webgl/webgl_compositor.js +0 -494
- package/src/polyfill/performance.js +0 -20
- package/src/polyfill/requestAnimationFrame.js +0 -39
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import primitiveVertex from "./../shaders/primitive.vert";
|
|
2
|
+
import primitiveFragment from "./../shaders/primitive.frag";
|
|
3
|
+
import Compositor from "./compositor.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @classdesc
|
|
7
|
+
* A WebGL Compositor object. This class handles all of the WebGL state<br>
|
|
8
|
+
* Pushes texture regions or shape geometry into WebGL buffers, automatically flushes to GPU
|
|
9
|
+
* @augments Compositor
|
|
10
|
+
*/
|
|
11
|
+
export default class PrimitiveCompositor extends Compositor {
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Initialize the compositor
|
|
15
|
+
* @ignore
|
|
16
|
+
*/
|
|
17
|
+
init(renderer) {
|
|
18
|
+
super.init(renderer, {
|
|
19
|
+
attributes: [
|
|
20
|
+
{name: "aVertex", size: 2, type: renderer.gl.FLOAT, normalized: false, offset: 0 * Float32Array.BYTES_PER_ELEMENT},
|
|
21
|
+
{name: "aColor", size: 4, type: renderer.gl.UNSIGNED_BYTE, normalized: true, offset: 2 * Float32Array.BYTES_PER_ELEMENT}
|
|
22
|
+
],
|
|
23
|
+
shader: {
|
|
24
|
+
vertex: primitiveVertex, fragment: primitiveFragment
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Draw an array of vertices
|
|
31
|
+
* @param {GLenum} mode - primitive type to render (gl.POINTS, gl.LINE_STRIP, gl.LINE_LOOP, gl.LINES, gl.TRIANGLE_STRIP, gl.TRIANGLE_FAN, gl.TRIANGLES)
|
|
32
|
+
* @param {Point[]} verts - an array of vertices
|
|
33
|
+
* @param {number} [vertexCount=verts.length] - amount of points defined in the points array
|
|
34
|
+
*/
|
|
35
|
+
drawVertices(mode, verts, vertexCount = verts.length) {
|
|
36
|
+
let viewMatrix = this.viewMatrix;
|
|
37
|
+
let vertexData = this.vertexData;
|
|
38
|
+
let color = this.renderer.currentColor;
|
|
39
|
+
let alpha = this.renderer.getGlobalAlpha();
|
|
40
|
+
|
|
41
|
+
if (vertexData.isFull(vertexCount)) {
|
|
42
|
+
// is the vertex buffer full if we add more vertices
|
|
43
|
+
this.flush();
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// flush if drawing vertices with a different drawing mode
|
|
47
|
+
if (mode !== this.mode) {
|
|
48
|
+
this.flush(this.mode);
|
|
49
|
+
this.mode = mode;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (!viewMatrix.isIdentity()) {
|
|
53
|
+
verts.forEach((vert) => {
|
|
54
|
+
viewMatrix.apply(vert);
|
|
55
|
+
vertexData.push(vert.x, vert.y, undefined, undefined, color.toUint32(alpha));
|
|
56
|
+
});
|
|
57
|
+
} else {
|
|
58
|
+
verts.forEach((vert) => {
|
|
59
|
+
vertexData.push(vert.x, vert.y, undefined, undefined, color.toUint32(alpha));
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// force flush for primitive using LINE_STRIP or LINE_LOOP
|
|
64
|
+
if (this.mode === this.gl.LINE_STRIP || this.mode === this.gl.LINE_LOOP) {
|
|
65
|
+
this.flush(this.mode);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -1,15 +1,11 @@
|
|
|
1
1
|
import Vector2d from "../../../math/vector2.js";
|
|
2
|
-
import GLShader from "../glshader.js";
|
|
3
|
-
import VertexArrayBuffer from "../buffer/vertex.js";
|
|
4
2
|
import { isPowerOfTwo } from "../../../math/math.js";
|
|
5
|
-
import primitiveVertex from "./../shaders/primitive.vert";
|
|
6
|
-
import primitiveFragment from "./../shaders/primitive.frag";
|
|
7
3
|
import quadVertex from "./../shaders/quad.vert";
|
|
8
4
|
import quadFragment from "./../shaders/quad.frag";
|
|
9
5
|
import Compositor from "./compositor.js";
|
|
10
6
|
|
|
11
7
|
// a pool of resuable vectors
|
|
12
|
-
|
|
8
|
+
let V_ARRAY = [
|
|
13
9
|
new Vector2d(),
|
|
14
10
|
new Vector2d(),
|
|
15
11
|
new Vector2d(),
|
|
@@ -22,33 +18,27 @@ var V_ARRAY = [
|
|
|
22
18
|
* Pushes texture regions or shape geometry into WebGL buffers, automatically flushes to GPU
|
|
23
19
|
* @augments Compositor
|
|
24
20
|
*/
|
|
25
|
-
export default class
|
|
21
|
+
export default class QuadCompositor extends Compositor {
|
|
26
22
|
|
|
27
23
|
/**
|
|
28
24
|
* Initialize the compositor
|
|
29
25
|
* @ignore
|
|
30
26
|
*/
|
|
31
27
|
init (renderer) {
|
|
32
|
-
super.init(renderer
|
|
28
|
+
super.init(renderer, {
|
|
29
|
+
attributes: [
|
|
30
|
+
{name: "aVertex", size: 2, type: renderer.gl.FLOAT, normalized: false, offset: 0 * Float32Array.BYTES_PER_ELEMENT},
|
|
31
|
+
{name: "aRegion", size: 2, type: renderer.gl.FLOAT, normalized: false, offset: 2 * Float32Array.BYTES_PER_ELEMENT},
|
|
32
|
+
{name: "aColor", size: 4, type: renderer.gl.UNSIGNED_BYTE, normalized: true, offset: 4 * Float32Array.BYTES_PER_ELEMENT}
|
|
33
|
+
],
|
|
34
|
+
shader: {
|
|
35
|
+
vertex: quadVertex, fragment: quadFragment
|
|
36
|
+
}
|
|
37
|
+
});
|
|
33
38
|
|
|
34
39
|
// list of active texture units
|
|
35
40
|
this.currentTextureUnit = -1;
|
|
36
41
|
this.boundTextures = [];
|
|
37
|
-
|
|
38
|
-
// Load and create shader programs
|
|
39
|
-
this.primitiveShader = new GLShader(this.gl, primitiveVertex, primitiveFragment);
|
|
40
|
-
this.quadShader = new GLShader(this.gl, quadVertex, quadFragment);
|
|
41
|
-
|
|
42
|
-
/// define all vertex attributes
|
|
43
|
-
this.addAttribute("aVertex", 2, this.gl.FLOAT, false, 0 * Float32Array.BYTES_PER_ELEMENT); // 0
|
|
44
|
-
this.addAttribute("aRegion", 2, this.gl.FLOAT, false, 2 * Float32Array.BYTES_PER_ELEMENT); // 1
|
|
45
|
-
this.addAttribute("aColor", 4, this.gl.UNSIGNED_BYTE, true, 4 * Float32Array.BYTES_PER_ELEMENT); // 2
|
|
46
|
-
|
|
47
|
-
this.vertexBuffer = new VertexArrayBuffer(this.vertexSize, 6); // 6 vertices per quad
|
|
48
|
-
|
|
49
|
-
// vertex buffer
|
|
50
|
-
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.gl.createBuffer());
|
|
51
|
-
this.gl.bufferData(this.gl.ARRAY_BUFFER, this.vertexBuffer.buffer, this.gl.STREAM_DRAW);
|
|
52
42
|
}
|
|
53
43
|
|
|
54
44
|
/**
|
|
@@ -59,37 +49,34 @@ var V_ARRAY = [
|
|
|
59
49
|
super.reset();
|
|
60
50
|
|
|
61
51
|
// delete all related bound texture
|
|
62
|
-
for (
|
|
63
|
-
|
|
52
|
+
for (let i = 0; i < this.renderer.maxTextures; i++) {
|
|
53
|
+
let texture2D = this.getTexture2D(i);
|
|
64
54
|
if (typeof texture2D !== "undefined") {
|
|
65
55
|
this.deleteTexture2D(texture2D);
|
|
66
56
|
}
|
|
67
57
|
}
|
|
68
58
|
this.currentTextureUnit = -1;
|
|
69
|
-
|
|
70
|
-
// set the quad shader as the default program
|
|
71
|
-
this.useShader(this.quadShader);
|
|
72
59
|
}
|
|
73
60
|
|
|
74
61
|
/**
|
|
75
62
|
* Create a WebGL texture from an image
|
|
76
63
|
* @param {number} unit - Destination texture unit
|
|
77
|
-
* @param {Image|HTMLCanvasElement|ImageData|Uint8Array[]|Float32Array[]}
|
|
64
|
+
* @param {Image|HTMLCanvasElement|ImageData|Uint8Array[]|Float32Array[]} [pixels=null] - Source image
|
|
78
65
|
* @param {number} filter - gl.LINEAR or gl.NEAREST
|
|
79
66
|
* @param {string} [repeat="no-repeat"] - Image repeat behavior (see {@link ImageLayer#repeat})
|
|
80
|
-
* @param {number} [w] - Source image width (Only use with UInt8Array[] or Float32Array[] source image)
|
|
81
|
-
* @param {number} [h] - Source image height (Only use with UInt8Array[] or Float32Array[] source image)
|
|
82
|
-
* @param {number} [b] - Source image border (Only use with UInt8Array[] or Float32Array[] source image)
|
|
67
|
+
* @param {number} [w=pixels.width] - Source image width (Only use with UInt8Array[] or Float32Array[] source image)
|
|
68
|
+
* @param {number} [h=pixels.height] - Source image height (Only use with UInt8Array[] or Float32Array[] source image)
|
|
83
69
|
* @param {boolean} [premultipliedAlpha=true] - Multiplies the alpha channel into the other color channels
|
|
84
70
|
* @param {boolean} [mipmap=true] - Whether mipmap levels should be generated for this texture
|
|
85
71
|
* @returns {WebGLTexture} a WebGL texture
|
|
86
72
|
*/
|
|
87
|
-
createTexture2D(unit,
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
73
|
+
createTexture2D(unit, pixels = null, filter, repeat = "no-repeat", w = pixels.width, h = pixels.height, premultipliedAlpha = true, mipmap = true) {
|
|
74
|
+
let gl = this.gl;
|
|
75
|
+
let isPOT = isPowerOfTwo(w) && isPowerOfTwo(h);
|
|
76
|
+
let rs = (repeat.search(/^repeat(-x)?$/) === 0) && (isPOT || this.renderer.WebGLVersion > 1) ? gl.REPEAT : gl.CLAMP_TO_EDGE;
|
|
77
|
+
let rt = (repeat.search(/^repeat(-y)?$/) === 0) && (isPOT || this.renderer.WebGLVersion > 1) ? gl.REPEAT : gl.CLAMP_TO_EDGE;
|
|
78
|
+
|
|
79
|
+
let texture = gl.createTexture();
|
|
93
80
|
|
|
94
81
|
this.bindTexture2D(texture, unit);
|
|
95
82
|
|
|
@@ -97,16 +84,21 @@ var V_ARRAY = [
|
|
|
97
84
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, rt);
|
|
98
85
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, filter);
|
|
99
86
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, filter);
|
|
87
|
+
|
|
100
88
|
gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, premultipliedAlpha);
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
89
|
+
|
|
90
|
+
if (pixels === null || typeof pixels.byteLength !== "undefined") {
|
|
91
|
+
// if pixels is undefined, or if it's Uint8Array/Float32Array TypedArray
|
|
92
|
+
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, w, h, 0, gl.RGBA, gl.UNSIGNED_BYTE, pixels, 0);
|
|
93
|
+
} else if (pixels instanceof OffscreenCanvas) {
|
|
94
|
+
// convert to ImageBitmap first (else Safari 16.4 and higher will throw an TypeError exception)
|
|
95
|
+
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, pixels.transferToImageBitmap());
|
|
96
|
+
} else {
|
|
97
|
+
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
|
|
106
98
|
}
|
|
107
99
|
|
|
108
100
|
// generate the sprite mimap (used when scaling) if a PowerOfTwo texture
|
|
109
|
-
if (isPOT && mipmap
|
|
101
|
+
if (isPOT && mipmap === true) {
|
|
110
102
|
gl.generateMipmap(gl.TEXTURE_2D);
|
|
111
103
|
}
|
|
112
104
|
|
|
@@ -138,7 +130,7 @@ var V_ARRAY = [
|
|
|
138
130
|
* @param {number} unit - Texture unit to which the given texture is bound
|
|
139
131
|
*/
|
|
140
132
|
bindTexture2D(texture, unit) {
|
|
141
|
-
|
|
133
|
+
let gl = this.gl;
|
|
142
134
|
|
|
143
135
|
if (texture !== this.boundTextures[unit]) {
|
|
144
136
|
this.flush();
|
|
@@ -179,9 +171,9 @@ var V_ARRAY = [
|
|
|
179
171
|
/**
|
|
180
172
|
* @ignore
|
|
181
173
|
*/
|
|
182
|
-
uploadTexture(texture, w, h,
|
|
183
|
-
|
|
184
|
-
|
|
174
|
+
uploadTexture(texture, w, h, force = false) {
|
|
175
|
+
let unit = this.renderer.cache.getUnit(texture);
|
|
176
|
+
let texture2D = this.boundTextures[unit];
|
|
185
177
|
|
|
186
178
|
if (typeof texture2D === "undefined" || force) {
|
|
187
179
|
this.createTexture2D(
|
|
@@ -191,7 +183,6 @@ var V_ARRAY = [
|
|
|
191
183
|
texture.repeat,
|
|
192
184
|
w,
|
|
193
185
|
h,
|
|
194
|
-
b,
|
|
195
186
|
texture.premultipliedAlpha
|
|
196
187
|
);
|
|
197
188
|
} else {
|
|
@@ -201,22 +192,6 @@ var V_ARRAY = [
|
|
|
201
192
|
return this.currentTextureUnit;
|
|
202
193
|
}
|
|
203
194
|
|
|
204
|
-
|
|
205
|
-
/**
|
|
206
|
-
* Select the shader to use for compositing
|
|
207
|
-
* @see GLShader
|
|
208
|
-
* @param {GLShader} shader - a reference to a GLShader instance
|
|
209
|
-
*/
|
|
210
|
-
useShader(shader) {
|
|
211
|
-
if (this.activeShader !== shader) {
|
|
212
|
-
this.flush();
|
|
213
|
-
this.activeShader = shader;
|
|
214
|
-
this.activeShader.bind();
|
|
215
|
-
this.activeShader.setUniform("uProjectionMatrix", this.renderer.projectionMatrix);
|
|
216
|
-
this.activeShader.setVertexAttributes(this.gl, this.attributes, this.vertexByteSize);
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
|
|
220
195
|
/**
|
|
221
196
|
* Add a textured quad
|
|
222
197
|
* @param {TextureAtlas} texture - Source texture atlas
|
|
@@ -231,26 +206,21 @@ var V_ARRAY = [
|
|
|
231
206
|
* @param {number} tint - tint color to be applied to the texture in UINT32 (argb) format
|
|
232
207
|
*/
|
|
233
208
|
addQuad(texture, x, y, w, h, u0, v0, u1, v1, tint) {
|
|
209
|
+
let vertexData = this.vertexData;
|
|
234
210
|
|
|
235
|
-
if (
|
|
236
|
-
// Fast path: don't send fully transparent quads
|
|
237
|
-
return;
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
this.useShader(this.quadShader);
|
|
241
|
-
|
|
242
|
-
if (this.vertexBuffer.isFull(6)) {
|
|
211
|
+
if (vertexData.isFull(6)) {
|
|
243
212
|
// is the vertex buffer full if we add 6 more vertices
|
|
244
213
|
this.flush();
|
|
245
214
|
}
|
|
246
215
|
|
|
247
216
|
// upload and activate the texture if necessary
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
217
|
+
let unit = this.uploadTexture(texture);
|
|
218
|
+
|
|
219
|
+
// set fragment sampler accordingly
|
|
220
|
+
this.currentShader.setUniform("uSampler", unit);
|
|
251
221
|
|
|
252
222
|
// Transform vertices
|
|
253
|
-
|
|
223
|
+
let m = this.viewMatrix,
|
|
254
224
|
vec0 = V_ARRAY[0].set(x, y),
|
|
255
225
|
vec1 = V_ARRAY[1].set(x + w, y),
|
|
256
226
|
vec2 = V_ARRAY[2].set(x, y + h),
|
|
@@ -263,38 +233,11 @@ var V_ARRAY = [
|
|
|
263
233
|
m.apply(vec3);
|
|
264
234
|
}
|
|
265
235
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
/**
|
|
275
|
-
* Draw an array of vertices
|
|
276
|
-
* @param {GLenum} mode - primitive type to render (gl.POINTS, gl.LINE_STRIP, gl.LINE_LOOP, gl.LINES, gl.TRIANGLE_STRIP, gl.TRIANGLE_FAN, gl.TRIANGLES)
|
|
277
|
-
* @param {Point[]} verts - an array of vertices
|
|
278
|
-
* @param {number} [vertexCount=verts.length] - amount of points defined in the points array
|
|
279
|
-
*/
|
|
280
|
-
drawVertices(mode, verts, vertexCount = verts.length) {
|
|
281
|
-
// use the primitive shader
|
|
282
|
-
this.useShader(this.primitiveShader);
|
|
283
|
-
// Set the line color
|
|
284
|
-
this.primitiveShader.setUniform("uColor", this.color);
|
|
285
|
-
|
|
286
|
-
var m = this.viewMatrix;
|
|
287
|
-
var vertex = this.vertexBuffer;
|
|
288
|
-
var m_isIdentity = m.isIdentity();
|
|
289
|
-
|
|
290
|
-
for (var i = 0; i < vertexCount; i++) {
|
|
291
|
-
if (!m_isIdentity) {
|
|
292
|
-
m.apply(verts[i]);
|
|
293
|
-
}
|
|
294
|
-
vertex.push(verts[i].x, verts[i].y);
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
// flush
|
|
298
|
-
this.flush(mode);
|
|
236
|
+
vertexData.push(vec0.x, vec0.y, u0, v0, tint);
|
|
237
|
+
vertexData.push(vec1.x, vec1.y, u1, v0, tint);
|
|
238
|
+
vertexData.push(vec2.x, vec2.y, u0, v1, tint);
|
|
239
|
+
vertexData.push(vec2.x, vec2.y, u0, v1, tint);
|
|
240
|
+
vertexData.push(vec1.x, vec1.y, u1, v0, tint);
|
|
241
|
+
vertexData.push(vec3.x, vec3.y, u1, v1, tint);
|
|
299
242
|
}
|
|
300
243
|
}
|
|
@@ -18,7 +18,7 @@ import { minify } from "./utils/string.js";
|
|
|
18
18
|
* @see https://developer.mozilla.org/en-US/docs/Games/Techniques/3D_on_the_web/GLSL_Shaders
|
|
19
19
|
* @example
|
|
20
20
|
* // create a basic shader
|
|
21
|
-
*
|
|
21
|
+
* let myShader = new me.GLShader(
|
|
22
22
|
* // WebGL rendering context
|
|
23
23
|
* gl,
|
|
24
24
|
* // vertex shader
|
|
@@ -93,7 +93,7 @@ import { minify } from "./utils/string.js";
|
|
|
93
93
|
* @returns {GLint} number indicating the location of the variable name if found. Returns -1 otherwise
|
|
94
94
|
*/
|
|
95
95
|
getAttribLocation(name) {
|
|
96
|
-
|
|
96
|
+
let attr = this.attributes[name];
|
|
97
97
|
if (typeof attr !== "undefined") {
|
|
98
98
|
return attr;
|
|
99
99
|
} else {
|
|
@@ -109,7 +109,7 @@ import { minify } from "./utils/string.js";
|
|
|
109
109
|
* myShader.setUniform("uProjectionMatrix", this.projectionMatrix);
|
|
110
110
|
*/
|
|
111
111
|
setUniform(name, value) {
|
|
112
|
-
|
|
112
|
+
let uniforms = this.uniforms;
|
|
113
113
|
if (typeof uniforms[name] !== "undefined") {
|
|
114
114
|
if (typeof value === "object" && typeof value.toArray === "function") {
|
|
115
115
|
uniforms[name] = value.toArray();
|
|
@@ -129,9 +129,9 @@ import { minify } from "./utils/string.js";
|
|
|
129
129
|
*/
|
|
130
130
|
setVertexAttributes(gl, attributes, vertexByteSize) {
|
|
131
131
|
// set the vertex attributes
|
|
132
|
-
for (
|
|
133
|
-
|
|
134
|
-
|
|
132
|
+
for (let index = 0; index < attributes.length; ++index) {
|
|
133
|
+
let element = attributes[index];
|
|
134
|
+
let location = this.getAttribLocation(element.name);
|
|
135
135
|
|
|
136
136
|
if (location !== -1) {
|
|
137
137
|
gl.enableVertexAttribArray(location);
|
|
@@ -1,18 +1,15 @@
|
|
|
1
1
|
// Current vertex point
|
|
2
2
|
attribute vec2 aVertex;
|
|
3
|
+
attribute vec4 aColor;
|
|
3
4
|
|
|
4
5
|
// Projection matrix
|
|
5
6
|
uniform mat4 uProjectionMatrix;
|
|
6
7
|
|
|
7
|
-
// Vertex color
|
|
8
|
-
uniform vec4 uColor;
|
|
9
|
-
|
|
10
|
-
// Fragment color
|
|
11
8
|
varying vec4 vColor;
|
|
12
9
|
|
|
13
10
|
void main(void) {
|
|
14
11
|
// Transform the vertex position by the projection matrix
|
|
15
12
|
gl_Position = uProjectionMatrix * vec4(aVertex, 0.0, 1.0);
|
|
16
13
|
// Pass the remaining attributes to the fragment shader
|
|
17
|
-
vColor = vec4(
|
|
14
|
+
vColor = vec4(aColor.bgr * aColor.a, aColor.a);
|
|
18
15
|
}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
// Current vertex point
|
|
1
2
|
attribute vec2 aVertex;
|
|
2
3
|
attribute vec2 aRegion;
|
|
3
4
|
attribute vec4 aColor;
|
|
4
5
|
|
|
6
|
+
// Projection matrix
|
|
5
7
|
uniform mat4 uProjectionMatrix;
|
|
6
8
|
|
|
7
9
|
varying vec2 vRegion;
|
|
@@ -9,7 +11,7 @@ varying vec4 vColor;
|
|
|
9
11
|
|
|
10
12
|
void main(void) {
|
|
11
13
|
// Transform the vertex position by the projection matrix
|
|
12
|
-
|
|
14
|
+
gl_Position = uProjectionMatrix * vec4(aVertex, 0.0, 1.0);
|
|
13
15
|
// Pass the remaining attributes to the fragment shader
|
|
14
16
|
vColor = vec4(aColor.bgr * aColor.a, aColor.a);
|
|
15
17
|
vRegion = aRegion;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* @ignore
|
|
3
3
|
*/
|
|
4
4
|
function compileShader(gl, type, source) {
|
|
5
|
-
|
|
5
|
+
let shader = gl.createShader(type);
|
|
6
6
|
gl.shaderSource(shader, source);
|
|
7
7
|
gl.compileShader(shader);
|
|
8
8
|
|
|
@@ -18,10 +18,10 @@ function compileShader(gl, type, source) {
|
|
|
18
18
|
* @ignore
|
|
19
19
|
*/
|
|
20
20
|
export function compileProgram(gl, vertex, fragment, attributes) {
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
let vertShader = compileShader(gl, gl.VERTEX_SHADER, vertex);
|
|
22
|
+
let fragShader = compileShader(gl, gl.FRAGMENT_SHADER, fragment);
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
let program = gl.createProgram();
|
|
25
25
|
|
|
26
26
|
gl.attachShader(program, vertShader);
|
|
27
27
|
gl.attachShader(program, fragShader);
|
|
@@ -29,14 +29,14 @@ export function compileProgram(gl, vertex, fragment, attributes) {
|
|
|
29
29
|
|
|
30
30
|
// force vertex attributes to use location 0 as starting location to prevent
|
|
31
31
|
// browser to do complicated emulation when running on desktop OpenGL (e.g. on macOS)
|
|
32
|
-
for (
|
|
32
|
+
for (let location in attributes) {
|
|
33
33
|
gl.bindAttribLocation(program, attributes[location], location);
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
gl.linkProgram(program);
|
|
37
37
|
|
|
38
38
|
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
|
|
39
|
-
|
|
39
|
+
let error_msg =
|
|
40
40
|
"Error initializing Shader " + this + "\n" +
|
|
41
41
|
"gl.VALIDATE_STATUS: " + gl.getProgramParameter(program, gl.VALIDATE_STATUS) + "\n" +
|
|
42
42
|
"gl.getError()" + gl.getError() + "\n" +
|
|
@@ -26,7 +26,7 @@ const fnHash = {
|
|
|
26
26
|
* @ignore
|
|
27
27
|
*/
|
|
28
28
|
export function extractUniforms(gl, shader) {
|
|
29
|
-
|
|
29
|
+
let uniforms = {},
|
|
30
30
|
uniRx = /uniform\s+(\w+)\s+(\w+)/g,
|
|
31
31
|
uniformsData = {},
|
|
32
32
|
descriptor = {},
|
|
@@ -42,7 +42,7 @@ export function extractUniforms(gl, shader) {
|
|
|
42
42
|
|
|
43
43
|
// Get uniform references
|
|
44
44
|
Object.keys(uniformsData).forEach((name) => {
|
|
45
|
-
|
|
45
|
+
let type = uniformsData[name];
|
|
46
46
|
locations[name] = gl.getUniformLocation(shader.program, name);
|
|
47
47
|
|
|
48
48
|
descriptor[name] = {
|
|
@@ -68,7 +68,7 @@ export function extractUniforms(gl, shader) {
|
|
|
68
68
|
* A generic setter for uniform vectors
|
|
69
69
|
*/
|
|
70
70
|
return function (val) {
|
|
71
|
-
|
|
71
|
+
let fnv = fn;
|
|
72
72
|
if (val.length && fn.slice(-1) !== "v") {
|
|
73
73
|
fnv += "v";
|
|
74
74
|
}
|