mirror of
https://github.com/photonstorm/phaser
synced 2025-02-16 14:08:28 +00:00
Add lighting and dynamic vertex indexes to Graphics.
This commit is contained in:
parent
ff4980d85d
commit
bd54cbb965
14 changed files with 648 additions and 413 deletions
|
@ -65,6 +65,7 @@ var Render = require('./GraphicsRender');
|
|||
* @extends Phaser.GameObjects.Components.AlphaSingle
|
||||
* @extends Phaser.GameObjects.Components.BlendMode
|
||||
* @extends Phaser.GameObjects.Components.Depth
|
||||
* @extends Phaser.GameObjects.Components.Lighting
|
||||
* @extends Phaser.GameObjects.Components.Mask
|
||||
* @extends Phaser.GameObjects.Components.Pipeline
|
||||
* @extends Phaser.GameObjects.Components.PostPipeline
|
||||
|
@ -83,6 +84,7 @@ var Graphics = new Class({
|
|||
Components.AlphaSingle,
|
||||
Components.BlendMode,
|
||||
Components.Depth,
|
||||
Components.Lighting,
|
||||
Components.Mask,
|
||||
Components.PostPipeline,
|
||||
Components.RenderNode,
|
||||
|
|
|
@ -70,6 +70,7 @@ var GraphicsWebGLRenderer = function (renderer, src, drawingContext, parentMatri
|
|||
|
||||
var customRenderNodes = src.customRenderNodes;
|
||||
var defaultRenderNodes = src.defaultRenderNodes;
|
||||
var submitterNode = customRenderNodes.Submitter || defaultRenderNodes.Submitter;
|
||||
|
||||
var currentContext = drawingContext;
|
||||
|
||||
|
@ -133,8 +134,9 @@ var GraphicsWebGLRenderer = function (renderer, src, drawingContext, parentMatri
|
|||
|
||||
(customRenderNodes.FillPath || defaultRenderNodes.FillPath).run(
|
||||
currentContext,
|
||||
path[pathIndex].points,
|
||||
renderMatrix,
|
||||
submitterNode,
|
||||
path[pathIndex].points,
|
||||
fillTint.TL,
|
||||
fillTint.TR,
|
||||
fillTint.BL
|
||||
|
@ -151,6 +153,7 @@ var GraphicsWebGLRenderer = function (renderer, src, drawingContext, parentMatri
|
|||
|
||||
(customRenderNodes.StrokePath || defaultRenderNodes.StrokePath).run(
|
||||
currentContext,
|
||||
submitterNode,
|
||||
path[pathIndex].points,
|
||||
lineWidth,
|
||||
pathOpen,
|
||||
|
@ -281,6 +284,7 @@ var GraphicsWebGLRenderer = function (renderer, src, drawingContext, parentMatri
|
|||
(customRenderNodes.FillRect || defaultRenderNodes.FillRect).run(
|
||||
currentContext,
|
||||
renderMatrix,
|
||||
submitterNode,
|
||||
commands[++cmdIndex],
|
||||
commands[++cmdIndex],
|
||||
commands[++cmdIndex],
|
||||
|
@ -301,6 +305,7 @@ var GraphicsWebGLRenderer = function (renderer, src, drawingContext, parentMatri
|
|||
(customRenderNodes.FillTri || defaultRenderNodes.FillTri).run(
|
||||
currentContext,
|
||||
renderMatrix,
|
||||
submitterNode,
|
||||
commands[++cmdIndex],
|
||||
commands[++cmdIndex],
|
||||
commands[++cmdIndex],
|
||||
|
@ -337,6 +342,7 @@ var GraphicsWebGLRenderer = function (renderer, src, drawingContext, parentMatri
|
|||
|
||||
(customRenderNodes.StrokePath || defaultRenderNodes.StrokePath).run(
|
||||
currentContext,
|
||||
submitterNode,
|
||||
trianglePath,
|
||||
lineWidth,
|
||||
false,
|
||||
|
|
|
@ -39,6 +39,15 @@ var BatchHandlerTriFlat = new Class({
|
|||
* @readonly
|
||||
*/
|
||||
this._emptyTextures = [];
|
||||
|
||||
/**
|
||||
* The number of vertices currently in the batch.
|
||||
*
|
||||
* @name Phaser.Renderer.WebGL.RenderNodes.BatchHandlerTriFlat#vertexCount
|
||||
* @type {number}
|
||||
* @since 3.90.0
|
||||
*/
|
||||
this.vertexCount = 0;
|
||||
},
|
||||
|
||||
defaultConfig: {
|
||||
|
@ -47,6 +56,7 @@ var BatchHandlerTriFlat = new Class({
|
|||
indicesPerInstance: 3,
|
||||
vertexSource: ShaderSourceVS,
|
||||
fragmentSource: ShaderSourceFS,
|
||||
indexBufferDynamic: true,
|
||||
vertexBufferLayout: {
|
||||
usage: 'DYNAMIC_DRAW',
|
||||
layout: [
|
||||
|
@ -68,11 +78,6 @@ var BatchHandlerTriFlat = new Class({
|
|||
* Generate element indices for the instance vertices.
|
||||
* This is called automatically when the node is initialized.
|
||||
*
|
||||
* By default, each instance is a triangle.
|
||||
* The triangle is drawn with TRIANGLES topology,
|
||||
* so the vertices are in the order 0, 1, 2,
|
||||
* and each instance is fully separate.
|
||||
*
|
||||
* @method Phaser.Renderer.WebGL.RenderNodes.BatchHandlerTriFlat#_generateElementIndices
|
||||
* @since 3.90.0
|
||||
* @private
|
||||
|
@ -81,17 +86,7 @@ var BatchHandlerTriFlat = new Class({
|
|||
*/
|
||||
_generateElementIndices: function (instances)
|
||||
{
|
||||
var buffer = new ArrayBuffer(instances * 3 * 2);
|
||||
var indices = new Uint16Array(buffer);
|
||||
var offset = 0;
|
||||
for (var i = 0; i < instances; i++)
|
||||
{
|
||||
var index = i * 3;
|
||||
indices[offset++] = index;
|
||||
indices[offset++] = index + 1;
|
||||
indices[offset++] = index + 2;
|
||||
}
|
||||
return buffer;
|
||||
return new ArrayBuffer(instances * 3 * 2);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -127,12 +122,19 @@ var BatchHandlerTriFlat = new Class({
|
|||
var vao = this.vao;
|
||||
var renderer = this.manager.renderer;
|
||||
var vertexBuffer = this.vertexBufferLayout.buffer;
|
||||
var stride = this.vertexBufferLayout.layout.stride;
|
||||
|
||||
// Update vertex buffers.
|
||||
// Because we are probably using a generic vertex buffer
|
||||
// which is larger than the current batch, we need to update
|
||||
// the buffer with the correct size.
|
||||
vertexBuffer.update(instanceCount * this.bytesPerInstance);
|
||||
vertexBuffer.update(this.vertexCount * stride);
|
||||
|
||||
// Update index buffer.
|
||||
// We must bind the VAO before updating the index buffer.
|
||||
// Each index is a 16-bit unsigned integer, so 2 bytes.
|
||||
vao.bind();
|
||||
vao.indexBuffer.update(instanceCount * indicesPerInstance * 2);
|
||||
|
||||
renderer.drawElements(
|
||||
drawingContext,
|
||||
|
@ -146,66 +148,99 @@ var BatchHandlerTriFlat = new Class({
|
|||
|
||||
// Reset batch accumulation.
|
||||
this.instanceCount = 0;
|
||||
this.vertexCount = 0;
|
||||
|
||||
this.onRunEnd(drawingContext);
|
||||
},
|
||||
|
||||
/**
|
||||
* Add a triangle to the batch.
|
||||
* Add data to the batch.
|
||||
*
|
||||
* The vertices are not textured, and are named A, B, and C.
|
||||
* The data is composed of vertices and indexed triangles.
|
||||
* Each triangle is defined by three indices into the vertices array.
|
||||
*
|
||||
* @method Phaser.Renderer.WebGL.RenderNodes.BatchHandlerTriFlat#batch
|
||||
* @since 3.90.0
|
||||
* @param {Phaser.Types.Renderer.WebGL.DrawingContext} currentContext - The current drawing context.
|
||||
* @param {number} xA - The x-coordinate of vertex A.
|
||||
* @param {number} yA - The y-coordinate of vertex A.
|
||||
* @param {number} xB - The x-coordinate of vertex B.
|
||||
* @param {number} yB - The y-coordinate of vertex B.
|
||||
* @param {number} xC - The x-coordinate of vertex C.
|
||||
* @param {number} yC - The y-coordinate of vertex C.
|
||||
* @param {number} tintA - The vertex A tint color.
|
||||
* @param {number} tintB - The vertex B tint color.
|
||||
* @param {number} tintC - The vertex C tint color.
|
||||
* @param {number[]} indexes - The index data. Each triangle is defined by three indices into the vertices array, so the length of this should be a multiple of 3.
|
||||
* @param {number[]} vertices - The vertices data. Each vertex is defined by an x-coordinate, a y-coordinate, a tint color, a pass ID (initially -1), and an index ID (initially -1).
|
||||
*/
|
||||
batch: function (currentContext, xA, yA, xB, yB, xC, yC, tintA, tintB, tintC)
|
||||
batch: function (currentContext, indexes, vertices)
|
||||
{
|
||||
if (this.instanceCount === 0)
|
||||
{
|
||||
this.manager.setCurrentBatchNode(this, currentContext);
|
||||
}
|
||||
|
||||
// Update the vertex buffer.
|
||||
var vertexOffset32 = this.instanceCount * this.floatsPerInstance;
|
||||
var passID = 0;
|
||||
var instanceCompletion = 0;
|
||||
var instancesPerBatch = this.instancesPerBatch;
|
||||
|
||||
// Buffer data
|
||||
var stride = this.vertexBufferLayout.layout.stride;
|
||||
var verticesPerInstance = this.verticesPerInstance;
|
||||
|
||||
var indexBuffer = this.vao.indexBuffer;
|
||||
var indexView16 = indexBuffer.viewU16;
|
||||
var indexOffset16 = this.instanceCount * this.indicesPerInstance;
|
||||
|
||||
var vertexBuffer = this.vertexBufferLayout.buffer;
|
||||
var vertexViewF32 = vertexBuffer.viewF32;
|
||||
var vertexViewU32 = vertexBuffer.viewU32;
|
||||
var vertexOffset32 = this.vertexCount * stride / vertexViewF32.BYTES_PER_ELEMENT;
|
||||
|
||||
// Vertex A
|
||||
vertexViewF32[vertexOffset32++] = xA;
|
||||
vertexViewF32[vertexOffset32++] = yA;
|
||||
vertexViewU32[vertexOffset32++] = tintA;
|
||||
|
||||
// Vertex B
|
||||
vertexViewF32[vertexOffset32++] = xB;
|
||||
vertexViewF32[vertexOffset32++] = yB;
|
||||
vertexViewU32[vertexOffset32++] = tintB;
|
||||
|
||||
// Vertex C
|
||||
vertexViewF32[vertexOffset32++] = xC;
|
||||
vertexViewF32[vertexOffset32++] = yC;
|
||||
vertexViewU32[vertexOffset32++] = tintC;
|
||||
|
||||
// Increment the instance count.
|
||||
this.instanceCount++;
|
||||
|
||||
// Check whether the batch should be rendered immediately.
|
||||
// This guarantees that none of the arrays are full above.
|
||||
if (this.instanceCount === this.instancesPerBatch)
|
||||
for (var i = 0; i < indexes.length; i++)
|
||||
{
|
||||
this.run(currentContext);
|
||||
var index = indexes[i] * 5;
|
||||
|
||||
// Now the batch is empty.
|
||||
if (vertices[index + 3] !== passID)
|
||||
{
|
||||
// Update the vertex buffer.
|
||||
vertexViewF32[vertexOffset32++] = vertices[index];
|
||||
vertexViewF32[vertexOffset32++] = vertices[index + 1];
|
||||
vertexViewU32[vertexOffset32++] = vertices[index + 2];
|
||||
|
||||
// Assign the vertex to the current pass.
|
||||
vertices[index + 3] = passID;
|
||||
|
||||
// Record the index where the vertex was stored.
|
||||
vertices[index + 4] = this.vertexCount;
|
||||
|
||||
this.vertexCount++;
|
||||
}
|
||||
var id = vertices[index + 4];
|
||||
|
||||
// Update the index buffer.
|
||||
// There is always at least one index per vertex,
|
||||
// so we can assume that the vertex buffer is large enough.
|
||||
indexView16[indexOffset16++] = id;
|
||||
|
||||
// Check whether the instance is complete.
|
||||
instanceCompletion++;
|
||||
if (instanceCompletion === verticesPerInstance)
|
||||
{
|
||||
this.instanceCount++;
|
||||
instanceCompletion = 0;
|
||||
}
|
||||
|
||||
// Check whether the batch should be rendered immediately.
|
||||
// This guarantees that none of the arrays are full above.
|
||||
if (
|
||||
// The instance count has been reached.
|
||||
this.instanceCount === instancesPerBatch ||
|
||||
|
||||
// This triangle is complete, and another would exceed the index buffer size.
|
||||
(instanceCompletion === 0 && indexOffset16 + verticesPerInstance >= indexView16.length)
|
||||
)
|
||||
{
|
||||
passID++;
|
||||
this.run(currentContext);
|
||||
|
||||
indexOffset16 = this.instanceCount * this.indicesPerInstance;
|
||||
vertexOffset32 = this.vertexCount * stride / vertexViewF32.BYTES_PER_ELEMENT;
|
||||
|
||||
// Now the batch is empty.
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
209
src/renderer/webgl/renderNodes/BatchHandlerTriFlatLight.js
Normal file
209
src/renderer/webgl/renderNodes/BatchHandlerTriFlatLight.js
Normal file
|
@ -0,0 +1,209 @@
|
|||
/**
|
||||
* @author Benjamin D. Richards <benjamindrichards@gmail.com>
|
||||
* @copyright 2013-2024 Phaser Studio Inc.
|
||||
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
||||
*/
|
||||
|
||||
var Vector2 = require('../../../math/Vector2');
|
||||
var Class = require('../../../utils/Class');
|
||||
var LightShaderSourceFS = require('../shaders/FlatLight-frag');
|
||||
var ShaderSourceVS = require('../shaders/Flat-vert');
|
||||
var BatchHandlerTriFlat = require('./BatchHandlerTriFlat');
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* This RenderNode draws vertex tinted triangles with a Light Shader
|
||||
* in batches.
|
||||
*
|
||||
* The fragment shader used by this RenderNode will be compiled
|
||||
* with a maximum light count defined by the renderer configuration.
|
||||
* The string `%LIGHT_COUNT%` in the fragment shader source will be
|
||||
* replaced with this value.
|
||||
*
|
||||
* @class BatchHandlerTriFlatLight
|
||||
* @memberof Phaser.Renderer.WebGL.RenderNodes
|
||||
* @constructor
|
||||
* @since 3.90.0
|
||||
* @extends Phaser.Renderer.WebGL.RenderNodes.BatchHandlerQuad
|
||||
* @param {Phaser.Renderer.WebGL.RenderNodes.RenderNodeManager} manager - The manager that owns this RenderNode.
|
||||
* @param {Phaser.Types.Renderer.WebGL.RenderNodes.BatchHandlerConfig} config - The configuration object for this RenderNode.
|
||||
*/
|
||||
var BatchHandlerTriFlatLight = new Class({
|
||||
Extends: BatchHandlerTriFlat,
|
||||
|
||||
initialize: function BatchHandlerTriFlatLight (manager, config)
|
||||
{
|
||||
BatchHandlerTriFlat.call(this, manager, config);
|
||||
|
||||
/**
|
||||
* Inverse rotation matrix for normal map rotations.
|
||||
*
|
||||
* @name Phaser.Renderer.WebGL.RenderNodes.BatchHandlerTriFlatLight#inverseRotationMatrix
|
||||
* @type {Float32Array}
|
||||
* @private
|
||||
* @since 3.90.0
|
||||
*/
|
||||
this.inverseRotationMatrix = new Float32Array([
|
||||
1, 0, 0,
|
||||
0, 1, 0,
|
||||
0, 0, 1
|
||||
]);
|
||||
|
||||
/**
|
||||
* A persistent calculation vector used when processing the lights.
|
||||
*
|
||||
* @name Phaser.Renderer.WebGL.RenderNodes.BatchHandlerTriFlatLight#_lightVector
|
||||
* @type {Phaser.Math.Vector2}
|
||||
* @private
|
||||
* @since 3.90.0
|
||||
*/
|
||||
this._lightVector = new Vector2();
|
||||
|
||||
/**
|
||||
* The rotation of the normal map texture.
|
||||
*
|
||||
* @name Phaser.Renderer.WebGL.RenderNodes.BatchHandlerTriFlatLight#_normalMapRotation
|
||||
* @type {number}
|
||||
* @private
|
||||
* @since 3.90.0
|
||||
*/
|
||||
this._normalMapRotation = 0;
|
||||
},
|
||||
|
||||
/**
|
||||
* The default configuration settings for BatchHandlerTriFlatLight.
|
||||
*
|
||||
* @name Phaser.Renderer.WebGL.RenderNodes.BatchHandlerTriFlatLight#defaultConfig
|
||||
* @type {Phaser.Types.Renderer.WebGL.RenderNodes.BatchHandlerConfig}
|
||||
* @since 3.90.0
|
||||
* @readonly
|
||||
*/
|
||||
defaultConfig: {
|
||||
name: 'BatchHandlerTriFlatLight',
|
||||
verticesPerInstance: 3,
|
||||
indicesPerInstance: 3,
|
||||
vertexSource: ShaderSourceVS,
|
||||
fragmentSource: LightShaderSourceFS,
|
||||
vertexBufferLayout: {
|
||||
usage: 'DYNAMIC_DRAW',
|
||||
layout: [
|
||||
{
|
||||
name: 'inPosition',
|
||||
size: 2
|
||||
},
|
||||
{
|
||||
name: 'inTint',
|
||||
size: 4,
|
||||
type: 'UNSIGNED_BYTE',
|
||||
normalized: true
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
_copyAndCompleteConfig: function (manager, config, defaultConfig)
|
||||
{
|
||||
var newConfig = BatchHandlerTriFlat.prototype._copyAndCompleteConfig.call(this, manager, config, defaultConfig);
|
||||
|
||||
newConfig.fragmentSource = newConfig.fragmentSource.replace(
|
||||
'%LIGHT_COUNT%',
|
||||
manager.renderer.config.maxLights
|
||||
);
|
||||
|
||||
return newConfig;
|
||||
},
|
||||
|
||||
/**
|
||||
* Set new dimensions for the renderer. This is called automatically when the renderer is resized.
|
||||
*
|
||||
* @method Phaser.Renderer.WebGL.RenderNodes.BatchHandlerTriFlatLight#resize
|
||||
* @since 3.90.0
|
||||
* @param {number} width - The new width of the renderer.
|
||||
* @param {number} height - The new height of the renderer.
|
||||
*/
|
||||
resize: function (width, height)
|
||||
{
|
||||
BatchHandlerTriFlat.prototype.resize.call(this, width, height);
|
||||
|
||||
this.program.setUniform('uResolution', [ width, height ]);
|
||||
},
|
||||
|
||||
/**
|
||||
* Called at the start of the `run` method.
|
||||
*
|
||||
* @method Phaser.Renderer.WebGL.RenderNodes.BatchHandlerTriFlatLight#onRunBegin
|
||||
* @since 3.90.0
|
||||
* @param {Phaser.Types.Renderer.WebGL.DrawingContext} drawingContext - The current drawing context.
|
||||
*/
|
||||
onRunBegin: function (drawingContext)
|
||||
{
|
||||
var camera = drawingContext.camera;
|
||||
var cameraMatrix = camera.matrix;
|
||||
var program = this.program;
|
||||
var scene = camera.scene;
|
||||
var lightManager = scene.sys.lights;
|
||||
var lights = lightManager.getLights(camera);
|
||||
var lightsCount = lights.length;
|
||||
var ambientColor = lightManager.ambientColor;
|
||||
var vec = this._lightVector;
|
||||
var height = this.manager.renderer.height;
|
||||
|
||||
program.setUniform(
|
||||
'uCamera',
|
||||
[
|
||||
camera.x,
|
||||
camera.y,
|
||||
camera.rotation,
|
||||
camera.zoom
|
||||
]
|
||||
);
|
||||
program.setUniform(
|
||||
'uAmbientLightColor',
|
||||
[
|
||||
ambientColor.r,
|
||||
ambientColor.g,
|
||||
ambientColor.b
|
||||
]
|
||||
);
|
||||
program.setUniform(
|
||||
'uLightCount',
|
||||
lightsCount
|
||||
);
|
||||
|
||||
for (var i = 0; i < lightsCount; i++)
|
||||
{
|
||||
var light = lights[i].light;
|
||||
var color = light.color;
|
||||
|
||||
var lightName = 'uLights[' + i + '].';
|
||||
|
||||
cameraMatrix.transformPoint(light.x, light.y, vec);
|
||||
|
||||
program.setUniform(
|
||||
lightName + 'position',
|
||||
[
|
||||
vec.x - (camera.scrollX * light.scrollFactorX * camera.zoom),
|
||||
height - (vec.y - (camera.scrollY * light.scrollFactorY * camera.zoom))
|
||||
]
|
||||
);
|
||||
program.setUniform(
|
||||
lightName + 'color',
|
||||
[
|
||||
color.r,
|
||||
color.g,
|
||||
color.b
|
||||
]
|
||||
);
|
||||
program.setUniform(
|
||||
lightName + 'intensity',
|
||||
light.intensity
|
||||
);
|
||||
program.setUniform(
|
||||
lightName + 'radius',
|
||||
light.radius
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = BatchHandlerTriFlatLight;
|
|
@ -9,7 +9,7 @@ var RenderNode = require('./RenderNode');
|
|||
|
||||
/**
|
||||
* @classdesc
|
||||
* A RenderNode which renders a line segment.
|
||||
* A RenderNode which computes the geometry of a line segment.
|
||||
*
|
||||
* @class DrawLine
|
||||
* @memberof Phaser.Renderer.WebGL.RenderNodes
|
||||
|
@ -26,79 +26,32 @@ var DrawLine = new Class({
|
|||
RenderNode.call(this, 'DrawLine', manager);
|
||||
|
||||
/**
|
||||
* The render node that handles the rendering of triangles.
|
||||
* The vertices of the line segment as a quad.
|
||||
* These values have been transformed.
|
||||
* They should be used before the next call to `run`,
|
||||
* whereupon they will be overridden.
|
||||
*
|
||||
* @name Phaser.Renderer.WebGL.RenderNodes.DrawLine#batchHandler
|
||||
* @type {Phaser.Renderer.WebGL.RenderNodes.BatchHandlerTriFlat}
|
||||
* @name Phaser.Renderer.WebGL.RenderNodes.DrawLine#quad
|
||||
* @type {{ xTL: number, yTL: number, xTR: number, yTR: number, xBL: number, yBL: number, xBR: number, yBR: number }}
|
||||
* @since 3.90.0
|
||||
*/
|
||||
this.batchHandler = this.manager.getNode('BatchHandlerTriFlat');
|
||||
|
||||
/**
|
||||
* The top and bottom vertices of the start of the first line in a loop.
|
||||
*
|
||||
* These values have been pre-transformed to save on redundant calculations.
|
||||
*
|
||||
* @name Phaser.Renderer.WebGL.RenderNodes.DrawLine#start
|
||||
* @type {number[]}
|
||||
* @since 3.90.0
|
||||
*/
|
||||
this.start = [ 0, 0, 0, 0 ];
|
||||
|
||||
/**
|
||||
* The top and bottom vertices of the end of the last line in a loop.
|
||||
*
|
||||
* These values have been pre-transformed to save on redundant calculations.
|
||||
*
|
||||
* @name Phaser.Renderer.WebGL.RenderNodes.DrawLine#previous
|
||||
* @type {number[]}
|
||||
* @since 3.90.0
|
||||
*/
|
||||
this.previous = [ 0, 0, 0, 0 ];
|
||||
this.quad = {
|
||||
xTL: 0,
|
||||
yTL: 0,
|
||||
xTR: 0,
|
||||
yTR: 0,
|
||||
xBL: 0,
|
||||
yBL: 0,
|
||||
xBR: 0,
|
||||
yBR: 0
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Constant that defines the first line in a loop.
|
||||
* If the line is not open, this is cached,
|
||||
* and will join to the last line in the loop.
|
||||
*
|
||||
* @name Phaser.Renderer.WebGL.RenderNodes.DrawLine#FIRST
|
||||
* @type {number}
|
||||
* @const
|
||||
* @since 3.90.0
|
||||
* @default 1
|
||||
* @readonly
|
||||
*/
|
||||
FIRST: 1,
|
||||
|
||||
/**
|
||||
* Constant that defines the last line in a loop.
|
||||
* This joins to the previous line in the loop.
|
||||
* If the line is not open, this also joins to the first line in the loop.
|
||||
*
|
||||
* @name Phaser.Renderer.WebGL.RenderNodes.DrawLine#LAST
|
||||
* @type {number}
|
||||
* @const
|
||||
* @since 3.90.0
|
||||
* @default 2
|
||||
* @readonly
|
||||
*/
|
||||
LAST: 2,
|
||||
|
||||
/**
|
||||
* Constant that defines a single line with no joins.
|
||||
*
|
||||
* @name Phaser.Renderer.WebGL.RenderNodes.DrawLine#SINGLE
|
||||
* @type {number}
|
||||
* @const
|
||||
* @since 3.90.0
|
||||
* @default 3
|
||||
* @readonly
|
||||
*/
|
||||
SINGLE: 3,
|
||||
|
||||
/**
|
||||
* Render a line segment as a quad.
|
||||
* Get the transformed vertices of a line segment as a quad.
|
||||
* The values are stored in the `quad` property.
|
||||
* Access the values directly or copy them to another object,
|
||||
* before the next call to `run`, whereupon they will be overridden.
|
||||
*
|
||||
* @method Phaser.Renderer.WebGL.RenderNodes.DrawLine#run
|
||||
* @since 3.90.0
|
||||
|
@ -110,14 +63,8 @@ var DrawLine = new Class({
|
|||
* @param {number} by - The y coordinate of the end of the line.
|
||||
* @param {number} aLineWidth - The width of the line at the start.
|
||||
* @param {number} bLineWidth - The width of the line at the end.
|
||||
* @param {number} lineWidth - The width of the line.
|
||||
* @param {number} tintTL - The top-left tint color.
|
||||
* @param {number} tintTR - The top-right tint color.
|
||||
* @param {number} tintBL - The bottom-left tint color.
|
||||
* @param {number} tintBR - The bottom-right tint color.
|
||||
* @param {this.FIRST|this.LAST|this.SINGLE} [connection] - The connection type. If omitted, the line start joins to the previous line.
|
||||
*/
|
||||
run: function (drawingContext, currentMatrix, ax, ay, bx, by, aLineWidth, bLineWidth, lineWidth, tintTL, tintTR, tintBL, tintBR, connection)
|
||||
run: function (drawingContext, currentMatrix, ax, ay, bx, by, aLineWidth, bLineWidth)
|
||||
{
|
||||
this.onRunBegin(drawingContext);
|
||||
|
||||
|
@ -126,11 +73,7 @@ var DrawLine = new Class({
|
|||
|
||||
var len = Math.sqrt(dx * dx + dy * dy);
|
||||
|
||||
if (len === 0)
|
||||
{
|
||||
// Because we cannot (and should not) divide by zero!
|
||||
return;
|
||||
}
|
||||
// A well-formed path has no zero length segments, so we don't check.
|
||||
|
||||
var al0 = aLineWidth * (by - ay) / len;
|
||||
var al1 = aLineWidth * (ax - bx) / len;
|
||||
|
@ -146,113 +89,29 @@ var DrawLine = new Class({
|
|||
var lx3 = ax + al0;
|
||||
var ly3 = ay + al1;
|
||||
|
||||
var brX, brY, blX, blY, trX, trY, tlX, tlY;
|
||||
var quad = this.quad;
|
||||
|
||||
if (currentMatrix)
|
||||
{
|
||||
// Bottom right
|
||||
brX = currentMatrix.getX(lx0, ly0);
|
||||
brY = currentMatrix.getY(lx0, ly0);
|
||||
|
||||
// Bottom left
|
||||
blX = currentMatrix.getX(lx1, ly1);
|
||||
blY = currentMatrix.getY(lx1, ly1);
|
||||
|
||||
// Top right
|
||||
trX = currentMatrix.getX(lx2, ly2);
|
||||
trY = currentMatrix.getY(lx2, ly2);
|
||||
|
||||
// Top left
|
||||
tlX = currentMatrix.getX(lx3, ly3);
|
||||
tlY = currentMatrix.getY(lx3, ly3);
|
||||
quad.xTL = currentMatrix.getX(lx3, ly3);
|
||||
quad.yTL = currentMatrix.getY(lx3, ly3);
|
||||
quad.xBL = currentMatrix.getX(lx1, ly1);
|
||||
quad.yBL = currentMatrix.getY(lx1, ly1);
|
||||
quad.xTR = currentMatrix.getX(lx2, ly2);
|
||||
quad.yTR = currentMatrix.getY(lx2, ly2);
|
||||
quad.xBR = currentMatrix.getX(lx0, ly0);
|
||||
quad.yBR = currentMatrix.getY(lx0, ly0);
|
||||
}
|
||||
else
|
||||
{
|
||||
brX = lx0;
|
||||
brY = ly0;
|
||||
blX = lx1;
|
||||
blY = ly1;
|
||||
trX = lx2;
|
||||
trY = ly2;
|
||||
tlX = lx3;
|
||||
tlY = ly3;
|
||||
}
|
||||
|
||||
// Draw the line
|
||||
this.batchHandler.batch(
|
||||
drawingContext,
|
||||
tlX, tlY,
|
||||
blX, blY,
|
||||
brX, brY,
|
||||
tintTL, tintBL, tintBR
|
||||
);
|
||||
this.batchHandler.batch(
|
||||
drawingContext,
|
||||
brX, brY,
|
||||
trX, trY,
|
||||
tlX, tlY,
|
||||
tintBR, tintTR, tintTL
|
||||
);
|
||||
|
||||
if (connection !== this.SINGLE)
|
||||
{
|
||||
var start = this.start;
|
||||
var previous = this.previous;
|
||||
|
||||
if (connection === this.FIRST)
|
||||
{
|
||||
start[0] = tlX;
|
||||
start[1] = tlY;
|
||||
start[2] = blX;
|
||||
start[3] = blY;
|
||||
}
|
||||
else if (lineWidth > 2)
|
||||
{
|
||||
// No point doing a linejoin if the line isn't thick enough
|
||||
|
||||
// Connect to previous line
|
||||
this.batchHandler.batch(
|
||||
drawingContext,
|
||||
tlX, tlY,
|
||||
blX, blY,
|
||||
previous[2], previous[3],
|
||||
tintTL, tintBL, tintBR
|
||||
);
|
||||
this.batchHandler.batch(
|
||||
drawingContext,
|
||||
previous[2], previous[3],
|
||||
previous[0], previous[1],
|
||||
tlX, tlY,
|
||||
tintBR, tintTR, tintTL
|
||||
);
|
||||
|
||||
if (connection === this.LAST)
|
||||
{
|
||||
// Connect to first line
|
||||
this.batchHandler.batch(
|
||||
drawingContext,
|
||||
brX, brY,
|
||||
trX, trY,
|
||||
start[0], start[1],
|
||||
tintTL, tintBL, tintBR
|
||||
);
|
||||
this.batchHandler.batch(
|
||||
drawingContext,
|
||||
start[0], start[1],
|
||||
start[2], start[3],
|
||||
brX, brY,
|
||||
tintBR, tintTR, tintTL
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (connection !== this.LAST)
|
||||
{
|
||||
previous[0] = trX;
|
||||
previous[1] = trY;
|
||||
previous[2] = brX;
|
||||
previous[3] = brY;
|
||||
}
|
||||
quad.xTL = lx3;
|
||||
quad.yTL = ly3;
|
||||
quad.xBL = lx1;
|
||||
quad.yBL = ly1;
|
||||
quad.xTR = lx2;
|
||||
quad.yTR = ly2;
|
||||
quad.xBR = lx0;
|
||||
quad.yBR = ly0;
|
||||
}
|
||||
|
||||
this.onRunEnd(drawingContext);
|
||||
|
|
|
@ -54,7 +54,7 @@ var FillCamera = new Class({
|
|||
var cw = camera.width;
|
||||
var ch = camera.height;
|
||||
|
||||
this.fillRectNode.run(drawingContext, null, cx, cy, cw, ch, color, color, color, color);
|
||||
this.fillRectNode.run(drawingContext, null, null, cx, cy, cw, ch, color, color, color, color);
|
||||
|
||||
this.onRunEnd(drawingContext);
|
||||
}
|
||||
|
|
|
@ -31,25 +31,6 @@ var FillPath = new Class({
|
|||
initialize: function FillPath (manager)
|
||||
{
|
||||
RenderNode.call(this, 'FillPath', manager);
|
||||
|
||||
/**
|
||||
* The RenderNode used to render polygons.
|
||||
* By default, we use `FillTri`.
|
||||
*
|
||||
* @name Phaser.Renderer.WebGL.RenderNodes.FillPath#polygonNode
|
||||
* @type {Phaser.Renderer.WebGL.RenderNodes.FillTri}
|
||||
* @since 3.90.0
|
||||
*/
|
||||
this.polygonNode = this.manager.getNode('FillTri');
|
||||
|
||||
/**
|
||||
* Used internally for triangulating a polygon.
|
||||
*
|
||||
* @name Phaser.Renderer.WebGL.RenderNodes.FillPath#polygonCache
|
||||
* @type {number[]}
|
||||
* @since 3.90.0
|
||||
*/
|
||||
this.polygonCache = [];
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -58,55 +39,118 @@ var FillPath = new Class({
|
|||
* @method Phaser.Renderer.WebGL.RenderNodes.FillPath#run
|
||||
* @since 3.90.0
|
||||
* @param {Phaser.Renderer.WebGL.DrawingContext} drawingContext - The context currently in use.
|
||||
* @param {{ x: number, y: number, width: number }[]} path - The points that define the line segments.
|
||||
* @param {Phaser.GameObjects.Components.TransformMatrix} currentMatrix - The current transform matrix.
|
||||
* @param {Phaser.Renderer.WebGL.RenderNodes.SubmitterGraphics} submitterNode - The Submitter node to use.
|
||||
* @param {{ x: number, y: number, width: number }[]} path - The points that define the line segments.
|
||||
* @param {number} tintTL - The top-left tint color.
|
||||
* @param {number} tintTR - The top-right tint color.
|
||||
* @param {number} tintBL - The bottom-left tint color.
|
||||
*/
|
||||
run: function (drawingContext, path, currentMatrix, tintTL, tintTR, tintBL)
|
||||
run: function (drawingContext, currentMatrix, submitterNode, path, tintTL, tintTR, tintBL)
|
||||
{
|
||||
this.onRunBegin(drawingContext);
|
||||
|
||||
var length = path.length;
|
||||
var polygonCache = this.polygonCache;
|
||||
var polygonIndexArray;
|
||||
var point;
|
||||
var index, pathIndex, point, polygonIndexArray, x, y;
|
||||
|
||||
for (var pathIndex = 0; pathIndex < length; pathIndex++)
|
||||
var polygonCacheIndex = 0;
|
||||
var verticesIndex = 0;
|
||||
var indexedTrianglesIndex = 0;
|
||||
|
||||
var polygonCache = Array(length * 2);
|
||||
var vertices = Array(length * 5);
|
||||
|
||||
if (tintTL === tintTR && tintTL === tintBL)
|
||||
{
|
||||
point = path[pathIndex];
|
||||
polygonCache.push(point.x, point.y);
|
||||
// If the tint colors are all the same,
|
||||
// then we can share vertices between the triangles.
|
||||
for (pathIndex = 0; pathIndex < length; pathIndex++)
|
||||
{
|
||||
point = path[pathIndex];
|
||||
|
||||
// Transform the point.
|
||||
x = currentMatrix.getX(point.x, point.y);
|
||||
y = currentMatrix.getY(point.x, point.y);
|
||||
|
||||
polygonCache[polygonCacheIndex++] = x;
|
||||
polygonCache[polygonCacheIndex++] = y;
|
||||
vertices[verticesIndex++] = x;
|
||||
vertices[verticesIndex++] = y;
|
||||
vertices[verticesIndex++] = tintTL;
|
||||
vertices[verticesIndex++] = -1;
|
||||
vertices[verticesIndex++] = -1;
|
||||
}
|
||||
|
||||
polygonIndexArray = Earcut(polygonCache);
|
||||
length = polygonIndexArray.length;
|
||||
|
||||
submitterNode.batch(drawingContext, polygonIndexArray, vertices);
|
||||
}
|
||||
|
||||
polygonIndexArray = Earcut(polygonCache);
|
||||
length = polygonIndexArray.length;
|
||||
|
||||
for (var index = 0; index < length; index += 3)
|
||||
else
|
||||
{
|
||||
var p0 = polygonIndexArray[index + 0] * 2;
|
||||
var p1 = polygonIndexArray[index + 1] * 2;
|
||||
var p2 = polygonIndexArray[index + 2] * 2;
|
||||
// If the tint colors are different,
|
||||
// then we need to create a new vertex for each triangle.
|
||||
for (pathIndex = 0; pathIndex < length; pathIndex++)
|
||||
{
|
||||
point = path[pathIndex];
|
||||
|
||||
var x0 = polygonCache[p0 + 0];
|
||||
var y0 = polygonCache[p0 + 1];
|
||||
var x1 = polygonCache[p1 + 0];
|
||||
var y1 = polygonCache[p1 + 1];
|
||||
var x2 = polygonCache[p2 + 0];
|
||||
var y2 = polygonCache[p2 + 1];
|
||||
// Transform the point.
|
||||
x = currentMatrix.getX(point.x, point.y);
|
||||
y = currentMatrix.getY(point.x, point.y);
|
||||
|
||||
this.polygonNode.run(
|
||||
drawingContext,
|
||||
currentMatrix,
|
||||
x0, y0,
|
||||
x1, y1,
|
||||
x2, y2,
|
||||
tintTL, tintTR, tintBL
|
||||
);
|
||||
polygonCache[polygonCacheIndex++] = x;
|
||||
polygonCache[polygonCacheIndex++] = y;
|
||||
}
|
||||
|
||||
polygonIndexArray = Earcut(polygonCache);
|
||||
length = polygonIndexArray.length;
|
||||
|
||||
var indexedTriangles = Array(length);
|
||||
|
||||
for (index = 0; index < length; index += 3)
|
||||
{
|
||||
// Vertex A
|
||||
var p = polygonIndexArray[index] * 2;
|
||||
x = polygonCache[p + 0];
|
||||
y = polygonCache[p + 1];
|
||||
|
||||
vertices[verticesIndex++] = x;
|
||||
vertices[verticesIndex++] = y;
|
||||
vertices[verticesIndex++] = tintTL;
|
||||
vertices[verticesIndex++] = -1;
|
||||
vertices[verticesIndex++] = -1;
|
||||
|
||||
// Vertex B
|
||||
p = polygonIndexArray[index + 1] * 2;
|
||||
x = polygonCache[p + 0];
|
||||
y = polygonCache[p + 1];
|
||||
|
||||
vertices[verticesIndex++] = x;
|
||||
vertices[verticesIndex++] = y;
|
||||
vertices[verticesIndex++] = tintTR;
|
||||
vertices[verticesIndex++] = -1;
|
||||
vertices[verticesIndex++] = -1;
|
||||
|
||||
// Vertex C
|
||||
p = polygonIndexArray[index + 2] * 2;
|
||||
x = polygonCache[p + 0];
|
||||
y = polygonCache[p + 1];
|
||||
|
||||
vertices[verticesIndex++] = x;
|
||||
vertices[verticesIndex++] = y;
|
||||
vertices[verticesIndex++] = tintBL;
|
||||
vertices[verticesIndex++] = -1;
|
||||
vertices[verticesIndex++] = -1;
|
||||
|
||||
// Add new indices for the triangle.
|
||||
indexedTriangles[indexedTrianglesIndex++] = index + 0;
|
||||
indexedTriangles[indexedTrianglesIndex++] = index + 1;
|
||||
indexedTriangles[indexedTrianglesIndex++] = index + 2;
|
||||
}
|
||||
|
||||
submitterNode.batch(drawingContext, indexedTriangles, vertices);
|
||||
}
|
||||
|
||||
polygonCache.length = 0;
|
||||
|
||||
this.onRunEnd(drawingContext);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -28,13 +28,15 @@ var FillRect = new Class({
|
|||
RenderNode.call(this, 'FillRect', manager);
|
||||
|
||||
/**
|
||||
* The RenderNode that handles the rendering of quads.
|
||||
* The fallback batch handler for this node.
|
||||
*
|
||||
* @name Phaser.Renderer.WebGL.RenderNodes.FillRect#batchHandler
|
||||
* @name Phaser.Renderer.WebGL.RenderNodes.FillRect#_batchHandlerDefault
|
||||
* @type {Phaser.Renderer.WebGL.RenderNodes.BatchHandlerTriFlat}
|
||||
* @since 3.90.0
|
||||
* @private
|
||||
* @readonly
|
||||
*/
|
||||
this.batchHandler = this.manager.getNode('BatchHandlerTriFlat');
|
||||
this._batchHandlerDefault = manager.getNode('BatchHandlerTriFlat');
|
||||
|
||||
/**
|
||||
* An unchanging identity matrix.
|
||||
|
@ -42,8 +44,24 @@ var FillRect = new Class({
|
|||
* @name Phaser.Renderer.WebGL.RenderNodes.FillRect#_identityMatrix
|
||||
* @type {Phaser.GameObjects.Components.TransformMatrix}
|
||||
* @private
|
||||
* @since 3.90.0
|
||||
*/
|
||||
this._identityMatrix = new TransformMatrix();
|
||||
|
||||
/**
|
||||
* Vertex indices for the rectangle.
|
||||
*
|
||||
* @name Phaser.Renderer.WebGL.RenderNodes.FillRect#_indexedTriangles
|
||||
* @type {number[]}
|
||||
* @private
|
||||
* @since 3.90
|
||||
* @default [0, 1, 2, 2, 3, 0]
|
||||
* @readonly
|
||||
*/
|
||||
this._indexedTriangles = [
|
||||
0, 1, 2,
|
||||
2, 3, 0
|
||||
];
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -53,6 +71,7 @@ var FillRect = new Class({
|
|||
* @since 3.90.0
|
||||
* @param {Phaser.Renderer.WebGL.DrawingContext} drawingContext - The context currently in use.
|
||||
* @param {Phaser.GameObjects.Components.TransformMatrix} [currentMatrix] - A transform matrix to apply to the vertices. If not defined, the identity matrix is used.
|
||||
* @param {Phaser.Renderer.WebGL.RenderNodes.SubmitterGraphics} [submitterNode] - The Submitter node to use.
|
||||
* @param {number} x - The x-coordinate of the rectangle.
|
||||
* @param {number} y - The y-coordinate of the rectangle.
|
||||
* @param {number} width - The width of the rectangle.
|
||||
|
@ -62,7 +81,7 @@ var FillRect = new Class({
|
|||
* @param {number} tintBL - The bottom-left tint color.
|
||||
* @param {number} tintBR - The bottom-right tint color.
|
||||
*/
|
||||
run: function (drawingContext, currentMatrix, x, y, width, height, tintTL, tintTR, tintBL, tintBR)
|
||||
run: function (drawingContext, currentMatrix, submitterNode, x, y, width, height, tintTL, tintTR, tintBL, tintBR)
|
||||
{
|
||||
this.onRunBegin(drawingContext);
|
||||
|
||||
|
@ -71,22 +90,22 @@ var FillRect = new Class({
|
|||
currentMatrix = this._identityMatrix;
|
||||
}
|
||||
|
||||
if (!submitterNode)
|
||||
{
|
||||
submitterNode = this._batchHandlerDefault;
|
||||
}
|
||||
|
||||
var quad = currentMatrix.setQuad(x, y, x + width, y + height);
|
||||
|
||||
this.batchHandler.batch(
|
||||
submitterNode.batch(
|
||||
drawingContext,
|
||||
quad[0], quad[1],
|
||||
quad[2], quad[3],
|
||||
quad[4], quad[5],
|
||||
tintTL, tintBL, tintBR
|
||||
);
|
||||
|
||||
this.batchHandler.batch(
|
||||
drawingContext,
|
||||
quad[4], quad[5],
|
||||
quad[6], quad[7],
|
||||
quad[0], quad[1],
|
||||
tintBR, tintTR, tintTL
|
||||
this._indexedTriangles,
|
||||
[
|
||||
quad[0], quad[1], tintTL, -1, -1,
|
||||
quad[2], quad[3], tintBL, -1, -1,
|
||||
quad[4], quad[5], tintBR, -1, -1,
|
||||
quad[6], quad[7], tintTR, -1, -1
|
||||
]
|
||||
);
|
||||
|
||||
this.onRunEnd(drawingContext);
|
||||
|
|
|
@ -10,8 +10,6 @@ var RenderNode = require('./RenderNode');
|
|||
/**
|
||||
* @classdesc
|
||||
* A RenderNode which renders a filled triangle.
|
||||
* This is useful for arbitrary geometry.
|
||||
* This does not use textures, and is intended to form part of a larger batch.
|
||||
*
|
||||
* @class FillTri
|
||||
* @memberof Phaser.Renderer.WebGL.RenderNodes
|
||||
|
@ -28,13 +26,18 @@ var FillTri = new Class({
|
|||
RenderNode.call(this, 'FillTri', manager);
|
||||
|
||||
/**
|
||||
* The BatchHandlerQuad that handles the rendering of quads.
|
||||
* Vertex indices for the triangle.
|
||||
*
|
||||
* @name Phaser.Renderer.WebGL.RenderNodes.FillTri#batchHandler
|
||||
* @type {Phaser.Renderer.WebGL.RenderNodes.BatchHandlerTriFlat}
|
||||
* @since 3.90.0
|
||||
* @name Phaser.Renderer.WebGL.RenderNodes.FillTri#_indexedTriangles
|
||||
* @type {number[]}
|
||||
* @private
|
||||
* @since 3.90
|
||||
* @default [0, 1, 2]
|
||||
* @readonly
|
||||
*/
|
||||
this.batchHandler = this.manager.getNode('BatchHandlerTriFlat');
|
||||
this._indexedTriangles = [
|
||||
0, 1, 2
|
||||
];
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -44,42 +47,70 @@ var FillTri = new Class({
|
|||
* @since 3.90.0
|
||||
* @param {Phaser.Renderer.WebGL.DrawingContext} drawingContext - The context currently in use.
|
||||
* @param {Phaser.GameObjects.Components.TransformMatrix} [currentMatrix] - A transform matrix to apply to the vertices. If not defined, the vertices are not transformed.
|
||||
* @param {Phaser.Renderer.WebGL.RenderNodes.SubmitterGraphics} submitterNode - The Submitter node to use.
|
||||
* @param {number} xA - The x-coordinate of the first vertex.
|
||||
* @param {number} yA - The y-coordinate of the first vertex.
|
||||
* @param {number} xB - The x-coordinate of the second vertex.
|
||||
* @param {number} yB - The y-coordinate of the second vertex.
|
||||
* @param {number} xC - The x-coordinate of the third vertex.
|
||||
* @param {number} yC - The y-coordinate of the third vertex.
|
||||
* @param {number} tintA - The tint color of the first vertex.
|
||||
* @param {number} tintB - The tint color of the second vertex.
|
||||
* @param {number} tintC - The tint color of the third vertex.
|
||||
*/
|
||||
run: function (drawingContext, currentMatrix, xA, yA, xB, yB, xC, yC, tintA, tintB, tintC)
|
||||
run: function (drawingContext, currentMatrix, submitterNode, xA, yA, xB, yB, xC, yC, tintA, tintB, tintC)
|
||||
{
|
||||
this.onRunBegin(drawingContext);
|
||||
|
||||
var txA, tyA, txB, tyB, txC, tyC;
|
||||
|
||||
if (currentMatrix)
|
||||
{
|
||||
txA = currentMatrix.getX(xA, yA);
|
||||
tyA = currentMatrix.getY(xA, yA);
|
||||
txB = currentMatrix.getX(xB, yB);
|
||||
tyB = currentMatrix.getY(xB, yB);
|
||||
txC = currentMatrix.getX(xC, yC);
|
||||
tyC = currentMatrix.getY(xC, yC);
|
||||
submitterNode.batch(
|
||||
drawingContext,
|
||||
this._indexedTriangles,
|
||||
[
|
||||
currentMatrix.getX(xA, yA),
|
||||
currentMatrix.getY(xA, yA),
|
||||
tintA,
|
||||
-1,
|
||||
-1,
|
||||
currentMatrix.getX(xB, yB),
|
||||
currentMatrix.getY(xB, yB),
|
||||
tintB,
|
||||
-1,
|
||||
-1,
|
||||
currentMatrix.getX(xC, yC),
|
||||
currentMatrix.getY(xC, yC),
|
||||
tintC,
|
||||
-1,
|
||||
-1
|
||||
]
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
txA = xA;
|
||||
tyA = yA;
|
||||
txB = xB;
|
||||
tyB = yB;
|
||||
txC = xC;
|
||||
tyC = yC;
|
||||
submitterNode.batch(
|
||||
drawingContext,
|
||||
this._indexedTriangles,
|
||||
[
|
||||
xA,
|
||||
yA,
|
||||
tintA,
|
||||
-1,
|
||||
-1,
|
||||
xB,
|
||||
yB,
|
||||
tintB,
|
||||
-1,
|
||||
-1,
|
||||
xC,
|
||||
yC,
|
||||
tintC,
|
||||
-1,
|
||||
-1
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
this.batchHandler.batch(
|
||||
drawingContext,
|
||||
|
||||
txA, tyA,
|
||||
txB, tyB,
|
||||
txC, tyC,
|
||||
|
||||
tintA, tintB, tintC
|
||||
);
|
||||
|
||||
this.onRunEnd(drawingContext);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -17,6 +17,7 @@ var DefaultParticleEmitterNodes = require('./defaults/DefaultParticleEmitterNode
|
|||
var BatchHandlerQuad = require('./BatchHandlerQuad');
|
||||
var BatchHandlerQuadLight = require('./BatchHandlerQuadLight');
|
||||
var BatchHandlerTriFlat = require('./BatchHandlerTriFlat');
|
||||
var BatchHandlerTriFlatLight = require('./BatchHandlerTriFlatLight');
|
||||
var Camera = require('./Camera');
|
||||
var DrawLine = require('./DrawLine');
|
||||
var FillCamera = require('./FillCamera');
|
||||
|
@ -135,6 +136,7 @@ var RenderNodeManager = new Class({
|
|||
BatchHandlerQuad: BatchHandlerQuad,
|
||||
BatchHandlerQuadLight: BatchHandlerQuadLight,
|
||||
BatchHandlerTriFlat: BatchHandlerTriFlat,
|
||||
BatchHandlerTriFlatLight: BatchHandlerTriFlatLight,
|
||||
Camera: Camera,
|
||||
DrawLine: DrawLine,
|
||||
FillCamera: FillCamera,
|
||||
|
|
|
@ -27,7 +27,7 @@ var StrokePath = new Class({
|
|||
RenderNode.call(this, 'StrokePath', manager);
|
||||
|
||||
/**
|
||||
* The RenderNode that draws a line segment.
|
||||
* The RenderNode that generates a line segment.
|
||||
*
|
||||
* @name Phaser.Renderer.WebGL.RenderNodes.StrokePath#drawLineNode
|
||||
* @type {Phaser.Renderer.WebGL.RenderNodes.DrawLine}
|
||||
|
@ -42,6 +42,7 @@ var StrokePath = new Class({
|
|||
* @method Phaser.Renderer.WebGL.RenderNodes.StrokePath#run
|
||||
* @since 3.90.0
|
||||
* @param {Phaser.Renderer.WebGL.DrawingContext} drawingContext - The context currently in use.
|
||||
* @param {Phaser.Renderer.WebGL.RenderNodes.SubmitterGraphics} submitterNode - The Submitter node to use.
|
||||
* @param {{ x: number, y: number, width: number }[]} path - The points that define the line segments.
|
||||
* @param {number} lineWidth - The width of the stroke.
|
||||
* @param {boolean} open - Whether the stroke is open or closed.
|
||||
|
@ -51,7 +52,7 @@ var StrokePath = new Class({
|
|||
* @param {number} tintBL - The bottom-left tint color.
|
||||
* @param {number} tintBR - The bottom-right tint color.
|
||||
*/
|
||||
run: function (drawingContext, path, lineWidth, open, currentMatrix, tintTL, tintTR, tintBL, tintBR)
|
||||
run: function (drawingContext, submitterNode, path, lineWidth, open, currentMatrix, tintTL, tintTR, tintBL, tintBR)
|
||||
{
|
||||
this.onRunBegin(drawingContext);
|
||||
|
||||
|
@ -59,77 +60,39 @@ var StrokePath = new Class({
|
|||
|
||||
var pathLength = path.length - 1;
|
||||
|
||||
var pathIndex, point, nextPoint;
|
||||
var point, nextPoint;
|
||||
|
||||
if (pathLength === 1)
|
||||
// Determine size of index array.
|
||||
var indexCount = pathLength * 6;
|
||||
var connect = false;
|
||||
var connectLoop = false;
|
||||
|
||||
if (lineWidth > 2 && pathLength > 1)
|
||||
{
|
||||
// Only one point, draw a single line
|
||||
point = path[0];
|
||||
nextPoint = path[1];
|
||||
connect = true;
|
||||
|
||||
drawLineNode.run(
|
||||
drawingContext,
|
||||
currentMatrix,
|
||||
point.x,
|
||||
point.y,
|
||||
nextPoint.x,
|
||||
nextPoint.y,
|
||||
point.width / 2,
|
||||
nextPoint.width / 2,
|
||||
lineWidth,
|
||||
tintTL,
|
||||
tintTR,
|
||||
tintBL,
|
||||
tintBR,
|
||||
drawLineNode.SINGLE
|
||||
);
|
||||
}
|
||||
else if (pathLength > 1)
|
||||
{
|
||||
point = path[0];
|
||||
nextPoint = path[1];
|
||||
|
||||
drawLineNode.run(
|
||||
drawingContext,
|
||||
currentMatrix,
|
||||
point.x,
|
||||
point.y,
|
||||
nextPoint.x,
|
||||
nextPoint.y,
|
||||
point.width / 2,
|
||||
nextPoint.width / 2,
|
||||
lineWidth,
|
||||
tintTL,
|
||||
tintTR,
|
||||
tintBL,
|
||||
tintBR,
|
||||
drawLineNode.FIRST
|
||||
);
|
||||
|
||||
for (pathIndex = 1; pathIndex < pathLength - 1; pathIndex++)
|
||||
// Lines will be connected by a secondary quad.
|
||||
indexCount *= 2;
|
||||
if (open)
|
||||
{
|
||||
point = path[pathIndex];
|
||||
nextPoint = path[pathIndex + 1];
|
||||
|
||||
drawLineNode.run(
|
||||
drawingContext,
|
||||
currentMatrix,
|
||||
point.x,
|
||||
point.y,
|
||||
nextPoint.x,
|
||||
nextPoint.y,
|
||||
point.width / 2,
|
||||
nextPoint.width / 2,
|
||||
lineWidth,
|
||||
tintTL,
|
||||
tintTR,
|
||||
tintBL,
|
||||
tintBR
|
||||
);
|
||||
// The last line will not be connected to the first line.
|
||||
indexCount -= 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
connectLoop = true;
|
||||
}
|
||||
}
|
||||
var indices = Array(indexCount);
|
||||
var indexOffset = 0;
|
||||
|
||||
point = path[pathLength - 1];
|
||||
nextPoint = path[pathLength];
|
||||
var vertices = Array(pathLength * 4 * 5);
|
||||
var vertexOffset = 0;
|
||||
|
||||
for (var i = 0; i < pathLength; i++)
|
||||
{
|
||||
point = path[i];
|
||||
nextPoint = path[i + 1];
|
||||
|
||||
drawLineNode.run(
|
||||
drawingContext,
|
||||
|
@ -139,16 +102,79 @@ var StrokePath = new Class({
|
|||
nextPoint.x,
|
||||
nextPoint.y,
|
||||
point.width / 2,
|
||||
nextPoint.width / 2,
|
||||
lineWidth,
|
||||
tintTL,
|
||||
tintTR,
|
||||
tintBL,
|
||||
tintBR,
|
||||
open ? undefined : drawLineNode.LAST
|
||||
nextPoint.width / 2
|
||||
);
|
||||
|
||||
var quad = drawLineNode.quad;
|
||||
|
||||
vertices[vertexOffset++] = quad.xTL;
|
||||
vertices[vertexOffset++] = quad.yTL;
|
||||
vertices[vertexOffset++] = tintTL;
|
||||
vertices[vertexOffset++] = -1;
|
||||
vertices[vertexOffset++] = -1;
|
||||
|
||||
vertices[vertexOffset++] = quad.xBL;
|
||||
vertices[vertexOffset++] = quad.yBL;
|
||||
vertices[vertexOffset++] = tintBL;
|
||||
vertices[vertexOffset++] = -1;
|
||||
vertices[vertexOffset++] = -1;
|
||||
|
||||
vertices[vertexOffset++] = quad.xBR;
|
||||
vertices[vertexOffset++] = quad.yBR;
|
||||
vertices[vertexOffset++] = tintBR;
|
||||
vertices[vertexOffset++] = -1;
|
||||
vertices[vertexOffset++] = -1;
|
||||
|
||||
vertices[vertexOffset++] = quad.xTR;
|
||||
vertices[vertexOffset++] = quad.yTR;
|
||||
vertices[vertexOffset++] = tintTR;
|
||||
vertices[vertexOffset++] = -1;
|
||||
vertices[vertexOffset++] = -1;
|
||||
|
||||
// Draw two triangles.
|
||||
// The vertices are in the order: TL, BL, BR, TR
|
||||
indices[indexOffset++] = i * 4;
|
||||
indices[indexOffset++] = i * 4 + 1;
|
||||
indices[indexOffset++] = i * 4 + 2;
|
||||
indices[indexOffset++] = i * 4 + 2;
|
||||
indices[indexOffset++] = i * 4 + 3;
|
||||
indices[indexOffset++] = i * 4;
|
||||
|
||||
if (connect && i !== 0)
|
||||
{
|
||||
// Draw a quad connecting to the previous line segment.
|
||||
// The vertices are in the order:
|
||||
// - TL
|
||||
// - BL
|
||||
// - Previous BR
|
||||
// - Previous TR
|
||||
indices[indexOffset++] = i * 4;
|
||||
indices[indexOffset++] = i * 4 + 1;
|
||||
indices[indexOffset++] = i * 4 - 2;
|
||||
indices[indexOffset++] = i * 4 - 2;
|
||||
indices[indexOffset++] = i * 4 - 1;
|
||||
indices[indexOffset++] = i * 4;
|
||||
|
||||
if (connectLoop && i === pathLength - 1)
|
||||
{
|
||||
// Connect the last line segment to the first.
|
||||
// The vertices are in the order:
|
||||
// - BR
|
||||
// - TR
|
||||
// - First TL
|
||||
// - First BL
|
||||
indices[indexOffset++] = i * 4 + 2;
|
||||
indices[indexOffset++] = i * 4 + 3;
|
||||
indices[indexOffset++] = 0;
|
||||
indices[indexOffset++] = 0;
|
||||
indices[indexOffset++] = 1;
|
||||
indices[indexOffset++] = i * 4 + 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
submitterNode.batch(drawingContext, indices, vertices);
|
||||
|
||||
this.onRunEnd(drawingContext);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
var Map = require('../../../../structs/Map');
|
||||
|
||||
var DefaultGraphicsNodes = new Map([
|
||||
[ 'BatchHandlerTriFlat', 'BatchHandlerTriFlat' ],
|
||||
// [ 'SubmitterLight', 'SubmitterQuadLight' ],
|
||||
[ 'Submitter', 'BatchHandlerTriFlat' ],
|
||||
[ 'SubmitterLight', 'BatchHandlerTriFlatLight' ],
|
||||
[ 'FillPath', 'FillPath' ],
|
||||
[ 'FillRect', 'FillRect' ],
|
||||
[ 'FillTri', 'FillTri' ],
|
||||
|
|
|
@ -13,6 +13,7 @@ var RenderNodes = {
|
|||
BatchHandlerQuad: require('./BatchHandlerQuad'),
|
||||
BatchHandlerQuadLight: require('./BatchHandlerQuadLight'),
|
||||
BatchHandlerTriFlat: require('./BatchHandlerTriFlat'),
|
||||
BatchHandlerTriFlatLight: require('./BatchHandlerTriFlatLight'),
|
||||
Camera: require('./Camera'),
|
||||
DrawLine: require('./DrawLine'),
|
||||
FillCamera: require('./FillCamera'),
|
||||
|
|
|
@ -34,6 +34,7 @@ module.exports = {
|
|||
FXWipeFrag: require('./FXWipe-frag.js'),
|
||||
FlatFrag: require('./Flat-frag.js'),
|
||||
FlatVert: require('./Flat-vert.js'),
|
||||
FlatLightFrag: require('./FlatLight-frag.js'),
|
||||
LightFrag: require('./Light-frag.js'),
|
||||
LinearBlendFrag: require('./LinearBlend-frag.js'),
|
||||
MeshFrag: require('./Mesh-frag.js'),
|
||||
|
|
Loading…
Add table
Reference in a new issue