Added stroke rendering to all shapes

This commit is contained in:
Richard Davey 2018-09-06 15:49:42 +01:00
parent a508cd2195
commit fb5bf5d9c1
11 changed files with 260 additions and 129 deletions

View file

@ -67,6 +67,7 @@ var Shape = new Class({
this.data = data;
// Holds earcut polygon fill data
this.pathData = [];
this.pathIndexes = [];

View file

@ -35,16 +35,16 @@ var Arc = new Class({
initialize:
function Arc (scene, x, y, radius, fillColor, fillAlpha, startAngle, endAngle, anticlockwise)
function Arc (scene, x, y, radius, startAngle, endAngle, anticlockwise, fillColor, fillAlpha)
{
if (x === undefined) { x = 0; }
if (y === undefined) { y = 0; }
if (radius === undefined) { radius = 128; }
if (startAngle === undefined) { startAngle = 0; }
if (endAngle === undefined) { endAngle = 360; }
if (anticlockwise === undefined) { anticlockwise = false; }
Shape.call(this, scene, 'Arc', new GeomCircle(x, y, radius));
this.pathData = [];
this.pathIndexes = [];
Shape.call(this, scene, 'Arc', new GeomCircle(0, 0, radius));
this.startAngle = DegToRad(startAngle);
this.endAngle = DegToRad(endAngle);
@ -54,13 +54,12 @@ var Arc = new Class({
this.setPosition(x, y);
this.setSize(this.data.radius, this.data.radius);
this.updateDisplayOrigin();
if (fillColor !== undefined)
{
this.setFillStyle(fillColor, fillAlpha);
}
this.updateDisplayOrigin();
this.updateData();
},
@ -102,14 +101,14 @@ var Arc = new Class({
var step = this.iterations;
var iteration = step;
var x = 0;
var y = 0;
var radius = this.data.radius;
var startAngle = this.startAngle;
var endAngle = this.endAngle;
var anticlockwise = this.anticlockwise;
var x = radius / 2;
var y = radius / 2;
endAngle -= startAngle;
if (anticlockwise)
@ -140,16 +139,16 @@ var Arc = new Class({
{
ta = endAngle * iteration + startAngle;
path.push(x + Math.cos(ta) * radius);
path.push(y + Math.sin(ta) * radius);
path.push(x + Math.cos(ta) * radius, y + Math.sin(ta) * radius);
iteration += step;
}
ta = endAngle + startAngle;
path.push(x + Math.cos(ta) * radius);
path.push(y + Math.sin(ta) * radius);
path.push(x + Math.cos(ta) * radius, y + Math.sin(ta) * radius);
path.push(x + Math.cos(startAngle) * radius, y + Math.sin(startAngle) * radius);
this.pathIndexes = Earcut(path);
this.pathData = path;

View file

@ -18,17 +18,17 @@ var GameObjectFactory = require('../../GameObjectFactory');
* @param {number} [x=0] - The horizontal position of this Game Object in the world.
* @param {number} [y=0] - The vertical position of this Game Object in the world.
* @param {number} [radius=128] - The radius of the arc.
* @param {number} [fillColor=0xffffff] - The color the arc will be filled with, i.e. 0xff0000 for red.
* @param {number} [fillAlpha=1] - The alpha the arc will be filled with. You can also set the alpha of the overall Shape using its `alpha` property.
* @param {number} [startAngle=0] - The start angle of the arc, in degrees.
* @param {number} [endAngle=360] - The end angle of the arc, in degrees.
* @param {boolean} [anticlockwise=false] - The winding order of the start and end angles.
* @param {number} [fillColor] - The color the arc will be filled with, i.e. 0xff0000 for red.
* @param {number} [fillAlpha] - The alpha the arc will be filled with. You can also set the alpha of the overall Shape using its `alpha` property.
*
* @return {Phaser.GameObjects.Arc} The Game Object that was created.
*/
GameObjectFactory.register('arc', function (x, y, radius, fillColor, fillAlpha, startAngle, endAngle, anticlockwise)
GameObjectFactory.register('arc', function (x, y, radius, startAngle, endAngle, anticlockwise, fillColor, fillAlpha)
{
return this.displayList.add(new Arc(this.scene, x, y, radius, fillColor, fillAlpha, startAngle, endAngle, anticlockwise));
return this.displayList.add(new Arc(this.scene, x, y, radius, startAngle, endAngle, anticlockwise, fillColor, fillAlpha));
});
/**
@ -51,5 +51,5 @@ GameObjectFactory.register('arc', function (x, y, radius, fillColor, fillAlpha,
*/
GameObjectFactory.register('circle', function (x, y, radius, fillColor, fillAlpha)
{
return this.displayList.add(new Arc(this.scene, x, y, radius, fillColor, fillAlpha));
return this.displayList.add(new Arc(this.scene, x, y, radius, 0, 360, false, fillColor, fillAlpha));
});

View file

@ -43,47 +43,91 @@ var ArcWebGLRenderer = function (renderer, src, interpolationPercentage, camera,
// Undo the camera scroll
shapeMatrix.e = src.x;
shapeMatrix.f = src.y;
// Multiply by the Sprite matrix, store result in calcMatrix
camMatrix.multiply(shapeMatrix, calcMatrix);
}
else
{
shapeMatrix.e -= camera.scrollX * src.scrollFactorX;
shapeMatrix.f -= camera.scrollY * src.scrollFactorY;
// Multiply by the Sprite matrix, store result in calcMatrix
camMatrix.multiply(shapeMatrix, calcMatrix);
}
var fillTintColor = Utils.getTintAppendFloatAlphaAndSwap(src.fillColor, src.fillAlpha * (camera.alpha * src.alpha));
camMatrix.multiply(shapeMatrix, calcMatrix);
var pathData = src.pathData;
var pathIndexes = src.pathIndexes;
var i;
var dx = src._displayOriginX;
var dy = src._displayOriginY;
var alpha = camera.alpha * src.alpha;
for (var i = 0; i < pathIndexes.length; i += 3)
var path = src.pathData;
if (src.isFilled)
{
var p0 = pathIndexes[i] * 2;
var p1 = pathIndexes[i + 1] * 2;
var p2 = pathIndexes[i + 2] * 2;
var fillTintColor = Utils.getTintAppendFloatAlphaAndSwap(src.fillColor, src.fillAlpha * alpha);
var x0 = pathData[p0 + 0];
var y0 = pathData[p0 + 1];
var x1 = pathData[p1 + 0];
var y1 = pathData[p1 + 1];
var x2 = pathData[p2 + 0];
var y2 = pathData[p2 + 1];
var tx0 = calcMatrix.getX(x0, y0);
var ty0 = calcMatrix.getY(x0, y0);
var tx1 = calcMatrix.getX(x1, y1);
var ty1 = calcMatrix.getY(x1, y1);
var tx2 = calcMatrix.getX(x2, y2);
var ty2 = calcMatrix.getY(x2, y2);
var pathIndexes = src.pathIndexes;
pipeline.batchTri(tx0, ty0, tx1, ty1, tx2, ty2, 0, 0, 1, 1, fillTintColor, fillTintColor, fillTintColor, pipeline.tintEffect);
for (i = 0; i < pathIndexes.length; i += 3)
{
var p0 = pathIndexes[i] * 2;
var p1 = pathIndexes[i + 1] * 2;
var p2 = pathIndexes[i + 2] * 2;
var x0 = path[p0 + 0] - dx;
var y0 = path[p0 + 1] - dy;
var x1 = path[p1 + 0] - dx;
var y1 = path[p1 + 1] - dy;
var x2 = path[p2 + 0] - dx;
var y2 = path[p2 + 1] - dy;
var tx0 = calcMatrix.getX(x0, y0);
var ty0 = calcMatrix.getY(x0, y0);
var tx1 = calcMatrix.getX(x1, y1);
var ty1 = calcMatrix.getY(x1, y1);
var tx2 = calcMatrix.getX(x2, y2);
var ty2 = calcMatrix.getY(x2, y2);
pipeline.batchTri(tx0, ty0, tx1, ty1, tx2, ty2, 0, 0, 1, 1, fillTintColor, fillTintColor, fillTintColor, pipeline.tintEffect);
}
}
if (src.isStroked)
{
var strokeTint = pipeline.strokeTint;
var strokeTintColor = Utils.getTintAppendFloatAlphaAndSwap(src.strokeColor, src.strokeAlpha * alpha);
strokeTint.TL = strokeTintColor;
strokeTint.TR = strokeTintColor;
strokeTint.BL = strokeTintColor;
strokeTint.BR = strokeTintColor;
var pathLength = path.length - 1;
var lineWidth = src.lineWidth;
var halfLineWidth = lineWidth / 2;
var px1 = path[0] - dx;
var py1 = path[1] - dy;
for (i = 2; i < pathLength; i += 2)
{
var px2 = path[i] - dx;
var py2 = path[i + 1] - dy;
pipeline.batchLine(
px1,
py1,
px2,
py2,
halfLineWidth,
halfLineWidth,
lineWidth,
i - 2,
(i === pathLength - 1)
);
px1 = px2;
py1 = py2;
}
}
};

View file

@ -33,27 +33,27 @@ var Ellipse = new Class({
initialize:
function Ellipse (scene, x, y, width, height, fillColor, fillAlpha, smoothness)
function Ellipse (scene, x, y, width, height, fillColor, fillAlpha)
{
if (smoothness === undefined) { smoothness = 32; }
if (x === undefined) { x = 0; }
if (y === undefined) { y = 0; }
if (width === undefined) { width = 128; }
if (height === undefined) { height = 128; }
Shape.call(this, scene, 'Ellipse', new GeomEllipse(0, 0, width, height));
Shape.call(this, scene, 'Ellipse', new GeomEllipse(width / 2, height / 2, width, height));
this.pathData = [];
this.pathIndexes = [];
this.smoothness = smoothness;
// The number of points used to draw the ellipse. Higher values create smoother renders at the cost of more triangles being drawn.
this.smoothness = 64;
this.setPosition(x, y);
this.setSize(width, height);
this.updateDisplayOrigin();
if (fillColor !== undefined)
{
this.setFillStyle(fillColor, fillAlpha);
}
this.updateDisplayOrigin();
this.updateData();
},

View file

@ -19,13 +19,12 @@ var GameObjectFactory = require('../../GameObjectFactory');
* @param {number} [y=0] - The vertical position of this Game Object in the world.
* @param {number} [width=128] - The width of the ellipse. An ellipse with equal width and height renders as a circle.
* @param {number} [height=128] - The height of the ellipse. An ellipse with equal width and height renders as a circle.
* @param {number} [fillColor=0xffffff] - The color the ellipse will be filled with, i.e. 0xff0000 for red.
* @param {number} [fillAlpha=1] - The alpha the ellipse will be filled with. You can also set the alpha of the overall Shape using its `alpha` property.
* @param {number} [smoothness=32] - The number of points used to draw the ellipse. Higher values create smoother renders at the cost of more triangles being drawn.
* @param {number} [fillColor] - The color the ellipse will be filled with, i.e. 0xff0000 for red.
* @param {number} [fillAlpha] - The alpha the ellipse will be filled with. You can also set the alpha of the overall Shape using its `alpha` property.
*
* @return {Phaser.GameObjects.Ellipse} The Game Object that was created.
*/
GameObjectFactory.register('ellipse', function (x, y, width, height, fillColor, fillAlpha, smoothness)
GameObjectFactory.register('ellipse', function (x, y, width, height, fillColor, fillAlpha)
{
return this.displayList.add(new Ellipse(this.scene, x, y, width, height, fillColor, fillAlpha, smoothness));
return this.displayList.add(new Ellipse(this.scene, x, y, width, height, fillColor, fillAlpha));
});

View file

@ -43,47 +43,91 @@ var EllipseWebGLRenderer = function (renderer, src, interpolationPercentage, cam
// Undo the camera scroll
shapeMatrix.e = src.x;
shapeMatrix.f = src.y;
// Multiply by the Sprite matrix, store result in calcMatrix
camMatrix.multiply(shapeMatrix, calcMatrix);
}
else
{
shapeMatrix.e -= camera.scrollX * src.scrollFactorX;
shapeMatrix.f -= camera.scrollY * src.scrollFactorY;
// Multiply by the Sprite matrix, store result in calcMatrix
camMatrix.multiply(shapeMatrix, calcMatrix);
}
var fillTintColor = Utils.getTintAppendFloatAlphaAndSwap(src.fillColor, src.fillAlpha * (camera.alpha * src.alpha));
camMatrix.multiply(shapeMatrix, calcMatrix);
var pathData = src.pathData;
var pathIndexes = src.pathIndexes;
var i;
var dx = src._displayOriginX;
var dy = src._displayOriginY;
var alpha = camera.alpha * src.alpha;
for (var i = 0; i < pathIndexes.length; i += 3)
var path = src.pathData;
if (src.isFilled)
{
var p0 = pathIndexes[i] * 2;
var p1 = pathIndexes[i + 1] * 2;
var p2 = pathIndexes[i + 2] * 2;
var fillTintColor = Utils.getTintAppendFloatAlphaAndSwap(src.fillColor, src.fillAlpha * alpha);
var x0 = pathData[p0 + 0];
var y0 = pathData[p0 + 1];
var x1 = pathData[p1 + 0];
var y1 = pathData[p1 + 1];
var x2 = pathData[p2 + 0];
var y2 = pathData[p2 + 1];
var tx0 = calcMatrix.getX(x0, y0);
var ty0 = calcMatrix.getY(x0, y0);
var tx1 = calcMatrix.getX(x1, y1);
var ty1 = calcMatrix.getY(x1, y1);
var tx2 = calcMatrix.getX(x2, y2);
var ty2 = calcMatrix.getY(x2, y2);
var pathIndexes = src.pathIndexes;
pipeline.batchTri(tx0, ty0, tx1, ty1, tx2, ty2, 0, 0, 1, 1, fillTintColor, fillTintColor, fillTintColor, pipeline.tintEffect);
for (i = 0; i < pathIndexes.length; i += 3)
{
var p0 = pathIndexes[i] * 2;
var p1 = pathIndexes[i + 1] * 2;
var p2 = pathIndexes[i + 2] * 2;
var x0 = path[p0 + 0] - dx;
var y0 = path[p0 + 1] - dy;
var x1 = path[p1 + 0] - dx;
var y1 = path[p1 + 1] - dy;
var x2 = path[p2 + 0] - dx;
var y2 = path[p2 + 1] - dy;
var tx0 = calcMatrix.getX(x0, y0);
var ty0 = calcMatrix.getY(x0, y0);
var tx1 = calcMatrix.getX(x1, y1);
var ty1 = calcMatrix.getY(x1, y1);
var tx2 = calcMatrix.getX(x2, y2);
var ty2 = calcMatrix.getY(x2, y2);
pipeline.batchTri(tx0, ty0, tx1, ty1, tx2, ty2, 0, 0, 1, 1, fillTintColor, fillTintColor, fillTintColor, pipeline.tintEffect);
}
}
if (src.isStroked)
{
var strokeTint = pipeline.strokeTint;
var strokeTintColor = Utils.getTintAppendFloatAlphaAndSwap(src.strokeColor, src.strokeAlpha * alpha);
strokeTint.TL = strokeTintColor;
strokeTint.TR = strokeTintColor;
strokeTint.BL = strokeTintColor;
strokeTint.BR = strokeTintColor;
var pathLength = path.length - 1;
var lineWidth = src.lineWidth;
var halfLineWidth = lineWidth / 2;
var px1 = path[0] - dx;
var py1 = path[1] - dy;
for (i = 2; i < pathLength; i += 2)
{
var px2 = path[i] - dx;
var py2 = path[i + 1] - dy;
pipeline.batchLine(
px1,
py1,
px2,
py2,
halfLineWidth,
halfLineWidth,
lineWidth,
i - 2,
(i === pathLength - 1)
);
px1 = px2;
py1 = py2;
}
}
};

View file

@ -37,24 +37,22 @@ var Polygon = new Class({
function Polygon (scene, x, y, points, fillColor, fillAlpha)
{
if (x === undefined) { x = 0; }
if (y === undefined) { y = 0; }
Shape.call(this, scene, 'Polygon', new GeomPolygon(points));
this.pathData = [];
this.pathIndexes = [];
this.setPosition(x, y);
var bounds = GetAABB(this.data);
this.setPosition(x, y);
this.setSize(bounds.width, bounds.height);
this.updateDisplayOrigin();
if (fillColor !== undefined)
{
this.setFillStyle(fillColor, fillAlpha);
}
this.updateDisplayOrigin();
this.updateData();
},
@ -80,6 +78,8 @@ var Polygon = new Class({
path.push(points[i].x, points[i].y);
}
path.push(points[0].x, points[0].y);
this.pathIndexes = Earcut(path);
this.pathData = path;

View file

@ -43,47 +43,91 @@ var PolygonWebGLRenderer = function (renderer, src, interpolationPercentage, cam
// Undo the camera scroll
shapeMatrix.e = src.x;
shapeMatrix.f = src.y;
// Multiply by the Sprite matrix, store result in calcMatrix
camMatrix.multiply(shapeMatrix, calcMatrix);
}
else
{
shapeMatrix.e -= camera.scrollX * src.scrollFactorX;
shapeMatrix.f -= camera.scrollY * src.scrollFactorY;
// Multiply by the Sprite matrix, store result in calcMatrix
camMatrix.multiply(shapeMatrix, calcMatrix);
}
var fillTintColor = Utils.getTintAppendFloatAlphaAndSwap(src.fillColor, src.fillAlpha * (camera.alpha * src.alpha));
camMatrix.multiply(shapeMatrix, calcMatrix);
var pathData = src.pathData;
var pathIndexes = src.pathIndexes;
var i;
var dx = src._displayOriginX;
var dy = src._displayOriginY;
var alpha = camera.alpha * src.alpha;
for (var i = 0; i < pathIndexes.length; i += 3)
var path = src.pathData;
if (src.isFilled)
{
var p0 = pathIndexes[i] * 2;
var p1 = pathIndexes[i + 1] * 2;
var p2 = pathIndexes[i + 2] * 2;
var fillTintColor = Utils.getTintAppendFloatAlphaAndSwap(src.fillColor, src.fillAlpha * alpha);
var x0 = pathData[p0 + 0];
var y0 = pathData[p0 + 1];
var x1 = pathData[p1 + 0];
var y1 = pathData[p1 + 1];
var x2 = pathData[p2 + 0];
var y2 = pathData[p2 + 1];
var tx0 = calcMatrix.getX(x0, y0);
var ty0 = calcMatrix.getY(x0, y0);
var tx1 = calcMatrix.getX(x1, y1);
var ty1 = calcMatrix.getY(x1, y1);
var tx2 = calcMatrix.getX(x2, y2);
var ty2 = calcMatrix.getY(x2, y2);
var pathIndexes = src.pathIndexes;
pipeline.batchTri(tx0, ty0, tx1, ty1, tx2, ty2, 0, 0, 1, 1, fillTintColor, fillTintColor, fillTintColor, pipeline.tintEffect);
for (i = 0; i < pathIndexes.length; i += 3)
{
var p0 = pathIndexes[i] * 2;
var p1 = pathIndexes[i + 1] * 2;
var p2 = pathIndexes[i + 2] * 2;
var x0 = path[p0 + 0] - dx;
var y0 = path[p0 + 1] - dy;
var x1 = path[p1 + 0] - dx;
var y1 = path[p1 + 1] - dy;
var x2 = path[p2 + 0] - dx;
var y2 = path[p2 + 1] - dy;
var tx0 = calcMatrix.getX(x0, y0);
var ty0 = calcMatrix.getY(x0, y0);
var tx1 = calcMatrix.getX(x1, y1);
var ty1 = calcMatrix.getY(x1, y1);
var tx2 = calcMatrix.getX(x2, y2);
var ty2 = calcMatrix.getY(x2, y2);
pipeline.batchTri(tx0, ty0, tx1, ty1, tx2, ty2, 0, 0, 1, 1, fillTintColor, fillTintColor, fillTintColor, pipeline.tintEffect);
}
}
if (src.isStroked)
{
var strokeTint = pipeline.strokeTint;
var strokeTintColor = Utils.getTintAppendFloatAlphaAndSwap(src.strokeColor, src.strokeAlpha * alpha);
strokeTint.TL = strokeTintColor;
strokeTint.TR = strokeTintColor;
strokeTint.BL = strokeTintColor;
strokeTint.BR = strokeTintColor;
var pathLength = path.length - 1;
var lineWidth = src.lineWidth;
var halfLineWidth = lineWidth / 2;
var px1 = path[0] - dx;
var py1 = path[1] - dy;
for (i = 2; i < pathLength; i += 2)
{
var px2 = path[i] - dx;
var py2 = path[i + 1] - dy;
pipeline.batchLine(
px1,
py1,
px2,
py2,
halfLineWidth,
halfLineWidth,
lineWidth,
i - 2,
(i === pathLength - 1)
);
px1 = px2;
py1 = py2;
}
}
};

View file

@ -75,7 +75,7 @@ var Rectangle = new Class({
path.push(line.x2, line.y2);
this.pathData = path;
this.lineData = path;
return this;
}

View file

@ -78,7 +78,7 @@ var Triangle = new Class({
path.push(line.x2, line.y2);
this.pathData = path;
this.lineData = path;
return this;
}