@vpmedia/phaser 1.0.1 → 1.0.3
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/README.md +20 -3
- package/dist/phaser.cjs +1 -1
- package/dist/phaser.cjs.LICENSE.txt +1 -1
- package/dist/phaser.cjs.map +1 -1
- package/dist/phaser.js +1 -1
- package/dist/phaser.js.LICENSE.txt +1 -1
- package/dist/phaser.js.map +1 -1
- package/package.json +23 -17
- package/src/index.js +142 -0
- package/src/phaser/core/animation.js +355 -0
- package/src/phaser/core/animation_manager.js +238 -0
- package/src/phaser/core/animation_parser.js +133 -0
- package/src/phaser/core/array_set.js +107 -0
- package/src/phaser/core/cache.js +558 -0
- package/src/phaser/core/const.js +106 -0
- package/src/phaser/core/device.js +67 -0
- package/src/phaser/core/device_util.js +388 -0
- package/src/phaser/core/dom.js +207 -0
- package/src/phaser/core/event_manager.js +243 -0
- package/src/phaser/core/factory.js +74 -0
- package/src/phaser/core/frame.js +75 -0
- package/src/phaser/core/frame_data.js +84 -0
- package/src/phaser/core/frame_util.js +33 -0
- package/src/phaser/core/game.js +412 -0
- package/src/phaser/core/input.js +401 -0
- package/src/phaser/core/input_button.js +102 -0
- package/src/phaser/core/input_handler.js +687 -0
- package/src/phaser/core/input_mouse.js +289 -0
- package/src/phaser/core/input_mspointer.js +197 -0
- package/src/phaser/core/input_pointer.js +427 -0
- package/src/phaser/core/input_touch.js +157 -0
- package/src/phaser/core/loader.js +1057 -0
- package/src/phaser/core/loader_parser.js +109 -0
- package/src/phaser/core/raf.js +46 -0
- package/src/phaser/core/raf_fb.js +75 -0
- package/src/phaser/core/raf_to.js +34 -0
- package/src/phaser/core/scale_manager.js +806 -0
- package/src/phaser/core/scene.js +65 -0
- package/src/phaser/core/scene_manager.js +309 -0
- package/src/phaser/core/signal.js +175 -0
- package/src/phaser/core/signal_binding.js +69 -0
- package/src/phaser/core/sound.js +538 -0
- package/src/phaser/core/sound_manager.js +364 -0
- package/src/phaser/core/stage.js +108 -0
- package/src/phaser/core/time.js +203 -0
- package/src/phaser/core/timer.js +276 -0
- package/src/phaser/core/timer_event.js +21 -0
- package/src/phaser/core/tween.js +329 -0
- package/src/phaser/core/tween_data.js +258 -0
- package/src/phaser/core/tween_easing.js +341 -0
- package/src/phaser/core/tween_manager.js +185 -0
- package/src/phaser/core/world.js +18 -0
- package/src/phaser/display/bitmap_text.js +322 -0
- package/src/phaser/display/button.js +194 -0
- package/src/phaser/display/canvas/buffer.js +36 -0
- package/src/phaser/display/canvas/graphics.js +227 -0
- package/src/phaser/display/canvas/masker.js +39 -0
- package/src/phaser/display/canvas/pool.js +126 -0
- package/src/phaser/display/canvas/renderer.js +123 -0
- package/src/phaser/display/canvas/tinter.js +144 -0
- package/src/phaser/display/canvas/util.js +159 -0
- package/src/phaser/display/display_object.js +597 -0
- package/src/phaser/display/graphics.js +723 -0
- package/src/phaser/display/graphics_data.js +27 -0
- package/src/phaser/display/graphics_data_util.js +15 -0
- package/src/phaser/display/group.js +227 -0
- package/src/phaser/display/image.js +288 -0
- package/src/phaser/display/sprite_batch.js +15 -0
- package/src/phaser/display/sprite_util.js +250 -0
- package/src/phaser/display/text.js +1089 -0
- package/src/phaser/display/webgl/abstract_filter.js +25 -0
- package/src/phaser/display/webgl/base_texture.js +68 -0
- package/src/phaser/display/webgl/blend_manager.js +35 -0
- package/src/phaser/display/webgl/earcut.js +662 -0
- package/src/phaser/display/webgl/earcut_node.js +28 -0
- package/src/phaser/display/webgl/fast_sprite_batch.js +242 -0
- package/src/phaser/display/webgl/filter_manager.js +46 -0
- package/src/phaser/display/webgl/filter_texture.js +61 -0
- package/src/phaser/display/webgl/graphics.js +624 -0
- package/src/phaser/display/webgl/graphics_data.js +42 -0
- package/src/phaser/display/webgl/mask_manager.js +36 -0
- package/src/phaser/display/webgl/render_texture.js +81 -0
- package/src/phaser/display/webgl/renderer.js +234 -0
- package/src/phaser/display/webgl/shader/complex.js +74 -0
- package/src/phaser/display/webgl/shader/fast.js +97 -0
- package/src/phaser/display/webgl/shader/normal.js +225 -0
- package/src/phaser/display/webgl/shader/primitive.js +72 -0
- package/src/phaser/display/webgl/shader/strip.js +77 -0
- package/src/phaser/display/webgl/shader_manager.js +89 -0
- package/src/phaser/display/webgl/sprite_batch.js +320 -0
- package/src/phaser/display/webgl/stencil_manager.js +170 -0
- package/src/phaser/display/webgl/texture.js +117 -0
- package/src/phaser/display/webgl/texture_util.js +34 -0
- package/src/phaser/display/webgl/util.js +78 -0
- package/src/phaser/geom/circle.js +186 -0
- package/src/phaser/geom/ellipse.js +65 -0
- package/src/phaser/geom/line.js +190 -0
- package/src/phaser/geom/matrix.js +147 -0
- package/src/phaser/geom/point.js +164 -0
- package/src/phaser/geom/polygon.js +140 -0
- package/src/phaser/geom/rectangle.js +306 -0
- package/src/phaser/geom/rounded_rectangle.js +36 -0
- package/src/phaser/geom/util/circle.js +122 -0
- package/src/phaser/geom/util/ellipse.js +34 -0
- package/src/phaser/geom/util/line.js +135 -0
- package/src/phaser/geom/util/matrix.js +53 -0
- package/src/phaser/geom/util/point.js +296 -0
- package/src/phaser/geom/util/polygon.js +28 -0
- package/src/phaser/geom/util/rectangle.js +229 -0
- package/src/phaser/geom/util/rounded_rectangle.js +32 -0
- package/src/phaser/util/math.js +297 -0
- package/src/phaser/util/string.js +32 -0
|
@@ -0,0 +1,624 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @author Andras Csizmadia <andras@vpmedia.hu>
|
|
3
|
+
* @author Richard Davey <rich@photonstorm.com>
|
|
4
|
+
* @author Mat Groves http://matgroves.com/ @Doormat23
|
|
5
|
+
* @copyright Copyright (c) 2018-present Richard Davey, Photon Storm Ltd., Andras Csizmadia <andras@vpmedia.hu> (www.vpmedia.hu)
|
|
6
|
+
*/
|
|
7
|
+
import GraphicsData from './graphics_data';
|
|
8
|
+
import Point from '../../geom/point';
|
|
9
|
+
import { GEOM_CIRCLE, GEOM_ELLIPSE, GEOM_POLYGON, GEOM_RECTANGLE, GEOM_ROUNDED_RECTANGLE } from '../../core/const';
|
|
10
|
+
import { hex2rgb } from '../../util/math';
|
|
11
|
+
import { triangulate } from './earcut';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* TBD
|
|
15
|
+
*
|
|
16
|
+
* @returns {number} TBD
|
|
17
|
+
*/
|
|
18
|
+
export function getStencilBufferLimit() {
|
|
19
|
+
if (!window.PhaserRegistry.stencilBufferLimit) {
|
|
20
|
+
window.PhaserRegistry.stencilBufferLimit = 6;
|
|
21
|
+
}
|
|
22
|
+
return window.PhaserRegistry.stencilBufferLimit;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* TBD
|
|
27
|
+
*
|
|
28
|
+
* @returns {object[]} TBD
|
|
29
|
+
*/
|
|
30
|
+
export function getGraphicsDataPool() {
|
|
31
|
+
if (!window.PhaserRegistry.graphicsDataPool) {
|
|
32
|
+
window.PhaserRegistry.graphicsDataPool = [];
|
|
33
|
+
}
|
|
34
|
+
return window.PhaserRegistry.graphicsDataPool;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
*
|
|
39
|
+
* @param {object} webGL TBD
|
|
40
|
+
* @param {number} type TBD
|
|
41
|
+
* @returns {object} TBD
|
|
42
|
+
*/
|
|
43
|
+
export function switchMode(webGL, type) {
|
|
44
|
+
let webGLData;
|
|
45
|
+
if (!webGL.data.length) {
|
|
46
|
+
webGLData = getGraphicsDataPool().pop() || new GraphicsData(webGL.gl);
|
|
47
|
+
webGLData.mode = type;
|
|
48
|
+
webGL.data.push(webGLData);
|
|
49
|
+
} else {
|
|
50
|
+
webGLData = webGL.data[webGL.data.length - 1];
|
|
51
|
+
if (webGLData.mode !== type || type === 1) {
|
|
52
|
+
webGLData = getGraphicsDataPool().pop() || new GraphicsData(webGL.gl);
|
|
53
|
+
webGLData.mode = type;
|
|
54
|
+
webGL.data.push(webGLData);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
webGLData.dirty = true;
|
|
58
|
+
return webGLData;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
*
|
|
63
|
+
* @param {object} graphicsData TBD
|
|
64
|
+
* @param {object} webGLData TBD
|
|
65
|
+
*/
|
|
66
|
+
export function buildLine(graphicsData, webGLData) {
|
|
67
|
+
// TODO OPTIMISE!
|
|
68
|
+
let i = 0;
|
|
69
|
+
let points = graphicsData.points;
|
|
70
|
+
if (points.length === 0) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
// if the line width is an odd number add 0.5 to align to a whole pixel
|
|
74
|
+
if (graphicsData.lineWidth % 2) {
|
|
75
|
+
for (i = 0; i < points.length; i += 1) {
|
|
76
|
+
points[i] += 0.5;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
// get first and last point.. figure out the middle!
|
|
80
|
+
const firstPoint = new Point(points[0], points[1]);
|
|
81
|
+
let lastPoint = new Point(points[points.length - 2], points[points.length - 1]);
|
|
82
|
+
// if the first point is the last point - gonna have issues :)
|
|
83
|
+
if (firstPoint.x === lastPoint.x && firstPoint.y === lastPoint.y) {
|
|
84
|
+
// need to clone as we are going to slightly modify the shape..
|
|
85
|
+
points = points.slice();
|
|
86
|
+
points.pop();
|
|
87
|
+
points.pop();
|
|
88
|
+
lastPoint = new Point(points[points.length - 2], points[points.length - 1]);
|
|
89
|
+
const midPointX = lastPoint.x + (firstPoint.x - lastPoint.x) * 0.5;
|
|
90
|
+
const midPointY = lastPoint.y + (firstPoint.y - lastPoint.y) * 0.5;
|
|
91
|
+
points.unshift(midPointX, midPointY);
|
|
92
|
+
points.push(midPointX, midPointY);
|
|
93
|
+
}
|
|
94
|
+
const verts = webGLData.points;
|
|
95
|
+
const indices = webGLData.indices;
|
|
96
|
+
const length = points.length / 2;
|
|
97
|
+
let indexCount = points.length;
|
|
98
|
+
let indexStart = verts.length / 6;
|
|
99
|
+
// DRAW the Line
|
|
100
|
+
const width = graphicsData.lineWidth / 2;
|
|
101
|
+
// sort color
|
|
102
|
+
const color = hex2rgb(graphicsData.lineColor);
|
|
103
|
+
const alpha = graphicsData.lineAlpha;
|
|
104
|
+
const r = color[0] * alpha;
|
|
105
|
+
const g = color[1] * alpha;
|
|
106
|
+
const b = color[2] * alpha;
|
|
107
|
+
let px;
|
|
108
|
+
let py;
|
|
109
|
+
let p1x;
|
|
110
|
+
let p1y;
|
|
111
|
+
let p2x;
|
|
112
|
+
let p2y;
|
|
113
|
+
let p3x;
|
|
114
|
+
let p3y;
|
|
115
|
+
let perpx;
|
|
116
|
+
let perpy;
|
|
117
|
+
let perp2x;
|
|
118
|
+
let perp2y;
|
|
119
|
+
let perp3x;
|
|
120
|
+
let perp3y;
|
|
121
|
+
let a1;
|
|
122
|
+
let b1;
|
|
123
|
+
let c1;
|
|
124
|
+
let a2;
|
|
125
|
+
let b2;
|
|
126
|
+
let c2;
|
|
127
|
+
let denom;
|
|
128
|
+
let pdist;
|
|
129
|
+
let dist;
|
|
130
|
+
p1x = points[0];
|
|
131
|
+
p1y = points[1];
|
|
132
|
+
p2x = points[2];
|
|
133
|
+
p2y = points[3];
|
|
134
|
+
perpx = -(p1y - p2y);
|
|
135
|
+
perpy = p1x - p2x;
|
|
136
|
+
dist = Math.sqrt((perpx * perpx) + (perpy * perpy));
|
|
137
|
+
perpx /= dist;
|
|
138
|
+
perpy /= dist;
|
|
139
|
+
perpx *= width;
|
|
140
|
+
perpy *= width;
|
|
141
|
+
// start
|
|
142
|
+
verts.push(p1x - perpx, p1y - perpy, r, g, b, alpha);
|
|
143
|
+
verts.push(p1x + perpx, p1y + perpy, r, g, b, alpha);
|
|
144
|
+
for (i = 1; i < length - 1; i += 1) {
|
|
145
|
+
p1x = points[(i - 1) * 2];
|
|
146
|
+
p1y = points[(i - 1) * 2 + 1];
|
|
147
|
+
p2x = points[(i) * 2];
|
|
148
|
+
p2y = points[(i) * 2 + 1];
|
|
149
|
+
p3x = points[(i + 1) * 2];
|
|
150
|
+
p3y = points[(i + 1) * 2 + 1];
|
|
151
|
+
perpx = -(p1y - p2y);
|
|
152
|
+
perpy = p1x - p2x;
|
|
153
|
+
dist = Math.sqrt((perpx * perpx) + (perpy * perpy));
|
|
154
|
+
perpx /= dist;
|
|
155
|
+
perpy /= dist;
|
|
156
|
+
perpx *= width;
|
|
157
|
+
perpy *= width;
|
|
158
|
+
perp2x = -(p2y - p3y);
|
|
159
|
+
perp2y = p2x - p3x;
|
|
160
|
+
dist = Math.sqrt(perp2x * perp2x + perp2y * perp2y);
|
|
161
|
+
perp2x /= dist;
|
|
162
|
+
perp2y /= dist;
|
|
163
|
+
perp2x *= width;
|
|
164
|
+
perp2y *= width;
|
|
165
|
+
a1 = (-perpy + p1y) - (-perpy + p2y);
|
|
166
|
+
b1 = (-perpx + p2x) - (-perpx + p1x);
|
|
167
|
+
c1 = (-perpx + p1x) * (-perpy + p2y) - (-perpx + p2x) * (-perpy + p1y);
|
|
168
|
+
a2 = (-perp2y + p3y) - (-perp2y + p2y);
|
|
169
|
+
b2 = (-perp2x + p2x) - (-perp2x + p3x);
|
|
170
|
+
c2 = (-perp2x + p3x) * (-perp2y + p2y) - (-perp2x + p2x) * (-perp2y + p3y);
|
|
171
|
+
denom = (a1 * b2) - (a2 * b1);
|
|
172
|
+
if (Math.abs(denom) < 0.1) {
|
|
173
|
+
denom += 10.1;
|
|
174
|
+
verts.push(p2x - perpx, p2y - perpy, r, g, b, alpha);
|
|
175
|
+
verts.push(p2x + perpx, p2y + perpy, r, g, b, alpha);
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
178
|
+
px = (b1 * c2 - b2 * c1) / denom;
|
|
179
|
+
py = (a2 * c1 - a1 * c2) / denom;
|
|
180
|
+
pdist = (px - p2x) * (px - p2x) + (py - p2y) + (py - p2y);
|
|
181
|
+
if (pdist > 140 * 140) {
|
|
182
|
+
perp3x = perpx - perp2x;
|
|
183
|
+
perp3y = perpy - perp2y;
|
|
184
|
+
dist = Math.sqrt(perp3x * perp3x + perp3y * perp3y);
|
|
185
|
+
perp3x /= dist;
|
|
186
|
+
perp3y /= dist;
|
|
187
|
+
perp3x *= width;
|
|
188
|
+
perp3y *= width;
|
|
189
|
+
verts.push(p2x - perp3x, p2y - perp3y);
|
|
190
|
+
verts.push(r, g, b, alpha);
|
|
191
|
+
verts.push(p2x + perp3x, p2y + perp3y);
|
|
192
|
+
verts.push(r, g, b, alpha);
|
|
193
|
+
verts.push(p2x - perp3x, p2y - perp3y);
|
|
194
|
+
verts.push(r, g, b, alpha);
|
|
195
|
+
indexCount += 1;
|
|
196
|
+
} else {
|
|
197
|
+
verts.push(px, py);
|
|
198
|
+
verts.push(r, g, b, alpha);
|
|
199
|
+
verts.push(p2x - (px - p2x), p2y - (py - p2y));
|
|
200
|
+
verts.push(r, g, b, alpha);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
p1x = points[(length - 2) * 2];
|
|
204
|
+
p1y = points[(length - 2) * 2 + 1];
|
|
205
|
+
p2x = points[(length - 1) * 2];
|
|
206
|
+
p2y = points[(length - 1) * 2 + 1];
|
|
207
|
+
perpx = -(p1y - p2y);
|
|
208
|
+
perpy = p1x - p2x;
|
|
209
|
+
dist = Math.sqrt((perpx * perpx) + (perpy * perpy));
|
|
210
|
+
perpx /= dist;
|
|
211
|
+
perpy /= dist;
|
|
212
|
+
perpx *= width;
|
|
213
|
+
perpy *= width;
|
|
214
|
+
verts.push(p2x - perpx, p2y - perpy);
|
|
215
|
+
verts.push(r, g, b, alpha);
|
|
216
|
+
verts.push(p2x + perpx, p2y + perpy);
|
|
217
|
+
verts.push(r, g, b, alpha);
|
|
218
|
+
indices.push(indexStart);
|
|
219
|
+
for (i = 0; i < indexCount; i += 1) {
|
|
220
|
+
indices.push(indexStart);
|
|
221
|
+
indexStart += 1;
|
|
222
|
+
}
|
|
223
|
+
indices.push(indexStart - 1);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
*
|
|
228
|
+
* @param {object} graphicsData TBD
|
|
229
|
+
* @param {object} webGLData TBD
|
|
230
|
+
*/
|
|
231
|
+
export function buildRectangle(graphicsData, webGLData) {
|
|
232
|
+
//
|
|
233
|
+
// need to convert points to a nice regular data
|
|
234
|
+
//
|
|
235
|
+
const rectData = graphicsData.shape;
|
|
236
|
+
const x = rectData.x;
|
|
237
|
+
const y = rectData.y;
|
|
238
|
+
const width = rectData.width;
|
|
239
|
+
const height = rectData.height;
|
|
240
|
+
|
|
241
|
+
if (graphicsData.fill) {
|
|
242
|
+
const color = hex2rgb(graphicsData.fillColor);
|
|
243
|
+
const alpha = graphicsData.fillAlpha;
|
|
244
|
+
const r = color[0] * alpha;
|
|
245
|
+
const g = color[1] * alpha;
|
|
246
|
+
const b = color[2] * alpha;
|
|
247
|
+
const verts = webGLData.points;
|
|
248
|
+
const indices = webGLData.indices;
|
|
249
|
+
const vertPos = verts.length / 6;
|
|
250
|
+
// start
|
|
251
|
+
verts.push(x, y);
|
|
252
|
+
verts.push(r, g, b, alpha);
|
|
253
|
+
verts.push(x + width, y);
|
|
254
|
+
verts.push(r, g, b, alpha);
|
|
255
|
+
verts.push(x, y + height);
|
|
256
|
+
verts.push(r, g, b, alpha);
|
|
257
|
+
verts.push(x + width, y + height);
|
|
258
|
+
verts.push(r, g, b, alpha);
|
|
259
|
+
// insert 2 dead triangles..
|
|
260
|
+
indices.push(vertPos, vertPos, vertPos + 1, vertPos + 2, vertPos + 3, vertPos + 3);
|
|
261
|
+
}
|
|
262
|
+
if (graphicsData.lineWidth) {
|
|
263
|
+
const tempPoints = graphicsData.points;
|
|
264
|
+
graphicsData.points = [x, y, x + width, y, x + width, y + height, x, y + height, x, y];
|
|
265
|
+
buildLine(graphicsData, webGLData);
|
|
266
|
+
graphicsData.points = tempPoints;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
*
|
|
272
|
+
* @param {number} fromX TBD
|
|
273
|
+
* @param {number} fromY TBD
|
|
274
|
+
* @param {number} cpX TBD
|
|
275
|
+
* @param {number} cpY TBD
|
|
276
|
+
* @param {number} toX TBD
|
|
277
|
+
* @param {number} toY TBD
|
|
278
|
+
* @returns {number[]} TBD
|
|
279
|
+
*/
|
|
280
|
+
export function quadraticBezierCurve(fromX, fromY, cpX, cpY, toX, toY) {
|
|
281
|
+
let xa;
|
|
282
|
+
let ya;
|
|
283
|
+
let xb;
|
|
284
|
+
let yb;
|
|
285
|
+
let x;
|
|
286
|
+
let y;
|
|
287
|
+
const n = 20;
|
|
288
|
+
const points = [];
|
|
289
|
+
const getPt = (n1, n2, perc) => {
|
|
290
|
+
const diff = n2 - n1;
|
|
291
|
+
return n1 + (diff * perc);
|
|
292
|
+
};
|
|
293
|
+
let j = 0;
|
|
294
|
+
for (let i = 0; i <= n; i += 1) {
|
|
295
|
+
j = i / n;
|
|
296
|
+
// The Green Line
|
|
297
|
+
xa = getPt(fromX, cpX, j);
|
|
298
|
+
ya = getPt(fromY, cpY, j);
|
|
299
|
+
xb = getPt(cpX, toX, j);
|
|
300
|
+
yb = getPt(cpY, toY, j);
|
|
301
|
+
// The Black Dot
|
|
302
|
+
x = getPt(xa, xb, j);
|
|
303
|
+
y = getPt(ya, yb, j);
|
|
304
|
+
points.push(x, y);
|
|
305
|
+
}
|
|
306
|
+
return points;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
*
|
|
311
|
+
* @param {object} graphicsData TBD
|
|
312
|
+
* @param {object} webGLData TBD
|
|
313
|
+
*/
|
|
314
|
+
export function buildRoundedRectangle(graphicsData, webGLData) {
|
|
315
|
+
const rrectData = graphicsData.shape;
|
|
316
|
+
const x = rrectData.x;
|
|
317
|
+
const y = rrectData.y;
|
|
318
|
+
const width = rrectData.width;
|
|
319
|
+
const height = rrectData.height;
|
|
320
|
+
const radius = rrectData.radius;
|
|
321
|
+
let recPoints = [];
|
|
322
|
+
recPoints.push(x, y + radius);
|
|
323
|
+
recPoints = recPoints.concat(quadraticBezierCurve(x, y + height - radius, x, y + height, x + radius, y + height));
|
|
324
|
+
recPoints = recPoints.concat(quadraticBezierCurve(x + width - radius, y + height, x + width, y + height, x + width, y + height - radius));
|
|
325
|
+
recPoints = recPoints.concat(quadraticBezierCurve(x + width, y + radius, x + width, y, x + width - radius, y));
|
|
326
|
+
recPoints = recPoints.concat(quadraticBezierCurve(x + radius, y, x, y, x, y + radius));
|
|
327
|
+
if (graphicsData.fill) {
|
|
328
|
+
const color = hex2rgb(graphicsData.fillColor);
|
|
329
|
+
const alpha = graphicsData.fillAlpha;
|
|
330
|
+
const r = color[0] * alpha;
|
|
331
|
+
const g = color[1] * alpha;
|
|
332
|
+
const b = color[2] * alpha;
|
|
333
|
+
const verts = webGLData.points;
|
|
334
|
+
const indices = webGLData.indices;
|
|
335
|
+
const vecPos = verts.length / 6;
|
|
336
|
+
const triangles = triangulate(recPoints, null, 2);
|
|
337
|
+
for (let i = 0; i < triangles.length; i += 3) {
|
|
338
|
+
indices.push(triangles[i] + vecPos);
|
|
339
|
+
indices.push(triangles[i] + vecPos);
|
|
340
|
+
indices.push(triangles[i + 1] + vecPos);
|
|
341
|
+
indices.push(triangles[i + 2] + vecPos);
|
|
342
|
+
indices.push(triangles[i + 2] + vecPos);
|
|
343
|
+
}
|
|
344
|
+
for (let i = 0; i < recPoints.length; i += 2) {
|
|
345
|
+
// TODO verify
|
|
346
|
+
verts.push(recPoints[i], recPoints[i + 1], r, g, b, alpha);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
if (graphicsData.lineWidth) {
|
|
350
|
+
const tempPoints = graphicsData.points;
|
|
351
|
+
graphicsData.points = recPoints;
|
|
352
|
+
buildLine(graphicsData, webGLData);
|
|
353
|
+
graphicsData.points = tempPoints;
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
/**
|
|
358
|
+
*
|
|
359
|
+
* @param {object} graphicsData TBD
|
|
360
|
+
* @param {object} webGLData TBD
|
|
361
|
+
*/
|
|
362
|
+
export function buildCircle(graphicsData, webGLData) {
|
|
363
|
+
// need to convert points to a nice regular data
|
|
364
|
+
const circleData = graphicsData.shape;
|
|
365
|
+
const x = circleData.x;
|
|
366
|
+
const y = circleData.y;
|
|
367
|
+
let width;
|
|
368
|
+
let height;
|
|
369
|
+
// TODO - bit hacky??
|
|
370
|
+
if (graphicsData.type === GEOM_CIRCLE) {
|
|
371
|
+
width = circleData.radius;
|
|
372
|
+
height = circleData.radius;
|
|
373
|
+
} else {
|
|
374
|
+
width = circleData.width;
|
|
375
|
+
height = circleData.height;
|
|
376
|
+
}
|
|
377
|
+
const totalSegs = 40;
|
|
378
|
+
const seg = (Math.PI * 2) / totalSegs;
|
|
379
|
+
if (graphicsData.fill) {
|
|
380
|
+
const color = hex2rgb(graphicsData.fillColor);
|
|
381
|
+
const alpha = graphicsData.fillAlpha;
|
|
382
|
+
const r = color[0] * alpha;
|
|
383
|
+
const g = color[1] * alpha;
|
|
384
|
+
const b = color[2] * alpha;
|
|
385
|
+
const verts = webGLData.points;
|
|
386
|
+
const indices = webGLData.indices;
|
|
387
|
+
let vecPos = verts.length / 6;
|
|
388
|
+
indices.push(vecPos);
|
|
389
|
+
for (let i = 0; i < totalSegs + 1; i += 1) {
|
|
390
|
+
verts.push(x, y, r, g, b, alpha);
|
|
391
|
+
verts.push(x + Math.sin(seg * i) * width, y + Math.cos(seg * i) * height, r, g, b, alpha);
|
|
392
|
+
indices.push(vecPos, vecPos + 1);
|
|
393
|
+
vecPos += 2;
|
|
394
|
+
}
|
|
395
|
+
indices.push(vecPos - 1);
|
|
396
|
+
}
|
|
397
|
+
if (graphicsData.lineWidth) {
|
|
398
|
+
const tempPoints = graphicsData.points;
|
|
399
|
+
graphicsData.points = [];
|
|
400
|
+
for (let i = 0; i < totalSegs + 1; i += 1) {
|
|
401
|
+
graphicsData.points.push(x + Math.sin(seg * i) * width, y + Math.cos(seg * i) * height);
|
|
402
|
+
}
|
|
403
|
+
buildLine(graphicsData, webGLData);
|
|
404
|
+
graphicsData.points = tempPoints;
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
/**
|
|
409
|
+
*
|
|
410
|
+
* @param {object} graphicsData TBD
|
|
411
|
+
* @param {object} webGLData TBD
|
|
412
|
+
*/
|
|
413
|
+
export function buildComplexPoly(graphicsData, webGLData) {
|
|
414
|
+
// TODO - no need to copy this as it gets turned into a Float32Array anyways..
|
|
415
|
+
const points = graphicsData.points.slice();
|
|
416
|
+
if (points.length < 6) {
|
|
417
|
+
return;
|
|
418
|
+
}
|
|
419
|
+
// get first and last point.. figure out the middle!
|
|
420
|
+
const indices = webGLData.indices;
|
|
421
|
+
webGLData.points = points;
|
|
422
|
+
webGLData.alpha = graphicsData.fillAlpha;
|
|
423
|
+
webGLData.color = hex2rgb(graphicsData.fillColor);
|
|
424
|
+
/*
|
|
425
|
+
calculate the bounds..
|
|
426
|
+
*/
|
|
427
|
+
let minX = Infinity;
|
|
428
|
+
let maxX = -Infinity;
|
|
429
|
+
let minY = Infinity;
|
|
430
|
+
let maxY = -Infinity;
|
|
431
|
+
let x;
|
|
432
|
+
let y;
|
|
433
|
+
// get size..
|
|
434
|
+
for (let i = 0; i < points.length; i += 2) {
|
|
435
|
+
x = points[i];
|
|
436
|
+
y = points[i + 1];
|
|
437
|
+
minX = x < minX ? x : minX;
|
|
438
|
+
maxX = x > maxX ? x : maxX;
|
|
439
|
+
minY = y < minY ? y : minY;
|
|
440
|
+
maxY = y > maxY ? y : maxY;
|
|
441
|
+
}
|
|
442
|
+
// add a quad to the end cos there is no point making another buffer!
|
|
443
|
+
points.push(minX, minY, maxX, minY, maxX, maxY, minX, maxY);
|
|
444
|
+
// push a quad onto the end..
|
|
445
|
+
// TODO - this aint needed!
|
|
446
|
+
const length = points.length / 2;
|
|
447
|
+
for (let i = 0; i < length; i += 1) {
|
|
448
|
+
indices.push(i);
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
/**
|
|
453
|
+
*
|
|
454
|
+
* @param {object} graphicsData TBD
|
|
455
|
+
* @param {object} webGLData TBD
|
|
456
|
+
* @returns {boolean} TBD
|
|
457
|
+
*/
|
|
458
|
+
export function buildPoly(graphicsData, webGLData) {
|
|
459
|
+
const points = graphicsData.points;
|
|
460
|
+
if (points.length < 6) {
|
|
461
|
+
return false;
|
|
462
|
+
}
|
|
463
|
+
// get first and last point.. figure out the middle!
|
|
464
|
+
const verts = webGLData.points;
|
|
465
|
+
const indices = webGLData.indices;
|
|
466
|
+
const length = points.length / 2;
|
|
467
|
+
// sort color
|
|
468
|
+
const color = hex2rgb(graphicsData.fillColor);
|
|
469
|
+
const alpha = graphicsData.fillAlpha;
|
|
470
|
+
const r = color[0] * alpha;
|
|
471
|
+
const g = color[1] * alpha;
|
|
472
|
+
const b = color[2] * alpha;
|
|
473
|
+
const triangles = triangulate(points, null, 2);
|
|
474
|
+
if (!triangles) {
|
|
475
|
+
return false;
|
|
476
|
+
}
|
|
477
|
+
const vertPos = verts.length / 6;
|
|
478
|
+
for (let i = 0; i < triangles.length; i += 3) {
|
|
479
|
+
indices.push(triangles[i] + vertPos);
|
|
480
|
+
indices.push(triangles[i] + vertPos);
|
|
481
|
+
indices.push(triangles[i + 1] + vertPos);
|
|
482
|
+
indices.push(triangles[i + 2] + vertPos);
|
|
483
|
+
indices.push(triangles[i + 2] + vertPos);
|
|
484
|
+
}
|
|
485
|
+
for (let i = 0; i < length; i += 1) {
|
|
486
|
+
verts.push(points[i * 2], points[i * 2 + 1], r, g, b, alpha);
|
|
487
|
+
}
|
|
488
|
+
return true;
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
/**
|
|
492
|
+
*
|
|
493
|
+
* @param {object} graphics TBD
|
|
494
|
+
* @param {object} gl TBD
|
|
495
|
+
*/
|
|
496
|
+
export function updateGraphics(graphics, gl) {
|
|
497
|
+
const stencilBufferLimit = getStencilBufferLimit();
|
|
498
|
+
// get the contexts graphics object
|
|
499
|
+
let webGL = graphics._webGL[gl.id];
|
|
500
|
+
// if the graphics object does not exist in the webGL context time to create it!
|
|
501
|
+
if (!webGL) {
|
|
502
|
+
webGL = { lastIndex: 0, data: [], gl };
|
|
503
|
+
graphics._webGL[gl.id] = webGL;
|
|
504
|
+
}
|
|
505
|
+
// flag the graphics as not dirty as we are about to update it...
|
|
506
|
+
graphics.dirty = false;
|
|
507
|
+
let i;
|
|
508
|
+
// if the user cleared the graphics object we will need to clear every object
|
|
509
|
+
if (graphics.clearDirty) {
|
|
510
|
+
graphics.clearDirty = false;
|
|
511
|
+
// lop through and return all the webGLDatas to the object pool so than can be reused later on
|
|
512
|
+
for (i = 0; i < webGL.data.length; i += 1) {
|
|
513
|
+
const graphicsData = webGL.data[i];
|
|
514
|
+
graphicsData.reset();
|
|
515
|
+
getGraphicsDataPool().push(graphicsData);
|
|
516
|
+
}
|
|
517
|
+
// clear the array and reset the index..
|
|
518
|
+
webGL.data = [];
|
|
519
|
+
webGL.lastIndex = 0;
|
|
520
|
+
}
|
|
521
|
+
let webGLData;
|
|
522
|
+
// loop through the graphics datas and construct each one..
|
|
523
|
+
// if the object is a complex fill then the new stencil buffer technique will be used
|
|
524
|
+
// other wise graphics objects will be pushed into a batch..
|
|
525
|
+
for (i = webGL.lastIndex; i < graphics.graphicsData.length; i += 1) {
|
|
526
|
+
const data = graphics.graphicsData[i];
|
|
527
|
+
if (data.type === GEOM_POLYGON) {
|
|
528
|
+
// need to add the points the the graphics object..
|
|
529
|
+
data.points = data.shape.points.slice();
|
|
530
|
+
if (data.shape.closed) {
|
|
531
|
+
// close the poly if the value is true!
|
|
532
|
+
if (data.points[0] !== data.points[data.points.length - 2] || data.points[1] !== data.points[data.points.length - 1]) {
|
|
533
|
+
data.points.push(data.points[0], data.points[1]);
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
// MAKE SURE WE HAVE THE CORRECT TYPE..
|
|
537
|
+
if (data.fill) {
|
|
538
|
+
if (data.points.length >= stencilBufferLimit) {
|
|
539
|
+
if (data.points.length < stencilBufferLimit * 2) {
|
|
540
|
+
webGLData = switchMode(webGL, 0);
|
|
541
|
+
const canDrawUsingSimple = buildPoly(data, webGLData);
|
|
542
|
+
// console.log(canDrawUsingSimple);
|
|
543
|
+
if (!canDrawUsingSimple) {
|
|
544
|
+
// console.log("<>>>")
|
|
545
|
+
webGLData = switchMode(webGL, 1);
|
|
546
|
+
buildComplexPoly(data, webGLData);
|
|
547
|
+
}
|
|
548
|
+
} else {
|
|
549
|
+
webGLData = switchMode(webGL, 1);
|
|
550
|
+
buildComplexPoly(data, webGLData);
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
if (data.lineWidth > 0) {
|
|
555
|
+
webGLData = switchMode(webGL, 0);
|
|
556
|
+
buildLine(data, webGLData);
|
|
557
|
+
}
|
|
558
|
+
} else {
|
|
559
|
+
webGLData = switchMode(webGL, 0);
|
|
560
|
+
if (data.type === GEOM_RECTANGLE) {
|
|
561
|
+
buildRectangle(data, webGLData);
|
|
562
|
+
} else if (data.type === GEOM_CIRCLE || data.type === GEOM_ELLIPSE) {
|
|
563
|
+
buildCircle(data, webGLData);
|
|
564
|
+
} else if (data.type === GEOM_ROUNDED_RECTANGLE) {
|
|
565
|
+
buildRoundedRectangle(data, webGLData);
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
webGL.lastIndex += 1;
|
|
569
|
+
}
|
|
570
|
+
// upload all the dirty data...
|
|
571
|
+
for (i = 0; i < webGL.data.length; i += 1) {
|
|
572
|
+
webGLData = webGL.data[i];
|
|
573
|
+
if (webGLData.dirty) {
|
|
574
|
+
webGLData.upload();
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
/**
|
|
580
|
+
*
|
|
581
|
+
* @param {object} graphics TBD
|
|
582
|
+
* @param {object} renderSession TBD
|
|
583
|
+
*/
|
|
584
|
+
export function renderGraphics(graphics, renderSession) {
|
|
585
|
+
const gl = renderSession.gl;
|
|
586
|
+
const projection = renderSession.projection;
|
|
587
|
+
const offset = renderSession.offset;
|
|
588
|
+
let shader = renderSession.shaderManager.primitiveShader;
|
|
589
|
+
let webGLData;
|
|
590
|
+
if (graphics.dirty) {
|
|
591
|
+
updateGraphics(graphics, gl);
|
|
592
|
+
}
|
|
593
|
+
const webGL = graphics._webGL[gl.id];
|
|
594
|
+
// https://github.com/photonstorm/phaser-ce/pull/179
|
|
595
|
+
if (!webGL) {
|
|
596
|
+
return;
|
|
597
|
+
}
|
|
598
|
+
// This could be speeded up for sure!
|
|
599
|
+
for (let i = 0; i < webGL.data.length; i += 1) {
|
|
600
|
+
if (webGL.data[i].mode === 1) {
|
|
601
|
+
webGLData = webGL.data[i];
|
|
602
|
+
renderSession.stencilManager.pushStencil(graphics, webGLData, renderSession);
|
|
603
|
+
// render quad..
|
|
604
|
+
gl.drawElements(gl.TRIANGLE_FAN, 4, gl.UNSIGNED_SHORT, (webGLData.indices.length - 4) * 2);
|
|
605
|
+
renderSession.stencilManager.popStencil(graphics, webGLData, renderSession);
|
|
606
|
+
} else {
|
|
607
|
+
webGLData = webGL.data[i];
|
|
608
|
+
renderSession.shaderManager.setShader(shader); // activatePrimitiveShader();
|
|
609
|
+
shader = renderSession.shaderManager.primitiveShader;
|
|
610
|
+
gl.uniformMatrix3fv(shader.translationMatrix, false, graphics.worldTransform.toArray(true));
|
|
611
|
+
gl.uniform1f(shader.flipY, 1);
|
|
612
|
+
gl.uniform2f(shader.projectionVector, projection.x, -projection.y);
|
|
613
|
+
gl.uniform2f(shader.offsetVector, -offset.x, -offset.y);
|
|
614
|
+
gl.uniform3fv(shader.tintColor, hex2rgb(graphics.tint));
|
|
615
|
+
gl.uniform1f(shader.alpha, graphics.worldAlpha);
|
|
616
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, webGLData.buffer);
|
|
617
|
+
gl.vertexAttribPointer(shader.aVertexPosition, 2, gl.FLOAT, false, 4 * 6, 0);
|
|
618
|
+
gl.vertexAttribPointer(shader.colorAttribute, 4, gl.FLOAT, false, 4 * 6, 2 * 4);
|
|
619
|
+
// set the index buffer!
|
|
620
|
+
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, webGLData.indexBuffer);
|
|
621
|
+
gl.drawElements(gl.TRIANGLE_STRIP, webGLData.indices.length, gl.UNSIGNED_SHORT, 0);
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @author Andras Csizmadia <andras@vpmedia.hu>
|
|
3
|
+
* @author Richard Davey <rich@photonstorm.com>
|
|
4
|
+
* @author Mat Groves http://matgroves.com/ @Doormat23
|
|
5
|
+
* @copyright Copyright (c) 2018-present Richard Davey, Photon Storm Ltd., Andras Csizmadia <andras@vpmedia.hu> (www.vpmedia.hu)
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export default class {
|
|
9
|
+
|
|
10
|
+
constructor(gl) {
|
|
11
|
+
this.gl = gl;
|
|
12
|
+
// TODO does this need to be split before uploading??
|
|
13
|
+
this.color = [0, 0, 0]; // color split!
|
|
14
|
+
this.points = [];
|
|
15
|
+
this.indices = [];
|
|
16
|
+
this.buffer = gl.createBuffer();
|
|
17
|
+
this.indexBuffer = gl.createBuffer();
|
|
18
|
+
this.mode = 1;
|
|
19
|
+
this.alpha = 1;
|
|
20
|
+
this.dirty = true;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
reset() {
|
|
24
|
+
this.points = [];
|
|
25
|
+
this.indices = [];
|
|
26
|
+
this.glPoints = null;
|
|
27
|
+
this.glIndicies = null;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
upload() {
|
|
31
|
+
const gl = this.gl;
|
|
32
|
+
// this.lastIndex = graphics.graphicsData.length;
|
|
33
|
+
this.glPoints = new Float32Array(this.points);
|
|
34
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);
|
|
35
|
+
gl.bufferData(gl.ARRAY_BUFFER, this.glPoints, gl.STATIC_DRAW);
|
|
36
|
+
this.glIndicies = new Uint16Array(this.indices);
|
|
37
|
+
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
|
|
38
|
+
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.glIndicies, gl.STATIC_DRAW);
|
|
39
|
+
this.dirty = false;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @author Andras Csizmadia <andras@vpmedia.hu>
|
|
3
|
+
* @author Richard Davey <rich@photonstorm.com>
|
|
4
|
+
* @author Mat Groves http://matgroves.com/ @Doormat23
|
|
5
|
+
* @copyright Copyright (c) 2018-present Richard Davey, Photon Storm Ltd., Andras Csizmadia <andras@vpmedia.hu> (www.vpmedia.hu)
|
|
6
|
+
*/
|
|
7
|
+
import { updateGraphics } from './graphics';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
*
|
|
11
|
+
* @param {object} maskData TBD
|
|
12
|
+
* @param {object} renderSession TBD
|
|
13
|
+
*/
|
|
14
|
+
export function pushMask(maskData, renderSession) {
|
|
15
|
+
const gl = renderSession.gl;
|
|
16
|
+
if (maskData.dirty) {
|
|
17
|
+
updateGraphics(maskData, gl);
|
|
18
|
+
}
|
|
19
|
+
if (maskData._webGL[gl.id] === undefined || maskData._webGL[gl.id].data === undefined || maskData._webGL[gl.id].data.length === 0) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
renderSession.stencilManager.pushStencil(maskData, maskData._webGL[gl.id].data[0], renderSession);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
*
|
|
27
|
+
* @param {object} maskData TBD
|
|
28
|
+
* @param {object} renderSession TBD
|
|
29
|
+
*/
|
|
30
|
+
export function popMask(maskData, renderSession) {
|
|
31
|
+
const gl = renderSession.gl;
|
|
32
|
+
if (maskData._webGL[gl.id] === undefined || maskData._webGL[gl.id].data === undefined || maskData._webGL[gl.id].data.length === 0) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
renderSession.stencilManager.popStencil(maskData, maskData._webGL[gl.id].data[0], renderSession);
|
|
36
|
+
}
|