littlejsengine 1.16.2 → 1.17.5
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/littlejs.d.ts +291 -246
- package/dist/littlejs.esm.js +1520 -1271
- package/dist/littlejs.esm.min.js +1 -1
- package/dist/littlejs.js +1178 -920
- package/dist/littlejs.min.js +1 -1
- package/dist/littlejs.release.js +1170 -912
- package/examples/box2d/gameObjects.js +4 -4
- package/examples/breakout/game.js +5 -6
- package/examples/electron/index.html +2 -2
- package/examples/electron/tiles.png +0 -0
- package/examples/htmlMenu/tiles.png +0 -0
- package/examples/index.html +9 -8
- package/examples/logo.png +0 -0
- package/examples/module/build.bat +7 -0
- package/examples/module/build.js +121 -0
- package/examples/module/tiles.png +0 -0
- package/examples/platformer/game.js +1 -1
- package/examples/platformer/gameEffects.js +25 -29
- package/examples/platformer/gameLevel.js +27 -28
- package/examples/puzzle/game.js +2 -2
- package/examples/shorts/base.html +4 -1
- package/examples/shorts/box2dPool.js +2 -2
- package/examples/shorts/box2dTileLayer.js +48 -0
- package/examples/shorts/clock.js +3 -3
- package/examples/shorts/fontImage.js +4 -3
- package/examples/shorts/music.js +2 -2
- package/examples/shorts/musicPlayer.js +2 -2
- package/examples/shorts/parallax.js +1 -1
- package/examples/shorts/sequencer.js +1 -1
- package/examples/shorts/shapes.js +1 -1
- package/examples/shorts/texture.js +10 -6
- package/examples/shorts/tiles.png +0 -0
- package/examples/shorts/tiltedView.js +2 -0
- package/examples/starter/index.html +2 -2
- package/examples/starter/tiles.png +0 -0
- package/examples/typescript/tiles.png +0 -0
- package/examples/uiSystem/game.js +1 -1
- package/examples/uiSystem/tiles.png +0 -0
- package/package.json +5 -5
- package/plugins/box2d.js +167 -63
- package/plugins/postProcess.js +47 -28
- package/plugins/uiSystem.js +18 -18
- package/plugins/zzfxm.js +2 -2
- package/reference.md +4 -3
- package/src/engine.js +182 -181
- package/src/engineAudio.js +47 -63
- package/src/engineDebug.js +8 -8
- package/src/engineDraw.js +184 -124
- package/src/engineExport.js +325 -334
- package/src/engineFont.png +0 -0
- package/src/engineInput.js +18 -24
- package/src/engineMath.js +24 -113
- package/src/engineObject.js +27 -26
- package/src/engineParticles.js +2 -2
- package/src/engineTileLayer.js +229 -192
- package/src/engineUtilities.js +100 -4
- package/src/engineWebGL.js +124 -73
|
@@ -7,7 +7,7 @@ function gameRender()
|
|
|
7
7
|
|
|
8
8
|
// polygon shapes
|
|
9
9
|
drawRectGradient(vec2(-6,0), vec2(5,4), RED, BLUE)
|
|
10
|
-
drawRegularPoly(vec2(
|
|
10
|
+
drawRegularPoly(vec2(), vec2(4), 3, PURPLE, .3, WHITE, time);
|
|
11
11
|
let starPath = []
|
|
12
12
|
for (let i=10; i--;)
|
|
13
13
|
starPath.push(vec2(0,2*(i%2?.4:1)).rotate(i/10*PI*2));
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
function gameRender()
|
|
2
2
|
{
|
|
3
3
|
// show the full texture
|
|
4
|
-
let pos = vec2(
|
|
5
|
-
let size = vec2(15);
|
|
6
|
-
let color = hsl(0,0,1);
|
|
7
|
-
let tilePos = vec2(
|
|
8
|
-
let tileSize = vec2(256);
|
|
4
|
+
let pos = vec2(); // world position to draw
|
|
5
|
+
let size = vec2(15); // world size of the tile
|
|
6
|
+
let color = hsl(0,0,1); // color to multiply the tile by
|
|
7
|
+
let tilePos = vec2(); // top left corner in pixels
|
|
8
|
+
let tileSize = vec2(256); // source size in pixels
|
|
9
9
|
let tileInfo = new TileInfo(tilePos, tileSize); // tile info
|
|
10
|
-
|
|
10
|
+
|
|
11
|
+
// draw background
|
|
12
|
+
drawRect(pos, size, GRAY);
|
|
13
|
+
|
|
14
|
+
// draw the tile
|
|
11
15
|
drawTile(pos, size, tileInfo, color);
|
|
12
16
|
}
|
|
Binary file
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
</head><body>
|
|
8
8
|
|
|
9
9
|
<!-- LittleJS Engine -->
|
|
10
|
-
<script src=../../dist/littlejs.js?1.
|
|
10
|
+
<script src=../../dist/littlejs.js?1.17.5></script>
|
|
11
11
|
|
|
12
12
|
<!-- LittleJS Engine Source
|
|
13
13
|
<script src=../../src/engine.js></script>
|
|
@@ -32,4 +32,4 @@
|
|
|
32
32
|
-->
|
|
33
33
|
|
|
34
34
|
<!-- Add your game scripts here -->
|
|
35
|
-
<script src=game.js?1.
|
|
35
|
+
<script src=game.js?1.17.5></script>
|
|
Binary file
|
|
Binary file
|
|
@@ -38,7 +38,7 @@ function createUI()
|
|
|
38
38
|
// setup example menu
|
|
39
39
|
uiMenu = new LJS.UIObject(vec2(0,500));
|
|
40
40
|
uiRoot.addChild(uiMenu);
|
|
41
|
-
const uiBackground = new LJS.UIObject(vec2(
|
|
41
|
+
const uiBackground = new LJS.UIObject(vec2(), vec2(450,580));
|
|
42
42
|
uiBackground.lineWidth = 8;
|
|
43
43
|
uiMenu.addChild(uiBackground);
|
|
44
44
|
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "littlejsengine",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.17.5",
|
|
4
4
|
"description": "LittleJS - Tiny and Fast HTML5 Game Engine",
|
|
5
5
|
"main": "dist/littlejs.esm.js",
|
|
6
6
|
"types": "dist/littlejs.d.ts",
|
|
@@ -34,11 +34,11 @@
|
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"bestzip": "^2.2.1",
|
|
37
|
+
"electron": "^38.2.0",
|
|
38
|
+
"electron-packager": "^17.1.2",
|
|
37
39
|
"google-closure-compiler": "~20230502.0.0",
|
|
38
40
|
"roadroller": "~2.1.0",
|
|
39
41
|
"typescript": "~5.1.6",
|
|
40
|
-
"uglify-js": "~3.17.4"
|
|
41
|
-
"electron": "^38.2.0",
|
|
42
|
-
"electron-packager": "^17.1.2"
|
|
42
|
+
"uglify-js": "~3.17.4"
|
|
43
43
|
}
|
|
44
|
-
}
|
|
44
|
+
}
|
package/plugins/box2d.js
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
* - Contact begin and end callbacks
|
|
10
10
|
* - Wraps b2Vec2 type to/from Vector2
|
|
11
11
|
* - Raycasting and querying
|
|
12
|
+
* - Box2dTileLayer for grid based collision
|
|
12
13
|
* - Every type of joint
|
|
13
14
|
* - Debug physics drawing
|
|
14
15
|
* @namespace Box2D
|
|
@@ -60,21 +61,24 @@ class Box2dObject extends EngineObject
|
|
|
60
61
|
bodyDef.set_type(bodyType);
|
|
61
62
|
bodyDef.set_position(box2d.vec2dTo(pos));
|
|
62
63
|
bodyDef.set_angle(-angle);
|
|
64
|
+
|
|
65
|
+
/** @property {Object} - The Box2d body */
|
|
63
66
|
this.body = box2d.world.CreateBody(bodyDef);
|
|
64
|
-
|
|
67
|
+
/** @property {Color} - Line color used for default box2d drawing */
|
|
65
68
|
this.lineColor = BLACK;
|
|
66
|
-
box2d
|
|
67
|
-
|
|
68
|
-
// edge lists and loops for drawing
|
|
69
|
+
/** @property {Array<Object>} - List of all edges for default box2d drawing */
|
|
69
70
|
this.edgeLists = [];
|
|
71
|
+
/** @property {Array<Object>} - List of all edge loops for default box2d drawing */
|
|
70
72
|
this.edgeLoops = [];
|
|
73
|
+
|
|
74
|
+
this.body.object = this; // link body to this object
|
|
75
|
+
box2d.objects.push(this); // keep track of all box2d objects
|
|
71
76
|
}
|
|
72
77
|
|
|
73
78
|
/** Destroy this object and its physics body */
|
|
74
79
|
destroy()
|
|
75
80
|
{
|
|
76
|
-
if (this.destroyed)
|
|
77
|
-
return;
|
|
81
|
+
if (this.destroyed) return;
|
|
78
82
|
|
|
79
83
|
// destroy physics body, fixtures, and joints
|
|
80
84
|
ASSERT(this.body, 'Box2dObject has no body to destroy');
|
|
@@ -105,11 +109,12 @@ class Box2dObject extends EngineObject
|
|
|
105
109
|
}
|
|
106
110
|
|
|
107
111
|
/** Draws all this object's fixtures
|
|
108
|
-
* @param {Color}
|
|
109
|
-
* @param {Color}
|
|
110
|
-
* @param {number}
|
|
112
|
+
* @param {Color} [color]
|
|
113
|
+
* @param {Color} [lineColor]
|
|
114
|
+
* @param {number} [lineWidth]
|
|
115
|
+
* @param {boolean} [useWebGL=glEnable]
|
|
111
116
|
* @param {CanvasRenderingContext2D} [context] */
|
|
112
|
-
drawFixtures(color=WHITE, lineColor=BLACK, lineWidth=.1, context)
|
|
117
|
+
drawFixtures(color=WHITE, lineColor=BLACK, lineWidth=.1, useWebGL, context)
|
|
113
118
|
{
|
|
114
119
|
// draw non-edge fixtures
|
|
115
120
|
this.getFixtureList().forEach((fixture)=>
|
|
@@ -117,7 +122,7 @@ class Box2dObject extends EngineObject
|
|
|
117
122
|
const shape = box2d.castObjectType(fixture.GetShape());
|
|
118
123
|
if (shape.GetType() !== box2d.instance.b2Shape.e_edge)
|
|
119
124
|
{
|
|
120
|
-
box2d.drawFixture(fixture, this.pos, this.angle, color, lineColor, lineWidth, context);
|
|
125
|
+
box2d.drawFixture(fixture, this.pos, this.angle, color, lineColor, lineWidth, useWebGL, context);
|
|
121
126
|
}
|
|
122
127
|
});
|
|
123
128
|
|
|
@@ -343,6 +348,14 @@ class Box2dObject extends EngineObject
|
|
|
343
348
|
return fixtures;
|
|
344
349
|
}
|
|
345
350
|
|
|
351
|
+
/** Destroy a fixture from the body
|
|
352
|
+
* @param {Object} [fixture] */
|
|
353
|
+
destroyFixture(fixture) { this.body.DestroyFixture(fixture); }
|
|
354
|
+
|
|
355
|
+
/** Destroy all fixture from the body */
|
|
356
|
+
destroyAllFixtures()
|
|
357
|
+
{ this.getFixtureList().forEach(fixture=>this.destroyFixture(fixture)); }
|
|
358
|
+
|
|
346
359
|
///////////////////////////////////////////////////////////////////////////////
|
|
347
360
|
// physics get functions
|
|
348
361
|
|
|
@@ -575,6 +588,136 @@ class Box2dObject extends EngineObject
|
|
|
575
588
|
}
|
|
576
589
|
}
|
|
577
590
|
|
|
591
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
592
|
+
/**
|
|
593
|
+
* Box2D Static Object - Box2d with a static physics body
|
|
594
|
+
* @extends Box2dObject
|
|
595
|
+
* @memberof Box2D
|
|
596
|
+
*/
|
|
597
|
+
class Box2dStaticObject extends Box2dObject
|
|
598
|
+
{
|
|
599
|
+
/** Create a LittleJS object with Box2d physics
|
|
600
|
+
* @param {Vector2} [pos]
|
|
601
|
+
* @param {Vector2} [size]
|
|
602
|
+
* @param {TileInfo} [tileInfo]
|
|
603
|
+
* @param {number} [angle]
|
|
604
|
+
* @param {Color} [color]
|
|
605
|
+
* @param {number} [renderOrder] */
|
|
606
|
+
constructor(pos, size, tileInfo, angle=0, color, renderOrder=0)
|
|
607
|
+
{
|
|
608
|
+
const bodyType = box2d.bodyTypeStatic;
|
|
609
|
+
super(pos, size, tileInfo, angle, color, bodyType, renderOrder);
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
614
|
+
/**
|
|
615
|
+
* Box2D Kiematic Object - Box2d with a kinematic physics body
|
|
616
|
+
* @extends Box2dObject
|
|
617
|
+
* @memberof Box2D
|
|
618
|
+
*/
|
|
619
|
+
class Box2dKiematicObject extends Box2dObject
|
|
620
|
+
{
|
|
621
|
+
/** Create a LittleJS object with Box2d physics
|
|
622
|
+
* @param {Vector2} [pos]
|
|
623
|
+
* @param {Vector2} [size]
|
|
624
|
+
* @param {TileInfo} [tileInfo]
|
|
625
|
+
* @param {number} [angle]
|
|
626
|
+
* @param {Color} [color]
|
|
627
|
+
* @param {number} [renderOrder] */
|
|
628
|
+
constructor(pos, size, tileInfo, angle=0, color, renderOrder=0)
|
|
629
|
+
{
|
|
630
|
+
const bodyType = box2d.bodyTypeKinematic;
|
|
631
|
+
super(pos, size, tileInfo, angle, color, bodyType, renderOrder);
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
636
|
+
/**
|
|
637
|
+
* Box2d Tile Layer
|
|
638
|
+
* - adds Box2d support to tile layers
|
|
639
|
+
* - creates static box2d fixtures for solid tiles
|
|
640
|
+
* @extends Box2dObject
|
|
641
|
+
* @memberof Box2D
|
|
642
|
+
*/
|
|
643
|
+
class Box2dTileLayer extends Box2dStaticObject
|
|
644
|
+
{
|
|
645
|
+
/** Create a Box2d tile layer object
|
|
646
|
+
* @param {TileCollisionLayer} tileLayer - Tile layer for this object */
|
|
647
|
+
constructor(tileLayer)
|
|
648
|
+
{
|
|
649
|
+
ASSERT(tileLayer instanceof TileCollisionLayer, 'tileLayer must be a TileCollisionLayer');
|
|
650
|
+
super(tileLayer.pos, tileLayer.size);
|
|
651
|
+
|
|
652
|
+
/** @property {TileLayer} - The tile layer */
|
|
653
|
+
this.tileLayer = tileLayer;
|
|
654
|
+
this.addChild(tileLayer);
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
render()
|
|
658
|
+
{
|
|
659
|
+
// do not render fixtures, tile layer handles rendering
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
/** Create box2d collision fixtures for solid tiles
|
|
663
|
+
* @param {number} [friction]
|
|
664
|
+
* @param {number} [restitution] */
|
|
665
|
+
buildCollision(friction=.2, restitution=0)
|
|
666
|
+
{
|
|
667
|
+
// destroy all fixtures and create new ones
|
|
668
|
+
this.destroyAllFixtures();
|
|
669
|
+
|
|
670
|
+
// create box2d object for this layer
|
|
671
|
+
const size = this.tileLayer.size;
|
|
672
|
+
this.pos = this.tileLayer.pos.copy();
|
|
673
|
+
this.size = size.copy();
|
|
674
|
+
|
|
675
|
+
// track which tiles have been processed
|
|
676
|
+
const processed = [];
|
|
677
|
+
const getIndex = (x, y)=> x + y * size.x;
|
|
678
|
+
const isSolidUnprocessed = (x, y)=>
|
|
679
|
+
!processed[getIndex(x, y)] &&
|
|
680
|
+
this.tileLayer.getCollisionData(vec2(x, y)) > 0;
|
|
681
|
+
|
|
682
|
+
// combine tiles into larger boxes
|
|
683
|
+
for (let x = 0; x < size.x; ++x)
|
|
684
|
+
for (let y = 0; y < size.y; ++y)
|
|
685
|
+
{
|
|
686
|
+
if (!isSolidUnprocessed(x, y)) continue;
|
|
687
|
+
|
|
688
|
+
// find max width by scanning right
|
|
689
|
+
let width = 1, height = 1, canExpand = true;
|
|
690
|
+
while (isSolidUnprocessed(x + width, y))
|
|
691
|
+
++width;
|
|
692
|
+
|
|
693
|
+
// find max height by scanning up, ensuring all rows have the same width
|
|
694
|
+
while (canExpand)
|
|
695
|
+
{
|
|
696
|
+
for (let checkX = 0; checkX < width; ++checkX)
|
|
697
|
+
{
|
|
698
|
+
if (!isSolidUnprocessed(x + checkX, y + height))
|
|
699
|
+
{
|
|
700
|
+
canExpand = false;
|
|
701
|
+
break;
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
if (canExpand)
|
|
705
|
+
++height;
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
// mark all tiles in this rectangle as processed
|
|
709
|
+
for (let rectX = width; rectX--;)
|
|
710
|
+
for (let rectY = height; rectY--;)
|
|
711
|
+
processed[getIndex(x + rectX, y + rectY)] = true;
|
|
712
|
+
|
|
713
|
+
// create a single fixture for the entire rectangle
|
|
714
|
+
const shapeSize = vec2(width, height);
|
|
715
|
+
const offset = vec2(x + width/2, y + height/2);
|
|
716
|
+
this.addBox(shapeSize, offset, 0, 0, friction, restitution);
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
|
|
578
721
|
///////////////////////////////////////////////////////////////////////////////
|
|
579
722
|
/**
|
|
580
723
|
* Box2D Raycast Result
|
|
@@ -616,6 +759,7 @@ class Box2dJoint
|
|
|
616
759
|
* @param {Object} jointDef */
|
|
617
760
|
constructor(jointDef)
|
|
618
761
|
{
|
|
762
|
+
/** @property {Object} - The Box2d joint */
|
|
619
763
|
this.box2dJoint = box2d.castObjectType(box2d.world.CreateJoint(jointDef));
|
|
620
764
|
}
|
|
621
765
|
|
|
@@ -962,7 +1106,7 @@ class Box2dGearJoint extends Box2dJoint
|
|
|
962
1106
|
* @param {Box2dObject} objectB
|
|
963
1107
|
* @param {Box2dJoint} joint1
|
|
964
1108
|
* @param {Box2dJoint} joint2
|
|
965
|
-
* @param {
|
|
1109
|
+
* @param {number} [ratio] */
|
|
966
1110
|
constructor(objectA, objectB, joint1, joint2, ratio=1)
|
|
967
1111
|
{
|
|
968
1112
|
const jointDef = new box2d.instance.b2GearJointDef();
|
|
@@ -1104,50 +1248,6 @@ class Box2dPrismaticJoint extends Box2dJoint
|
|
|
1104
1248
|
getMotorForce(time) { return this.box2dJoint.GetMotorForce(1/time); }
|
|
1105
1249
|
}
|
|
1106
1250
|
|
|
1107
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
1108
|
-
/**
|
|
1109
|
-
* Box2D Static Object - Box2d with a static physics body
|
|
1110
|
-
* @extends Box2dObject
|
|
1111
|
-
* @memberof Box2D
|
|
1112
|
-
*/
|
|
1113
|
-
class Box2dStaticObject extends Box2dObject
|
|
1114
|
-
{
|
|
1115
|
-
/** Create a LittleJS object with Box2d physics
|
|
1116
|
-
* @param {Vector2} [pos]
|
|
1117
|
-
* @param {Vector2} [size]
|
|
1118
|
-
* @param {TileInfo} [tileInfo]
|
|
1119
|
-
* @param {number} [angle]
|
|
1120
|
-
* @param {Color} [color]
|
|
1121
|
-
* @param {number} [renderOrder] */
|
|
1122
|
-
constructor(pos, size, tileInfo, angle=0, color, renderOrder=0)
|
|
1123
|
-
{
|
|
1124
|
-
const bodyType = box2d.bodyTypeStatic;
|
|
1125
|
-
super(pos, size, tileInfo, angle, color, bodyType, renderOrder);
|
|
1126
|
-
}
|
|
1127
|
-
}
|
|
1128
|
-
|
|
1129
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
1130
|
-
/**
|
|
1131
|
-
* Box2D Kiematic Object - Box2d with a kinematic physics body
|
|
1132
|
-
* @extends Box2dObject
|
|
1133
|
-
* @memberof Box2D
|
|
1134
|
-
*/
|
|
1135
|
-
class Box2dKiematicObject extends Box2dObject
|
|
1136
|
-
{
|
|
1137
|
-
/** Create a LittleJS object with Box2d physics
|
|
1138
|
-
* @param {Vector2} [pos]
|
|
1139
|
-
* @param {Vector2} [size]
|
|
1140
|
-
* @param {TileInfo} [tileInfo]
|
|
1141
|
-
* @param {number} [angle]
|
|
1142
|
-
* @param {Color} [color]
|
|
1143
|
-
* @param {number} [renderOrder] */
|
|
1144
|
-
constructor(pos, size, tileInfo, angle=0, color, renderOrder=0)
|
|
1145
|
-
{
|
|
1146
|
-
const bodyType = box2d.bodyTypeKinematic;
|
|
1147
|
-
super(pos, size, tileInfo, angle, color, bodyType, renderOrder);
|
|
1148
|
-
}
|
|
1149
|
-
}
|
|
1150
|
-
|
|
1151
1251
|
///////////////////////////////////////////////////////////////////////////////
|
|
1152
1252
|
/**
|
|
1153
1253
|
* Box2D Wheel Joint
|
|
@@ -1508,10 +1608,13 @@ class Box2dPlugin
|
|
|
1508
1608
|
{
|
|
1509
1609
|
ASSERT(!box2d, 'Box2D already initialized');
|
|
1510
1610
|
box2d = this;
|
|
1611
|
+
|
|
1612
|
+
/** @property {Object} - The Box2d instance */
|
|
1511
1613
|
this.instance = instance;
|
|
1614
|
+
/** @property {Object} - The Box2d world */
|
|
1512
1615
|
this.world = new box2d.instance.b2World();
|
|
1616
|
+
/** @property {Array<Box2dObject>} - List of all Box2d objects */
|
|
1513
1617
|
this.objects = [];
|
|
1514
|
-
|
|
1515
1618
|
/** @property {number} - Velocity iterations per update*/
|
|
1516
1619
|
this.velocityIterations = 8;
|
|
1517
1620
|
/** @property {number} - Position iterations per update*/
|
|
@@ -1710,8 +1813,9 @@ class Box2dPlugin
|
|
|
1710
1813
|
* @param {Color} [color]
|
|
1711
1814
|
* @param {Color} [lineColor]
|
|
1712
1815
|
* @param {number} [lineWidth]
|
|
1816
|
+
* @param {boolean} [useWebGL=glEnable]
|
|
1713
1817
|
* @param {CanvasRenderingContext2D} [context] */
|
|
1714
|
-
drawFixture(fixture, pos, angle, color=WHITE, lineColor=BLACK, lineWidth=.1, context)
|
|
1818
|
+
drawFixture(fixture, pos, angle, color=WHITE, lineColor=BLACK, lineWidth=.1, useWebgl, context)
|
|
1715
1819
|
{
|
|
1716
1820
|
const shape = box2d.castObjectType(fixture.GetShape());
|
|
1717
1821
|
switch (shape.GetType())
|
|
@@ -1721,20 +1825,20 @@ class Box2dPlugin
|
|
|
1721
1825
|
let points = [];
|
|
1722
1826
|
for (let i=shape.GetVertexCount(); i--;)
|
|
1723
1827
|
points.push(box2d.vec2From(shape.GetVertex(i)));
|
|
1724
|
-
drawPoly(points, color, lineWidth, lineColor, pos, angle);
|
|
1828
|
+
drawPoly(points, color, lineWidth, lineColor, pos, angle, useWebgl, false, context);
|
|
1725
1829
|
break;
|
|
1726
1830
|
}
|
|
1727
1831
|
case box2d.instance.b2Shape.e_circle:
|
|
1728
1832
|
{
|
|
1729
1833
|
const radius = shape.get_m_radius();
|
|
1730
|
-
drawCircle(pos, radius*2, color, lineWidth, lineColor);
|
|
1834
|
+
drawCircle(pos, radius*2, color, lineWidth, lineColor, useWebgl, false, context);
|
|
1731
1835
|
break;
|
|
1732
1836
|
}
|
|
1733
1837
|
case box2d.instance.b2Shape.e_edge:
|
|
1734
1838
|
{
|
|
1735
1839
|
const v1 = box2d.vec2From(shape.get_m_vertex1());
|
|
1736
1840
|
const v2 = box2d.vec2From(shape.get_m_vertex2());
|
|
1737
|
-
drawLine(v1, v2, lineWidth, lineColor, pos, angle);
|
|
1841
|
+
drawLine(v1, v2, lineWidth, lineColor, pos, angle, useWebgl, false, context);
|
|
1738
1842
|
break;
|
|
1739
1843
|
}
|
|
1740
1844
|
}
|
|
@@ -1752,7 +1856,7 @@ class Box2dPlugin
|
|
|
1752
1856
|
}
|
|
1753
1857
|
|
|
1754
1858
|
/** converts a box2d vec2 pointer to a Vector2
|
|
1755
|
-
* @param {Object}
|
|
1859
|
+
* @param {Object} vp */
|
|
1756
1860
|
vec2FromPointer(vp)
|
|
1757
1861
|
{
|
|
1758
1862
|
const v = box2d.instance.wrapPointer(vp, box2d.instance.b2Vec2);
|
|
@@ -1864,7 +1968,7 @@ async function box2dInit()
|
|
|
1864
1968
|
const box2dColorPointer = (c)=>
|
|
1865
1969
|
box2dColor(box2d.instance.wrapPointer(c, box2d.instance.b2Color));
|
|
1866
1970
|
const getDebugColor = (color)=>box2dColorPointer(color).scale(1,.8);
|
|
1867
|
-
const getPointsList = (vertices, vertexCount)
|
|
1971
|
+
const getPointsList = (vertices, vertexCount)=>
|
|
1868
1972
|
{
|
|
1869
1973
|
const points = [];
|
|
1870
1974
|
for (let i=vertexCount; i--;)
|
package/plugins/postProcess.js
CHANGED
|
@@ -24,14 +24,16 @@ class PostProcessPlugin
|
|
|
24
24
|
{
|
|
25
25
|
/** Create global post processing shader
|
|
26
26
|
* @param {string} shaderCode
|
|
27
|
-
* @param {boolean} [includeMainCanvas]
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
27
|
+
* @param {boolean} [includeMainCanvas] - combine mainCanvs onto glCanvas
|
|
28
|
+
* @param {boolean} [feedbackTexture] - use glCanvas from previous frame as the texture
|
|
29
|
+
* @example
|
|
30
|
+
* // create the post process plugin object
|
|
31
|
+
* new PostProcessPlugin(shaderCode);
|
|
32
|
+
*/
|
|
33
|
+
constructor(shaderCode, includeMainCanvas=false, feedbackTexture=false)
|
|
33
34
|
{
|
|
34
35
|
ASSERT(!postProcess, 'Post process already initialized');
|
|
36
|
+
ASSERT(!(includeMainCanvas && feedbackTexture), 'Post process cannot both include main canvas and use feedback texture');
|
|
35
37
|
postProcess = this;
|
|
36
38
|
|
|
37
39
|
if (!shaderCode) // default shader pass through
|
|
@@ -39,9 +41,10 @@ class PostProcessPlugin
|
|
|
39
41
|
|
|
40
42
|
/** @property {WebGLProgram} - Shader for post processing */
|
|
41
43
|
this.shader = undefined;
|
|
42
|
-
|
|
43
44
|
/** @property {WebGLTexture} - Texture for post processing */
|
|
44
45
|
this.texture = undefined;
|
|
46
|
+
/** @property {WebGLVertexArrayObject} - Vertex array object */
|
|
47
|
+
this.vao = undefined;
|
|
45
48
|
|
|
46
49
|
// setup the post processing plugin
|
|
47
50
|
initPostProcess();
|
|
@@ -50,7 +53,6 @@ class PostProcessPlugin
|
|
|
50
53
|
function initPostProcess()
|
|
51
54
|
{
|
|
52
55
|
if (headlessMode) return;
|
|
53
|
-
|
|
54
56
|
if (!glEnable)
|
|
55
57
|
{
|
|
56
58
|
console.warn('PostProcessPlugin: WebGL not enabled!');
|
|
@@ -61,14 +63,14 @@ class PostProcessPlugin
|
|
|
61
63
|
postProcess.texture = glCreateTexture();
|
|
62
64
|
postProcess.shader = glCreateProgram(
|
|
63
65
|
'#version 300 es\n' + // specify GLSL ES version
|
|
64
|
-
'precision highp float;'+ // use highp for
|
|
66
|
+
'precision highp float;'+ // use highp for accuracy
|
|
65
67
|
'in vec2 p;'+ // position
|
|
66
68
|
'void main(){'+ // shader entry point
|
|
67
69
|
'gl_Position=vec4(p+p-1.,1,1);'+ // set position
|
|
68
70
|
'}' // end of shader
|
|
69
71
|
,
|
|
70
72
|
'#version 300 es\n' + // specify GLSL ES version
|
|
71
|
-
'precision highp float;'+ // use highp for
|
|
73
|
+
'precision highp float;'+ // use highp for accuracy
|
|
72
74
|
'uniform sampler2D iChannel0;'+ // input texture
|
|
73
75
|
'uniform vec3 iResolution;'+ // size of output texture
|
|
74
76
|
'uniform float iTime;'+ // time
|
|
@@ -79,6 +81,17 @@ class PostProcessPlugin
|
|
|
79
81
|
'c.a=1.;'+ // always use full alpha
|
|
80
82
|
'}' // end of shader
|
|
81
83
|
);
|
|
84
|
+
|
|
85
|
+
// setup VAO for post processing
|
|
86
|
+
postProcess.vao = glContext.createVertexArray();
|
|
87
|
+
glContext.bindVertexArray(postProcess.vao);
|
|
88
|
+
glContext.bindBuffer(glContext.ARRAY_BUFFER, glGeometryBuffer);
|
|
89
|
+
|
|
90
|
+
// configure vertex attributes
|
|
91
|
+
const vertexByteStride = 8;
|
|
92
|
+
const pLocation = glContext.getAttribLocation(postProcess.shader, 'p');
|
|
93
|
+
glContext.enableVertexAttribArray(pLocation);
|
|
94
|
+
glContext.vertexAttribPointer(pLocation, 2, glContext.FLOAT, false, vertexByteStride, 0);
|
|
82
95
|
}
|
|
83
96
|
function postProcessContextLost()
|
|
84
97
|
{
|
|
@@ -93,14 +106,17 @@ class PostProcessPlugin
|
|
|
93
106
|
}
|
|
94
107
|
function postProcessRender()
|
|
95
108
|
{
|
|
96
|
-
if (headlessMode) return;
|
|
97
|
-
|
|
98
|
-
if (!glEnable)
|
|
99
|
-
return;
|
|
109
|
+
if (headlessMode || !glEnable) return;
|
|
100
110
|
|
|
101
111
|
// clear out the buffer
|
|
102
112
|
glFlush();
|
|
103
|
-
|
|
113
|
+
|
|
114
|
+
// setup shader program to draw a quad
|
|
115
|
+
glContext.useProgram(postProcess.shader);
|
|
116
|
+
glContext.bindVertexArray(postProcess.vao);
|
|
117
|
+
glContext.pixelStorei(glContext.UNPACK_FLIP_Y_WEBGL, true);
|
|
118
|
+
glContext.disable(glContext.BLEND);
|
|
119
|
+
|
|
104
120
|
// setup texture
|
|
105
121
|
glContext.activeTexture(glContext.TEXTURE0);
|
|
106
122
|
glContext.bindTexture(glContext.TEXTURE_2D, postProcess.texture);
|
|
@@ -111,29 +127,32 @@ class PostProcessPlugin
|
|
|
111
127
|
workCanvas.height = mainCanvasSize.y;
|
|
112
128
|
glCopyToContext(workContext);
|
|
113
129
|
workContext.drawImage(mainCanvas, 0, 0);
|
|
130
|
+
mainCanvas.width |= 0
|
|
114
131
|
|
|
115
132
|
// copy work canvas to texture
|
|
116
133
|
glContext.texImage2D(glContext.TEXTURE_2D, 0, glContext.RGBA, glContext.RGBA, glContext.UNSIGNED_BYTE, workCanvas);
|
|
117
134
|
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
// set vertex position attribute
|
|
126
|
-
const vertexByteStride = 8;
|
|
127
|
-
const pLocation = glContext.getAttribLocation(postProcess.shader, 'p');
|
|
128
|
-
glContext.enableVertexAttribArray(pLocation);
|
|
129
|
-
glContext.vertexAttribPointer(pLocation, 2, glContext.FLOAT, false, vertexByteStride, 0);
|
|
130
|
-
|
|
135
|
+
else if (!feedbackTexture)
|
|
136
|
+
{
|
|
137
|
+
// copy glCanvas to texture
|
|
138
|
+
glContext.texImage2D(glContext.TEXTURE_2D, 0, glContext.RGBA, glContext.RGBA, glContext.UNSIGNED_BYTE, glCanvas);
|
|
139
|
+
}
|
|
140
|
+
|
|
131
141
|
// set uniforms and draw
|
|
132
142
|
const uniformLocation = (name)=>glContext.getUniformLocation(postProcess.shader, name);
|
|
133
143
|
glContext.uniform1i(uniformLocation('iChannel0'), 0);
|
|
134
144
|
glContext.uniform1f(uniformLocation('iTime'), time);
|
|
135
145
|
glContext.uniform3f(uniformLocation('iResolution'), mainCanvas.width, mainCanvas.height, 1);
|
|
136
146
|
glContext.drawArrays(glContext.TRIANGLE_STRIP, 0, 4);
|
|
147
|
+
|
|
148
|
+
if (feedbackTexture)
|
|
149
|
+
{
|
|
150
|
+
// pass glCanvas back to overlay texture
|
|
151
|
+
glContext.texImage2D(glContext.TEXTURE_2D, 0, glContext.RGBA, glContext.RGBA, glContext.UNSIGNED_BYTE, glCanvas);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// force it to set instanced mode
|
|
155
|
+
glSetInstancedMode(true);
|
|
137
156
|
}
|
|
138
157
|
}
|
|
139
158
|
}
|