littlejsengine 1.16.2 → 1.17.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.
- package/dist/littlejs.d.ts +200 -166
- package/dist/littlejs.esm.js +1231 -1086
- package/dist/littlejs.esm.min.js +1 -1
- package/dist/littlejs.js +888 -735
- package/dist/littlejs.min.js +1 -1
- package/dist/littlejs.release.js +884 -731
- package/examples/box2d/gameObjects.js +1 -1
- 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 +1 -1
- package/examples/logo.png +0 -0
- package/examples/module/tiles.png +0 -0
- package/examples/platformer/gameEffects.js +23 -22
- package/examples/platformer/gameLevel.js +24 -25
- package/examples/shorts/base.html +1 -1
- package/examples/shorts/clock.js +3 -3
- package/examples/shorts/fontImage.js +4 -3
- 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 +1 -1
- package/plugins/postProcess.js +47 -28
- package/plugins/uiSystem.js +15 -15
- package/reference.md +1 -1
- package/src/engine.js +174 -174
- package/src/engineAudio.js +4 -6
- package/src/engineDebug.js +4 -4
- package/src/engineDraw.js +179 -122
- package/src/engineExport.js +326 -334
- package/src/engineFont.png +0 -0
- package/src/engineInput.js +14 -20
- package/src/engineMath.js +15 -104
- package/src/engineObject.js +26 -25
- package/src/engineParticles.js +2 -2
- package/src/engineTileLayer.js +196 -170
- package/src/engineUtilities.js +100 -4
- package/src/engineWebGL.js +123 -72
|
@@ -76,7 +76,7 @@ export function spawnRandomEdges()
|
|
|
76
76
|
edgePoints.push(vec2(40,0));
|
|
77
77
|
for (let i=40, y=0; i--;)
|
|
78
78
|
edgePoints.push(vec2(i, y=LJS.clamp(y+LJS.rand(-2,2),0,5)));
|
|
79
|
-
edgePoints.push(vec2(
|
|
79
|
+
edgePoints.push(vec2());
|
|
80
80
|
const o = new LJS.Box2dStaticObject;
|
|
81
81
|
o.addEdgeList(edgePoints);
|
|
82
82
|
}
|
|
@@ -103,13 +103,12 @@ function gameRender()
|
|
|
103
103
|
function gameRenderPost()
|
|
104
104
|
{
|
|
105
105
|
// use built in image font for text
|
|
106
|
-
const font =
|
|
107
|
-
|
|
108
|
-
font.drawText('Score: ' + score, LJS.cameraPos.add(vec2(0,9.7)), .15, true);
|
|
106
|
+
const font = LJS.engineFontImage;
|
|
107
|
+
font.drawText('Score: ' + score, LJS.cameraPos.add(vec2(0,9.2)), 1);
|
|
109
108
|
if (!brickCount)
|
|
110
|
-
font.drawText('You Win!', LJS.cameraPos.add(vec2(0,-5)),
|
|
109
|
+
font.drawText('You Win!', LJS.cameraPos.add(vec2(0,-5)), 2);
|
|
111
110
|
else if (!ball)
|
|
112
|
-
font.drawText('Click to Play', LJS.cameraPos.add(vec2(0,-5)),
|
|
111
|
+
font.drawText('Click to Play', LJS.cameraPos.add(vec2(0,-5)), 2);
|
|
113
112
|
}
|
|
114
113
|
|
|
115
114
|
///////////////////////////////////////////////////////////////////////////////
|
|
@@ -138,7 +137,7 @@ function setupPostProcess()
|
|
|
138
137
|
|
|
139
138
|
// scan lines
|
|
140
139
|
const float scanlineScale = 2.;
|
|
141
|
-
const float scanlineAlpha = .
|
|
140
|
+
const float scanlineAlpha = .6;
|
|
142
141
|
c *= 1. - scanlineAlpha*cos(p.y*2.*iResolution.y/scanlineScale);
|
|
143
142
|
|
|
144
143
|
{
|
|
@@ -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.1></script>
|
|
11
11
|
|
|
12
12
|
<!-- Add your game scripts here -->
|
|
13
|
-
<script src=game.js?1.
|
|
13
|
+
<script src=game.js?1.17.1></script>
|
|
Binary file
|
|
Binary file
|
package/examples/index.html
CHANGED
|
@@ -113,7 +113,6 @@ const exampleList =
|
|
|
113
113
|
new ExampleInfo('Piano', 'piano.js', 'Interactive piano keyboard', false, 'music, sound, audio, notes, ui, instrument'),
|
|
114
114
|
new ExampleInfo('Step Sequencer', 'sequencer.js', 'Simple music loop creation tool', false, 'music, sound, audio, notes, ui, instrument'),
|
|
115
115
|
new ExampleInfo('Music Player', 'musicPlayer.js', 'Music player with audio seeking and drag and drop', false, 'sound, loading, audio, ui'),
|
|
116
|
-
new ExampleInfo('WebGL Shader', 'shader.js', 'Full canvas webgl shader', false, 'webgl, visual, effect'),
|
|
117
116
|
new ExampleInfo('--- MINI GAMES ---'),
|
|
118
117
|
new ExampleInfo('Pong Game', 'pongGame.js', 'Classic paddle ball bouncing', false, 'objects, collision'),
|
|
119
118
|
new ExampleInfo('Platformer Game', 'platformer.js', 'Jump and run side view', false, 'objects, gravity, level, tiles, camera'),
|
|
@@ -129,6 +128,7 @@ const exampleList =
|
|
|
129
128
|
new ExampleInfo('Box2d Demo', 'box2d.js', 'Box2D physics plugin', false, 'objects, mouse'),
|
|
130
129
|
new ExampleInfo('Box2d Car', 'box2dCar.js', 'Drivable car with Box2D physics', false, 'objects, vehicle, suspension, wheels'),
|
|
131
130
|
new ExampleInfo('Box2d Pool', 'box2dPool.js', 'Billiard table pool game with physics', false, 'objects, game'),
|
|
131
|
+
new ExampleInfo('WebGL Shader', 'shader.js', 'Full canvas webgl shader', false, 'webgl, visual, effect'),
|
|
132
132
|
new ExampleInfo('Post Processing', 'postProcess.js', 'Shader effects and filters', false, 'webgl, visual, effect'),
|
|
133
133
|
new ExampleInfo('UI System', 'uiSystem.js', 'Buttons, sliders, and checkboxes', false, 'objects, widgets, interactive'),
|
|
134
134
|
new ExampleInfo('Nine Slice', 'nineSlice.js', 'Scalable UI panels', false, 'three slice, stretch, corners, text, tiles'),
|
package/examples/logo.png
CHANGED
|
Binary file
|
|
Binary file
|
|
@@ -43,8 +43,6 @@ export const persistentParticleDestroyCallback = (particle)=>
|
|
|
43
43
|
if (particle.groundObject)
|
|
44
44
|
{
|
|
45
45
|
GameLevel.foregroundTileLayer.drawTile(particle.pos, particle.size, particle.tileInfo, particle.color, particle.angle, particle.mirror);
|
|
46
|
-
// update WebGL texture
|
|
47
|
-
GameLevel.foregroundTileLayer.useWebGL();
|
|
48
46
|
}
|
|
49
47
|
}
|
|
50
48
|
|
|
@@ -74,26 +72,27 @@ export function explosion(pos, radius=3)
|
|
|
74
72
|
|
|
75
73
|
sound_explosion.play(pos);
|
|
76
74
|
|
|
77
|
-
// destroy level
|
|
78
|
-
for (let x = -radius; x < radius; ++x)
|
|
79
75
|
{
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
76
|
+
// destroy level
|
|
77
|
+
const layer = GameLevel.tileLayers[1];
|
|
78
|
+
layer.redrawStart();
|
|
79
|
+
for (let x = -radius; x < radius; ++x)
|
|
80
|
+
{
|
|
81
|
+
const h = (radius*radius - x*x)**.5;
|
|
82
|
+
for (let y = -h; y <= h; ++y)
|
|
83
|
+
destroyTile(pos.add(vec2(x,y)), 0, 0);
|
|
84
|
+
}
|
|
85
|
+
// cleanup neighbors
|
|
86
|
+
const cleanupRadius = radius + 2;
|
|
87
|
+
for (let x = -cleanupRadius; x < cleanupRadius; ++x)
|
|
88
|
+
{
|
|
89
|
+
const h = (cleanupRadius**2 - x**2)**.5;
|
|
90
|
+
for (let y = -h; y < h; ++y)
|
|
91
|
+
GameLevel.decorateTile(pos.add(vec2(x,y)).floor(), layer);
|
|
92
|
+
}
|
|
93
|
+
layer.redrawEnd();
|
|
92
94
|
}
|
|
93
95
|
|
|
94
|
-
// update WebGL texture
|
|
95
|
-
GameLevel.foregroundTileLayer.useWebGL();
|
|
96
|
-
|
|
97
96
|
// kill/push objects
|
|
98
97
|
LJS.engineObjectsCallback(pos, radius*3, (o)=>
|
|
99
98
|
{
|
|
@@ -165,10 +164,12 @@ export function destroyTile(pos, makeSound = 1, cleanup = 1)
|
|
|
165
164
|
// cleanup neighbors and rebuild WebGL
|
|
166
165
|
if (cleanup)
|
|
167
166
|
{
|
|
167
|
+
const layer = GameLevel.tileLayers[1];
|
|
168
|
+
layer.redrawStart();
|
|
168
169
|
for (let i=-1;i<=1;++i)
|
|
169
170
|
for (let j=-1;j<=1;++j)
|
|
170
|
-
GameLevel.decorateTile(pos.add(vec2(i,j)));
|
|
171
|
-
layer.
|
|
171
|
+
GameLevel.decorateTile(pos.add(vec2(i,j)), layer);
|
|
172
|
+
layer.redrawEnd();
|
|
172
173
|
}
|
|
173
174
|
|
|
174
175
|
return true;
|
|
@@ -260,7 +261,7 @@ export class ParallaxLayer extends LJS.CanvasLayer
|
|
|
260
261
|
this.context.clearRect(0,0,1,h);
|
|
261
262
|
|
|
262
263
|
// make WebGL texture
|
|
263
|
-
this.
|
|
264
|
+
this.updateWebGL();
|
|
264
265
|
}
|
|
265
266
|
|
|
266
267
|
render()
|
|
@@ -126,28 +126,25 @@ function loadLevelData()
|
|
|
126
126
|
}
|
|
127
127
|
}
|
|
128
128
|
}
|
|
129
|
+
|
|
130
|
+
tileLayer.onRedraw = ()=>
|
|
131
|
+
{
|
|
132
|
+
// apply decoration to level tiles
|
|
133
|
+
for (let x=levelSize.x; x--;)
|
|
134
|
+
for (let y=levelSize.y; y--;)
|
|
135
|
+
decorateTile(vec2(x,y), tileLayer);
|
|
136
|
+
}
|
|
129
137
|
tileLayer.redraw();
|
|
130
138
|
}
|
|
131
|
-
|
|
132
|
-
// apply decoration to all level tiles
|
|
133
|
-
const pos = vec2();
|
|
134
|
-
const layerCount = tileMapData.layers.length;
|
|
135
|
-
for (let layer=layerCount; layer--;)
|
|
136
|
-
{
|
|
137
|
-
for (pos.x=levelSize.x; pos.x--;)
|
|
138
|
-
for (pos.y=levelSize.y; pos.y--;)
|
|
139
|
-
decorateTile(pos, layer);
|
|
140
|
-
tileLayers[layer].useWebGL();
|
|
141
|
-
}
|
|
142
139
|
}
|
|
143
140
|
|
|
144
|
-
export function decorateTile(pos,
|
|
141
|
+
export function decorateTile(pos, tileLayer)
|
|
145
142
|
{
|
|
146
143
|
LJS.ASSERT((pos.x|0) == pos.x && (pos.y|0)== pos.y);
|
|
147
|
-
const tileLayer = tileLayers[layer];
|
|
148
144
|
if (!tileLayer)
|
|
149
145
|
return;
|
|
150
146
|
|
|
147
|
+
const w = tileLayer.tileInfo.size.x;
|
|
151
148
|
if (tileLayer == foregroundTileLayer)
|
|
152
149
|
{
|
|
153
150
|
const tileType = tileLayer.getCollisionData(pos);
|
|
@@ -167,12 +164,11 @@ export function decorateTile(pos, layer=1)
|
|
|
167
164
|
|
|
168
165
|
// make pixel perfect outlines
|
|
169
166
|
const size = i&1 ? vec2(2, 16) : vec2(16, 2);
|
|
170
|
-
tileLayer.context.fillStyle = levelOutlineColor.mutate(.1);
|
|
171
167
|
const drawPos = pos.scale(16)
|
|
172
168
|
.add(vec2(i==1?14:0,(i==0?14:0)))
|
|
173
169
|
.subtract((i&1? vec2(0,8-size.y/2) : vec2(8-size.x/2,0)));
|
|
174
|
-
|
|
175
|
-
|
|
170
|
+
const color = levelOutlineColor.mutate(.1);
|
|
171
|
+
tileLayer.drawLayerRect(drawPos, size, color);
|
|
176
172
|
}
|
|
177
173
|
}
|
|
178
174
|
else
|
|
@@ -185,15 +181,18 @@ export function decorateTile(pos, layer=1)
|
|
|
185
181
|
const neighborTileDataB = tileLayer.getData(pos.add(vec2().setDirection((i+1)%4))).tile;
|
|
186
182
|
if (neighborTileDataA > 0 || neighborTileDataB > 0)
|
|
187
183
|
continue;
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
const
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
184
|
+
|
|
185
|
+
// get direction of corner
|
|
186
|
+
const directionVector = vec2();
|
|
187
|
+
if (i==0) directionVector.set(w-1,w-1);
|
|
188
|
+
if (i==1) directionVector.set(w-1,1);
|
|
189
|
+
if (i==2) directionVector.set(1,1);
|
|
190
|
+
if (i==3) directionVector.set(1,w-1);
|
|
191
|
+
|
|
192
|
+
// clear rect from corner
|
|
193
|
+
const s = vec2(2);
|
|
194
|
+
const drawPos = pos.scale(w).add(directionVector).subtract(s.scale(.5));
|
|
195
|
+
tileLayer.clearLayerRect(drawPos, s);
|
|
197
196
|
}
|
|
198
197
|
}
|
|
199
198
|
}
|
package/examples/shorts/clock.js
CHANGED
|
@@ -15,7 +15,7 @@ function gameRender()
|
|
|
15
15
|
const h = (d.slice(0,2)|0) + m/60;
|
|
16
16
|
|
|
17
17
|
// draw clock hands
|
|
18
|
-
drawLine(vec2(
|
|
19
|
-
drawLine(vec2(
|
|
20
|
-
drawLine(vec2(
|
|
18
|
+
drawLine(vec2(), vec2(0,4).rotate(h/12*2*PI), 1);
|
|
19
|
+
drawLine(vec2(), vec2(0,6).rotate(m/60*2*PI), .4);
|
|
20
|
+
drawLine(vec2(), vec2(0,8).rotate(s/60*2*PI), .1);
|
|
21
21
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
function gameRender()
|
|
2
2
|
{
|
|
3
3
|
// draw text with built in engine font image
|
|
4
|
-
const font =
|
|
5
|
-
font.drawText('Engine Font
|
|
4
|
+
const font = engineFontImage
|
|
5
|
+
font.drawText('Engine Font', vec2(0,3), 2);
|
|
6
6
|
|
|
7
7
|
// show every character in the font
|
|
8
8
|
let s = '';
|
|
@@ -12,5 +12,6 @@ function gameRender()
|
|
|
12
12
|
s += '\n';
|
|
13
13
|
s += String.fromCharCode(i);
|
|
14
14
|
}
|
|
15
|
-
|
|
15
|
+
|
|
16
|
+
font.drawText(s, vec2());
|
|
16
17
|
}
|
|
@@ -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.1></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.1></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
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
|
}
|
package/plugins/uiSystem.js
CHANGED
|
@@ -512,7 +512,7 @@ class UISystemPlugin
|
|
|
512
512
|
const up = 'ArrowUp', down = 'ArrowDown', left = 'ArrowLeft', right = 'ArrowRight';
|
|
513
513
|
if (both)
|
|
514
514
|
{
|
|
515
|
-
return keyIsDown(up) || keyIsDown(left) ? -1 :
|
|
515
|
+
return keyIsDown(up) || keyIsDown(left) ? -1 :
|
|
516
516
|
keyIsDown(down) || keyIsDown(right) ? 1 : 0;
|
|
517
517
|
}
|
|
518
518
|
const back = vertical ? up : left;
|
|
@@ -543,7 +543,7 @@ class UISystemPlugin
|
|
|
543
543
|
* @return {boolean} */
|
|
544
544
|
getNavigationWasPressed()
|
|
545
545
|
{
|
|
546
|
-
return isUsingGamepad ? gamepadWasPressed(0, gamepadPrimary) :
|
|
546
|
+
return isUsingGamepad ? gamepadWasPressed(0, gamepadPrimary) :
|
|
547
547
|
keyWasPressed('Space') || keyWasPressed('Enter');
|
|
548
548
|
}
|
|
549
549
|
|
|
@@ -591,7 +591,7 @@ class UISystemPlugin
|
|
|
591
591
|
buttonYes.textHeight = 40;
|
|
592
592
|
buttonYes.navigationIndex = 1;
|
|
593
593
|
buttonYes.hoverColor = hsl(0,1,.5);
|
|
594
|
-
buttonYes.onClick = ()=> { closeMenu(); yesCallback && yesCallback(); };
|
|
594
|
+
buttonYes.onClick = ()=> { closeMenu(); yesCallback && yesCallback(); };
|
|
595
595
|
confirmMenu.addChild(buttonYes);
|
|
596
596
|
|
|
597
597
|
// no button
|
|
@@ -621,8 +621,8 @@ class UISystemPlugin
|
|
|
621
621
|
class UIObject
|
|
622
622
|
{
|
|
623
623
|
/** Create a UIObject
|
|
624
|
-
* @param {Vector2} [pos=(
|
|
625
|
-
* @param {Vector2} [size=(1
|
|
624
|
+
* @param {Vector2} [pos=vec2()]
|
|
625
|
+
* @param {Vector2} [size=vec2(1)]
|
|
626
626
|
*/
|
|
627
627
|
constructor(pos=vec2(), size=vec2())
|
|
628
628
|
{
|
|
@@ -637,7 +637,7 @@ class UIObject
|
|
|
637
637
|
this.size = size.copy();
|
|
638
638
|
/** @property {Color} - Color of the object */
|
|
639
639
|
this.color = uiSystem.defaultColor.copy();
|
|
640
|
-
/** @property {Color} - Color of the object when active, uses
|
|
640
|
+
/** @property {Color} - Color of the object when active, uses hoverColor if undefined */
|
|
641
641
|
this.activeColor = undefined;
|
|
642
642
|
/** @property {string} - Text for this ui object */
|
|
643
643
|
this.text = undefined;
|
|
@@ -735,10 +735,10 @@ class UIObject
|
|
|
735
735
|
|
|
736
736
|
// disconnect from parent and destroy children
|
|
737
737
|
this.destroyed = 1;
|
|
738
|
-
this.parent
|
|
738
|
+
this.parent?.removeChild(this);
|
|
739
739
|
for (const child of this.children)
|
|
740
740
|
{
|
|
741
|
-
child.parent =
|
|
741
|
+
child.parent = undefined;
|
|
742
742
|
child.destroy();
|
|
743
743
|
}
|
|
744
744
|
}
|
|
@@ -834,10 +834,10 @@ class UIObject
|
|
|
834
834
|
this.interactive && this.isActiveObject() && !this.disabled ?
|
|
835
835
|
this.color : this.lineColor;
|
|
836
836
|
const color = isNavigationObject ? this.hoverColor :
|
|
837
|
-
this.disabled ? this.disabledColor :
|
|
838
|
-
this.interactive ?
|
|
839
|
-
this.
|
|
840
|
-
this.
|
|
837
|
+
this.disabled ? this.disabledColor :
|
|
838
|
+
this.interactive ?
|
|
839
|
+
this.isActiveObject() ? this.activeColor || this.hoverColor :
|
|
840
|
+
this.isHoverObject() ? this.hoverColor :
|
|
841
841
|
this.color : this.color;
|
|
842
842
|
const lineWidth = this.lineWidth * (isNavigationObject ? 1.5 : 1);
|
|
843
843
|
|
|
@@ -849,7 +849,7 @@ class UIObject
|
|
|
849
849
|
getTextSize()
|
|
850
850
|
{
|
|
851
851
|
return vec2(
|
|
852
|
-
this.textWidth || this.textFitScale * this.size.x,
|
|
852
|
+
this.textWidth || this.textFitScale * this.size.x,
|
|
853
853
|
this.textHeight || this.textFitScale * this.size.y);
|
|
854
854
|
}
|
|
855
855
|
|
|
@@ -897,9 +897,9 @@ class UIObject
|
|
|
897
897
|
renderDebug(visible=true)
|
|
898
898
|
{
|
|
899
899
|
// apply color based on state
|
|
900
|
-
const color =
|
|
900
|
+
const color =
|
|
901
901
|
!visible ? GREEN :
|
|
902
|
-
this.isHoverObject() ? YELLOW :
|
|
902
|
+
this.isHoverObject() ? YELLOW :
|
|
903
903
|
this.disabled ? PURPLE :
|
|
904
904
|
this.interactive ? RED : BLUE;
|
|
905
905
|
uiSystem.drawRect(this.pos, this.size, CLEAR_BLACK, 4, color);
|
package/reference.md
CHANGED
|
@@ -375,7 +375,7 @@ CanvasLayer(position, size) // Create a canvas layer object
|
|
|
375
375
|
CanvasLayer.canvas // The canvas used by this layer
|
|
376
376
|
CanvasLayer.context // The 2D context of the canvas
|
|
377
377
|
CanvasLayer.getImageData() // Get image data from canvas
|
|
378
|
-
CanvasLayer.
|
|
378
|
+
CanvasLayer.updateWebGL() // Creates or updates WebGL texture
|
|
379
379
|
|
|
380
380
|
// LittleJS Layer System
|
|
381
381
|
TileLayer(position, size, tileInfo, scale) // Create a tile layer object
|