mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-04 22:34:53 +08:00
Merge branch '3.6' into 3.7-beta
This commit is contained in:
commit
65d8363333
@ -240,7 +240,7 @@ public class SkeletonRenderer {
|
||||
if (vertexEffect != null) vertexEffect.begin(skeleton);
|
||||
|
||||
boolean premultipliedAlpha = this.premultipliedAlpha;
|
||||
int darkPremultipliedAlpha = (premultipliedAlpha ? 255 : 0) << 24;
|
||||
batch.setPremultipliedAlpha(premultipliedAlpha);
|
||||
BlendMode blendMode = null;
|
||||
int verticesLength = 0;
|
||||
float[] vertices = null, uvs = null;
|
||||
@ -288,16 +288,18 @@ public class SkeletonRenderer {
|
||||
Color lightColor = slot.getColor();
|
||||
float alpha = a * lightColor.a * color.a * 255;
|
||||
float multiplier = premultipliedAlpha ? alpha : 255;
|
||||
float red = r * color.r * multiplier;
|
||||
float green = g * color.g * multiplier;
|
||||
float blue = b * color.b * multiplier;
|
||||
float light = NumberUtils.intToFloatColor(((int)alpha << 24) //
|
||||
| ((int)(b * lightColor.b * color.b * multiplier) << 16) //
|
||||
| ((int)(g * lightColor.g * color.g * multiplier) << 8) //
|
||||
| (int)(r * lightColor.r * color.r * multiplier));
|
||||
| ((int)(blue * lightColor.b) << 16) //
|
||||
| ((int)(green * lightColor.g) << 8) //
|
||||
| (int)(red * lightColor.r));
|
||||
Color darkColor = slot.getDarkColor();
|
||||
if (darkColor == null) darkColor = Color.BLACK;
|
||||
float dark = darkColor == null ? 0 : NumberUtils.intToFloatColor(darkPremultipliedAlpha //
|
||||
| (int)(b * darkColor.b * color.b * multiplier) << 16 //
|
||||
| (int)(g * darkColor.g * color.g * multiplier) << 8 //
|
||||
| (int)(r * darkColor.r * color.r * multiplier));
|
||||
float dark = darkColor == null ? 0
|
||||
: NumberUtils.intToFloatColor((int)(blue * darkColor.b) << 16 //
|
||||
| (int)(green * darkColor.g) << 8 //
|
||||
| (int)(red * darkColor.r));
|
||||
|
||||
BlendMode slotBlendMode = slot.data.getBlendMode();
|
||||
if (slotBlendMode != blendMode) {
|
||||
|
||||
@ -54,6 +54,9 @@ public class TwoColorPolygonBatch {
|
||||
private boolean drawing;
|
||||
private int blendSrcFunc = GL20.GL_SRC_ALPHA;
|
||||
private int blendDstFunc = GL20.GL_ONE_MINUS_SRC_ALPHA;
|
||||
private int blendSrcFuncAlpha = GL20.GL_SRC_ALPHA;
|
||||
private int blendDstFuncAlpha = GL20.GL_ONE_MINUS_SRC_ALPHA;
|
||||
private boolean premultipliedAlpha;
|
||||
|
||||
public TwoColorPolygonBatch (int size) {
|
||||
this(size, size * 2);
|
||||
@ -69,7 +72,7 @@ public class TwoColorPolygonBatch {
|
||||
mesh = new Mesh(vertexDataType, false, maxVertices, maxTriangles * 3, //
|
||||
new VertexAttribute(Usage.Position, 2, "a_position"), //
|
||||
new VertexAttribute(Usage.ColorPacked, 4, "a_light"), //
|
||||
new VertexAttribute(Usage.ColorPacked, 4, "a_dark"), //
|
||||
new VertexAttribute(Usage.ColorPacked, 4, "a_dark"), // Dark alpha is unused, but colors are packed as 4 byte floats.
|
||||
new VertexAttribute(Usage.TextureCoordinates, 2, "a_texCoord0"));
|
||||
|
||||
vertices = new float[maxVertices * 6];
|
||||
@ -130,7 +133,7 @@ public class TwoColorPolygonBatch {
|
||||
mesh.setVertices(vertices, 0, vertexIndex);
|
||||
mesh.setIndices(triangles, 0, triangleIndex);
|
||||
Gdx.gl.glEnable(GL20.GL_BLEND);
|
||||
if (blendSrcFunc != -1) Gdx.gl.glBlendFunc(blendSrcFunc, blendDstFunc);
|
||||
if (blendSrcFunc != -1) Gdx.gl.glBlendFuncSeparate(blendSrcFunc, blendDstFunc, blendSrcFuncAlpha, blendDstFuncAlpha);
|
||||
mesh.render(shader, GL20.GL_TRIANGLES, 0, triangleIndex);
|
||||
|
||||
vertexIndex = 0;
|
||||
@ -150,25 +153,39 @@ public class TwoColorPolygonBatch {
|
||||
return transformMatrix;
|
||||
}
|
||||
|
||||
/** Flushes the batch. */
|
||||
public void setProjectionMatrix (Matrix4 projection) {
|
||||
if (drawing) flush();
|
||||
projectionMatrix.set(projection);
|
||||
if (drawing) setupMatrices();
|
||||
}
|
||||
|
||||
/** Flushes the batch. */
|
||||
public void setTransformMatrix (Matrix4 transform) {
|
||||
if (drawing) flush();
|
||||
transformMatrix.set(transform);
|
||||
if (drawing) setupMatrices();
|
||||
}
|
||||
|
||||
/** Specifies whether the texture colors have premultiplied alpha. Required for correct dark color tinting. Does not change the
|
||||
* blending function. Flushes the batch if the setting was changed. */
|
||||
public void setPremultipliedAlpha (boolean premultipliedAlpha) {
|
||||
if (this.premultipliedAlpha == premultipliedAlpha) return;
|
||||
if (drawing) flush();
|
||||
this.premultipliedAlpha = premultipliedAlpha;
|
||||
if (drawing) setupMatrices();
|
||||
}
|
||||
|
||||
private void setupMatrices () {
|
||||
combinedMatrix.set(projectionMatrix).mul(transformMatrix);
|
||||
shader.setUniformf("u_pma", premultipliedAlpha ? 1 : 0);
|
||||
shader.setUniformMatrix("u_projTrans", combinedMatrix);
|
||||
shader.setUniformi("u_texture", 0);
|
||||
}
|
||||
|
||||
/** Flushes the batch if the shader was changed. */
|
||||
public void setShader (ShaderProgram newShader) {
|
||||
if (shader == newShader) return;
|
||||
if (drawing) {
|
||||
flush();
|
||||
shader.end();
|
||||
@ -180,21 +197,30 @@ public class TwoColorPolygonBatch {
|
||||
}
|
||||
}
|
||||
|
||||
/** Flushes the batch if the blend function was changed. */
|
||||
public void setBlendFunction (int srcFunc, int dstFunc) {
|
||||
if (blendSrcFunc == srcFunc && blendDstFunc == dstFunc) return;
|
||||
setBlendFunctionSeparate(srcFunc, dstFunc, srcFunc, dstFunc);
|
||||
}
|
||||
|
||||
/** Flushes the batch if the blend function was changed. */
|
||||
public void setBlendFunctionSeparate (int srcFuncColor, int dstFuncColor, int srcFuncAlpha, int dstFuncAlpha) {
|
||||
if (blendSrcFunc == srcFuncColor && blendDstFunc == dstFuncColor && blendSrcFuncAlpha == srcFuncAlpha
|
||||
&& blendDstFuncAlpha == dstFuncAlpha) return;
|
||||
flush();
|
||||
blendSrcFunc = srcFunc;
|
||||
blendDstFunc = dstFunc;
|
||||
blendSrcFunc = srcFuncColor;
|
||||
blendDstFunc = dstFuncColor;
|
||||
blendSrcFuncAlpha = srcFuncAlpha;
|
||||
blendDstFuncAlpha = dstFuncAlpha;
|
||||
}
|
||||
|
||||
private ShaderProgram createDefaultShader () {
|
||||
String vertexShader = "attribute vec4 a_position;\n" //
|
||||
+ "attribute vec4 a_light;\n" //
|
||||
+ "attribute vec3 a_dark;\n" //
|
||||
+ "attribute vec4 a_dark;\n" //
|
||||
+ "attribute vec2 a_texCoord0;\n" //
|
||||
+ "uniform mat4 u_projTrans;\n" //
|
||||
+ "varying vec4 v_light;\n" //
|
||||
+ "varying vec3 v_dark;\n" //
|
||||
+ "varying vec4 v_dark;\n" //
|
||||
+ "varying vec2 v_texCoords;\n" //
|
||||
+ "\n" //
|
||||
+ "void main()\n" //
|
||||
@ -212,14 +238,15 @@ public class TwoColorPolygonBatch {
|
||||
+ "#define LOWP \n" //
|
||||
+ "#endif\n" //
|
||||
+ "varying LOWP vec4 v_light;\n" //
|
||||
+ "varying LOWP vec3 v_dark;\n" //
|
||||
+ "varying LOWP vec4 v_dark;\n" //
|
||||
+ "uniform float u_pma;\n" //
|
||||
+ "varying vec2 v_texCoords;\n" //
|
||||
+ "uniform sampler2D u_texture;\n" //
|
||||
+ "void main()\n"//
|
||||
+ "{\n" //
|
||||
+ " vec4 texColor = texture2D(u_texture, v_texCoords);\n" //
|
||||
+ " gl_FragColor.a = texColor.a * v_light.a;\n" //
|
||||
+ " gl_FragColor.rgb = ((texColor.a - 1.0) * v_dark.a + 1.0 - texColor.rgb) * v_dark.rgb + texColor.rgb * v_light.rgb;\n" //
|
||||
+ " gl_FragColor.rgb = ((texColor.a - 1.0) * u_pma + 1.0 - texColor.rgb) * v_dark.rgb + texColor.rgb * v_light.rgb;\n" //
|
||||
+ "}";
|
||||
|
||||
ShaderProgram shader = new ShaderProgram(vertexShader, fragmentShader);
|
||||
|
||||
@ -904,26 +904,31 @@ public class SkeletonViewer extends ApplicationAdapter {
|
||||
}
|
||||
|
||||
void loadPrefs () {
|
||||
debugBonesCheckbox.setChecked(prefs.getBoolean("debugBones", true));
|
||||
debugRegionsCheckbox.setChecked(prefs.getBoolean("debugRegions", false));
|
||||
debugMeshHullCheckbox.setChecked(prefs.getBoolean("debugMeshHull", false));
|
||||
debugMeshTrianglesCheckbox.setChecked(prefs.getBoolean("debugMeshTriangles", false));
|
||||
debugPathsCheckbox.setChecked(prefs.getBoolean("debugPaths", true));
|
||||
debugPointsCheckbox.setChecked(prefs.getBoolean("debugPoints", true));
|
||||
debugClippingCheckbox.setChecked(prefs.getBoolean("debugClipping", true));
|
||||
premultipliedCheckbox.setChecked(prefs.getBoolean("premultiplied", true));
|
||||
loopCheckbox.setChecked(prefs.getBoolean("loop", false));
|
||||
speedSlider.setValue(prefs.getFloat("speed", 0.3f));
|
||||
mixSlider.setValue(prefs.getFloat("mix", 0.3f));
|
||||
try {
|
||||
debugBonesCheckbox.setChecked(prefs.getBoolean("debugBones", true));
|
||||
debugRegionsCheckbox.setChecked(prefs.getBoolean("debugRegions", false));
|
||||
debugMeshHullCheckbox.setChecked(prefs.getBoolean("debugMeshHull", false));
|
||||
debugMeshTrianglesCheckbox.setChecked(prefs.getBoolean("debugMeshTriangles", false));
|
||||
debugPathsCheckbox.setChecked(prefs.getBoolean("debugPaths", true));
|
||||
debugPointsCheckbox.setChecked(prefs.getBoolean("debugPoints", true));
|
||||
debugClippingCheckbox.setChecked(prefs.getBoolean("debugClipping", true));
|
||||
premultipliedCheckbox.setChecked(prefs.getBoolean("premultiplied", true));
|
||||
loopCheckbox.setChecked(prefs.getBoolean("loop", false));
|
||||
speedSlider.setValue(prefs.getFloat("speed", 0.3f));
|
||||
mixSlider.setValue(prefs.getFloat("mix", 0.3f));
|
||||
|
||||
zoomSlider.setValue(prefs.getFloat("zoom", 1));
|
||||
camera.zoom = 1 / prefs.getFloat("zoom", 1);
|
||||
camera.position.x = prefs.getFloat("x", 0);
|
||||
camera.position.y = prefs.getFloat("y", 0);
|
||||
zoomSlider.setValue(prefs.getFloat("zoom", 1));
|
||||
camera.zoom = 1 / prefs.getFloat("zoom", 1);
|
||||
camera.position.x = prefs.getFloat("x", 0);
|
||||
camera.position.y = prefs.getFloat("y", 0);
|
||||
|
||||
scaleSlider.setValue(prefs.getFloat("scale", 1));
|
||||
animationList.setSelected(prefs.getString("animationName", null));
|
||||
skinList.setSelected(prefs.getString("skinName", null));
|
||||
scaleSlider.setValue(prefs.getFloat("scale", 1));
|
||||
animationList.setSelected(prefs.getString("animationName", null));
|
||||
skinList.setSelected(prefs.getString("skinName", null));
|
||||
} catch (Exception ex) {
|
||||
System.out.println("Unable to read preferences:");
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -457,7 +457,7 @@ namespace Spine.Unity.Editor {
|
||||
static Bone extractionBone;
|
||||
static Slot extractionSlot;
|
||||
|
||||
static Bone GetExtractionBone () {
|
||||
internal static Bone GetExtractionBone () {
|
||||
if (extractionBone != null)
|
||||
return extractionBone;
|
||||
|
||||
@ -479,7 +479,7 @@ namespace Spine.Unity.Editor {
|
||||
return extractionBone;
|
||||
}
|
||||
|
||||
static Slot GetExtractionSlot () {
|
||||
internal static Slot GetExtractionSlot () {
|
||||
if (extractionSlot != null)
|
||||
return extractionSlot;
|
||||
|
||||
@ -491,11 +491,14 @@ namespace Spine.Unity.Editor {
|
||||
return extractionSlot;
|
||||
}
|
||||
|
||||
static Mesh ExtractRegionAttachment (string name, RegionAttachment attachment, Mesh mesh = null) {
|
||||
internal static Mesh ExtractRegionAttachment (string name, RegionAttachment attachment, Mesh mesh = null, bool centered = true) {
|
||||
var bone = GetExtractionBone();
|
||||
|
||||
bone.X = -attachment.X;
|
||||
bone.Y = -attachment.Y;
|
||||
if (centered) {
|
||||
bone.X = -attachment.X;
|
||||
bone.Y = -attachment.Y;
|
||||
}
|
||||
|
||||
bone.UpdateWorldTransform();
|
||||
|
||||
Vector2[] uvs = ExtractUV(attachment.UVs);
|
||||
@ -504,12 +507,13 @@ namespace Spine.Unity.Editor {
|
||||
Vector3[] verts = ExtractVerts(floatVerts);
|
||||
|
||||
//unrotate verts now that they're centered
|
||||
for (int i = 0; i < verts.Length; i++) {
|
||||
verts[i] = Quaternion.Euler(0, 0, -attachment.Rotation) * verts[i];
|
||||
if (centered) {
|
||||
for (int i = 0; i < verts.Length; i++)
|
||||
verts[i] = Quaternion.Euler(0, 0, -attachment.Rotation) * verts[i];
|
||||
}
|
||||
|
||||
int[] triangles = new int[6] { 1, 3, 0, 2, 3, 1 };
|
||||
Color color = new Color(attachment.R, attachment.G, attachment.B, attachment.A);
|
||||
int[] triangles = { 1, 3, 0, 2, 3, 1 };
|
||||
Color color = attachment.GetColor();
|
||||
|
||||
if (mesh == null)
|
||||
mesh = new Mesh();
|
||||
@ -519,7 +523,7 @@ namespace Spine.Unity.Editor {
|
||||
mesh.vertices = verts;
|
||||
mesh.uv = uvs;
|
||||
mesh.triangles = triangles;
|
||||
mesh.colors = new Color[] { color, color, color, color };
|
||||
mesh.colors = new [] { color, color, color, color };
|
||||
mesh.RecalculateBounds();
|
||||
mesh.RecalculateNormals();
|
||||
mesh.name = name;
|
||||
@ -527,7 +531,7 @@ namespace Spine.Unity.Editor {
|
||||
return mesh;
|
||||
}
|
||||
|
||||
static Mesh ExtractMeshAttachment (string name, MeshAttachment attachment, Mesh mesh = null) {
|
||||
internal static Mesh ExtractMeshAttachment (string name, MeshAttachment attachment, Mesh mesh = null) {
|
||||
var slot = GetExtractionSlot();
|
||||
|
||||
slot.Bone.X = 0;
|
||||
@ -592,7 +596,7 @@ namespace Spine.Unity.Editor {
|
||||
}
|
||||
}
|
||||
|
||||
static Mesh ExtractWeightedMeshAttachment (string name, MeshAttachment attachment, int slotIndex, SkeletonData skeletonData, List<Transform> boneList, Mesh mesh = null) {
|
||||
internal static Mesh ExtractWeightedMeshAttachment (string name, MeshAttachment attachment, int slotIndex, SkeletonData skeletonData, List<Transform> boneList, Mesh mesh = null) {
|
||||
if (attachment.Bones == null)
|
||||
throw new System.ArgumentException("Mesh is not weighted.", "attachment");
|
||||
|
||||
@ -708,7 +712,7 @@ namespace Spine.Unity.Editor {
|
||||
return mesh;
|
||||
}
|
||||
|
||||
static Vector2[] ExtractUV (float[] floats) {
|
||||
internal static Vector2[] ExtractUV (float[] floats) {
|
||||
Vector2[] arr = new Vector2[floats.Length / 2];
|
||||
|
||||
for (int i = 0; i < floats.Length; i += 2) {
|
||||
@ -718,7 +722,7 @@ namespace Spine.Unity.Editor {
|
||||
return arr;
|
||||
}
|
||||
|
||||
static Vector3[] ExtractVerts (float[] floats) {
|
||||
internal static Vector3[] ExtractVerts (float[] floats) {
|
||||
Vector3[] arr = new Vector3[floats.Length / 2];
|
||||
|
||||
for (int i = 0; i < floats.Length; i += 2) {
|
||||
|
||||
@ -52,7 +52,7 @@ Shader "Spine/Skeleton Tint" {
|
||||
|
||||
float4 frag (VertexOutput i) : COLOR {
|
||||
float4 texColor = tex2D(_MainTex, i.uv);
|
||||
return (texColor * i.vertexColor) + float4(((1-texColor.rgb) * texColor.a * _Black.rgb), 0);
|
||||
return (texColor * i.vertexColor) + float4(((1-texColor.rgb) * _Black.rgb * texColor.a*_Color.a*i.vertexColor.a), 0);
|
||||
}
|
||||
ENDCG
|
||||
}
|
||||
|
||||
@ -110,7 +110,7 @@ Shader "Spine/SkeletonGraphic Tint Black (Premultiply Alpha)"
|
||||
clip (texColor.a - 0.001);
|
||||
#endif
|
||||
|
||||
return (texColor * IN.color) + float4(((1-texColor.rgb) * texColor.a * (_Black.rgb + float3(IN.uv1.r, IN.uv1.g, IN.uv2.r))), 0);
|
||||
return (texColor * IN.color) + float4(((1-texColor.rgb) * (_Black.rgb + float3(IN.uv1.r, IN.uv1.g, IN.uv2.r)) * texColor.a*_Color.a*i.vertexColor.a), 0);
|
||||
}
|
||||
ENDCG
|
||||
}
|
||||
|
||||
@ -61,7 +61,7 @@ Shader "Spine/Skeleton Tint Black" {
|
||||
|
||||
float4 frag (VertexOutput i) : COLOR {
|
||||
float4 texColor = tex2D(_MainTex, i.uv);
|
||||
return (texColor * i.vertexColor) + float4(((1-texColor.rgb) * texColor.a * (_Black.rgb + float3(i.uv1.r, i.uv1.g, i.uv2.r))), 0);
|
||||
return (texColor * i.vertexColor) + float4(((1-texColor.rgb) * (_Black.rgb + float3(i.uv1.r, i.uv1.g, i.uv2.r)) * texColor.a*_Color.a*i.vertexColor.a), 0);
|
||||
}
|
||||
ENDCG
|
||||
}
|
||||
|
||||
@ -144,6 +144,12 @@ namespace Spine.Unity {
|
||||
return new Quaternion(0, 0, Mathf.Sin(halfRotation), Mathf.Cos(halfRotation));
|
||||
}
|
||||
|
||||
/// <summary>Gets a bone-local space UnityEngine.Quaternion representation of bone.rotation.</summary>
|
||||
public static Quaternion GetLocalQuaternion (this Bone bone) {
|
||||
var halfRotation = bone.rotation * Mathf.Deg2Rad * 0.5f;
|
||||
return new Quaternion(0, 0, Mathf.Sin(halfRotation), Mathf.Cos(halfRotation));
|
||||
}
|
||||
|
||||
/// <summary>Gets the PointAttachment's Unity World position using its Spine GameObject Transform.</summary>
|
||||
public static Vector3 GetWorldPosition (this PointAttachment attachment, Slot slot, Transform spineGameObjectTransform) {
|
||||
Vector3 skeletonSpacePosition;
|
||||
@ -288,6 +294,10 @@ namespace Spine {
|
||||
return va.bones != null && va.bones.Length > 0;
|
||||
}
|
||||
|
||||
public static bool IsRenderable (this Attachment a) {
|
||||
return a is RegionAttachment || a is MeshAttachment;
|
||||
}
|
||||
|
||||
#region Transform Modes
|
||||
public static bool InheritsRotation (this TransformMode mode) {
|
||||
const int RotationBit = 0;
|
||||
|
||||
@ -213,7 +213,7 @@ namespace Spine.Unity {
|
||||
for (int i = 0; i < separatorSlotNames.Length; i++)
|
||||
separatorSlots.Add(skeleton.FindSlot(separatorSlotNames[i]));
|
||||
|
||||
LateUpdate();
|
||||
LateUpdate(); // Generate mesh for the first frame it exists.
|
||||
|
||||
if (OnRebuild != null)
|
||||
OnRebuild(this);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user