[ts] Added 2 color tinting support, made it default, barely a performance difference. You can disable it via the constructors of SceneRenderer, SkeletonRenderer and PolygonBatcher, depending on which level of granularity you use. Also fixed performance issue submitting geometry as STATIC_DRAW instead of DYNAMIC_DRAW. Fixed another performance issue regarding size of buffer data that's being updated.

This commit is contained in:
badlogic 2017-02-24 15:00:30 +01:00
parent 2c92a4689b
commit 9eb42b65f2
30 changed files with 1199 additions and 277 deletions

View File

@ -1122,6 +1122,17 @@ declare module spine {
length: number;
[n: number]: T;
}
class WindowedMean {
values: Array<number>;
addedValues: number;
lastValue: number;
mean: number;
dirty: boolean;
constructor(windowSize?: number);
hasEnoughData(): boolean;
addValue(value: number): void;
getMean(): number;
}
}
declare module spine.threejs {
class AssetManager extends spine.AssetManager {
@ -1322,6 +1333,7 @@ declare module spine.webgl {
numIndices(): number;
setIndicesLength(length: number): void;
getIndices(): Uint16Array;
getVertexSizeInFloats(): number;
constructor(gl: WebGLRenderingContext, attributes: VertexAttribute[], maxVertices: number, maxIndices: number);
setVertices(vertices: Array<number>): void;
setIndices(indices: Array<number>): void;
@ -1350,6 +1362,9 @@ declare module spine.webgl {
class ColorAttribute extends VertexAttribute {
constructor();
}
class Color2Attribute extends VertexAttribute {
constructor();
}
enum VertexAttributeType {
Float = 0,
}
@ -1366,7 +1381,7 @@ declare module spine.webgl {
private indicesLength;
private srcBlend;
private dstBlend;
constructor(gl: WebGLRenderingContext, maxVertices?: number);
constructor(gl: WebGLRenderingContext, twoColorTint?: boolean, maxVertices?: number);
begin(shader: Shader): void;
setBlendMode(srcBlend: number, dstBlend: number): void;
draw(texture: GLTexture, vertices: ArrayLike<number>, indices: Array<number>): void;
@ -1391,7 +1406,7 @@ declare module spine.webgl {
private QUAD;
private QUAD_TRIANGLES;
private WHITE;
constructor(canvas: HTMLCanvasElement, gl: WebGLRenderingContext);
constructor(canvas: HTMLCanvasElement, gl: WebGLRenderingContext, twoColorTint?: boolean);
begin(): void;
drawSkeleton(skeleton: Skeleton, premultipliedAlpha?: boolean): void;
drawSkeletonDebug(skeleton: Skeleton, premultipliedAlpha?: boolean, ignoredBones?: Array<string>): void;
@ -1424,6 +1439,7 @@ declare module spine.webgl {
static MVP_MATRIX: string;
static POSITION: string;
static COLOR: string;
static COLOR2: string;
static TEXCOORDS: string;
static SAMPLER: string;
private gl;
@ -1454,6 +1470,7 @@ declare module spine.webgl {
getAttributeLocation(attribute: string): number;
dispose(): void;
static newColoredTextured(gl: WebGLRenderingContext): Shader;
static newTwoColorTextured(gl: WebGLRenderingContext): Shader;
static newColored(gl: WebGLRenderingContext): Shader;
}
}
@ -1527,16 +1544,19 @@ declare module spine.webgl {
}
declare module spine.webgl {
class SkeletonRenderer {
static VERTEX_SIZE: number;
static QUAD_TRIANGLES: number[];
premultipliedAlpha: boolean;
private gl;
private tempColor;
private tempColor2;
private vertices;
constructor(gl: WebGLRenderingContext);
private vertexSize;
private twoColorTint;
private renderable;
constructor(gl: WebGLRenderingContext, twoColorTint?: boolean);
draw(batcher: PolygonBatcher, skeleton: Skeleton): void;
computeRegionVertices(slot: Slot, region: RegionAttachment, pma: boolean): ArrayLike<number>;
computeMeshVertices(slot: Slot, mesh: MeshAttachment, pma: boolean): ArrayLike<number>;
private computeRegionVertices(slot, region, pma, twoColorTint?);
private computeMeshVertices(slot, mesh, pma, twoColorTint?);
}
}
declare module spine.webgl {

View File

@ -4376,8 +4376,10 @@ var spine;
if (color != null)
data.color.setFromString(color);
var dark = this.getValue(slotMap, "dark", null);
if (dark != null)
data.darkColor.setFromString(color);
if (dark != null) {
data.darkColor = new spine.Color(1, 1, 1, 1);
data.darkColor.setFromString(dark);
}
data.attachmentName = this.getValue(slotMap, "attachment", null);
data.blendMode = SkeletonJson.blendModeFromString(this.getValue(slotMap, "blend", "normal"));
skeletonData.slots.push(data);
@ -4680,7 +4682,7 @@ var spine;
var valueMap = timelineMap[i];
var light = new spine.Color();
var dark = new spine.Color();
light.setFromString(valueMap.color);
light.setFromString(valueMap.light);
dark.setFromString(valueMap.dark);
timeline.setFrame(frameIndex, valueMap.time, light.r, light.g, light.b, light.a, dark.r, dark.g, dark.b);
this.readCurve(valueMap, timeline, frameIndex);
@ -5818,6 +5820,45 @@ var spine;
return TimeKeeper;
}());
spine.TimeKeeper = TimeKeeper;
var WindowedMean = (function () {
function WindowedMean(windowSize) {
if (windowSize === void 0) { windowSize = 32; }
this.addedValues = 0;
this.lastValue = 0;
this.mean = 0;
this.dirty = true;
this.values = new Array(windowSize);
}
WindowedMean.prototype.hasEnoughData = function () {
return this.addedValues >= this.values.length;
};
WindowedMean.prototype.addValue = function (value) {
if (this.addedValues < this.values.length)
this.addedValues++;
this.values[this.lastValue++] = value;
if (this.lastValue > this.values.length - 1)
this.lastValue = 0;
this.dirty = true;
};
WindowedMean.prototype.getMean = function () {
if (this.hasEnoughData()) {
if (this.dirty) {
var mean = 0;
for (var i = 0; i < this.values.length; i++) {
mean += this.values[i];
}
this.mean = mean / this.values.length;
this.dirty = false;
}
return this.mean;
}
else {
return 0;
}
};
return WindowedMean;
}());
spine.WindowedMean = WindowedMean;
})(spine || (spine = {}));
var spine;
(function (spine) {
@ -6848,6 +6889,14 @@ var spine;
};
Mesh.prototype.getIndices = function () { return this.indices; };
;
Mesh.prototype.getVertexSizeInFloats = function () {
var size = 0;
for (var i = 0; i < this.attributes.length; i++) {
var attribute = this.attributes[i];
size += attribute.numElements;
}
return size;
};
Mesh.prototype.setVertices = function (vertices) {
this.dirtyVertices = true;
if (vertices.length > this.vertices.length)
@ -6908,7 +6957,7 @@ var spine;
this.verticesBuffer = gl.createBuffer();
}
gl.bindBuffer(gl.ARRAY_BUFFER, this.verticesBuffer);
gl.bufferData(gl.ARRAY_BUFFER, this.vertices.subarray(0, this.verticesLength), gl.STATIC_DRAW);
gl.bufferData(gl.ARRAY_BUFFER, this.vertices.subarray(0, this.verticesLength), gl.DYNAMIC_DRAW);
this.dirtyVertices = false;
}
if (this.dirtyIndices) {
@ -6916,7 +6965,7 @@ var spine;
this.indicesBuffer = gl.createBuffer();
}
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indicesBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices.subarray(0, this.indicesLength), gl.STATIC_DRAW);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices.subarray(0, this.indicesLength), gl.DYNAMIC_DRAW);
this.dirtyIndices = false;
}
};
@ -6970,6 +7019,14 @@ var spine;
return ColorAttribute;
}(VertexAttribute));
webgl.ColorAttribute = ColorAttribute;
var Color2Attribute = (function (_super) {
__extends(Color2Attribute, _super);
function Color2Attribute() {
_super.call(this, webgl.Shader.COLOR2, VertexAttributeType.Float, 4);
}
return Color2Attribute;
}(VertexAttribute));
webgl.Color2Attribute = Color2Attribute;
(function (VertexAttributeType) {
VertexAttributeType[VertexAttributeType["Float"] = 0] = "Float";
})(webgl.VertexAttributeType || (webgl.VertexAttributeType = {}));
@ -6981,7 +7038,8 @@ var spine;
var webgl;
(function (webgl) {
var PolygonBatcher = (function () {
function PolygonBatcher(gl, maxVertices) {
function PolygonBatcher(gl, twoColorTint, maxVertices) {
if (twoColorTint === void 0) { twoColorTint = true; }
if (maxVertices === void 0) { maxVertices = 10920; }
this.isDrawing = false;
this.shader = null;
@ -6993,7 +7051,10 @@ var spine;
if (maxVertices > 10920)
throw new Error("Can't have more than 10920 triangles per batch: " + maxVertices);
this.gl = gl;
this.mesh = new webgl.Mesh(gl, [new webgl.Position2Attribute(), new webgl.ColorAttribute(), new webgl.TexCoordAttribute()], maxVertices, maxVertices * 3);
var attributes = twoColorTint ?
[new webgl.Position2Attribute(), new webgl.ColorAttribute(), new webgl.TexCoordAttribute(), new webgl.Color2Attribute()] :
[new webgl.Position2Attribute(), new webgl.ColorAttribute(), new webgl.TexCoordAttribute()];
this.mesh = new webgl.Mesh(gl, attributes, maxVertices, maxVertices * 3);
}
PolygonBatcher.prototype.begin = function (shader) {
var gl = this.gl;
@ -7071,7 +7132,8 @@ var spine;
var webgl;
(function (webgl) {
var SceneRenderer = (function () {
function SceneRenderer(canvas, gl) {
function SceneRenderer(canvas, gl, twoColorTint) {
if (twoColorTint === void 0) { twoColorTint = true; }
this.activeRenderer = null;
this.QUAD = [
0, 0, 1, 1, 1, 1, 0, 0,
@ -7084,11 +7146,11 @@ var spine;
this.canvas = canvas;
this.gl = gl;
this.camera = new webgl.OrthoCamera(canvas.width, canvas.height);
this.batcherShader = webgl.Shader.newColoredTextured(gl);
this.batcher = new webgl.PolygonBatcher(gl);
this.batcherShader = twoColorTint ? webgl.Shader.newTwoColorTextured(gl) : webgl.Shader.newColoredTextured(gl);
this.batcher = new webgl.PolygonBatcher(gl, twoColorTint);
this.shapesShader = webgl.Shader.newColored(gl);
this.shapes = new webgl.ShapeRenderer(gl);
this.skeletonRenderer = new webgl.SkeletonRenderer(gl);
this.skeletonRenderer = new webgl.SkeletonRenderer(gl, twoColorTint);
this.skeletonDebugRenderer = new webgl.SkeletonDebugRenderer(gl);
}
SceneRenderer.prototype.begin = function () {
@ -7526,6 +7588,11 @@ var spine;
var fs = "\n\t\t\t\t#ifdef GL_ES\n\t\t\t\t\t#define LOWP lowp\n\t\t\t\t\tprecision mediump float;\n\t\t\t\t#else\n\t\t\t\t\t#define LOWP\n\t\t\t\t#endif\n\t\t\t\tvarying LOWP vec4 v_color;\n\t\t\t\tvarying vec2 v_texCoords;\n\t\t\t\tuniform sampler2D u_texture;\n\n\t\t\t\tvoid main () {\n\t\t\t\t\tgl_FragColor = v_color * texture2D(u_texture, v_texCoords);\n\t\t\t\t}\n\t\t\t";
return new Shader(gl, vs, fs);
};
Shader.newTwoColorTextured = function (gl) {
var vs = "\n\t\t\t\tattribute vec4 " + Shader.POSITION + ";\n\t\t\t\tattribute vec4 " + Shader.COLOR + ";\n\t\t\t\tattribute vec4 " + Shader.COLOR2 + ";\n\t\t\t\tattribute vec2 " + Shader.TEXCOORDS + ";\n\t\t\t\tuniform mat4 " + Shader.MVP_MATRIX + ";\n\t\t\t\tvarying vec4 v_light;\n\t\t\t\tvarying vec4 v_dark;\n\t\t\t\tvarying vec2 v_texCoords;\n\n\t\t\t\tvoid main () {\n\t\t\t\t\tv_light = " + Shader.COLOR + ";\n\t\t\t\t\tv_dark = " + Shader.COLOR2 + ";\n\t\t\t\t\tv_texCoords = " + Shader.TEXCOORDS + ";\n\t\t\t\t\tgl_Position = " + Shader.MVP_MATRIX + " * " + Shader.POSITION + ";\n\t\t\t\t}\n\t\t\t";
var fs = "\n\t\t\t\t#ifdef GL_ES\n\t\t\t\t\t#define LOWP lowp\n\t\t\t\t\tprecision mediump float;\n\t\t\t\t#else\n\t\t\t\t\t#define LOWP\n\t\t\t\t#endif\n\t\t\t\tvarying LOWP vec4 v_light;\n\t\t\t\tvarying LOWP vec4 v_dark;\n\t\t\t\tvarying vec2 v_texCoords;\n\t\t\t\tuniform sampler2D u_texture;\n\n\t\t\t\tvoid main () {\n\t\t\t\t\tvec4 texColor = texture2D(u_texture, v_texCoords);\n\t\t\t\t\tfloat alpha = texColor.a * v_light.a;\n\t\t\t\t\tgl_FragColor.a = alpha;\n\t\t\t\t\tgl_FragColor.rgb = (1.0 - texColor.rgb) * v_dark.rgb * alpha + texColor.rgb * v_light.rgb;\n\t\t\t\t}\n\t\t\t";
return new Shader(gl, vs, fs);
};
Shader.newColored = function (gl) {
var vs = "\n\t\t\t\tattribute vec4 " + Shader.POSITION + ";\n\t\t\t\tattribute vec4 " + Shader.COLOR + ";\n\t\t\t\tuniform mat4 " + Shader.MVP_MATRIX + ";\n\t\t\t\tvarying vec4 v_color;\n\n\t\t\t\tvoid main () {\n\t\t\t\t\tv_color = " + Shader.COLOR + ";\n\t\t\t\t\tgl_Position = " + Shader.MVP_MATRIX + " * " + Shader.POSITION + ";\n\t\t\t\t}\n\t\t\t";
var fs = "\n\t\t\t\t#ifdef GL_ES\n\t\t\t\t\t#define LOWP lowp\n\t\t\t\t\tprecision mediump float;\n\t\t\t\t#else\n\t\t\t\t\t#define LOWP\n\t\t\t\t#endif\n\t\t\t\tvarying LOWP vec4 v_color;\n\n\t\t\t\tvoid main () {\n\t\t\t\t\tgl_FragColor = v_color;\n\t\t\t\t}\n\t\t\t";
@ -7534,6 +7601,7 @@ var spine;
Shader.MVP_MATRIX = "u_projTrans";
Shader.POSITION = "a_position";
Shader.COLOR = "a_color";
Shader.COLOR2 = "a_color2";
Shader.TEXCOORDS = "a_texCoords";
Shader.SAMPLER = "u_texture";
return Shader;
@ -7889,7 +7957,7 @@ var spine;
this.boneWidth = 2;
this.bounds = new spine.SkeletonBounds();
this.temp = new Array();
this.vertices = spine.Utils.newFloatArray(webgl.SkeletonRenderer.VERTEX_SIZE * 1024);
this.vertices = spine.Utils.newFloatArray(2 * 1024);
this.gl = gl;
}
SkeletonDebugRenderer.prototype.draw = function (shapes, skeleton, ignoredBones) {
@ -8038,12 +8106,28 @@ var spine;
(function (spine) {
var webgl;
(function (webgl) {
var Renderable = (function () {
function Renderable(vertices, numFloats) {
this.vertices = vertices;
this.numFloats = numFloats;
}
return Renderable;
}());
;
var SkeletonRenderer = (function () {
function SkeletonRenderer(gl) {
function SkeletonRenderer(gl, twoColorTint) {
if (twoColorTint === void 0) { twoColorTint = true; }
this.premultipliedAlpha = false;
this.tempColor = new spine.Color();
this.vertices = spine.Utils.newFloatArray(SkeletonRenderer.VERTEX_SIZE * 1024);
this.tempColor2 = new spine.Color();
this.vertexSize = 2 + 2 + 4;
this.twoColorTint = false;
this.renderable = new Renderable(null, 0);
this.gl = gl;
this.twoColorTint = twoColorTint;
if (twoColorTint)
this.vertexSize += 4;
this.vertices = spine.Utils.newFloatArray(this.vertexSize * 1024);
}
SkeletonRenderer.prototype.draw = function (batcher, skeleton) {
var premultipliedAlpha = this.premultipliedAlpha;
@ -8057,13 +8141,13 @@ var spine;
var texture = null;
if (attachment instanceof spine.RegionAttachment) {
var region = attachment;
vertices = this.computeRegionVertices(slot, region, premultipliedAlpha);
vertices = this.computeRegionVertices(slot, region, premultipliedAlpha, this.twoColorTint);
triangles = SkeletonRenderer.QUAD_TRIANGLES;
texture = region.region.renderObject.texture;
}
else if (attachment instanceof spine.MeshAttachment) {
var mesh = attachment;
vertices = this.computeMeshVertices(slot, mesh, premultipliedAlpha);
vertices = this.computeMeshVertices(slot, mesh, premultipliedAlpha, this.twoColorTint);
triangles = mesh.triangles;
texture = mesh.region.renderObject.texture;
}
@ -8075,11 +8159,13 @@ var spine;
blendMode = slotBlendMode;
batcher.setBlendMode(webgl.getSourceGLBlendMode(this.gl, blendMode, premultipliedAlpha), webgl.getDestGLBlendMode(this.gl, blendMode));
}
batcher.draw(texture, vertices, triangles);
var view = vertices.vertices.subarray(0, vertices.numFloats);
batcher.draw(texture, view, triangles);
}
}
};
SkeletonRenderer.prototype.computeRegionVertices = function (slot, region, pma) {
SkeletonRenderer.prototype.computeRegionVertices = function (slot, region, pma, twoColorTint) {
if (twoColorTint === void 0) { twoColorTint = false; }
var skeleton = slot.bone.skeleton;
var skeletonColor = skeleton.color;
var slotColor = slot.color;
@ -8088,36 +8174,72 @@ var spine;
var multiplier = pma ? alpha : 1;
var color = this.tempColor;
color.set(skeletonColor.r * slotColor.r * regionColor.r * multiplier, skeletonColor.g * slotColor.g * regionColor.g * multiplier, skeletonColor.b * slotColor.b * regionColor.b * multiplier, alpha);
region.computeWorldVertices(slot.bone, this.vertices, 0, SkeletonRenderer.VERTEX_SIZE);
var dark = this.tempColor2;
if (slot.darkColor == null)
dark.set(0, 0, 0, 1);
else
dark.setFromColor(slot.darkColor);
region.computeWorldVertices(slot.bone, this.vertices, 0, this.vertexSize);
var vertices = this.vertices;
var uvs = region.uvs;
vertices[spine.RegionAttachment.C1R] = color.r;
vertices[spine.RegionAttachment.C1G] = color.g;
vertices[spine.RegionAttachment.C1B] = color.b;
vertices[spine.RegionAttachment.C1A] = color.a;
vertices[spine.RegionAttachment.U1] = uvs[0];
vertices[spine.RegionAttachment.V1] = uvs[1];
vertices[spine.RegionAttachment.C2R] = color.r;
vertices[spine.RegionAttachment.C2G] = color.g;
vertices[spine.RegionAttachment.C2B] = color.b;
vertices[spine.RegionAttachment.C2A] = color.a;
vertices[spine.RegionAttachment.U2] = uvs[2];
vertices[spine.RegionAttachment.V2] = uvs[3];
vertices[spine.RegionAttachment.C3R] = color.r;
vertices[spine.RegionAttachment.C3G] = color.g;
vertices[spine.RegionAttachment.C3B] = color.b;
vertices[spine.RegionAttachment.C3A] = color.a;
vertices[spine.RegionAttachment.U3] = uvs[4];
vertices[spine.RegionAttachment.V3] = uvs[5];
vertices[spine.RegionAttachment.C4R] = color.r;
vertices[spine.RegionAttachment.C4G] = color.g;
vertices[spine.RegionAttachment.C4B] = color.b;
vertices[spine.RegionAttachment.C4A] = color.a;
vertices[spine.RegionAttachment.U4] = uvs[6];
vertices[spine.RegionAttachment.V4] = uvs[7];
return vertices;
var i = 2;
vertices[i++] = color.r;
vertices[i++] = color.g;
vertices[i++] = color.b;
vertices[i++] = color.a;
vertices[i++] = uvs[0];
vertices[i++] = uvs[1];
if (twoColorTint) {
vertices[i++] = dark.r;
vertices[i++] = dark.g;
vertices[i++] = dark.b;
vertices[i++] = 1;
}
i += 2;
vertices[i++] = color.r;
vertices[i++] = color.g;
vertices[i++] = color.b;
vertices[i++] = color.a;
vertices[i++] = uvs[2];
vertices[i++] = uvs[3];
if (twoColorTint) {
vertices[i++] = dark.r;
vertices[i++] = dark.g;
vertices[i++] = dark.b;
vertices[i++] = 1;
}
i += 2;
vertices[i++] = color.r;
vertices[i++] = color.g;
vertices[i++] = color.b;
vertices[i++] = color.a;
vertices[i++] = uvs[4];
vertices[i++] = uvs[5];
if (twoColorTint) {
vertices[i++] = dark.r;
vertices[i++] = dark.g;
vertices[i++] = dark.b;
vertices[i++] = 1;
}
i += 2;
vertices[i++] = color.r;
vertices[i++] = color.g;
vertices[i++] = color.b;
vertices[i++] = color.a;
vertices[i++] = uvs[6];
vertices[i++] = uvs[7];
if (twoColorTint) {
vertices[i++] = dark.r;
vertices[i++] = dark.g;
vertices[i++] = dark.b;
vertices[i++] = 1;
}
this.renderable.vertices = vertices;
this.renderable.numFloats = 4 * (twoColorTint ? 12 : 8);
return this.renderable;
};
SkeletonRenderer.prototype.computeMeshVertices = function (slot, mesh, pma) {
SkeletonRenderer.prototype.computeMeshVertices = function (slot, mesh, pma, twoColorTint) {
if (twoColorTint === void 0) { twoColorTint = false; }
var skeleton = slot.bone.skeleton;
var skeletonColor = skeleton.color;
var slotColor = slot.color;
@ -8126,25 +8248,48 @@ var spine;
var multiplier = pma ? alpha : 1;
var color = this.tempColor;
color.set(skeletonColor.r * slotColor.r * regionColor.r * multiplier, skeletonColor.g * slotColor.g * regionColor.g * multiplier, skeletonColor.b * slotColor.b * regionColor.b * multiplier, alpha);
var dark = this.tempColor2;
if (slot.darkColor == null)
dark.set(0, 0, 0, 1);
else
dark.setFromColor(slot.darkColor);
var numVertices = mesh.worldVerticesLength / 2;
if (this.vertices.length < mesh.worldVerticesLength) {
this.vertices = spine.Utils.newFloatArray(mesh.worldVerticesLength);
}
var vertices = this.vertices;
mesh.computeWorldVertices(slot, 0, mesh.worldVerticesLength, vertices, 0, SkeletonRenderer.VERTEX_SIZE);
mesh.computeWorldVertices(slot, 0, mesh.worldVerticesLength, vertices, 0, this.vertexSize);
var uvs = mesh.uvs;
for (var i = 0, n = numVertices, u = 0, v = 2; i < n; i++) {
vertices[v++] = color.r;
vertices[v++] = color.g;
vertices[v++] = color.b;
vertices[v++] = color.a;
vertices[v++] = uvs[u++];
vertices[v++] = uvs[u++];
v += 2;
if (!twoColorTint) {
for (var i = 0, n = numVertices, u = 0, v = 2; i < n; i++) {
vertices[v++] = color.r;
vertices[v++] = color.g;
vertices[v++] = color.b;
vertices[v++] = color.a;
vertices[v++] = uvs[u++];
vertices[v++] = uvs[u++];
v += 2;
}
}
return vertices;
else {
for (var i = 0, n = numVertices, u = 0, v = 2; i < n; i++) {
vertices[v++] = color.r;
vertices[v++] = color.g;
vertices[v++] = color.b;
vertices[v++] = color.a;
vertices[v++] = uvs[u++];
vertices[v++] = uvs[u++];
vertices[v++] = dark.r;
vertices[v++] = dark.g;
vertices[v++] = dark.b;
vertices[v++] = 1;
v += 2;
}
}
this.renderable.vertices = vertices;
this.renderable.numFloats = numVertices * (twoColorTint ? 12 : 8);
return this.renderable;
};
SkeletonRenderer.VERTEX_SIZE = 2 + 2 + 4;
SkeletonRenderer.QUAD_TRIANGLES = [0, 1, 2, 2, 3, 0];
return SkeletonRenderer;
}());

File diff suppressed because one or more lines are too long

View File

@ -1122,4 +1122,15 @@ declare module spine {
length: number;
[n: number]: T;
}
class WindowedMean {
values: Array<number>;
addedValues: number;
lastValue: number;
mean: number;
dirty: boolean;
constructor(windowSize?: number);
hasEnoughData(): boolean;
addValue(value: number): void;
getMean(): number;
}
}

View File

@ -4376,8 +4376,10 @@ var spine;
if (color != null)
data.color.setFromString(color);
var dark = this.getValue(slotMap, "dark", null);
if (dark != null)
data.darkColor.setFromString(color);
if (dark != null) {
data.darkColor = new spine.Color(1, 1, 1, 1);
data.darkColor.setFromString(dark);
}
data.attachmentName = this.getValue(slotMap, "attachment", null);
data.blendMode = SkeletonJson.blendModeFromString(this.getValue(slotMap, "blend", "normal"));
skeletonData.slots.push(data);
@ -4680,7 +4682,7 @@ var spine;
var valueMap = timelineMap[i];
var light = new spine.Color();
var dark = new spine.Color();
light.setFromString(valueMap.color);
light.setFromString(valueMap.light);
dark.setFromString(valueMap.dark);
timeline.setFrame(frameIndex, valueMap.time, light.r, light.g, light.b, light.a, dark.r, dark.g, dark.b);
this.readCurve(valueMap, timeline, frameIndex);
@ -5818,5 +5820,44 @@ var spine;
return TimeKeeper;
}());
spine.TimeKeeper = TimeKeeper;
var WindowedMean = (function () {
function WindowedMean(windowSize) {
if (windowSize === void 0) { windowSize = 32; }
this.addedValues = 0;
this.lastValue = 0;
this.mean = 0;
this.dirty = true;
this.values = new Array(windowSize);
}
WindowedMean.prototype.hasEnoughData = function () {
return this.addedValues >= this.values.length;
};
WindowedMean.prototype.addValue = function (value) {
if (this.addedValues < this.values.length)
this.addedValues++;
this.values[this.lastValue++] = value;
if (this.lastValue > this.values.length - 1)
this.lastValue = 0;
this.dirty = true;
};
WindowedMean.prototype.getMean = function () {
if (this.hasEnoughData()) {
if (this.dirty) {
var mean = 0;
for (var i = 0; i < this.values.length; i++) {
mean += this.values[i];
}
this.mean = mean / this.values.length;
this.dirty = false;
}
return this.mean;
}
else {
return 0;
}
};
return WindowedMean;
}());
spine.WindowedMean = WindowedMean;
})(spine || (spine = {}));
//# sourceMappingURL=spine-canvas.js.map

File diff suppressed because one or more lines are too long

View File

@ -1091,4 +1091,15 @@ declare module spine {
length: number;
[n: number]: T;
}
class WindowedMean {
values: Array<number>;
addedValues: number;
lastValue: number;
mean: number;
dirty: boolean;
constructor(windowSize?: number);
hasEnoughData(): boolean;
addValue(value: number): void;
getMean(): number;
}
}

View File

@ -4065,8 +4065,10 @@ var spine;
if (color != null)
data.color.setFromString(color);
var dark = this.getValue(slotMap, "dark", null);
if (dark != null)
data.darkColor.setFromString(color);
if (dark != null) {
data.darkColor = new spine.Color(1, 1, 1, 1);
data.darkColor.setFromString(dark);
}
data.attachmentName = this.getValue(slotMap, "attachment", null);
data.blendMode = SkeletonJson.blendModeFromString(this.getValue(slotMap, "blend", "normal"));
skeletonData.slots.push(data);
@ -4369,7 +4371,7 @@ var spine;
var valueMap = timelineMap[i];
var light = new spine.Color();
var dark = new spine.Color();
light.setFromString(valueMap.color);
light.setFromString(valueMap.light);
dark.setFromString(valueMap.dark);
timeline.setFrame(frameIndex, valueMap.time, light.r, light.g, light.b, light.a, dark.r, dark.g, dark.b);
this.readCurve(valueMap, timeline, frameIndex);
@ -5573,5 +5575,44 @@ var spine;
return TimeKeeper;
}());
spine.TimeKeeper = TimeKeeper;
var WindowedMean = (function () {
function WindowedMean(windowSize) {
if (windowSize === void 0) { windowSize = 32; }
this.addedValues = 0;
this.lastValue = 0;
this.mean = 0;
this.dirty = true;
this.values = new Array(windowSize);
}
WindowedMean.prototype.hasEnoughData = function () {
return this.addedValues >= this.values.length;
};
WindowedMean.prototype.addValue = function (value) {
if (this.addedValues < this.values.length)
this.addedValues++;
this.values[this.lastValue++] = value;
if (this.lastValue > this.values.length - 1)
this.lastValue = 0;
this.dirty = true;
};
WindowedMean.prototype.getMean = function () {
if (this.hasEnoughData()) {
if (this.dirty) {
var mean = 0;
for (var i = 0; i < this.values.length; i++) {
mean += this.values[i];
}
this.mean = mean / this.values.length;
this.dirty = false;
}
return this.mean;
}
else {
return 0;
}
};
return WindowedMean;
}());
spine.WindowedMean = WindowedMean;
})(spine || (spine = {}));
//# sourceMappingURL=spine-core.js.map

File diff suppressed because one or more lines are too long

View File

@ -1091,6 +1091,17 @@ declare module spine {
length: number;
[n: number]: T;
}
class WindowedMean {
values: Array<number>;
addedValues: number;
lastValue: number;
mean: number;
dirty: boolean;
constructor(windowSize?: number);
hasEnoughData(): boolean;
addValue(value: number): void;
getMean(): number;
}
}
declare module spine.threejs {
class AssetManager extends spine.AssetManager {

View File

@ -4065,8 +4065,10 @@ var spine;
if (color != null)
data.color.setFromString(color);
var dark = this.getValue(slotMap, "dark", null);
if (dark != null)
data.darkColor.setFromString(color);
if (dark != null) {
data.darkColor = new spine.Color(1, 1, 1, 1);
data.darkColor.setFromString(dark);
}
data.attachmentName = this.getValue(slotMap, "attachment", null);
data.blendMode = SkeletonJson.blendModeFromString(this.getValue(slotMap, "blend", "normal"));
skeletonData.slots.push(data);
@ -4369,7 +4371,7 @@ var spine;
var valueMap = timelineMap[i];
var light = new spine.Color();
var dark = new spine.Color();
light.setFromString(valueMap.color);
light.setFromString(valueMap.light);
dark.setFromString(valueMap.dark);
timeline.setFrame(frameIndex, valueMap.time, light.r, light.g, light.b, light.a, dark.r, dark.g, dark.b);
this.readCurve(valueMap, timeline, frameIndex);
@ -5573,6 +5575,45 @@ var spine;
return TimeKeeper;
}());
spine.TimeKeeper = TimeKeeper;
var WindowedMean = (function () {
function WindowedMean(windowSize) {
if (windowSize === void 0) { windowSize = 32; }
this.addedValues = 0;
this.lastValue = 0;
this.mean = 0;
this.dirty = true;
this.values = new Array(windowSize);
}
WindowedMean.prototype.hasEnoughData = function () {
return this.addedValues >= this.values.length;
};
WindowedMean.prototype.addValue = function (value) {
if (this.addedValues < this.values.length)
this.addedValues++;
this.values[this.lastValue++] = value;
if (this.lastValue > this.values.length - 1)
this.lastValue = 0;
this.dirty = true;
};
WindowedMean.prototype.getMean = function () {
if (this.hasEnoughData()) {
if (this.dirty) {
var mean = 0;
for (var i = 0; i < this.values.length; i++) {
mean += this.values[i];
}
this.mean = mean / this.values.length;
this.dirty = false;
}
return this.mean;
}
else {
return 0;
}
};
return WindowedMean;
}());
spine.WindowedMean = WindowedMean;
})(spine || (spine = {}));
var spine;
(function (spine) {

File diff suppressed because one or more lines are too long

View File

@ -1091,6 +1091,17 @@ declare module spine {
length: number;
[n: number]: T;
}
class WindowedMean {
values: Array<number>;
addedValues: number;
lastValue: number;
mean: number;
dirty: boolean;
constructor(windowSize?: number);
hasEnoughData(): boolean;
addValue(value: number): void;
getMean(): number;
}
}
declare module spine.webgl {
class AssetManager extends spine.AssetManager {
@ -1243,6 +1254,7 @@ declare module spine.webgl {
numIndices(): number;
setIndicesLength(length: number): void;
getIndices(): Uint16Array;
getVertexSizeInFloats(): number;
constructor(gl: WebGLRenderingContext, attributes: VertexAttribute[], maxVertices: number, maxIndices: number);
setVertices(vertices: Array<number>): void;
setIndices(indices: Array<number>): void;
@ -1271,6 +1283,9 @@ declare module spine.webgl {
class ColorAttribute extends VertexAttribute {
constructor();
}
class Color2Attribute extends VertexAttribute {
constructor();
}
enum VertexAttributeType {
Float = 0,
}
@ -1287,7 +1302,7 @@ declare module spine.webgl {
private indicesLength;
private srcBlend;
private dstBlend;
constructor(gl: WebGLRenderingContext, maxVertices?: number);
constructor(gl: WebGLRenderingContext, twoColorTint?: boolean, maxVertices?: number);
begin(shader: Shader): void;
setBlendMode(srcBlend: number, dstBlend: number): void;
draw(texture: GLTexture, vertices: ArrayLike<number>, indices: Array<number>): void;
@ -1312,7 +1327,7 @@ declare module spine.webgl {
private QUAD;
private QUAD_TRIANGLES;
private WHITE;
constructor(canvas: HTMLCanvasElement, gl: WebGLRenderingContext);
constructor(canvas: HTMLCanvasElement, gl: WebGLRenderingContext, twoColorTint?: boolean);
begin(): void;
drawSkeleton(skeleton: Skeleton, premultipliedAlpha?: boolean): void;
drawSkeletonDebug(skeleton: Skeleton, premultipliedAlpha?: boolean, ignoredBones?: Array<string>): void;
@ -1345,6 +1360,7 @@ declare module spine.webgl {
static MVP_MATRIX: string;
static POSITION: string;
static COLOR: string;
static COLOR2: string;
static TEXCOORDS: string;
static SAMPLER: string;
private gl;
@ -1375,6 +1391,7 @@ declare module spine.webgl {
getAttributeLocation(attribute: string): number;
dispose(): void;
static newColoredTextured(gl: WebGLRenderingContext): Shader;
static newTwoColorTextured(gl: WebGLRenderingContext): Shader;
static newColored(gl: WebGLRenderingContext): Shader;
}
}
@ -1448,16 +1465,19 @@ declare module spine.webgl {
}
declare module spine.webgl {
class SkeletonRenderer {
static VERTEX_SIZE: number;
static QUAD_TRIANGLES: number[];
premultipliedAlpha: boolean;
private gl;
private tempColor;
private tempColor2;
private vertices;
constructor(gl: WebGLRenderingContext);
private vertexSize;
private twoColorTint;
private renderable;
constructor(gl: WebGLRenderingContext, twoColorTint?: boolean);
draw(batcher: PolygonBatcher, skeleton: Skeleton): void;
computeRegionVertices(slot: Slot, region: RegionAttachment, pma: boolean): ArrayLike<number>;
computeMeshVertices(slot: Slot, mesh: MeshAttachment, pma: boolean): ArrayLike<number>;
private computeRegionVertices(slot, region, pma, twoColorTint?);
private computeMeshVertices(slot, mesh, pma, twoColorTint?);
}
}
declare module spine.webgl {

View File

@ -4065,8 +4065,10 @@ var spine;
if (color != null)
data.color.setFromString(color);
var dark = this.getValue(slotMap, "dark", null);
if (dark != null)
data.darkColor.setFromString(color);
if (dark != null) {
data.darkColor = new spine.Color(1, 1, 1, 1);
data.darkColor.setFromString(dark);
}
data.attachmentName = this.getValue(slotMap, "attachment", null);
data.blendMode = SkeletonJson.blendModeFromString(this.getValue(slotMap, "blend", "normal"));
skeletonData.slots.push(data);
@ -4369,7 +4371,7 @@ var spine;
var valueMap = timelineMap[i];
var light = new spine.Color();
var dark = new spine.Color();
light.setFromString(valueMap.color);
light.setFromString(valueMap.light);
dark.setFromString(valueMap.dark);
timeline.setFrame(frameIndex, valueMap.time, light.r, light.g, light.b, light.a, dark.r, dark.g, dark.b);
this.readCurve(valueMap, timeline, frameIndex);
@ -5573,6 +5575,45 @@ var spine;
return TimeKeeper;
}());
spine.TimeKeeper = TimeKeeper;
var WindowedMean = (function () {
function WindowedMean(windowSize) {
if (windowSize === void 0) { windowSize = 32; }
this.addedValues = 0;
this.lastValue = 0;
this.mean = 0;
this.dirty = true;
this.values = new Array(windowSize);
}
WindowedMean.prototype.hasEnoughData = function () {
return this.addedValues >= this.values.length;
};
WindowedMean.prototype.addValue = function (value) {
if (this.addedValues < this.values.length)
this.addedValues++;
this.values[this.lastValue++] = value;
if (this.lastValue > this.values.length - 1)
this.lastValue = 0;
this.dirty = true;
};
WindowedMean.prototype.getMean = function () {
if (this.hasEnoughData()) {
if (this.dirty) {
var mean = 0;
for (var i = 0; i < this.values.length; i++) {
mean += this.values[i];
}
this.mean = mean / this.values.length;
this.dirty = false;
}
return this.mean;
}
else {
return 0;
}
};
return WindowedMean;
}());
spine.WindowedMean = WindowedMean;
})(spine || (spine = {}));
var spine;
(function (spine) {
@ -6319,6 +6360,14 @@ var spine;
};
Mesh.prototype.getIndices = function () { return this.indices; };
;
Mesh.prototype.getVertexSizeInFloats = function () {
var size = 0;
for (var i = 0; i < this.attributes.length; i++) {
var attribute = this.attributes[i];
size += attribute.numElements;
}
return size;
};
Mesh.prototype.setVertices = function (vertices) {
this.dirtyVertices = true;
if (vertices.length > this.vertices.length)
@ -6379,7 +6428,7 @@ var spine;
this.verticesBuffer = gl.createBuffer();
}
gl.bindBuffer(gl.ARRAY_BUFFER, this.verticesBuffer);
gl.bufferData(gl.ARRAY_BUFFER, this.vertices.subarray(0, this.verticesLength), gl.STATIC_DRAW);
gl.bufferData(gl.ARRAY_BUFFER, this.vertices.subarray(0, this.verticesLength), gl.DYNAMIC_DRAW);
this.dirtyVertices = false;
}
if (this.dirtyIndices) {
@ -6387,7 +6436,7 @@ var spine;
this.indicesBuffer = gl.createBuffer();
}
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indicesBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices.subarray(0, this.indicesLength), gl.STATIC_DRAW);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices.subarray(0, this.indicesLength), gl.DYNAMIC_DRAW);
this.dirtyIndices = false;
}
};
@ -6441,6 +6490,14 @@ var spine;
return ColorAttribute;
}(VertexAttribute));
webgl.ColorAttribute = ColorAttribute;
var Color2Attribute = (function (_super) {
__extends(Color2Attribute, _super);
function Color2Attribute() {
_super.call(this, webgl.Shader.COLOR2, VertexAttributeType.Float, 4);
}
return Color2Attribute;
}(VertexAttribute));
webgl.Color2Attribute = Color2Attribute;
(function (VertexAttributeType) {
VertexAttributeType[VertexAttributeType["Float"] = 0] = "Float";
})(webgl.VertexAttributeType || (webgl.VertexAttributeType = {}));
@ -6452,7 +6509,8 @@ var spine;
var webgl;
(function (webgl) {
var PolygonBatcher = (function () {
function PolygonBatcher(gl, maxVertices) {
function PolygonBatcher(gl, twoColorTint, maxVertices) {
if (twoColorTint === void 0) { twoColorTint = true; }
if (maxVertices === void 0) { maxVertices = 10920; }
this.isDrawing = false;
this.shader = null;
@ -6464,7 +6522,10 @@ var spine;
if (maxVertices > 10920)
throw new Error("Can't have more than 10920 triangles per batch: " + maxVertices);
this.gl = gl;
this.mesh = new webgl.Mesh(gl, [new webgl.Position2Attribute(), new webgl.ColorAttribute(), new webgl.TexCoordAttribute()], maxVertices, maxVertices * 3);
var attributes = twoColorTint ?
[new webgl.Position2Attribute(), new webgl.ColorAttribute(), new webgl.TexCoordAttribute(), new webgl.Color2Attribute()] :
[new webgl.Position2Attribute(), new webgl.ColorAttribute(), new webgl.TexCoordAttribute()];
this.mesh = new webgl.Mesh(gl, attributes, maxVertices, maxVertices * 3);
}
PolygonBatcher.prototype.begin = function (shader) {
var gl = this.gl;
@ -6542,7 +6603,8 @@ var spine;
var webgl;
(function (webgl) {
var SceneRenderer = (function () {
function SceneRenderer(canvas, gl) {
function SceneRenderer(canvas, gl, twoColorTint) {
if (twoColorTint === void 0) { twoColorTint = true; }
this.activeRenderer = null;
this.QUAD = [
0, 0, 1, 1, 1, 1, 0, 0,
@ -6555,11 +6617,11 @@ var spine;
this.canvas = canvas;
this.gl = gl;
this.camera = new webgl.OrthoCamera(canvas.width, canvas.height);
this.batcherShader = webgl.Shader.newColoredTextured(gl);
this.batcher = new webgl.PolygonBatcher(gl);
this.batcherShader = twoColorTint ? webgl.Shader.newTwoColorTextured(gl) : webgl.Shader.newColoredTextured(gl);
this.batcher = new webgl.PolygonBatcher(gl, twoColorTint);
this.shapesShader = webgl.Shader.newColored(gl);
this.shapes = new webgl.ShapeRenderer(gl);
this.skeletonRenderer = new webgl.SkeletonRenderer(gl);
this.skeletonRenderer = new webgl.SkeletonRenderer(gl, twoColorTint);
this.skeletonDebugRenderer = new webgl.SkeletonDebugRenderer(gl);
}
SceneRenderer.prototype.begin = function () {
@ -6997,6 +7059,11 @@ var spine;
var fs = "\n\t\t\t\t#ifdef GL_ES\n\t\t\t\t\t#define LOWP lowp\n\t\t\t\t\tprecision mediump float;\n\t\t\t\t#else\n\t\t\t\t\t#define LOWP\n\t\t\t\t#endif\n\t\t\t\tvarying LOWP vec4 v_color;\n\t\t\t\tvarying vec2 v_texCoords;\n\t\t\t\tuniform sampler2D u_texture;\n\n\t\t\t\tvoid main () {\n\t\t\t\t\tgl_FragColor = v_color * texture2D(u_texture, v_texCoords);\n\t\t\t\t}\n\t\t\t";
return new Shader(gl, vs, fs);
};
Shader.newTwoColorTextured = function (gl) {
var vs = "\n\t\t\t\tattribute vec4 " + Shader.POSITION + ";\n\t\t\t\tattribute vec4 " + Shader.COLOR + ";\n\t\t\t\tattribute vec4 " + Shader.COLOR2 + ";\n\t\t\t\tattribute vec2 " + Shader.TEXCOORDS + ";\n\t\t\t\tuniform mat4 " + Shader.MVP_MATRIX + ";\n\t\t\t\tvarying vec4 v_light;\n\t\t\t\tvarying vec4 v_dark;\n\t\t\t\tvarying vec2 v_texCoords;\n\n\t\t\t\tvoid main () {\n\t\t\t\t\tv_light = " + Shader.COLOR + ";\n\t\t\t\t\tv_dark = " + Shader.COLOR2 + ";\n\t\t\t\t\tv_texCoords = " + Shader.TEXCOORDS + ";\n\t\t\t\t\tgl_Position = " + Shader.MVP_MATRIX + " * " + Shader.POSITION + ";\n\t\t\t\t}\n\t\t\t";
var fs = "\n\t\t\t\t#ifdef GL_ES\n\t\t\t\t\t#define LOWP lowp\n\t\t\t\t\tprecision mediump float;\n\t\t\t\t#else\n\t\t\t\t\t#define LOWP\n\t\t\t\t#endif\n\t\t\t\tvarying LOWP vec4 v_light;\n\t\t\t\tvarying LOWP vec4 v_dark;\n\t\t\t\tvarying vec2 v_texCoords;\n\t\t\t\tuniform sampler2D u_texture;\n\n\t\t\t\tvoid main () {\n\t\t\t\t\tvec4 texColor = texture2D(u_texture, v_texCoords);\n\t\t\t\t\tfloat alpha = texColor.a * v_light.a;\n\t\t\t\t\tgl_FragColor.a = alpha;\n\t\t\t\t\tgl_FragColor.rgb = (1.0 - texColor.rgb) * v_dark.rgb * alpha + texColor.rgb * v_light.rgb;\n\t\t\t\t}\n\t\t\t";
return new Shader(gl, vs, fs);
};
Shader.newColored = function (gl) {
var vs = "\n\t\t\t\tattribute vec4 " + Shader.POSITION + ";\n\t\t\t\tattribute vec4 " + Shader.COLOR + ";\n\t\t\t\tuniform mat4 " + Shader.MVP_MATRIX + ";\n\t\t\t\tvarying vec4 v_color;\n\n\t\t\t\tvoid main () {\n\t\t\t\t\tv_color = " + Shader.COLOR + ";\n\t\t\t\t\tgl_Position = " + Shader.MVP_MATRIX + " * " + Shader.POSITION + ";\n\t\t\t\t}\n\t\t\t";
var fs = "\n\t\t\t\t#ifdef GL_ES\n\t\t\t\t\t#define LOWP lowp\n\t\t\t\t\tprecision mediump float;\n\t\t\t\t#else\n\t\t\t\t\t#define LOWP\n\t\t\t\t#endif\n\t\t\t\tvarying LOWP vec4 v_color;\n\n\t\t\t\tvoid main () {\n\t\t\t\t\tgl_FragColor = v_color;\n\t\t\t\t}\n\t\t\t";
@ -7005,6 +7072,7 @@ var spine;
Shader.MVP_MATRIX = "u_projTrans";
Shader.POSITION = "a_position";
Shader.COLOR = "a_color";
Shader.COLOR2 = "a_color2";
Shader.TEXCOORDS = "a_texCoords";
Shader.SAMPLER = "u_texture";
return Shader;
@ -7360,7 +7428,7 @@ var spine;
this.boneWidth = 2;
this.bounds = new spine.SkeletonBounds();
this.temp = new Array();
this.vertices = spine.Utils.newFloatArray(webgl.SkeletonRenderer.VERTEX_SIZE * 1024);
this.vertices = spine.Utils.newFloatArray(2 * 1024);
this.gl = gl;
}
SkeletonDebugRenderer.prototype.draw = function (shapes, skeleton, ignoredBones) {
@ -7509,12 +7577,28 @@ var spine;
(function (spine) {
var webgl;
(function (webgl) {
var Renderable = (function () {
function Renderable(vertices, numFloats) {
this.vertices = vertices;
this.numFloats = numFloats;
}
return Renderable;
}());
;
var SkeletonRenderer = (function () {
function SkeletonRenderer(gl) {
function SkeletonRenderer(gl, twoColorTint) {
if (twoColorTint === void 0) { twoColorTint = true; }
this.premultipliedAlpha = false;
this.tempColor = new spine.Color();
this.vertices = spine.Utils.newFloatArray(SkeletonRenderer.VERTEX_SIZE * 1024);
this.tempColor2 = new spine.Color();
this.vertexSize = 2 + 2 + 4;
this.twoColorTint = false;
this.renderable = new Renderable(null, 0);
this.gl = gl;
this.twoColorTint = twoColorTint;
if (twoColorTint)
this.vertexSize += 4;
this.vertices = spine.Utils.newFloatArray(this.vertexSize * 1024);
}
SkeletonRenderer.prototype.draw = function (batcher, skeleton) {
var premultipliedAlpha = this.premultipliedAlpha;
@ -7528,13 +7612,13 @@ var spine;
var texture = null;
if (attachment instanceof spine.RegionAttachment) {
var region = attachment;
vertices = this.computeRegionVertices(slot, region, premultipliedAlpha);
vertices = this.computeRegionVertices(slot, region, premultipliedAlpha, this.twoColorTint);
triangles = SkeletonRenderer.QUAD_TRIANGLES;
texture = region.region.renderObject.texture;
}
else if (attachment instanceof spine.MeshAttachment) {
var mesh = attachment;
vertices = this.computeMeshVertices(slot, mesh, premultipliedAlpha);
vertices = this.computeMeshVertices(slot, mesh, premultipliedAlpha, this.twoColorTint);
triangles = mesh.triangles;
texture = mesh.region.renderObject.texture;
}
@ -7546,11 +7630,13 @@ var spine;
blendMode = slotBlendMode;
batcher.setBlendMode(webgl.getSourceGLBlendMode(this.gl, blendMode, premultipliedAlpha), webgl.getDestGLBlendMode(this.gl, blendMode));
}
batcher.draw(texture, vertices, triangles);
var view = vertices.vertices.subarray(0, vertices.numFloats);
batcher.draw(texture, view, triangles);
}
}
};
SkeletonRenderer.prototype.computeRegionVertices = function (slot, region, pma) {
SkeletonRenderer.prototype.computeRegionVertices = function (slot, region, pma, twoColorTint) {
if (twoColorTint === void 0) { twoColorTint = false; }
var skeleton = slot.bone.skeleton;
var skeletonColor = skeleton.color;
var slotColor = slot.color;
@ -7559,36 +7645,72 @@ var spine;
var multiplier = pma ? alpha : 1;
var color = this.tempColor;
color.set(skeletonColor.r * slotColor.r * regionColor.r * multiplier, skeletonColor.g * slotColor.g * regionColor.g * multiplier, skeletonColor.b * slotColor.b * regionColor.b * multiplier, alpha);
region.computeWorldVertices(slot.bone, this.vertices, 0, SkeletonRenderer.VERTEX_SIZE);
var dark = this.tempColor2;
if (slot.darkColor == null)
dark.set(0, 0, 0, 1);
else
dark.setFromColor(slot.darkColor);
region.computeWorldVertices(slot.bone, this.vertices, 0, this.vertexSize);
var vertices = this.vertices;
var uvs = region.uvs;
vertices[spine.RegionAttachment.C1R] = color.r;
vertices[spine.RegionAttachment.C1G] = color.g;
vertices[spine.RegionAttachment.C1B] = color.b;
vertices[spine.RegionAttachment.C1A] = color.a;
vertices[spine.RegionAttachment.U1] = uvs[0];
vertices[spine.RegionAttachment.V1] = uvs[1];
vertices[spine.RegionAttachment.C2R] = color.r;
vertices[spine.RegionAttachment.C2G] = color.g;
vertices[spine.RegionAttachment.C2B] = color.b;
vertices[spine.RegionAttachment.C2A] = color.a;
vertices[spine.RegionAttachment.U2] = uvs[2];
vertices[spine.RegionAttachment.V2] = uvs[3];
vertices[spine.RegionAttachment.C3R] = color.r;
vertices[spine.RegionAttachment.C3G] = color.g;
vertices[spine.RegionAttachment.C3B] = color.b;
vertices[spine.RegionAttachment.C3A] = color.a;
vertices[spine.RegionAttachment.U3] = uvs[4];
vertices[spine.RegionAttachment.V3] = uvs[5];
vertices[spine.RegionAttachment.C4R] = color.r;
vertices[spine.RegionAttachment.C4G] = color.g;
vertices[spine.RegionAttachment.C4B] = color.b;
vertices[spine.RegionAttachment.C4A] = color.a;
vertices[spine.RegionAttachment.U4] = uvs[6];
vertices[spine.RegionAttachment.V4] = uvs[7];
return vertices;
var i = 2;
vertices[i++] = color.r;
vertices[i++] = color.g;
vertices[i++] = color.b;
vertices[i++] = color.a;
vertices[i++] = uvs[0];
vertices[i++] = uvs[1];
if (twoColorTint) {
vertices[i++] = dark.r;
vertices[i++] = dark.g;
vertices[i++] = dark.b;
vertices[i++] = 1;
}
i += 2;
vertices[i++] = color.r;
vertices[i++] = color.g;
vertices[i++] = color.b;
vertices[i++] = color.a;
vertices[i++] = uvs[2];
vertices[i++] = uvs[3];
if (twoColorTint) {
vertices[i++] = dark.r;
vertices[i++] = dark.g;
vertices[i++] = dark.b;
vertices[i++] = 1;
}
i += 2;
vertices[i++] = color.r;
vertices[i++] = color.g;
vertices[i++] = color.b;
vertices[i++] = color.a;
vertices[i++] = uvs[4];
vertices[i++] = uvs[5];
if (twoColorTint) {
vertices[i++] = dark.r;
vertices[i++] = dark.g;
vertices[i++] = dark.b;
vertices[i++] = 1;
}
i += 2;
vertices[i++] = color.r;
vertices[i++] = color.g;
vertices[i++] = color.b;
vertices[i++] = color.a;
vertices[i++] = uvs[6];
vertices[i++] = uvs[7];
if (twoColorTint) {
vertices[i++] = dark.r;
vertices[i++] = dark.g;
vertices[i++] = dark.b;
vertices[i++] = 1;
}
this.renderable.vertices = vertices;
this.renderable.numFloats = 4 * (twoColorTint ? 12 : 8);
return this.renderable;
};
SkeletonRenderer.prototype.computeMeshVertices = function (slot, mesh, pma) {
SkeletonRenderer.prototype.computeMeshVertices = function (slot, mesh, pma, twoColorTint) {
if (twoColorTint === void 0) { twoColorTint = false; }
var skeleton = slot.bone.skeleton;
var skeletonColor = skeleton.color;
var slotColor = slot.color;
@ -7597,25 +7719,48 @@ var spine;
var multiplier = pma ? alpha : 1;
var color = this.tempColor;
color.set(skeletonColor.r * slotColor.r * regionColor.r * multiplier, skeletonColor.g * slotColor.g * regionColor.g * multiplier, skeletonColor.b * slotColor.b * regionColor.b * multiplier, alpha);
var dark = this.tempColor2;
if (slot.darkColor == null)
dark.set(0, 0, 0, 1);
else
dark.setFromColor(slot.darkColor);
var numVertices = mesh.worldVerticesLength / 2;
if (this.vertices.length < mesh.worldVerticesLength) {
this.vertices = spine.Utils.newFloatArray(mesh.worldVerticesLength);
}
var vertices = this.vertices;
mesh.computeWorldVertices(slot, 0, mesh.worldVerticesLength, vertices, 0, SkeletonRenderer.VERTEX_SIZE);
mesh.computeWorldVertices(slot, 0, mesh.worldVerticesLength, vertices, 0, this.vertexSize);
var uvs = mesh.uvs;
for (var i = 0, n = numVertices, u = 0, v = 2; i < n; i++) {
vertices[v++] = color.r;
vertices[v++] = color.g;
vertices[v++] = color.b;
vertices[v++] = color.a;
vertices[v++] = uvs[u++];
vertices[v++] = uvs[u++];
v += 2;
if (!twoColorTint) {
for (var i = 0, n = numVertices, u = 0, v = 2; i < n; i++) {
vertices[v++] = color.r;
vertices[v++] = color.g;
vertices[v++] = color.b;
vertices[v++] = color.a;
vertices[v++] = uvs[u++];
vertices[v++] = uvs[u++];
v += 2;
}
}
return vertices;
else {
for (var i = 0, n = numVertices, u = 0, v = 2; i < n; i++) {
vertices[v++] = color.r;
vertices[v++] = color.g;
vertices[v++] = color.b;
vertices[v++] = color.a;
vertices[v++] = uvs[u++];
vertices[v++] = uvs[u++];
vertices[v++] = dark.r;
vertices[v++] = dark.g;
vertices[v++] = dark.b;
vertices[v++] = 1;
v += 2;
}
}
this.renderable.vertices = vertices;
this.renderable.numFloats = numVertices * (twoColorTint ? 12 : 8);
return this.renderable;
};
SkeletonRenderer.VERTEX_SIZE = 2 + 2 + 4;
SkeletonRenderer.QUAD_TRIANGLES = [0, 1, 2, 2, 3, 0];
return SkeletonRenderer;
}());

File diff suppressed because one or more lines are too long

View File

@ -1091,6 +1091,17 @@ declare module spine {
length: number;
[n: number]: T;
}
class WindowedMean {
values: Array<number>;
addedValues: number;
lastValue: number;
mean: number;
dirty: boolean;
constructor(windowSize?: number);
hasEnoughData(): boolean;
addValue(value: number): void;
getMean(): number;
}
}
declare module spine.webgl {
class AssetManager extends spine.AssetManager {
@ -1243,6 +1254,7 @@ declare module spine.webgl {
numIndices(): number;
setIndicesLength(length: number): void;
getIndices(): Uint16Array;
getVertexSizeInFloats(): number;
constructor(gl: WebGLRenderingContext, attributes: VertexAttribute[], maxVertices: number, maxIndices: number);
setVertices(vertices: Array<number>): void;
setIndices(indices: Array<number>): void;
@ -1271,6 +1283,9 @@ declare module spine.webgl {
class ColorAttribute extends VertexAttribute {
constructor();
}
class Color2Attribute extends VertexAttribute {
constructor();
}
enum VertexAttributeType {
Float = 0,
}
@ -1287,7 +1302,7 @@ declare module spine.webgl {
private indicesLength;
private srcBlend;
private dstBlend;
constructor(gl: WebGLRenderingContext, maxVertices?: number);
constructor(gl: WebGLRenderingContext, twoColorTint?: boolean, maxVertices?: number);
begin(shader: Shader): void;
setBlendMode(srcBlend: number, dstBlend: number): void;
draw(texture: GLTexture, vertices: ArrayLike<number>, indices: Array<number>): void;
@ -1312,7 +1327,7 @@ declare module spine.webgl {
private QUAD;
private QUAD_TRIANGLES;
private WHITE;
constructor(canvas: HTMLCanvasElement, gl: WebGLRenderingContext);
constructor(canvas: HTMLCanvasElement, gl: WebGLRenderingContext, twoColorTint?: boolean);
begin(): void;
drawSkeleton(skeleton: Skeleton, premultipliedAlpha?: boolean): void;
drawSkeletonDebug(skeleton: Skeleton, premultipliedAlpha?: boolean, ignoredBones?: Array<string>): void;
@ -1345,6 +1360,7 @@ declare module spine.webgl {
static MVP_MATRIX: string;
static POSITION: string;
static COLOR: string;
static COLOR2: string;
static TEXCOORDS: string;
static SAMPLER: string;
private gl;
@ -1375,6 +1391,7 @@ declare module spine.webgl {
getAttributeLocation(attribute: string): number;
dispose(): void;
static newColoredTextured(gl: WebGLRenderingContext): Shader;
static newTwoColorTextured(gl: WebGLRenderingContext): Shader;
static newColored(gl: WebGLRenderingContext): Shader;
}
}
@ -1448,16 +1465,19 @@ declare module spine.webgl {
}
declare module spine.webgl {
class SkeletonRenderer {
static VERTEX_SIZE: number;
static QUAD_TRIANGLES: number[];
premultipliedAlpha: boolean;
private gl;
private tempColor;
private tempColor2;
private vertices;
constructor(gl: WebGLRenderingContext);
private vertexSize;
private twoColorTint;
private renderable;
constructor(gl: WebGLRenderingContext, twoColorTint?: boolean);
draw(batcher: PolygonBatcher, skeleton: Skeleton): void;
computeRegionVertices(slot: Slot, region: RegionAttachment, pma: boolean): ArrayLike<number>;
computeMeshVertices(slot: Slot, mesh: MeshAttachment, pma: boolean): ArrayLike<number>;
private computeRegionVertices(slot, region, pma, twoColorTint?);
private computeMeshVertices(slot, mesh, pma, twoColorTint?);
}
}
declare module spine.webgl {

View File

@ -4065,8 +4065,10 @@ var spine;
if (color != null)
data.color.setFromString(color);
var dark = this.getValue(slotMap, "dark", null);
if (dark != null)
data.darkColor.setFromString(color);
if (dark != null) {
data.darkColor = new spine.Color(1, 1, 1, 1);
data.darkColor.setFromString(dark);
}
data.attachmentName = this.getValue(slotMap, "attachment", null);
data.blendMode = SkeletonJson.blendModeFromString(this.getValue(slotMap, "blend", "normal"));
skeletonData.slots.push(data);
@ -4369,7 +4371,7 @@ var spine;
var valueMap = timelineMap[i];
var light = new spine.Color();
var dark = new spine.Color();
light.setFromString(valueMap.color);
light.setFromString(valueMap.light);
dark.setFromString(valueMap.dark);
timeline.setFrame(frameIndex, valueMap.time, light.r, light.g, light.b, light.a, dark.r, dark.g, dark.b);
this.readCurve(valueMap, timeline, frameIndex);
@ -5573,6 +5575,45 @@ var spine;
return TimeKeeper;
}());
spine.TimeKeeper = TimeKeeper;
var WindowedMean = (function () {
function WindowedMean(windowSize) {
if (windowSize === void 0) { windowSize = 32; }
this.addedValues = 0;
this.lastValue = 0;
this.mean = 0;
this.dirty = true;
this.values = new Array(windowSize);
}
WindowedMean.prototype.hasEnoughData = function () {
return this.addedValues >= this.values.length;
};
WindowedMean.prototype.addValue = function (value) {
if (this.addedValues < this.values.length)
this.addedValues++;
this.values[this.lastValue++] = value;
if (this.lastValue > this.values.length - 1)
this.lastValue = 0;
this.dirty = true;
};
WindowedMean.prototype.getMean = function () {
if (this.hasEnoughData()) {
if (this.dirty) {
var mean = 0;
for (var i = 0; i < this.values.length; i++) {
mean += this.values[i];
}
this.mean = mean / this.values.length;
this.dirty = false;
}
return this.mean;
}
else {
return 0;
}
};
return WindowedMean;
}());
spine.WindowedMean = WindowedMean;
})(spine || (spine = {}));
var spine;
(function (spine) {
@ -6319,6 +6360,14 @@ var spine;
};
Mesh.prototype.getIndices = function () { return this.indices; };
;
Mesh.prototype.getVertexSizeInFloats = function () {
var size = 0;
for (var i = 0; i < this.attributes.length; i++) {
var attribute = this.attributes[i];
size += attribute.numElements;
}
return size;
};
Mesh.prototype.setVertices = function (vertices) {
this.dirtyVertices = true;
if (vertices.length > this.vertices.length)
@ -6379,7 +6428,7 @@ var spine;
this.verticesBuffer = gl.createBuffer();
}
gl.bindBuffer(gl.ARRAY_BUFFER, this.verticesBuffer);
gl.bufferData(gl.ARRAY_BUFFER, this.vertices.subarray(0, this.verticesLength), gl.STATIC_DRAW);
gl.bufferData(gl.ARRAY_BUFFER, this.vertices.subarray(0, this.verticesLength), gl.DYNAMIC_DRAW);
this.dirtyVertices = false;
}
if (this.dirtyIndices) {
@ -6387,7 +6436,7 @@ var spine;
this.indicesBuffer = gl.createBuffer();
}
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indicesBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices.subarray(0, this.indicesLength), gl.STATIC_DRAW);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices.subarray(0, this.indicesLength), gl.DYNAMIC_DRAW);
this.dirtyIndices = false;
}
};
@ -6441,6 +6490,14 @@ var spine;
return ColorAttribute;
}(VertexAttribute));
webgl.ColorAttribute = ColorAttribute;
var Color2Attribute = (function (_super) {
__extends(Color2Attribute, _super);
function Color2Attribute() {
_super.call(this, webgl.Shader.COLOR2, VertexAttributeType.Float, 4);
}
return Color2Attribute;
}(VertexAttribute));
webgl.Color2Attribute = Color2Attribute;
(function (VertexAttributeType) {
VertexAttributeType[VertexAttributeType["Float"] = 0] = "Float";
})(webgl.VertexAttributeType || (webgl.VertexAttributeType = {}));
@ -6452,7 +6509,8 @@ var spine;
var webgl;
(function (webgl) {
var PolygonBatcher = (function () {
function PolygonBatcher(gl, maxVertices) {
function PolygonBatcher(gl, twoColorTint, maxVertices) {
if (twoColorTint === void 0) { twoColorTint = true; }
if (maxVertices === void 0) { maxVertices = 10920; }
this.isDrawing = false;
this.shader = null;
@ -6464,7 +6522,10 @@ var spine;
if (maxVertices > 10920)
throw new Error("Can't have more than 10920 triangles per batch: " + maxVertices);
this.gl = gl;
this.mesh = new webgl.Mesh(gl, [new webgl.Position2Attribute(), new webgl.ColorAttribute(), new webgl.TexCoordAttribute()], maxVertices, maxVertices * 3);
var attributes = twoColorTint ?
[new webgl.Position2Attribute(), new webgl.ColorAttribute(), new webgl.TexCoordAttribute(), new webgl.Color2Attribute()] :
[new webgl.Position2Attribute(), new webgl.ColorAttribute(), new webgl.TexCoordAttribute()];
this.mesh = new webgl.Mesh(gl, attributes, maxVertices, maxVertices * 3);
}
PolygonBatcher.prototype.begin = function (shader) {
var gl = this.gl;
@ -6542,7 +6603,8 @@ var spine;
var webgl;
(function (webgl) {
var SceneRenderer = (function () {
function SceneRenderer(canvas, gl) {
function SceneRenderer(canvas, gl, twoColorTint) {
if (twoColorTint === void 0) { twoColorTint = true; }
this.activeRenderer = null;
this.QUAD = [
0, 0, 1, 1, 1, 1, 0, 0,
@ -6555,11 +6617,11 @@ var spine;
this.canvas = canvas;
this.gl = gl;
this.camera = new webgl.OrthoCamera(canvas.width, canvas.height);
this.batcherShader = webgl.Shader.newColoredTextured(gl);
this.batcher = new webgl.PolygonBatcher(gl);
this.batcherShader = twoColorTint ? webgl.Shader.newTwoColorTextured(gl) : webgl.Shader.newColoredTextured(gl);
this.batcher = new webgl.PolygonBatcher(gl, twoColorTint);
this.shapesShader = webgl.Shader.newColored(gl);
this.shapes = new webgl.ShapeRenderer(gl);
this.skeletonRenderer = new webgl.SkeletonRenderer(gl);
this.skeletonRenderer = new webgl.SkeletonRenderer(gl, twoColorTint);
this.skeletonDebugRenderer = new webgl.SkeletonDebugRenderer(gl);
}
SceneRenderer.prototype.begin = function () {
@ -6997,6 +7059,11 @@ var spine;
var fs = "\n\t\t\t\t#ifdef GL_ES\n\t\t\t\t\t#define LOWP lowp\n\t\t\t\t\tprecision mediump float;\n\t\t\t\t#else\n\t\t\t\t\t#define LOWP\n\t\t\t\t#endif\n\t\t\t\tvarying LOWP vec4 v_color;\n\t\t\t\tvarying vec2 v_texCoords;\n\t\t\t\tuniform sampler2D u_texture;\n\n\t\t\t\tvoid main () {\n\t\t\t\t\tgl_FragColor = v_color * texture2D(u_texture, v_texCoords);\n\t\t\t\t}\n\t\t\t";
return new Shader(gl, vs, fs);
};
Shader.newTwoColorTextured = function (gl) {
var vs = "\n\t\t\t\tattribute vec4 " + Shader.POSITION + ";\n\t\t\t\tattribute vec4 " + Shader.COLOR + ";\n\t\t\t\tattribute vec4 " + Shader.COLOR2 + ";\n\t\t\t\tattribute vec2 " + Shader.TEXCOORDS + ";\n\t\t\t\tuniform mat4 " + Shader.MVP_MATRIX + ";\n\t\t\t\tvarying vec4 v_light;\n\t\t\t\tvarying vec4 v_dark;\n\t\t\t\tvarying vec2 v_texCoords;\n\n\t\t\t\tvoid main () {\n\t\t\t\t\tv_light = " + Shader.COLOR + ";\n\t\t\t\t\tv_dark = " + Shader.COLOR2 + ";\n\t\t\t\t\tv_texCoords = " + Shader.TEXCOORDS + ";\n\t\t\t\t\tgl_Position = " + Shader.MVP_MATRIX + " * " + Shader.POSITION + ";\n\t\t\t\t}\n\t\t\t";
var fs = "\n\t\t\t\t#ifdef GL_ES\n\t\t\t\t\t#define LOWP lowp\n\t\t\t\t\tprecision mediump float;\n\t\t\t\t#else\n\t\t\t\t\t#define LOWP\n\t\t\t\t#endif\n\t\t\t\tvarying LOWP vec4 v_light;\n\t\t\t\tvarying LOWP vec4 v_dark;\n\t\t\t\tvarying vec2 v_texCoords;\n\t\t\t\tuniform sampler2D u_texture;\n\n\t\t\t\tvoid main () {\n\t\t\t\t\tvec4 texColor = texture2D(u_texture, v_texCoords);\n\t\t\t\t\tfloat alpha = texColor.a * v_light.a;\n\t\t\t\t\tgl_FragColor.a = alpha;\n\t\t\t\t\tgl_FragColor.rgb = (1.0 - texColor.rgb) * v_dark.rgb * alpha + texColor.rgb * v_light.rgb;\n\t\t\t\t}\n\t\t\t";
return new Shader(gl, vs, fs);
};
Shader.newColored = function (gl) {
var vs = "\n\t\t\t\tattribute vec4 " + Shader.POSITION + ";\n\t\t\t\tattribute vec4 " + Shader.COLOR + ";\n\t\t\t\tuniform mat4 " + Shader.MVP_MATRIX + ";\n\t\t\t\tvarying vec4 v_color;\n\n\t\t\t\tvoid main () {\n\t\t\t\t\tv_color = " + Shader.COLOR + ";\n\t\t\t\t\tgl_Position = " + Shader.MVP_MATRIX + " * " + Shader.POSITION + ";\n\t\t\t\t}\n\t\t\t";
var fs = "\n\t\t\t\t#ifdef GL_ES\n\t\t\t\t\t#define LOWP lowp\n\t\t\t\t\tprecision mediump float;\n\t\t\t\t#else\n\t\t\t\t\t#define LOWP\n\t\t\t\t#endif\n\t\t\t\tvarying LOWP vec4 v_color;\n\n\t\t\t\tvoid main () {\n\t\t\t\t\tgl_FragColor = v_color;\n\t\t\t\t}\n\t\t\t";
@ -7005,6 +7072,7 @@ var spine;
Shader.MVP_MATRIX = "u_projTrans";
Shader.POSITION = "a_position";
Shader.COLOR = "a_color";
Shader.COLOR2 = "a_color2";
Shader.TEXCOORDS = "a_texCoords";
Shader.SAMPLER = "u_texture";
return Shader;
@ -7360,7 +7428,7 @@ var spine;
this.boneWidth = 2;
this.bounds = new spine.SkeletonBounds();
this.temp = new Array();
this.vertices = spine.Utils.newFloatArray(webgl.SkeletonRenderer.VERTEX_SIZE * 1024);
this.vertices = spine.Utils.newFloatArray(2 * 1024);
this.gl = gl;
}
SkeletonDebugRenderer.prototype.draw = function (shapes, skeleton, ignoredBones) {
@ -7509,12 +7577,28 @@ var spine;
(function (spine) {
var webgl;
(function (webgl) {
var Renderable = (function () {
function Renderable(vertices, numFloats) {
this.vertices = vertices;
this.numFloats = numFloats;
}
return Renderable;
}());
;
var SkeletonRenderer = (function () {
function SkeletonRenderer(gl) {
function SkeletonRenderer(gl, twoColorTint) {
if (twoColorTint === void 0) { twoColorTint = true; }
this.premultipliedAlpha = false;
this.tempColor = new spine.Color();
this.vertices = spine.Utils.newFloatArray(SkeletonRenderer.VERTEX_SIZE * 1024);
this.tempColor2 = new spine.Color();
this.vertexSize = 2 + 2 + 4;
this.twoColorTint = false;
this.renderable = new Renderable(null, 0);
this.gl = gl;
this.twoColorTint = twoColorTint;
if (twoColorTint)
this.vertexSize += 4;
this.vertices = spine.Utils.newFloatArray(this.vertexSize * 1024);
}
SkeletonRenderer.prototype.draw = function (batcher, skeleton) {
var premultipliedAlpha = this.premultipliedAlpha;
@ -7528,13 +7612,13 @@ var spine;
var texture = null;
if (attachment instanceof spine.RegionAttachment) {
var region = attachment;
vertices = this.computeRegionVertices(slot, region, premultipliedAlpha);
vertices = this.computeRegionVertices(slot, region, premultipliedAlpha, this.twoColorTint);
triangles = SkeletonRenderer.QUAD_TRIANGLES;
texture = region.region.renderObject.texture;
}
else if (attachment instanceof spine.MeshAttachment) {
var mesh = attachment;
vertices = this.computeMeshVertices(slot, mesh, premultipliedAlpha);
vertices = this.computeMeshVertices(slot, mesh, premultipliedAlpha, this.twoColorTint);
triangles = mesh.triangles;
texture = mesh.region.renderObject.texture;
}
@ -7546,11 +7630,13 @@ var spine;
blendMode = slotBlendMode;
batcher.setBlendMode(webgl.getSourceGLBlendMode(this.gl, blendMode, premultipliedAlpha), webgl.getDestGLBlendMode(this.gl, blendMode));
}
batcher.draw(texture, vertices, triangles);
var view = vertices.vertices.subarray(0, vertices.numFloats);
batcher.draw(texture, view, triangles);
}
}
};
SkeletonRenderer.prototype.computeRegionVertices = function (slot, region, pma) {
SkeletonRenderer.prototype.computeRegionVertices = function (slot, region, pma, twoColorTint) {
if (twoColorTint === void 0) { twoColorTint = false; }
var skeleton = slot.bone.skeleton;
var skeletonColor = skeleton.color;
var slotColor = slot.color;
@ -7559,36 +7645,72 @@ var spine;
var multiplier = pma ? alpha : 1;
var color = this.tempColor;
color.set(skeletonColor.r * slotColor.r * regionColor.r * multiplier, skeletonColor.g * slotColor.g * regionColor.g * multiplier, skeletonColor.b * slotColor.b * regionColor.b * multiplier, alpha);
region.computeWorldVertices(slot.bone, this.vertices, 0, SkeletonRenderer.VERTEX_SIZE);
var dark = this.tempColor2;
if (slot.darkColor == null)
dark.set(0, 0, 0, 1);
else
dark.setFromColor(slot.darkColor);
region.computeWorldVertices(slot.bone, this.vertices, 0, this.vertexSize);
var vertices = this.vertices;
var uvs = region.uvs;
vertices[spine.RegionAttachment.C1R] = color.r;
vertices[spine.RegionAttachment.C1G] = color.g;
vertices[spine.RegionAttachment.C1B] = color.b;
vertices[spine.RegionAttachment.C1A] = color.a;
vertices[spine.RegionAttachment.U1] = uvs[0];
vertices[spine.RegionAttachment.V1] = uvs[1];
vertices[spine.RegionAttachment.C2R] = color.r;
vertices[spine.RegionAttachment.C2G] = color.g;
vertices[spine.RegionAttachment.C2B] = color.b;
vertices[spine.RegionAttachment.C2A] = color.a;
vertices[spine.RegionAttachment.U2] = uvs[2];
vertices[spine.RegionAttachment.V2] = uvs[3];
vertices[spine.RegionAttachment.C3R] = color.r;
vertices[spine.RegionAttachment.C3G] = color.g;
vertices[spine.RegionAttachment.C3B] = color.b;
vertices[spine.RegionAttachment.C3A] = color.a;
vertices[spine.RegionAttachment.U3] = uvs[4];
vertices[spine.RegionAttachment.V3] = uvs[5];
vertices[spine.RegionAttachment.C4R] = color.r;
vertices[spine.RegionAttachment.C4G] = color.g;
vertices[spine.RegionAttachment.C4B] = color.b;
vertices[spine.RegionAttachment.C4A] = color.a;
vertices[spine.RegionAttachment.U4] = uvs[6];
vertices[spine.RegionAttachment.V4] = uvs[7];
return vertices;
var i = 2;
vertices[i++] = color.r;
vertices[i++] = color.g;
vertices[i++] = color.b;
vertices[i++] = color.a;
vertices[i++] = uvs[0];
vertices[i++] = uvs[1];
if (twoColorTint) {
vertices[i++] = dark.r;
vertices[i++] = dark.g;
vertices[i++] = dark.b;
vertices[i++] = 1;
}
i += 2;
vertices[i++] = color.r;
vertices[i++] = color.g;
vertices[i++] = color.b;
vertices[i++] = color.a;
vertices[i++] = uvs[2];
vertices[i++] = uvs[3];
if (twoColorTint) {
vertices[i++] = dark.r;
vertices[i++] = dark.g;
vertices[i++] = dark.b;
vertices[i++] = 1;
}
i += 2;
vertices[i++] = color.r;
vertices[i++] = color.g;
vertices[i++] = color.b;
vertices[i++] = color.a;
vertices[i++] = uvs[4];
vertices[i++] = uvs[5];
if (twoColorTint) {
vertices[i++] = dark.r;
vertices[i++] = dark.g;
vertices[i++] = dark.b;
vertices[i++] = 1;
}
i += 2;
vertices[i++] = color.r;
vertices[i++] = color.g;
vertices[i++] = color.b;
vertices[i++] = color.a;
vertices[i++] = uvs[6];
vertices[i++] = uvs[7];
if (twoColorTint) {
vertices[i++] = dark.r;
vertices[i++] = dark.g;
vertices[i++] = dark.b;
vertices[i++] = 1;
}
this.renderable.vertices = vertices;
this.renderable.numFloats = 4 * (twoColorTint ? 12 : 8);
return this.renderable;
};
SkeletonRenderer.prototype.computeMeshVertices = function (slot, mesh, pma) {
SkeletonRenderer.prototype.computeMeshVertices = function (slot, mesh, pma, twoColorTint) {
if (twoColorTint === void 0) { twoColorTint = false; }
var skeleton = slot.bone.skeleton;
var skeletonColor = skeleton.color;
var slotColor = slot.color;
@ -7597,25 +7719,48 @@ var spine;
var multiplier = pma ? alpha : 1;
var color = this.tempColor;
color.set(skeletonColor.r * slotColor.r * regionColor.r * multiplier, skeletonColor.g * slotColor.g * regionColor.g * multiplier, skeletonColor.b * slotColor.b * regionColor.b * multiplier, alpha);
var dark = this.tempColor2;
if (slot.darkColor == null)
dark.set(0, 0, 0, 1);
else
dark.setFromColor(slot.darkColor);
var numVertices = mesh.worldVerticesLength / 2;
if (this.vertices.length < mesh.worldVerticesLength) {
this.vertices = spine.Utils.newFloatArray(mesh.worldVerticesLength);
}
var vertices = this.vertices;
mesh.computeWorldVertices(slot, 0, mesh.worldVerticesLength, vertices, 0, SkeletonRenderer.VERTEX_SIZE);
mesh.computeWorldVertices(slot, 0, mesh.worldVerticesLength, vertices, 0, this.vertexSize);
var uvs = mesh.uvs;
for (var i = 0, n = numVertices, u = 0, v = 2; i < n; i++) {
vertices[v++] = color.r;
vertices[v++] = color.g;
vertices[v++] = color.b;
vertices[v++] = color.a;
vertices[v++] = uvs[u++];
vertices[v++] = uvs[u++];
v += 2;
if (!twoColorTint) {
for (var i = 0, n = numVertices, u = 0, v = 2; i < n; i++) {
vertices[v++] = color.r;
vertices[v++] = color.g;
vertices[v++] = color.b;
vertices[v++] = color.a;
vertices[v++] = uvs[u++];
vertices[v++] = uvs[u++];
v += 2;
}
}
return vertices;
else {
for (var i = 0, n = numVertices, u = 0, v = 2; i < n; i++) {
vertices[v++] = color.r;
vertices[v++] = color.g;
vertices[v++] = color.b;
vertices[v++] = color.a;
vertices[v++] = uvs[u++];
vertices[v++] = uvs[u++];
vertices[v++] = dark.r;
vertices[v++] = dark.g;
vertices[v++] = dark.b;
vertices[v++] = 1;
v += 2;
}
}
this.renderable.vertices = vertices;
this.renderable.numFloats = numVertices * (twoColorTint ? 12 : 8);
return this.renderable;
};
SkeletonRenderer.VERTEX_SIZE = 2 + 2 + 4;
SkeletonRenderer.QUAD_TRIANGLES = [0, 1, 2, 2, 3, 0];
return SkeletonRenderer;
}());

File diff suppressed because one or more lines are too long

View File

@ -94,7 +94,10 @@ module spine {
if (color != null) data.color.setFromString(color);
let dark: string = this.getValue(slotMap, "dark", null);
if (dark != null) data.darkColor.setFromString(color);
if (dark != null) {
data.darkColor = new Color(1, 1, 1, 1);
data.darkColor.setFromString(dark);
}
data.attachmentName = this.getValue(slotMap, "attachment", null);
data.blendMode = SkeletonJson.blendModeFromString(this.getValue(slotMap, "blend", "normal"));
@ -421,7 +424,7 @@ module spine {
let valueMap = timelineMap[i];
let light = new Color();
let dark = new Color();
light.setFromString(valueMap.color);
light.setFromString(valueMap.light);
dark.setFromString(valueMap.dark);
timeline.setFrame(frameIndex, valueMap.time, light.r, light.g, light.b, light.a, dark.r, dark.g, dark.b);
this.readCurve(valueMap, timeline, frameIndex);

View File

@ -296,4 +296,44 @@ module spine {
length: number;
[n: number]: T;
}
export class WindowedMean {
values: Array<number>;
addedValues = 0;
lastValue = 0;
mean = 0;
dirty = true;
constructor (windowSize: number = 32) {
this.values = new Array<number>(windowSize);
}
hasEnoughData () {
return this.addedValues >= this.values.length;
}
addValue (value: number) {
if (this.addedValues < this.values.length)
this.addedValues++;
this.values[this.lastValue++] = value;
if (this.lastValue > this.values.length - 1) this.lastValue = 0;
this.dirty = true;
}
getMean () {
if (this.hasEnoughData()) {
if (this.dirty) {
let mean = 0;
for (let i = 0; i < this.values.length; i++) {
mean += this.values[i];
}
this.mean = mean / this.values.length;
this.dirty = false;
}
return this.mean;
} else {
return 0;
}
}
}
}

View File

@ -0,0 +1,13 @@
twocolor.png
size: 512,512
format: RGBA8888
filter: Linear,Linear
repeat: none
squareWithBorder
rotate: false
xy: 2, 2
size: 300, 300
orig: 300, 300
offset: 0, 0
index: -1

View File

@ -0,0 +1,66 @@
{
"skeleton": { "hash": "F1HM8+VG3WR6tPJTA5IpJM8nDs4", "spine": "3.6.05-beta", "width": 300.48, "height": 300.48 },
"bones": [
{ "name": "root", "rotation": -0.09 },
{ "name": "singleColorTint", "parent": "root", "x": -400 },
{ "name": "twoColorTint", "parent": "root", "x": 800 },
{ "name": "twoColorTint (blackOnly)", "parent": "root" },
{ "name": "twoColorTint (colorOnly)", "parent": "root", "x": 400 }
],
"slots": [
{ "name": "squareWithBorder", "bone": "singleColorTint", "attachment": "squareWithBorder" },
{ "name": "squareWithBorder2", "bone": "twoColorTint (blackOnly)", "dark": "000000", "attachment": "squareWithBorder" },
{ "name": "squareWithBorder4", "bone": "twoColorTint (colorOnly)", "dark": "000000", "attachment": "squareWithBorder" },
{ "name": "squareWithBorder3", "bone": "twoColorTint", "dark": "000000", "attachment": "squareWithBorder" }
],
"skins": {
"default": {
"squareWithBorder": {
"squareWithBorder": { "width": 300, "height": 300 }
},
"squareWithBorder2": {
"squareWithBorder": { "width": 300, "height": 300 }
},
"squareWithBorder3": {
"squareWithBorder": { "width": 300, "height": 300 }
},
"squareWithBorder4": {
"squareWithBorder": { "width": 300, "height": 300 }
}
}
},
"animations": {
"animation": {
"slots": {
"squareWithBorder": {
"color": [
{ "time": 0, "color": "fffffffe" },
{ "time": 1, "color": "9e17b3fe" },
{ "time": 2, "color": "fffffffe" }
]
},
"squareWithBorder2": {
"twoColor": [
{ "time": 0, "light": "fffffffe", "dark": "000000" },
{ "time": 1, "light": "fffffffe", "dark": "ff0000" },
{ "time": 2, "light": "fffffffe", "dark": "000000" }
]
},
"squareWithBorder3": {
"twoColor": [
{ "time": 0, "light": "fffffffe", "dark": "000000" },
{ "time": 1, "light": "80ff00fe", "dark": "001cff" },
{ "time": 2, "light": "fffffffe", "dark": "000000" }
]
},
"squareWithBorder4": {
"twoColor": [
{ "time": 0, "light": "fffffffe", "dark": "000000" },
{ "time": 1, "light": "ffd300fe", "dark": "000000" },
{ "time": 2, "light": "fffffffe", "dark": "000000" }
]
}
}
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -7,13 +7,17 @@
canvas { position: absolute; width: 100% ;height: 100%; }
</style>
<body>
<div id="label" style="position: absolute; top: 0; left: 0; color: #fff; z-index: 10"></div>
<canvas id="canvas"></canvas>
</body>
<script>
var canvas, gl, renderer, input, assetManager;
var skeleton, bounds, state;
var skeletons = [];
var timeKeeper;
var label = document.getElementById("label");
var updateMean = new spine.WindowedMean();
var renderMean = new spine.WindowedMean();
function init() {
canvas = document.getElementById("canvas");
@ -24,9 +28,9 @@ function init() {
assetManager = new spine.webgl.AssetManager(gl, "assets/");
var textureLoader = function(img) { return new spine.webgl.GLTexture(gl, img); };
input = new spine.webgl.Input(canvas);
assetManager.loadTexture("raptor.png");
assetManager.loadText("raptor.atlas");
assetManager.loadText("raptor.json");
assetManager.loadTexture("spineboy.png");
assetManager.loadText("spineboy.atlas");
assetManager.loadText("spineboy.json");
timeKeeper = new spine.TimeKeeper();
requestAnimationFrame(load);
}
@ -34,21 +38,25 @@ function init() {
function load() {
timeKeeper.update();
if (assetManager.isLoadingComplete()) {
var atlas = new spine.TextureAtlas(assetManager.get("raptor.atlas"), function(path) {
var atlas = new spine.TextureAtlas(assetManager.get("spineboy.atlas"), function(path) {
return assetManager.get(path);
});
var atlasLoader = new spine.AtlasAttachmentLoader(atlas);
var skeletonJson = new spine.SkeletonJson(atlasLoader);
skeletonJson.scale = 0.5;
var skeletonData = skeletonJson.readSkeletonData(JSON.parse(assetManager.get("raptor.json")));
skeleton = new spine.Skeleton(skeletonData);
var stateData = new spine.AnimationStateData(skeleton.data);
state = new spine.AnimationState(stateData);
stateData.setMix("walk", "Jump", 0.5);
state.setAnimation(0, "walk", false);
state.addAnimation(0, "Jump", false, 0);
state.apply(skeleton);
skeleton.updateWorldTransform();
skeletonJson.scale = 0.01;
var skeletonData = skeletonJson.readSkeletonData(JSON.parse(assetManager.get("spineboy.json")));
for (var i = 0; i < 1000; i++) {
skeleton = new spine.Skeleton(skeletonData);
var stateData = new spine.AnimationStateData(skeleton.data);
state = new spine.AnimationState(stateData);
state.setAnimation(0, "walk", true);
state.apply(skeleton);
skeleton.x = Math.random() * 200 - Math.random() * 200;
skeleton.y = Math.random() * 200 - Math.random() * 200;
skeleton.updateWorldTransform();
skeletons.push({ skeleton: skeleton, state: state });
}
requestAnimationFrame(render);
} else {
@ -57,23 +65,36 @@ function load() {
}
function render() {
var start = Date.now()
timeKeeper.update();
var delta = timeKeeper.delta;
delta = 0.016;
state.update(delta);
state.apply(skeleton);
skeleton.updateWorldTransform();
for (var i = 0; i < skeletons.length; i++) {
var state = skeletons[i].state;
var skeleton = skeletons[i].skeleton;
state.update(delta);
state.apply(skeleton);
skeleton.updateWorldTransform();
}
updateMean.addValue(Date.now() - start);
start = Date.now();
gl.clearColor(0, 0, 0, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
renderer.resize(spine.webgl.ResizeMode.Fit);
renderer.begin();
renderer.drawSkeleton(skeleton);
for (var i = 0; i < skeletons.length; i++) {
var skeleton = skeletons[i].skeleton;
renderer.drawSkeleton(skeleton);
}
renderer.end();
requestAnimationFrame(render)
renderMean.addValue(Date.now() - start);
label.innerHTML = ("Update time: " + Number(updateMean.getMean()).toFixed(2) + " ms\n" +
"Render time: " + Number(renderMean.getMean()).toFixed(2) + " ms\n");
}
init();

View File

@ -59,6 +59,15 @@ module spine.webgl {
}
getIndices (): Uint16Array { return this.indices };
getVertexSizeInFloats (): number {
let size = 0;
for (var i = 0; i < this.attributes.length; i++) {
let attribute = this.attributes[i];
size += attribute.numElements;
}
return size;
}
constructor (gl: WebGLRenderingContext, private attributes: VertexAttribute[], maxVertices: number, maxIndices: number) {
this.gl = gl;
this.elementsPerVertex = 0;
@ -128,7 +137,7 @@ module spine.webgl {
this.verticesBuffer = gl.createBuffer();
}
gl.bindBuffer(gl.ARRAY_BUFFER, this.verticesBuffer);
gl.bufferData(gl.ARRAY_BUFFER, this.vertices.subarray(0, this.verticesLength), gl.STATIC_DRAW);
gl.bufferData(gl.ARRAY_BUFFER, this.vertices.subarray(0, this.verticesLength), gl.DYNAMIC_DRAW);
this.dirtyVertices = false;
}
@ -137,7 +146,7 @@ module spine.webgl {
this.indicesBuffer = gl.createBuffer();
}
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indicesBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices.subarray(0, this.indicesLength), gl.STATIC_DRAW);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices.subarray(0, this.indicesLength), gl.DYNAMIC_DRAW);
this.dirtyIndices = false;
}
}
@ -177,6 +186,12 @@ module spine.webgl {
}
}
export class Color2Attribute extends VertexAttribute {
constructor () {
super(Shader.COLOR2, VertexAttributeType.Float, 4);
}
}
export enum VertexAttributeType {
Float
}

View File

@ -41,10 +41,13 @@ module spine.webgl {
private srcBlend: number = WebGLRenderingContext.SRC_ALPHA;
private dstBlend: number = WebGLRenderingContext.ONE_MINUS_SRC_ALPHA;
constructor (gl: WebGLRenderingContext, maxVertices: number = 10920) {
constructor (gl: WebGLRenderingContext, twoColorTint: boolean = true, maxVertices: number = 10920) {
if (maxVertices > 10920) throw new Error("Can't have more than 10920 triangles per batch: " + maxVertices);
this.gl = gl;
this.mesh = new Mesh(gl, [new Position2Attribute(), new ColorAttribute(), new TexCoordAttribute()], maxVertices, maxVertices * 3);
let attributes = twoColorTint ?
[new Position2Attribute(), new ColorAttribute(), new TexCoordAttribute(), new Color2Attribute()] :
[new Position2Attribute(), new ColorAttribute(), new TexCoordAttribute()];
this.mesh = new Mesh(gl, attributes, maxVertices, maxVertices * 3);
}
begin (shader: Shader) {

View File

@ -49,15 +49,15 @@ module spine.webgl {
private QUAD_TRIANGLES = [0, 1, 2, 2, 3, 0];
private WHITE = new Color(1, 1, 1, 1);
constructor (canvas: HTMLCanvasElement, gl: WebGLRenderingContext) {
constructor (canvas: HTMLCanvasElement, gl: WebGLRenderingContext, twoColorTint: boolean = true) {
this.canvas = canvas;
this.gl = gl;
this.camera = new OrthoCamera(canvas.width, canvas.height);
this.batcherShader = Shader.newColoredTextured(gl);
this.batcher = new PolygonBatcher(gl);
this.batcherShader = twoColorTint ? Shader.newTwoColorTextured(gl) : Shader.newColoredTextured(gl);
this.batcher = new PolygonBatcher(gl, twoColorTint);
this.shapesShader = Shader.newColored(gl);
this.shapes = new ShapeRenderer(gl);
this.skeletonRenderer = new SkeletonRenderer(gl);
this.shapes = new ShapeRenderer(gl);
this.skeletonRenderer = new SkeletonRenderer(gl, twoColorTint);
this.skeletonDebugRenderer = new SkeletonDebugRenderer(gl);
}

View File

@ -33,6 +33,7 @@ module spine.webgl {
public static MVP_MATRIX = "u_projTrans";
public static POSITION = "a_position";
public static COLOR = "a_color";
public static COLOR2 = "a_color2";
public static TEXCOORDS = "a_texCoords";
public static SAMPLER = "u_texture";
@ -206,6 +207,48 @@ module spine.webgl {
return new Shader(gl, vs, fs);
}
public static newTwoColorTextured (gl: WebGLRenderingContext): Shader {
let vs = `
attribute vec4 ${Shader.POSITION};
attribute vec4 ${Shader.COLOR};
attribute vec4 ${Shader.COLOR2};
attribute vec2 ${Shader.TEXCOORDS};
uniform mat4 ${Shader.MVP_MATRIX};
varying vec4 v_light;
varying vec4 v_dark;
varying vec2 v_texCoords;
void main () {
v_light = ${Shader.COLOR};
v_dark = ${Shader.COLOR2};
v_texCoords = ${Shader.TEXCOORDS};
gl_Position = ${Shader.MVP_MATRIX} * ${Shader.POSITION};
}
`;
let fs = `
#ifdef GL_ES
#define LOWP lowp
precision mediump float;
#else
#define LOWP
#endif
varying LOWP vec4 v_light;
varying LOWP vec4 v_dark;
varying vec2 v_texCoords;
uniform sampler2D u_texture;
void main () {
vec4 texColor = texture2D(u_texture, v_texCoords);
float alpha = texColor.a * v_light.a;
gl_FragColor.a = alpha;
gl_FragColor.rgb = (1.0 - texColor.rgb) * v_dark.rgb * alpha + texColor.rgb * v_light.rgb;
}
`;
return new Shader(gl, vs, fs);
}
public static newColored (gl: WebGLRenderingContext): Shader {
let vs = `
attribute vec4 ${Shader.POSITION};

View File

@ -50,7 +50,7 @@ module spine.webgl {
private gl: WebGLRenderingContext;
private bounds = new SkeletonBounds();
private temp = new Array<number>();
private vertices = Utils.newFloatArray(SkeletonRenderer.VERTEX_SIZE * 1024);
private vertices = Utils.newFloatArray(2 * 1024);
private static LIGHT_GRAY = new Color(192 / 255, 192 / 255, 192 / 255, 1);
private static GREEN = new Color(0, 1, 0, 1);

View File

@ -29,24 +29,35 @@
*****************************************************************************/
module spine.webgl {
class Renderable {
constructor(public vertices: ArrayLike<number>, public numFloats: number) {}
};
export class SkeletonRenderer {
static VERTEX_SIZE = 2 + 2 + 4;
static QUAD_TRIANGLES = [0, 1, 2, 2, 3, 0];
premultipliedAlpha = false;
private gl: WebGLRenderingContext;
private tempColor = new Color();
private vertices = Utils.newFloatArray(SkeletonRenderer.VERTEX_SIZE * 1024);
private tempColor2 = new Color();
private vertices:ArrayLike<number>;
private vertexSize = 2 + 2 + 4;
private twoColorTint = false;
private renderable: Renderable = new Renderable(null, 0);
constructor (gl: WebGLRenderingContext) {
constructor (gl: WebGLRenderingContext, twoColorTint: boolean = true) {
this.gl = gl;
this.twoColorTint = twoColorTint;
if (twoColorTint)
this.vertexSize += 4;
this.vertices = Utils.newFloatArray(this.vertexSize * 1024);
}
draw (batcher: PolygonBatcher, skeleton: Skeleton) {
let premultipliedAlpha = this.premultipliedAlpha;
let blendMode: BlendMode = null;
let vertices: ArrayLike<number> = null;
let vertices: Renderable = null;
let triangles: Array<number> = null;
let drawOrder = skeleton.drawOrder;
for (let i = 0, n = drawOrder.length; i < n; i++) {
@ -55,13 +66,13 @@ module spine.webgl {
let texture: GLTexture = null;
if (attachment instanceof RegionAttachment) {
let region = <RegionAttachment>attachment;
vertices = this.computeRegionVertices(slot, region, premultipliedAlpha);
vertices = this.computeRegionVertices(slot, region, premultipliedAlpha, this.twoColorTint);
triangles = SkeletonRenderer.QUAD_TRIANGLES;
texture = <GLTexture>(<TextureAtlasRegion>region.region.renderObject).texture;
} else if (attachment instanceof MeshAttachment) {
let mesh = <MeshAttachment>attachment;
vertices = this.computeMeshVertices(slot, mesh, premultipliedAlpha);
vertices = this.computeMeshVertices(slot, mesh, premultipliedAlpha, this.twoColorTint);
triangles = mesh.triangles;
texture = <GLTexture>(<TextureAtlasRegion>mesh.region.renderObject).texture;
} else continue;
@ -72,12 +83,14 @@ module spine.webgl {
blendMode = slotBlendMode;
batcher.setBlendMode(getSourceGLBlendMode(this.gl, blendMode, premultipliedAlpha), getDestGLBlendMode(this.gl, blendMode));
}
batcher.draw(texture, vertices, triangles);
let view = (vertices.vertices as Float32Array).subarray(0, vertices.numFloats);
batcher.draw(texture, view, triangles);
}
}
}
computeRegionVertices(slot: Slot, region: RegionAttachment, pma: boolean) {
private computeRegionVertices(slot: Slot, region: RegionAttachment, pma: boolean, twoColorTint: boolean = false) {
let skeleton = slot.bone.skeleton;
let skeletonColor = skeleton.color;
let slotColor = slot.color;
@ -89,44 +102,77 @@ module spine.webgl {
skeletonColor.g * slotColor.g * regionColor.g * multiplier,
skeletonColor.b * slotColor.b * regionColor.b * multiplier,
alpha);
let dark = this.tempColor2;
if (slot.darkColor == null) dark.set(0, 0, 0, 1);
else dark.setFromColor(slot.darkColor);
region.computeWorldVertices(slot.bone, this.vertices, 0, SkeletonRenderer.VERTEX_SIZE);
region.computeWorldVertices(slot.bone, this.vertices, 0, this.vertexSize);
let vertices = this.vertices;
let uvs = region.uvs;
vertices[RegionAttachment.C1R] = color.r;
vertices[RegionAttachment.C1G] = color.g;
vertices[RegionAttachment.C1B] = color.b;
vertices[RegionAttachment.C1A] = color.a;
vertices[RegionAttachment.U1] = uvs[0];
vertices[RegionAttachment.V1] = uvs[1];
let i = 2;
vertices[i++] = color.r;
vertices[i++] = color.g;
vertices[i++] = color.b;
vertices[i++] = color.a;
vertices[i++] = uvs[0];
vertices[i++] = uvs[1];
if (twoColorTint) {
vertices[i++] = dark.r;
vertices[i++] = dark.g;
vertices[i++] = dark.b;
vertices[i++] = 1;
}
i+=2;
vertices[RegionAttachment.C2R] = color.r;
vertices[RegionAttachment.C2G] = color.g;
vertices[RegionAttachment.C2B] = color.b;
vertices[RegionAttachment.C2A] = color.a;
vertices[RegionAttachment.U2] = uvs[2];
vertices[RegionAttachment.V2] = uvs[3];
vertices[i++] = color.r;
vertices[i++] = color.g;
vertices[i++] = color.b;
vertices[i++] = color.a;
vertices[i++] = uvs[2];
vertices[i++] = uvs[3];
if (twoColorTint) {
vertices[i++] = dark.r;
vertices[i++] = dark.g;
vertices[i++] = dark.b;
vertices[i++] = 1;
}
i+=2;
vertices[RegionAttachment.C3R] = color.r;
vertices[RegionAttachment.C3G] = color.g;
vertices[RegionAttachment.C3B] = color.b;
vertices[RegionAttachment.C3A] = color.a;
vertices[RegionAttachment.U3] = uvs[4];
vertices[RegionAttachment.V3] = uvs[5];
vertices[i++] = color.r;
vertices[i++] = color.g;
vertices[i++] = color.b;
vertices[i++] = color.a;
vertices[i++] = uvs[4];
vertices[i++] = uvs[5];
if (twoColorTint) {
vertices[i++] = dark.r;
vertices[i++] = dark.g;
vertices[i++] = dark.b;
vertices[i++] = 1;
}
i+=2;
vertices[RegionAttachment.C4R] = color.r;
vertices[RegionAttachment.C4G] = color.g;
vertices[RegionAttachment.C4B] = color.b;
vertices[RegionAttachment.C4A] = color.a;
vertices[RegionAttachment.U4] = uvs[6];
vertices[RegionAttachment.V4] = uvs[7];
vertices[i++] = color.r;
vertices[i++] = color.g;
vertices[i++] = color.b;
vertices[i++] = color.a;
vertices[i++] = uvs[6];
vertices[i++] = uvs[7];
if (twoColorTint) {
vertices[i++] = dark.r;
vertices[i++] = dark.g;
vertices[i++] = dark.b;
vertices[i++] = 1;
}
return vertices;
this.renderable.vertices = vertices;
this.renderable.numFloats = 4 * (twoColorTint ? 12 : 8);
return this.renderable;
}
computeMeshVertices(slot: Slot, mesh: MeshAttachment, pma: boolean) {
private computeMeshVertices(slot: Slot, mesh: MeshAttachment, pma: boolean, twoColorTint: boolean = false) {
let skeleton = slot.bone.skeleton;
let skeletonColor = skeleton.color;
let slotColor = slot.color;
@ -138,26 +184,47 @@ module spine.webgl {
skeletonColor.g * slotColor.g * regionColor.g * multiplier,
skeletonColor.b * slotColor.b * regionColor.b * multiplier,
alpha);
let dark = this.tempColor2;
if (slot.darkColor == null) dark.set(0, 0, 0, 1);
else dark.setFromColor(slot.darkColor);
let numVertices = mesh.worldVerticesLength / 2;
if (this.vertices.length < mesh.worldVerticesLength) {
this.vertices = Utils.newFloatArray(mesh.worldVerticesLength);
}
let vertices = this.vertices;
mesh.computeWorldVertices(slot, 0, mesh.worldVerticesLength, vertices, 0, SkeletonRenderer.VERTEX_SIZE);
mesh.computeWorldVertices(slot, 0, mesh.worldVerticesLength, vertices, 0, this.vertexSize);
let uvs = mesh.uvs;
for (let i = 0, n = numVertices, u = 0, v = 2; i < n; i++) {
vertices[v++] = color.r;
vertices[v++] = color.g;
vertices[v++] = color.b;
vertices[v++] = color.a;
vertices[v++] = uvs[u++];
vertices[v++] = uvs[u++];
v += 2;
if (!twoColorTint) {
for (let i = 0, n = numVertices, u = 0, v = 2; i < n; i++) {
vertices[v++] = color.r;
vertices[v++] = color.g;
vertices[v++] = color.b;
vertices[v++] = color.a;
vertices[v++] = uvs[u++];
vertices[v++] = uvs[u++];
v += 2;
}
} else {
for (let i = 0, n = numVertices, u = 0, v = 2; i < n; i++) {
vertices[v++] = color.r;
vertices[v++] = color.g;
vertices[v++] = color.b;
vertices[v++] = color.a;
vertices[v++] = uvs[u++];
vertices[v++] = uvs[u++];
vertices[v++] = dark.r;
vertices[v++] = dark.g;
vertices[v++] = dark.b;
vertices[v++] = 1;
v += 2;
}
}
return vertices;
this.renderable.vertices = vertices;
this.renderable.numFloats = numVertices * (twoColorTint ? 12 : 8);
return this.renderable;
}
}
}