Skip to content

Commit ac9d8ff

Browse files
committed
Fill canvas rendering on WebGL for Graphics GO
1 parent 011014d commit ac9d8ff

9 files changed

Lines changed: 329 additions & 36 deletions

File tree

v3/src/gameobjects/graphics/Commands.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,6 @@ module.exports = {
1010
STROKE_CIRCLE: 8,
1111
STROKE_RECT: 9,
1212
FILL_PATH: 10,
13-
STROKE_PATH: 11
13+
STROKE_PATH: 11,
14+
FILL_STYLE: 12
1415
};

v3/src/gameobjects/graphics/Graphics.js

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ var GameObject = require('../GameObject');
33
var Components = require('../../components');
44
var Render = require('./GraphicsRender');
55
var Commands = require('./Commands');
6+
var PI2 = 2 * Math.PI;
67

78
var Graphics = new Class({
89

@@ -78,32 +79,32 @@ var Graphics = new Class({
7879

7980
fillCircle: function (x, y, radius)
8081
{
81-
this.commandBuffer.push(
82-
Commands.DRAW_CIRCLE,
83-
x, y, radius
84-
);
82+
this.beginPath();
83+
this.arc(x, y, radius, 0, PI2);
84+
this.fillPath();
85+
this.closePath();
8586
},
8687

8788
fillRect: function (x, y, width, height)
8889
{
8990
this.commandBuffer.push(
90-
Commands.DRAW_RECT,
91+
Commands.FILL_RECT,
9192
x, y, width, height
9293
);
9394
},
9495

9596
strokeCircle: function (x, y, radius)
9697
{
97-
this.commandBuffer.push(
98-
Commands.DRAW_CIRCLE,
99-
x, y, radius
100-
);
98+
this.beginPath();
99+
this.arc(x, y, radius, 0, PI2);
100+
this.strokePath();
101+
this.closePath();
101102
},
102103

103104
strokeRect: function (x, y, width, height)
104105
{
105106
this.commandBuffer.push(
106-
Commands.DRAW_RECT,
107+
Commands.STROKE_RECT,
107108
x, y, width, height
108109
);
109110
},

v3/src/gameobjects/graphics/GraphicsCanvasRenderer.js

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -103,19 +103,6 @@ var GraphicsCanvasRenderer = function (renderer, src, interpolationPercentage, c
103103
ctx.lineWidth = lineWidth;
104104
ctx.stroke();
105105
break;
106-
case Commands.FILL_CIRCLE:
107-
ctx.beginPath();
108-
ctx.arc(
109-
commandBuffer[index + 1],
110-
commandBuffer[index + 2],
111-
commandBuffer[index + 3],
112-
0,
113-
PI2
114-
);
115-
ctx.fill();
116-
ctx.closePath();
117-
index += 3;
118-
break;
119106
case Commands.FILL_RECT:
120107
ctx.fillRect(
121108
commandBuffer[index + 1],
Lines changed: 288 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,297 @@
1+
var Commands = require('./Commands');
2+
var Earcut = require('./earcut');
3+
var pathArray = [];
4+
var cos = Math.cos;
5+
var sin = Math.sin;
6+
7+
8+
var Point = function (x, y)
9+
{
10+
this.x = x;
11+
this.y = y;
12+
};
13+
14+
var Path = function (x, y)
15+
{
16+
this.points = [];
17+
this.points.push(new Point(x, y));
18+
};
19+
20+
var lerp = function (norm, min, max)
21+
{
22+
return (max - min) * norm + min;
23+
};
24+
125
var GraphicsWebGLRenderer = function (renderer, src, interpolationPercentage, camera)
226
{
327
if (this.renderMask !== this.renderFlags)
428
{
529
return;
630
}
31+
var shapeBatch = renderer.shapeBatch;
32+
var vertexDataBuffer = shapeBatch.vertexDataBuffer;
33+
var vertexBufferF32 = vertexDataBuffer.floatView;
34+
var vertexBufferU32 = vertexDataBuffer.uintView;
35+
var vertexOffset = 0;
36+
var cameraScrollX = camera.scrollX;
37+
var cameraScrollY = camera.scrollY;
38+
var srcX = src.x;
39+
var srcY = src.y;
40+
var srcScaleX = src.scaleX;
41+
var srcScaleY = src.scaleY;
42+
var srcRotation = src.rotation;
43+
var commandBuffer = src.commandBuffer;
44+
var value;
45+
var lineAlpha = 1.0;
46+
var fillAlpha = 1.0;
47+
var lineColor = 0;
48+
var fillColor = 0;
49+
var lineWidth = 1.0;
50+
var cameraMatrix = camera.matrix.matrix;
51+
var a = cameraMatrix[0];
52+
var b = cameraMatrix[1];
53+
var c = cameraMatrix[2];
54+
var d = cameraMatrix[3];
55+
var e = cameraMatrix[4];
56+
var f = cameraMatrix[5];
57+
var lastPath = null;
58+
var iteration = 0;
59+
var iterStep = 0.01;
60+
var tx = 0;
61+
var ty = 0;
62+
var ta = 0;
63+
var x, y, radius, startAngle, endAngle, anticlockwise;
64+
var width, height, txw, tyh;
65+
var vertexCount = shapeBatch.vertexCount;
66+
var polygon = [];
67+
var x0, y0, x1, y1, x2, y2;
68+
var tx0, ty0, tx1, ty1, tx2, ty2;
69+
var v0, v1, v2;
70+
var polygonIndex;
71+
var path;
72+
var pathLength;
73+
var point;
74+
75+
renderer.setBatch(shapeBatch, null);
76+
77+
for (var cmdIndex = 0, cmdLength = commandBuffer.length; cmdIndex < cmdLength; ++cmdIndex)
78+
{
79+
var cmd = commandBuffer[cmdIndex];
80+
81+
switch(cmd)
82+
{
83+
case Commands.ARC:
84+
x = commandBuffer[cmdIndex + 1];
85+
y = commandBuffer[cmdIndex + 2];
86+
radius = commandBuffer[cmdIndex + 3];
87+
startAngle = commandBuffer[cmdIndex + 4];
88+
endAngle = commandBuffer[cmdIndex + 5];
89+
anticlockwise = commandBuffer[cmdIndex + 6];
90+
91+
while (iteration < 1) {
92+
ta = lerp(iteration, startAngle, endAngle);
93+
tx = x + cos(ta) * radius;
94+
ty = y + sin(ta) * radius;
95+
if (iteration === 0) {
96+
lastPath = new Path(tx, ty);
97+
pathArray.push(lastPath);
98+
} else {
99+
lastPath.points.push(new Point(tx, ty));
100+
}
101+
iteration += iterStep;
102+
}
103+
104+
cmdIndex += 6;
105+
break;
106+
case Commands.LINE_STYLE:
107+
lineWidth = commandBuffer[cmdIndex + 1];
108+
lineColor = commandBuffer[cmdIndex + 2]
109+
lineAlpha = commandBuffer[cmdIndex + 3];
110+
cmdIndex += 3;
111+
break;
112+
case Commands.FILL_STYLE:
113+
fillColor = commandBuffer[cmdIndex + 1];
114+
fillAlpha = commandBuffer[cmdIndex + 2];
115+
cmdIndex += 2;
116+
break;
117+
case Commands.BEGIN_PATH:
118+
pathArray.length = 0;
119+
break;
120+
case Commands.CLOSE_PATH:
121+
if (lastPath !== null && lastPath.points.length > 0) {
122+
var firstPoint = lastPath.points[0];
123+
var lastPoint = lastPath.points[lastPath.points.length - 1];
124+
lastPath.points.push(firstPoint);
125+
lastPath = new Path(x, y);
126+
pathArray.push(lastPath);
127+
}
128+
break;
129+
case Commands.FILL_PATH:
130+
for (var pathArrayIndex = 0, pathArrayLength = pathArray.length; pathArrayIndex < pathArrayLength; ++pathArrayIndex)
131+
{
132+
path = pathArray[pathArrayIndex].points;
133+
pathLength = path.length;
134+
for (var pathIndex = 0; pathIndex < pathLength; ++pathIndex)
135+
{
136+
point = path[pathIndex];
137+
polygon.push(point.x, point.y);
138+
}
139+
polygonIndex = Earcut(polygon);
140+
for (var index = 0, length = polygonIndex.length; index < length; index += 3)
141+
{
142+
v0 = polygonIndex[index + 0] * 2;
143+
v1 = polygonIndex[index + 1] * 2;
144+
v2 = polygonIndex[index + 2] * 2;
145+
vertexOffset = vertexDataBuffer.allocate(9 * 3);
146+
vertexCount += 3;
147+
148+
x0 = polygon[v0 + 0] - cameraScrollX;
149+
y0 = polygon[v0 + 1] - cameraScrollY;
150+
x1 = polygon[v1 + 0] - cameraScrollX;
151+
y1 = polygon[v1 + 1] - cameraScrollY;
152+
x2 = polygon[v2 + 0] - cameraScrollX;
153+
y2 = polygon[v2 + 1] - cameraScrollY;
154+
155+
tx0 = x0 * a + y0 * c + e;
156+
ty0 = x0 * b + y0 * d + f;
157+
tx1 = x1 * a + y1 * c + e;
158+
ty1 = x1 * b + y1 * d + f;
159+
tx2 = x2 * a + y2 * c + e;
160+
ty2 = x2 * b + y2 * d + f;
161+
162+
vertexBufferF32[vertexOffset++] = tx0;
163+
vertexBufferF32[vertexOffset++] = ty0;
164+
vertexBufferU32[vertexOffset++] = fillColor;
165+
vertexBufferF32[vertexOffset++] = fillAlpha;
166+
vertexBufferF32[vertexOffset++] = srcX;
167+
vertexBufferF32[vertexOffset++] = srcY;
168+
vertexBufferF32[vertexOffset++] = srcScaleX;
169+
vertexBufferF32[vertexOffset++] = srcScaleY;
170+
vertexBufferF32[vertexOffset++] = srcRotation;
171+
172+
vertexBufferF32[vertexOffset++] = tx1;
173+
vertexBufferF32[vertexOffset++] = ty1;
174+
vertexBufferU32[vertexOffset++] = fillColor;
175+
vertexBufferF32[vertexOffset++] = fillAlpha;
176+
vertexBufferF32[vertexOffset++] = srcX;
177+
vertexBufferF32[vertexOffset++] = srcY;
178+
vertexBufferF32[vertexOffset++] = srcScaleX;
179+
vertexBufferF32[vertexOffset++] = srcScaleY;
180+
vertexBufferF32[vertexOffset++] = srcRotation;
181+
182+
vertexBufferF32[vertexOffset++] = tx2;
183+
vertexBufferF32[vertexOffset++] = ty2;
184+
vertexBufferU32[vertexOffset++] = fillColor;
185+
vertexBufferF32[vertexOffset++] = fillAlpha;
186+
vertexBufferF32[vertexOffset++] = srcX;
187+
vertexBufferF32[vertexOffset++] = srcY;
188+
vertexBufferF32[vertexOffset++] = srcScaleX;
189+
vertexBufferF32[vertexOffset++] = srcScaleY;
190+
vertexBufferF32[vertexOffset++] = srcRotation;
191+
192+
}
193+
polygon.length = 0;
194+
}
195+
break;
196+
case Commands.STROKE_PATH:
197+
break;
198+
case Commands.FILL_RECT:
199+
vertexOffset = vertexDataBuffer.allocate(9 * 6);
200+
vertexCount += 6;
201+
202+
x = commandBuffer[cmdIndex + 1] - cameraScrollX;
203+
y = commandBuffer[cmdIndex + 2] - cameraScrollY;
204+
xw = x + commandBuffer[cmdIndex + 3];
205+
yh = y + commandBuffer[cmdIndex + 4];
206+
tx = x * a + y * c + e;
207+
ty = x * b + y * d + f;
208+
txw = xw * a + yh * c + e;
209+
tyh = xw * b + yh * d + f;
210+
211+
vertexBufferF32[vertexOffset++] = tx;
212+
vertexBufferF32[vertexOffset++] = ty;
213+
vertexBufferU32[vertexOffset++] = fillColor;
214+
vertexBufferF32[vertexOffset++] = fillAlpha;
215+
vertexBufferF32[vertexOffset++] = srcX;
216+
vertexBufferF32[vertexOffset++] = srcY;
217+
vertexBufferF32[vertexOffset++] = srcScaleX;
218+
vertexBufferF32[vertexOffset++] = srcScaleY;
219+
vertexBufferF32[vertexOffset++] = srcRotation;
220+
vertexBufferF32[vertexOffset++] = tx;
221+
vertexBufferF32[vertexOffset++] = tyh;
222+
vertexBufferU32[vertexOffset++] = fillColor;
223+
vertexBufferF32[vertexOffset++] = fillAlpha;
224+
vertexBufferF32[vertexOffset++] = srcX;
225+
vertexBufferF32[vertexOffset++] = srcY;
226+
vertexBufferF32[vertexOffset++] = srcScaleX;
227+
vertexBufferF32[vertexOffset++] = srcScaleY;
228+
vertexBufferF32[vertexOffset++] = srcRotation;
229+
vertexBufferF32[vertexOffset++] = txw;
230+
vertexBufferF32[vertexOffset++] = tyh;
231+
vertexBufferU32[vertexOffset++] = fillColor;
232+
vertexBufferF32[vertexOffset++] = fillAlpha;
233+
vertexBufferF32[vertexOffset++] = srcX;
234+
vertexBufferF32[vertexOffset++] = srcY;
235+
vertexBufferF32[vertexOffset++] = srcScaleX;
236+
vertexBufferF32[vertexOffset++] = srcScaleY;
237+
vertexBufferF32[vertexOffset++] = srcRotation;
238+
vertexBufferF32[vertexOffset++] = tx;
239+
vertexBufferF32[vertexOffset++] = ty;
240+
vertexBufferU32[vertexOffset++] = fillColor;
241+
vertexBufferF32[vertexOffset++] = fillAlpha;
242+
vertexBufferF32[vertexOffset++] = srcX;
243+
vertexBufferF32[vertexOffset++] = srcY;
244+
vertexBufferF32[vertexOffset++] = srcScaleX;
245+
vertexBufferF32[vertexOffset++] = srcScaleY;
246+
vertexBufferF32[vertexOffset++] = srcRotation;
247+
vertexBufferF32[vertexOffset++] = txw;
248+
vertexBufferF32[vertexOffset++] = tyh;
249+
vertexBufferU32[vertexOffset++] = fillColor;
250+
vertexBufferF32[vertexOffset++] = fillAlpha;
251+
vertexBufferF32[vertexOffset++] = srcX;
252+
vertexBufferF32[vertexOffset++] = srcY;
253+
vertexBufferF32[vertexOffset++] = srcScaleX;
254+
vertexBufferF32[vertexOffset++] = srcScaleY;
255+
vertexBufferF32[vertexOffset++] = srcRotation;
256+
vertexBufferF32[vertexOffset++] = txw;
257+
vertexBufferF32[vertexOffset++] = ty;
258+
vertexBufferU32[vertexOffset++] = fillColor;
259+
vertexBufferF32[vertexOffset++] = fillAlpha;
260+
vertexBufferF32[vertexOffset++] = srcX;
261+
vertexBufferF32[vertexOffset++] = srcY;
262+
vertexBufferF32[vertexOffset++] = srcScaleX;
263+
vertexBufferF32[vertexOffset++] = srcScaleY;
264+
vertexBufferF32[vertexOffset++] = srcRotation;
265+
266+
cmdIndex += 4;
267+
break;
268+
case Commands.STROKE_CIRCLE:
269+
cmdIndex += 3;
270+
break;
271+
case Commands.STROKE_RECT:
272+
cmdIndex += 4;
273+
break;
274+
case Commands.LINE_TO:
275+
if (lastPath !== null) {
276+
lastPath.points.push(new Point(commandBuffer[cmdIndex + 1], commandBuffer[cmdIndex + 2]));
277+
} else {
278+
lastPath = new Path(commandBuffer[cmdIndex + 1], commandBuffer[cmdIndex + 2]);
279+
pathArray.push(lastPath);
280+
}
281+
cmdIndex += 2;
282+
break;
283+
case Commands.MOVE_TO:
284+
lastPath = new Path(commandBuffer[cmdIndex + 1], commandBuffer[cmdIndex + 2]);
285+
pathArray.push(lastPath);
286+
cmdIndex += 2;
287+
break;
288+
default:
289+
console.error('Phaser: Invalid Graphics Command ID ' + cmd);
290+
break;
291+
}
292+
}
293+
shapeBatch.vertexCount = vertexCount;
294+
pathArray.length = 0;
7295
}
8296

9297
module.exports = GraphicsWebGLRenderer;

0 commit comments

Comments
 (0)