From 400b18b5ce2ba4f3567a4b85cc6391de4db12859 Mon Sep 17 00:00:00 2001 From: Felipe Alfonso Date: Tue, 14 Mar 2017 19:13:31 -0300 Subject: [PATCH] Fixed bug on ShapeBatch with corner wrapping to the first element. Also added lineWidthTo and moveWidthTo allowing easy creation of trails --- v3/src/gameobjects/graphics/Commands.js | 4 +- v3/src/gameobjects/graphics/Graphics.js | 16 ++ .../graphics/GraphicsCanvasRenderer.js | 16 ++ .../graphics/GraphicsWebGLRenderer.js | 39 +++- .../webgl/batches/shape/ShapeBatch.js | 209 +++++++----------- 5 files changed, 141 insertions(+), 143 deletions(-) diff --git a/v3/src/gameobjects/graphics/Commands.js b/v3/src/gameobjects/graphics/Commands.js index 4197a0774..b181588d6 100644 --- a/v3/src/gameobjects/graphics/Commands.js +++ b/v3/src/gameobjects/graphics/Commands.js @@ -10,5 +10,7 @@ module.exports = { FILL_PATH: 8, STROKE_PATH: 9, FILL_TRIANGLE: 10, - STROKE_TRIANGLE: 11 + STROKE_TRIANGLE: 11, + LINE_WIDTH_TO: 12, + MOVE_WIDTH_TO: 13 }; diff --git a/v3/src/gameobjects/graphics/Graphics.js b/v3/src/gameobjects/graphics/Graphics.js index c01554004..c7c8da400 100644 --- a/v3/src/gameobjects/graphics/Graphics.js +++ b/v3/src/gameobjects/graphics/Graphics.js @@ -148,6 +148,22 @@ var Graphics = new Class({ ); }, + lineWidthTo: function (x, y, width) + { + this.commandBuffer.push( + Commands.LINE_WIDTH_TO, + x, y, width + ); + }, + + moveWidthTo: function (x, y, width) + { + this.commandBuffer.push( + Commands.MOVE_WIDTH_TO, + x, y, width + ); + }, + clear: function () { this.commandBuffer.length = 0; diff --git a/v3/src/gameobjects/graphics/GraphicsCanvasRenderer.js b/v3/src/gameobjects/graphics/GraphicsCanvasRenderer.js index c85e11eb0..e923007b6 100644 --- a/v3/src/gameobjects/graphics/GraphicsCanvasRenderer.js +++ b/v3/src/gameobjects/graphics/GraphicsCanvasRenderer.js @@ -158,6 +158,22 @@ var GraphicsCanvasRenderer = function (renderer, src, interpolationPercentage, c index += 2; break; + case Commands.LINE_WIDTH_TO: + ctx.lineTo( + commandBuffer[index + 1], + commandBuffer[index + 2] + ); + index += 3; + break; + + case Commands.MOVE_WIDTH_TO: + ctx.moveTo( + commandBuffer[index + 1], + commandBuffer[index + 2] + ); + index += 3; + break; + default: console.error('Phaser: Invalid Graphics Command ID ' + commandID); break; diff --git a/v3/src/gameobjects/graphics/GraphicsWebGLRenderer.js b/v3/src/gameobjects/graphics/GraphicsWebGLRenderer.js index 4109232f9..448e51a53 100644 --- a/v3/src/gameobjects/graphics/GraphicsWebGLRenderer.js +++ b/v3/src/gameobjects/graphics/GraphicsWebGLRenderer.js @@ -6,17 +6,18 @@ var sin = Math.sin; var sqrt = Math.sqrt; var tempMatrix = new TransformMatrix(); -var Point = function (x, y) +var Point = function (x, y, width) { this.x = x; this.y = y; + this.width = width; }; -var Path = function (x, y) +var Path = function (x, y, width) { this.points = []; this.pointsLength = 1; - this.points[0] = new Point(x, y); + this.points[0] = new Point(x, y, width); }; var GraphicsWebGLRenderer = function (renderer, src, interpolationPercentage, camera) @@ -116,12 +117,12 @@ var GraphicsWebGLRenderer = function (renderer, src, interpolationPercentage, ca if (iteration === 0) { - lastPath = new Path(tx, ty); + lastPath = new Path(tx, ty, lineWidth); pathArray.push(lastPath); } else { - lastPath.points.push(new Point(tx, ty)); + lastPath.points.push(new Point(tx, ty, lineWidth)); } iteration += iterStep; @@ -150,8 +151,9 @@ var GraphicsWebGLRenderer = function (renderer, src, interpolationPercentage, ca if (lastPath !== null && lastPath.points.length > 0) { var firstPoint = lastPath.points[0]; + var lastPoint = lastPath.points[lastPath.points.length - 1]; lastPath.points.push(firstPoint); - lastPath = new Path(x, y); + lastPath = new Path(lastPoint.x, lastPoint.y, lineWidth); pathArray.push(lastPath); } break; @@ -257,22 +259,41 @@ var GraphicsWebGLRenderer = function (renderer, src, interpolationPercentage, ca case Commands.LINE_TO: if (lastPath !== null) { - lastPath.points.push(new Point(commandBuffer[cmdIndex + 1], commandBuffer[cmdIndex + 2])); + lastPath.points.push(new Point(commandBuffer[cmdIndex + 1], commandBuffer[cmdIndex + 2], lineWidth)); } else { - lastPath = new Path(commandBuffer[cmdIndex + 1], commandBuffer[cmdIndex + 2]); + lastPath = new Path(commandBuffer[cmdIndex + 1], commandBuffer[cmdIndex + 2], lineWidth); pathArray.push(lastPath); } cmdIndex += 2; break; case Commands.MOVE_TO: - lastPath = new Path(commandBuffer[cmdIndex + 1], commandBuffer[cmdIndex + 2]); + lastPath = new Path(commandBuffer[cmdIndex + 1], commandBuffer[cmdIndex + 2], lineWidth); pathArray.push(lastPath); cmdIndex += 2; break; + case Commands.LINE_WIDTH_TO: + if (lastPath !== null) + { + lastPath.points.push(new Point(commandBuffer[cmdIndex + 1], commandBuffer[cmdIndex + 2], commandBuffer[cmdIndex + 3])); + } + else + { + lastPath = new Path(commandBuffer[cmdIndex + 1], commandBuffer[cmdIndex + 2], commandBuffer[cmdIndex + 3]); + pathArray.push(lastPath); + } + cmdIndex += 3; + break; + + case Commands.MOVE_WIDTH_TO: + lastPath = new Path(commandBuffer[cmdIndex + 1], commandBuffer[cmdIndex + 2], commandBuffer[cmdIndex + 3]); + pathArray.push(lastPath); + cmdIndex += 3; + break; + default: console.error('Phaser: Invalid Graphics Command ID ' + cmd); break; diff --git a/v3/src/renderer/webgl/batches/shape/ShapeBatch.js b/v3/src/renderer/webgl/batches/shape/ShapeBatch.js index eb10a633a..24136c96c 100644 --- a/v3/src/renderer/webgl/batches/shape/ShapeBatch.js +++ b/v3/src/renderer/webgl/batches/shape/ShapeBatch.js @@ -28,10 +28,10 @@ var ShapeBatch = function (game, gl, manager) this.vertexCount = 0; this.viewMatrixLocation = null; this.tempTriangle = [ - {x: 0, y: 0}, - {x: 0, y: 0}, - {x: 0, y: 0}, - {x: 0, y: 0} + {x: 0, y: 0, width: 0}, + {x: 0, y: 0, width: 0}, + {x: 0, y: 0, width: 0}, + {x: 0, y: 0, width: 0} ]; // All of these settings will be able to be controlled via the Game Config @@ -162,7 +162,7 @@ ShapeBatch.prototype = { /* Graphics Game Object properties */ srcX, srcY, srcScaleX, srcScaleY, srcRotation, /* line properties */ - ax, ay, bx, by, lineWidth, lineColor, lineAlpha, + ax, ay, bx, by, aLineWidth, bLineWidth, lineColor, lineAlpha, /* transform */ a, b, c, d, e, f ) { @@ -179,16 +179,18 @@ ShapeBatch.prototype = { var dx = bx - ax; var dy = by - ay; var len = Math.sqrt(dx * dx + dy * dy); - var l0 = lineWidth * (by - ay) / len; - var l1 = lineWidth * (ax - bx) / len; - var lx0 = bx - l0; - var ly0 = by - l1; - var lx1 = ax - l0; - var ly1 = ay - l1; - var lx2 = bx + l0; - var ly2 = by + l1; - var lx3 = ax + l0; - var ly3 = ay + l1; + var al0 = aLineWidth * (by - ay) / len; + var al1 = aLineWidth * (ax - bx) / len; + var bl0 = bLineWidth * (by - ay) / len; + var bl1 = bLineWidth * (ax - bx) / len; + var lx0 = bx - bl0; + var ly0 = by - bl1; + var lx1 = ax - al0; + var ly1 = ay - al1; + var lx2 = bx + bl0; + var ly2 = by + bl1; + var lx3 = ax + al0; + var ly3 = ay + al1; var x0 = lx0 * a + ly0 * c + e; var y0 = lx0 * b + ly0 * d + f; var x1 = lx1 * a + ly1 * c + e; @@ -203,27 +205,22 @@ ShapeBatch.prototype = { vertexBufferF32[vertexOffset++] = y0; vertexBufferU32[vertexOffset++] = lineColor; vertexBufferF32[vertexOffset++] = lineAlpha; - vertexBufferF32[vertexOffset++] = x1; vertexBufferF32[vertexOffset++] = y1; vertexBufferU32[vertexOffset++] = lineColor; vertexBufferF32[vertexOffset++] = lineAlpha; - vertexBufferF32[vertexOffset++] = x2; vertexBufferF32[vertexOffset++] = y2; vertexBufferU32[vertexOffset++] = lineColor; vertexBufferF32[vertexOffset++] = lineAlpha; - vertexBufferF32[vertexOffset++] = x1; vertexBufferF32[vertexOffset++] = y1; vertexBufferU32[vertexOffset++] = lineColor; vertexBufferF32[vertexOffset++] = lineAlpha; - vertexBufferF32[vertexOffset++] = x3; vertexBufferF32[vertexOffset++] = y3; vertexBufferU32[vertexOffset++] = lineColor; vertexBufferF32[vertexOffset++] = lineAlpha; - vertexBufferF32[vertexOffset++] = x2; vertexBufferF32[vertexOffset++] = y2; vertexBufferU32[vertexOffset++] = lineColor; @@ -258,136 +255,78 @@ ShapeBatch.prototype = { var vertexBufferU32 = vertexDataBuffer.uintView; var vertexOffset; var x0, y0, x1, y1, x2, y2; + var line; for (var pathIndex = 0; pathIndex + 1 < pathLength; pathIndex += 1) { point0 = path[pathIndex]; point1 = path[pathIndex + 1]; - polylines.push(this.addLine( + line = this.addLine( srcX, srcY, srcScaleX, srcScaleY, srcRotation, - point0.x, point0.y, point1.x, point1.y, halfLineWidth, lineColor, lineAlpha, + point0.x, point0.y, + point1.x, point1.y, + point0.width / 2, point1.width / 2, + lineColor, lineAlpha, a, b, c, d, e, f - )); + ); + polylines.push(line); } - if (lineWidth < 1.0) - return; - - if (isLastPath) + /* Render joints */ + for (var index = 1, polylinesLength = polylines.length; + index < polylinesLength; ++index) { - for (var index = 0, polylinesLength = polylines.length; - index < polylinesLength; ++index) + + if (this.vertexCount + 6 > this.maxVertices) { + this.flush(); + } - if (this.vertexCount + 6 > this.maxVertices) - { - this.flush(); - } + last = polylines[index - 1] || polylines[polylinesLength - 1]; + curr = polylines[index]; + vertexOffset = vertexDataBuffer.allocate(24) - last = polylines[index - 1]; - curr = polylines[index]; - vertexOffset = vertexDataBuffer.allocate(24) + x0 = last[2 * 2 + 0]; + y0 = last[2 * 2 + 1]; + x1 = last[2 * 0 + 0]; + y1 = last[2 * 0 + 1]; + x2 = curr[2 * 3 + 0]; + y2 = curr[2 * 3 + 1]; - x0 = last[2 * 2 + 0]; - y0 = last[2 * 2 + 1]; - x1 = last[2 * 0 + 0]; - y1 = last[2 * 0 + 1]; - x2 = curr[2 * 3 + 0]; - y2 = curr[2 * 3 + 1]; + vertexBufferF32[vertexOffset++] = x0; + vertexBufferF32[vertexOffset++] = y0; + vertexBufferU32[vertexOffset++] = lineColor; + vertexBufferF32[vertexOffset++] = lineAlpha; + vertexBufferF32[vertexOffset++] = x1; + vertexBufferF32[vertexOffset++] = y1; + vertexBufferU32[vertexOffset++] = lineColor; + vertexBufferF32[vertexOffset++] = lineAlpha; + vertexBufferF32[vertexOffset++] = x2; + vertexBufferF32[vertexOffset++] = y2; + vertexBufferU32[vertexOffset++] = lineColor; + vertexBufferF32[vertexOffset++] = lineAlpha; - vertexBufferF32[vertexOffset++] = x0; - vertexBufferF32[vertexOffset++] = y0; - vertexBufferU32[vertexOffset++] = lineColor; - vertexBufferF32[vertexOffset++] = lineAlpha; - vertexBufferF32[vertexOffset++] = x1; - vertexBufferF32[vertexOffset++] = y1; - vertexBufferU32[vertexOffset++] = lineColor; - vertexBufferF32[vertexOffset++] = lineAlpha; - vertexBufferF32[vertexOffset++] = x2; - vertexBufferF32[vertexOffset++] = y2; - vertexBufferU32[vertexOffset++] = lineColor; - vertexBufferF32[vertexOffset++] = lineAlpha; - - x0 = last[2 * 0 + 0]; - y0 = last[2 * 0 + 1]; - x1 = last[2 * 2 + 0]; - y1 = last[2 * 2 + 1]; - x2 = curr[2 * 1 + 0]; - y2 = curr[2 * 1 + 1]; - - vertexBufferF32[vertexOffset++] = x0; - vertexBufferF32[vertexOffset++] = y0; - vertexBufferU32[vertexOffset++] = lineColor; - vertexBufferF32[vertexOffset++] = lineAlpha; - vertexBufferF32[vertexOffset++] = x1; - vertexBufferF32[vertexOffset++] = y1; - vertexBufferU32[vertexOffset++] = lineColor; - vertexBufferF32[vertexOffset++] = lineAlpha; - vertexBufferF32[vertexOffset++] = x2; - vertexBufferF32[vertexOffset++] = y2; - vertexBufferU32[vertexOffset++] = lineColor; - vertexBufferF32[vertexOffset++] = lineAlpha; + x0 = last[2 * 0 + 0]; + y0 = last[2 * 0 + 1]; + x1 = last[2 * 2 + 0]; + y1 = last[2 * 2 + 1]; + x2 = curr[2 * 1 + 0]; + y2 = curr[2 * 1 + 1]; - this.vertexCount += 6; - } - } - else - { - for (var index = 0, polylinesLength = polylines.length; - index < polylinesLength; ++index) - { + vertexBufferF32[vertexOffset++] = x0; + vertexBufferF32[vertexOffset++] = y0; + vertexBufferU32[vertexOffset++] = lineColor; + vertexBufferF32[vertexOffset++] = lineAlpha; + vertexBufferF32[vertexOffset++] = x1; + vertexBufferF32[vertexOffset++] = y1; + vertexBufferU32[vertexOffset++] = lineColor; + vertexBufferF32[vertexOffset++] = lineAlpha; + vertexBufferF32[vertexOffset++] = x2; + vertexBufferF32[vertexOffset++] = y2; + vertexBufferU32[vertexOffset++] = lineColor; + vertexBufferF32[vertexOffset++] = lineAlpha; - if (this.vertexCount + 6 > this.maxVertices) - { - this.flush(); - } - - last = polylines[index - 1] || polylines[polylinesLength - 1]; - curr = polylines[index]; - vertexOffset = vertexDataBuffer.allocate(24) - - x0 = last[2 * 2 + 0]; - y0 = last[2 * 2 + 1]; - x1 = last[2 * 0 + 0]; - y1 = last[2 * 0 + 1]; - x2 = curr[2 * 3 + 0]; - y2 = curr[2 * 3 + 1]; - - vertexBufferF32[vertexOffset++] = x0; - vertexBufferF32[vertexOffset++] = y0; - vertexBufferU32[vertexOffset++] = lineColor; - vertexBufferF32[vertexOffset++] = lineAlpha; - vertexBufferF32[vertexOffset++] = x1; - vertexBufferF32[vertexOffset++] = y1; - vertexBufferU32[vertexOffset++] = lineColor; - vertexBufferF32[vertexOffset++] = lineAlpha; - vertexBufferF32[vertexOffset++] = x2; - vertexBufferF32[vertexOffset++] = y2; - vertexBufferU32[vertexOffset++] = lineColor; - vertexBufferF32[vertexOffset++] = lineAlpha; - - x0 = last[2 * 0 + 0]; - y0 = last[2 * 0 + 1]; - x1 = last[2 * 2 + 0]; - y1 = last[2 * 2 + 1]; - x2 = curr[2 * 1 + 0]; - y2 = curr[2 * 1 + 1]; - - vertexBufferF32[vertexOffset++] = x0; - vertexBufferF32[vertexOffset++] = y0; - vertexBufferU32[vertexOffset++] = lineColor; - vertexBufferF32[vertexOffset++] = lineAlpha; - vertexBufferF32[vertexOffset++] = x1; - vertexBufferF32[vertexOffset++] = y1; - vertexBufferU32[vertexOffset++] = lineColor; - vertexBufferF32[vertexOffset++] = lineAlpha; - vertexBufferF32[vertexOffset++] = x2; - vertexBufferF32[vertexOffset++] = y2; - vertexBufferU32[vertexOffset++] = lineColor; - vertexBufferF32[vertexOffset++] = lineAlpha; - - this.vertexCount += 6; - } + this.vertexCount += 6; } polylines.length = 0; }, @@ -584,12 +523,16 @@ ShapeBatch.prototype = { tempTriangle[0].x = x0; tempTriangle[0].y = y0; + tempTriangle[0].width = lineWidth; tempTriangle[1].x = x1; tempTriangle[1].y = y1; + tempTriangle[1].width = lineWidth; tempTriangle[2].x = x2; tempTriangle[2].y = y2; + tempTriangle[2].width = lineWidth; tempTriangle[3].x = x0; tempTriangle[3].y = y0; + tempTriangle[3].width = lineWidth; this.addStrokePath( srcX, srcY, srcScaleX, srcScaleY, srcRotation,