@vpmedia/phaser 1.0.1 → 1.0.2

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