mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2025-12-21 01:36:02 +08:00
Blend modes for all runtimes.
This commit is contained in:
parent
142e770e5b
commit
f8a76c6455
@ -54,7 +54,7 @@
|
|||||||
{ "name": "goggles", "bone": "head", "attachment": "goggles" },
|
{ "name": "goggles", "bone": "head", "attachment": "goggles" },
|
||||||
{ "name": "front_bracer", "bone": "front_bracer", "attachment": "front_bracer" },
|
{ "name": "front_bracer", "bone": "front_bracer", "attachment": "front_bracer" },
|
||||||
{ "name": "front_fist", "bone": "front_fist", "attachment": "front_fist_closed" },
|
{ "name": "front_fist", "bone": "front_fist", "attachment": "front_fist_closed" },
|
||||||
{ "name": "muzzle", "bone": "gunTip", "additive": true },
|
{ "name": "muzzle", "bone": "gunTip", "blend": "additive" },
|
||||||
{ "name": "head-bb", "bone": "head" }
|
{ "name": "head-bb", "bone": "head" }
|
||||||
],
|
],
|
||||||
"skins": {
|
"skins": {
|
||||||
|
|||||||
46
spine-as3/spine-as3/src/spine/BlendMode.as
Normal file
46
spine-as3/spine-as3/src/spine/BlendMode.as
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Spine Runtimes Software License
|
||||||
|
* Version 2.1
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013, Esoteric Software
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* You are granted a perpetual, non-exclusive, non-sublicensable and
|
||||||
|
* non-transferable license to install, execute and perform the Spine Runtimes
|
||||||
|
* Software (the "Software") solely for internal use. Without the written
|
||||||
|
* permission of Esoteric Software (typically granted by licensing Spine), you
|
||||||
|
* may not (a) modify, translate, adapt or otherwise create derivative works,
|
||||||
|
* improvements of the Software or develop new applications using the Software
|
||||||
|
* or (b) remove, delete, alter or obscure any trademarks or any copyright,
|
||||||
|
* trademark, patent or other intellectual property or proprietary rights
|
||||||
|
* notices on or in the Software, including any copy thereof. Redistributions
|
||||||
|
* in binary or source form must include this license and terms.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||||
|
* EVENT SHALL ESOTERIC SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||||
|
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||||
|
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
package spine {
|
||||||
|
|
||||||
|
public class BlendMode {
|
||||||
|
public static const normal:BlendMode = new BlendMode(0);
|
||||||
|
public static const additive:BlendMode = new BlendMode(1);
|
||||||
|
public static const multiply:BlendMode = new BlendMode(2);
|
||||||
|
public static const screen:BlendMode = new BlendMode(3);
|
||||||
|
|
||||||
|
public var ordinal:int;
|
||||||
|
|
||||||
|
public function BlendMode (ordinal:int) {
|
||||||
|
this.ordinal = ordinal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -145,7 +145,7 @@ public class SkeletonJson {
|
|||||||
}
|
}
|
||||||
|
|
||||||
slotData.attachmentName = slotMap["attachment"];
|
slotData.attachmentName = slotMap["attachment"];
|
||||||
slotData.additiveBlending = slotMap["additive"];
|
slotData.blendMode = BlendMode[slotMap["blend"] || "normal"];
|
||||||
|
|
||||||
skeletonData.slots[skeletonData.slots.length] = slotData;
|
skeletonData.slots[skeletonData.slots.length] = slotData;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -38,7 +38,7 @@ public class SlotData {
|
|||||||
public var b:Number = 1;
|
public var b:Number = 1;
|
||||||
public var a:Number = 1;
|
public var a:Number = 1;
|
||||||
public var attachmentName:String;
|
public var attachmentName:String;
|
||||||
public var additiveBlending:Boolean;
|
public var blendMode:BlendMode;
|
||||||
|
|
||||||
public function SlotData (name:String, boneData:BoneData) {
|
public function SlotData (name:String, boneData:BoneData) {
|
||||||
if (name == null) throw new ArgumentError("name cannot be null.");
|
if (name == null) throw new ArgumentError("name cannot be null.");
|
||||||
|
|||||||
@ -52,6 +52,8 @@ import spine.attachments.RegionAttachment;
|
|||||||
public class SkeletonSprite extends Sprite {
|
public class SkeletonSprite extends Sprite {
|
||||||
static private var tempPoint:Point = new Point();
|
static private var tempPoint:Point = new Point();
|
||||||
static private var tempMatrix:Matrix = new Matrix();
|
static private var tempMatrix:Matrix = new Matrix();
|
||||||
|
static private var blendModes:Vector.<String> = new <String>[
|
||||||
|
BlendMode.NORMAL, BlendMode.ADD, BlendMode.MULTIPLY, BlendMode.SCREEN];
|
||||||
|
|
||||||
private var _skeleton:Skeleton;
|
private var _skeleton:Skeleton;
|
||||||
public var timeScale:Number = 1;
|
public var timeScale:Number = 1;
|
||||||
@ -119,7 +121,7 @@ public class SkeletonSprite extends Sprite {
|
|||||||
regionAttachment["wrapper"] = wrapper;
|
regionAttachment["wrapper"] = wrapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
wrapper.blendMode = slot.data.additiveBlending ? BlendMode.ADD : BlendMode.NORMAL;
|
wrapper.blendMode = blendModes[slot.data.blendMode.ordinal];
|
||||||
|
|
||||||
var colorTransform:ColorTransform = wrapper.transform.colorTransform;
|
var colorTransform:ColorTransform = wrapper.transform.colorTransform;
|
||||||
colorTransform.redMultiplier = skeleton.r * slot.r * regionAttachment.r;
|
colorTransform.redMultiplier = skeleton.r * slot.r * regionAttachment.r;
|
||||||
|
|||||||
@ -53,7 +53,7 @@ typedef struct spSlot {
|
|||||||
spSlot() :
|
spSlot() :
|
||||||
data(0),
|
data(0),
|
||||||
bone(0),
|
bone(0),
|
||||||
r(0), b(0), g(0), a(0),
|
r(0), g(0), b(0), a(0),
|
||||||
attachment(0),
|
attachment(0),
|
||||||
attachmentVerticesCapacity(0),
|
attachmentVerticesCapacity(0),
|
||||||
attachmentVerticesCount(0),
|
attachmentVerticesCount(0),
|
||||||
|
|||||||
@ -37,12 +37,16 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
SP_BLEND_MODE_NORMAL, SP_BLEND_MODE_ADDITIVE, SP_BLEND_MODE_MULTIPLY, SP_BLEND_MODE_SCREEN
|
||||||
|
} spBlendMode;
|
||||||
|
|
||||||
typedef struct spSlotData {
|
typedef struct spSlotData {
|
||||||
const char* const name;
|
const char* const name;
|
||||||
const spBoneData* const boneData;
|
const spBoneData* const boneData;
|
||||||
const char* attachmentName;
|
const char* attachmentName;
|
||||||
float r, g, b, a;
|
float r, g, b, a;
|
||||||
int/*bool*/additiveBlending;
|
spBlendMode blendMode;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
spSlotData() :
|
spSlotData() :
|
||||||
@ -50,7 +54,7 @@ typedef struct spSlotData {
|
|||||||
boneData(0),
|
boneData(0),
|
||||||
attachmentName(0),
|
attachmentName(0),
|
||||||
r(0), g(0), b(0), a(0),
|
r(0), g(0), b(0), a(0),
|
||||||
additiveBlending(0) {
|
blendMode(SP_BLEND_MODE_NORMAL) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
} spSlotData;
|
} spSlotData;
|
||||||
@ -62,6 +66,11 @@ void spSlotData_dispose (spSlotData* self);
|
|||||||
void spSlotData_setAttachmentName (spSlotData* self, const char* attachmentName);
|
void spSlotData_setAttachmentName (spSlotData* self, const char* attachmentName);
|
||||||
|
|
||||||
#ifdef SPINE_SHORT_NAMES
|
#ifdef SPINE_SHORT_NAMES
|
||||||
|
typedef spBlendMode BlendMode;
|
||||||
|
#define BLEND_MODE_NORMAL SP_BLEND_MODE_NORMAL
|
||||||
|
#define BLEND_MODE_ADDITIVE SP_BLEND_MODE_ADDITIVE
|
||||||
|
#define BLEND_MODE_MULTIPLY SP_BLEND_MODE_MULTIPLY
|
||||||
|
#define BLEND_MODE_SCREEN SP_BLEND_MODE_SCREEN
|
||||||
typedef spSlotData SlotData;
|
typedef spSlotData SlotData;
|
||||||
#define SlotData_create(...) spSlotData_create(__VA_ARGS__)
|
#define SlotData_create(...) spSlotData_create(__VA_ARGS__)
|
||||||
#define SlotData_dispose(...) spSlotData_dispose(__VA_ARGS__)
|
#define SlotData_dispose(...) spSlotData_dispose(__VA_ARGS__)
|
||||||
|
|||||||
@ -519,7 +519,7 @@ spSkeletonData* spSkeletonJson_readSkeletonData (spSkeletonJson* self, const cha
|
|||||||
for (slotMap = slots->child, i = 0; slotMap; slotMap = slotMap->next, ++i) {
|
for (slotMap = slots->child, i = 0; slotMap; slotMap = slotMap->next, ++i) {
|
||||||
spSlotData* slotData;
|
spSlotData* slotData;
|
||||||
const char* color;
|
const char* color;
|
||||||
Json *attachmentItem;
|
Json *item;
|
||||||
|
|
||||||
const char* boneName = Json_getString(slotMap, "bone", 0);
|
const char* boneName = Json_getString(slotMap, "bone", 0);
|
||||||
spBoneData* boneData = spSkeletonData_findBone(skeletonData, boneName);
|
spBoneData* boneData = spSkeletonData_findBone(skeletonData, boneName);
|
||||||
@ -539,10 +539,18 @@ spSkeletonData* spSkeletonJson_readSkeletonData (spSkeletonJson* self, const cha
|
|||||||
slotData->a = toColor(color, 3);
|
slotData->a = toColor(color, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
attachmentItem = Json_getItem(slotMap, "attachment");
|
item = Json_getItem(slotMap, "attachment");
|
||||||
if (attachmentItem) spSlotData_setAttachmentName(slotData, attachmentItem->valueString);
|
if (item) spSlotData_setAttachmentName(slotData, item->valueString);
|
||||||
|
|
||||||
slotData->additiveBlending = Json_getInt(slotMap, "additive", 0);
|
item = Json_getItem(slotMap, "blend");
|
||||||
|
if (item) {
|
||||||
|
if (strcmp(item->valueString, "additive") == 0)
|
||||||
|
slotData->blendMode = SP_BLEND_MODE_ADDITIVE;
|
||||||
|
else if (strcmp(item->valueString, "multiply") == 0)
|
||||||
|
slotData->blendMode = SP_BLEND_MODE_MULTIPLY;
|
||||||
|
else if (strcmp(item->valueString, "screen") == 0)
|
||||||
|
slotData->blendMode = SP_BLEND_MODE_SCREEN;
|
||||||
|
}
|
||||||
|
|
||||||
skeletonData->slots[i] = slotData;
|
skeletonData->slots[i] = slotData;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -142,7 +142,7 @@ static const int quadTriangles[6] = {0, 1, 2, 2, 3, 0};
|
|||||||
_skeleton->b = nodeColor.b / (float)255;
|
_skeleton->b = nodeColor.b / (float)255;
|
||||||
_skeleton->a = self.opacity / (float)255;
|
_skeleton->a = self.opacity / (float)255;
|
||||||
|
|
||||||
int additive = -1;
|
int blendMode = -1;
|
||||||
ccColor4B color;
|
ccColor4B color;
|
||||||
const float* uvs = 0;
|
const float* uvs = 0;
|
||||||
int verticesCount = 0;
|
int verticesCount = 0;
|
||||||
@ -199,10 +199,22 @@ static const int quadTriangles[6] = {0, 1, 2, 2, 3, 0};
|
|||||||
default: ;
|
default: ;
|
||||||
}
|
}
|
||||||
if (texture) {
|
if (texture) {
|
||||||
if (slot->data->additiveBlending != additive) {
|
if (slot->data->blendMode != blendMode) {
|
||||||
[batch flush];
|
[batch flush];
|
||||||
ccGLBlendFunc(_blendFunc.src, slot->data->additiveBlending ? GL_ONE : _blendFunc.dst);
|
blendMode = slot->data->blendMode;
|
||||||
additive = slot->data->additiveBlending;
|
switch (slot->data->blendMode) {
|
||||||
|
case SP_BLEND_MODE_ADDITIVE:
|
||||||
|
ccGLBlendFunc(_premultipliedAlpha ? GL_ONE : GL_SRC_ALPHA, GL_ONE);
|
||||||
|
break;
|
||||||
|
case SP_BLEND_MODE_MULTIPLY:
|
||||||
|
ccGLBlendFunc(GL_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
break;
|
||||||
|
case SP_BLEND_MODE_SCREEN:
|
||||||
|
ccGLBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ccGLBlendFunc(_premultipliedAlpha ? GL_ONE : GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
color.a = _skeleton->a * slot->a * a * 255;
|
color.a = _skeleton->a * slot->a * a * 255;
|
||||||
float multiplier = _premultipliedAlpha ? color.a : 255;
|
float multiplier = _premultipliedAlpha ? color.a : 255;
|
||||||
|
|||||||
@ -39,10 +39,11 @@
|
|||||||
bool _debugBones;
|
bool _debugBones;
|
||||||
bool _premultipliedAlpha;
|
bool _premultipliedAlpha;
|
||||||
ccBlendFunc _blendFunc;
|
ccBlendFunc _blendFunc;
|
||||||
CCDrawNode *_drawNode;
|
CCDrawNode* _drawNode;
|
||||||
bool _ownsSkeletonData;
|
bool _ownsSkeletonData;
|
||||||
spAtlas* _atlas;
|
spAtlas* _atlas;
|
||||||
float* worldVertices;
|
float* _worldVertices;
|
||||||
|
CCBlendMode* screenMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (id) skeletonWithData:(spSkeletonData*)skeletonData ownsSkeletonData:(bool)ownsSkeletonData;
|
+ (id) skeletonWithData:(spSkeletonData*)skeletonData ownsSkeletonData:(bool)ownsSkeletonData;
|
||||||
|
|||||||
@ -62,7 +62,7 @@ static const int quadTriangles[6] = {0, 1, 2, 2, 3, 0};
|
|||||||
- (void) initialize:(spSkeletonData*)skeletonData ownsSkeletonData:(bool)ownsSkeletonData {
|
- (void) initialize:(spSkeletonData*)skeletonData ownsSkeletonData:(bool)ownsSkeletonData {
|
||||||
_ownsSkeletonData = ownsSkeletonData;
|
_ownsSkeletonData = ownsSkeletonData;
|
||||||
|
|
||||||
worldVertices = MALLOC(float, 1000); // Max number of vertices per mesh.
|
_worldVertices = MALLOC(float, 1000); // Max number of vertices per mesh.
|
||||||
|
|
||||||
_skeleton = spSkeleton_create(skeletonData);
|
_skeleton = spSkeleton_create(skeletonData);
|
||||||
_rootBone = _skeleton->bones[0];
|
_rootBone = _skeleton->bones[0];
|
||||||
@ -74,6 +74,12 @@ static const int quadTriangles[6] = {0, 1, 2, 2, 3, 0};
|
|||||||
[self addChild:_drawNode];
|
[self addChild:_drawNode];
|
||||||
|
|
||||||
[self setShader:[CCShader positionTextureColorShader]];
|
[self setShader:[CCShader positionTextureColorShader]];
|
||||||
|
|
||||||
|
_premultipliedAlpha = true;
|
||||||
|
screenMode = [CCBlendMode blendModeWithOptions:@{
|
||||||
|
CCBlendFuncSrcColor: @(GL_ONE),
|
||||||
|
CCBlendFuncDstColor: @(GL_ONE_MINUS_SRC_COLOR)}
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id) initWithData:(spSkeletonData*)skeletonData ownsSkeletonData:(bool)ownsSkeletonData {
|
- (id) initWithData:(spSkeletonData*)skeletonData ownsSkeletonData:(bool)ownsSkeletonData {
|
||||||
@ -127,7 +133,7 @@ static const int quadTriangles[6] = {0, 1, 2, 2, 3, 0};
|
|||||||
if (_ownsSkeletonData) spSkeletonData_dispose(_skeleton->data);
|
if (_ownsSkeletonData) spSkeletonData_dispose(_skeleton->data);
|
||||||
if (_atlas) spAtlas_dispose(_atlas);
|
if (_atlas) spAtlas_dispose(_atlas);
|
||||||
spSkeleton_dispose(_skeleton);
|
spSkeleton_dispose(_skeleton);
|
||||||
FREE(worldVertices);
|
FREE(_worldVertices);
|
||||||
[super dealloc];
|
[super dealloc];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,7 +144,7 @@ static const int quadTriangles[6] = {0, 1, 2, 2, 3, 0};
|
|||||||
_skeleton->b = nodeColor.blue;
|
_skeleton->b = nodeColor.blue;
|
||||||
_skeleton->a = self.displayedOpacity;
|
_skeleton->a = self.displayedOpacity;
|
||||||
|
|
||||||
int additive = -1;
|
int blendMode = -1;
|
||||||
const float* uvs = 0;
|
const float* uvs = 0;
|
||||||
int verticesCount = 0;
|
int verticesCount = 0;
|
||||||
const int* triangles = 0;
|
const int* triangles = 0;
|
||||||
@ -151,7 +157,7 @@ static const int quadTriangles[6] = {0, 1, 2, 2, 3, 0};
|
|||||||
switch (slot->attachment->type) {
|
switch (slot->attachment->type) {
|
||||||
case SP_ATTACHMENT_REGION: {
|
case SP_ATTACHMENT_REGION: {
|
||||||
spRegionAttachment* attachment = (spRegionAttachment*)slot->attachment;
|
spRegionAttachment* attachment = (spRegionAttachment*)slot->attachment;
|
||||||
spRegionAttachment_computeWorldVertices(attachment, slot->bone, worldVertices);
|
spRegionAttachment_computeWorldVertices(attachment, slot->bone, _worldVertices);
|
||||||
texture = [self getTextureForRegion:attachment];
|
texture = [self getTextureForRegion:attachment];
|
||||||
uvs = attachment->uvs;
|
uvs = attachment->uvs;
|
||||||
verticesCount = 8;
|
verticesCount = 8;
|
||||||
@ -165,7 +171,7 @@ static const int quadTriangles[6] = {0, 1, 2, 2, 3, 0};
|
|||||||
}
|
}
|
||||||
case SP_ATTACHMENT_MESH: {
|
case SP_ATTACHMENT_MESH: {
|
||||||
spMeshAttachment* attachment = (spMeshAttachment*)slot->attachment;
|
spMeshAttachment* attachment = (spMeshAttachment*)slot->attachment;
|
||||||
spMeshAttachment_computeWorldVertices(attachment, slot, worldVertices);
|
spMeshAttachment_computeWorldVertices(attachment, slot, _worldVertices);
|
||||||
texture = [self getTextureForMesh:attachment];
|
texture = [self getTextureForMesh:attachment];
|
||||||
uvs = attachment->uvs;
|
uvs = attachment->uvs;
|
||||||
verticesCount = attachment->verticesCount;
|
verticesCount = attachment->verticesCount;
|
||||||
@ -179,7 +185,7 @@ static const int quadTriangles[6] = {0, 1, 2, 2, 3, 0};
|
|||||||
}
|
}
|
||||||
case SP_ATTACHMENT_SKINNED_MESH: {
|
case SP_ATTACHMENT_SKINNED_MESH: {
|
||||||
spSkinnedMeshAttachment* attachment = (spSkinnedMeshAttachment*)slot->attachment;
|
spSkinnedMeshAttachment* attachment = (spSkinnedMeshAttachment*)slot->attachment;
|
||||||
spSkinnedMeshAttachment_computeWorldVertices(attachment, slot, worldVertices);
|
spSkinnedMeshAttachment_computeWorldVertices(attachment, slot, _worldVertices);
|
||||||
texture = [self getTextureForSkinnedMesh:attachment];
|
texture = [self getTextureForSkinnedMesh:attachment];
|
||||||
uvs = attachment->uvs;
|
uvs = attachment->uvs;
|
||||||
verticesCount = attachment->uvsCount;
|
verticesCount = attachment->uvsCount;
|
||||||
@ -194,22 +200,34 @@ static const int quadTriangles[6] = {0, 1, 2, 2, 3, 0};
|
|||||||
default: ;
|
default: ;
|
||||||
}
|
}
|
||||||
if (texture) {
|
if (texture) {
|
||||||
if (slot->data->additiveBlending != additive) {
|
if (slot->data->blendMode != blendMode) {
|
||||||
[self setBlendMode:[CCBlendMode blendModeWithOptions:@{CCBlendFuncSrcColor: @(_blendFunc.src),CCBlendFuncDstColor: @(slot->data->additiveBlending ? GL_ONE : _blendFunc.dst)}]];
|
blendMode = slot->data->blendMode;
|
||||||
additive = slot->data->additiveBlending;
|
switch (slot->data->blendMode) {
|
||||||
|
case SP_BLEND_MODE_ADDITIVE:
|
||||||
|
[self setBlendMode:[CCBlendMode addMode]];
|
||||||
|
break;
|
||||||
|
case SP_BLEND_MODE_MULTIPLY:
|
||||||
|
[self setBlendMode:[CCBlendMode multiplyMode]];
|
||||||
|
break;
|
||||||
|
case SP_BLEND_MODE_SCREEN:
|
||||||
|
[self setBlendMode:screenMode];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
[self setBlendMode:_premultipliedAlpha ? [CCBlendMode premultipliedAlphaMode] : [CCBlendMode alphaMode]];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (_premultipliedAlpha) {
|
if (_premultipliedAlpha) {
|
||||||
a *= _skeleton->a * slot->a;
|
a *= _skeleton->a * slot->a;
|
||||||
r *= _skeleton->r * slot->r * a;
|
r *= _skeleton->r * slot->r * a;
|
||||||
g *= _skeleton->g * slot->g * a;
|
g *= _skeleton->g * slot->g * a;
|
||||||
b *= _skeleton->b * slot->b * a;
|
b *= _skeleton->b * slot->b * a;
|
||||||
} else {
|
} else {
|
||||||
a *= _skeleton->a * slot->a;
|
a *= _skeleton->a * slot->a;
|
||||||
r *= _skeleton->r * slot->r;
|
r *= _skeleton->r * slot->r;
|
||||||
g *= _skeleton->g * slot->g;
|
g *= _skeleton->g * slot->g;
|
||||||
b *= _skeleton->b * slot->b;
|
b *= _skeleton->b * slot->b;
|
||||||
}
|
}
|
||||||
self.texture = texture;
|
self.texture = texture;
|
||||||
CGSize size = texture.contentSize;
|
CGSize size = texture.contentSize;
|
||||||
GLKVector2 center = GLKVector2Make(size.width / 2.0, size.height / 2.0);
|
GLKVector2 center = GLKVector2Make(size.width / 2.0, size.height / 2.0);
|
||||||
GLKVector2 extents = GLKVector2Make(size.width / 2.0, size.height / 2.0);
|
GLKVector2 extents = GLKVector2Make(size.width / 2.0, size.height / 2.0);
|
||||||
@ -217,7 +235,7 @@ static const int quadTriangles[6] = {0, 1, 2, 2, 3, 0};
|
|||||||
CCRenderBuffer buffer = [renderer enqueueTriangles:(trianglesCount / 3) andVertexes:verticesCount withState:self.renderState globalSortOrder:0];
|
CCRenderBuffer buffer = [renderer enqueueTriangles:(trianglesCount / 3) andVertexes:verticesCount withState:self.renderState globalSortOrder:0];
|
||||||
for (int i = 0; i * 2 < verticesCount; ++i) {
|
for (int i = 0; i * 2 < verticesCount; ++i) {
|
||||||
CCVertex vertex;
|
CCVertex vertex;
|
||||||
vertex.position = GLKVector4Make(worldVertices[i * 2], worldVertices[i * 2 + 1], 0.0, 1.0);
|
vertex.position = GLKVector4Make(_worldVertices[i * 2], _worldVertices[i * 2 + 1], 0.0, 1.0);
|
||||||
vertex.color = GLKVector4Make(r, g, b, a);
|
vertex.color = GLKVector4Make(r, g, b, a);
|
||||||
vertex.texCoord1 = GLKVector2Make(uvs[i * 2], 1 - uvs[i * 2 + 1]);
|
vertex.texCoord1 = GLKVector2Make(uvs[i * 2], 1 - uvs[i * 2 + 1]);
|
||||||
CCRenderBufferSetVertex(buffer, i, CCVertexApplyTransform(vertex, transform));
|
CCRenderBufferSetVertex(buffer, i, CCVertexApplyTransform(vertex, transform));
|
||||||
@ -236,11 +254,11 @@ static const int quadTriangles[6] = {0, 1, 2, 2, 3, 0};
|
|||||||
spSlot* slot = _skeleton->drawOrder[i];
|
spSlot* slot = _skeleton->drawOrder[i];
|
||||||
if (!slot->attachment || slot->attachment->type != SP_ATTACHMENT_REGION) continue;
|
if (!slot->attachment || slot->attachment->type != SP_ATTACHMENT_REGION) continue;
|
||||||
spRegionAttachment* attachment = (spRegionAttachment*)slot->attachment;
|
spRegionAttachment* attachment = (spRegionAttachment*)slot->attachment;
|
||||||
spRegionAttachment_computeWorldVertices(attachment, slot->bone, worldVertices);
|
spRegionAttachment_computeWorldVertices(attachment, slot->bone, _worldVertices);
|
||||||
points[0] = ccp(worldVertices[0], worldVertices[1]);
|
points[0] = ccp(_worldVertices[0], _worldVertices[1]);
|
||||||
points[1] = ccp(worldVertices[2], worldVertices[3]);
|
points[1] = ccp(_worldVertices[2], _worldVertices[3]);
|
||||||
points[2] = ccp(worldVertices[4], worldVertices[5]);
|
points[2] = ccp(_worldVertices[4], _worldVertices[5]);
|
||||||
points[3] = ccp(worldVertices[6], worldVertices[7]);
|
points[3] = ccp(_worldVertices[6], _worldVertices[7]);
|
||||||
[_drawNode drawPolyWithVerts:points count:4 fillColor:[CCColor clearColor] borderWidth:1 borderColor:[CCColor blueColor]];
|
[_drawNode drawPolyWithVerts:points count:4 fillColor:[CCColor clearColor] borderWidth:1 borderColor:[CCColor blueColor]];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -283,20 +301,20 @@ static const int quadTriangles[6] = {0, 1, 2, 2, 3, 0};
|
|||||||
int verticesCount;
|
int verticesCount;
|
||||||
if (slot->attachment->type == SP_ATTACHMENT_REGION) {
|
if (slot->attachment->type == SP_ATTACHMENT_REGION) {
|
||||||
spRegionAttachment* attachment = (spRegionAttachment*)slot->attachment;
|
spRegionAttachment* attachment = (spRegionAttachment*)slot->attachment;
|
||||||
spRegionAttachment_computeWorldVertices(attachment, slot->bone, worldVertices);
|
spRegionAttachment_computeWorldVertices(attachment, slot->bone, _worldVertices);
|
||||||
verticesCount = 8;
|
verticesCount = 8;
|
||||||
} else if (slot->attachment->type == SP_ATTACHMENT_MESH) {
|
} else if (slot->attachment->type == SP_ATTACHMENT_MESH) {
|
||||||
spMeshAttachment* mesh = (spMeshAttachment*)slot->attachment;
|
spMeshAttachment* mesh = (spMeshAttachment*)slot->attachment;
|
||||||
spMeshAttachment_computeWorldVertices(mesh, slot, worldVertices);
|
spMeshAttachment_computeWorldVertices(mesh, slot, _worldVertices);
|
||||||
verticesCount = mesh->verticesCount;
|
verticesCount = mesh->verticesCount;
|
||||||
} else if (slot->attachment->type == SP_ATTACHMENT_SKINNED_MESH) {
|
} else if (slot->attachment->type == SP_ATTACHMENT_SKINNED_MESH) {
|
||||||
spSkinnedMeshAttachment* mesh = (spSkinnedMeshAttachment*)slot->attachment;
|
spSkinnedMeshAttachment* mesh = (spSkinnedMeshAttachment*)slot->attachment;
|
||||||
spSkinnedMeshAttachment_computeWorldVertices(mesh, slot, worldVertices);
|
spSkinnedMeshAttachment_computeWorldVertices(mesh, slot, _worldVertices);
|
||||||
verticesCount = mesh->uvsCount;
|
verticesCount = mesh->uvsCount;
|
||||||
} else
|
} else
|
||||||
continue;
|
continue;
|
||||||
for (int ii = 0; ii < verticesCount; ii += 2) {
|
for (int ii = 0; ii < verticesCount; ii += 2) {
|
||||||
float x = worldVertices[ii] * scaleX, y = worldVertices[ii + 1] * scaleY;
|
float x = _worldVertices[ii] * scaleX, y = _worldVertices[ii + 1] * scaleY;
|
||||||
minX = fmin(minX, x);
|
minX = fmin(minX, x);
|
||||||
minY = fmin(minY, y);
|
minY = fmin(minY, y);
|
||||||
maxX = fmax(maxX, x);
|
maxX = fmax(maxX, x);
|
||||||
|
|||||||
@ -144,7 +144,7 @@ void SkeletonRenderer::draw () {
|
|||||||
skeleton->b = nodeColor.b / (float)255;
|
skeleton->b = nodeColor.b / (float)255;
|
||||||
skeleton->a = getDisplayedOpacity() / (float)255;
|
skeleton->a = getDisplayedOpacity() / (float)255;
|
||||||
|
|
||||||
int additive = -1;
|
int blendMode = -1;
|
||||||
ccColor4B color;
|
ccColor4B color;
|
||||||
const float* uvs = nullptr;
|
const float* uvs = nullptr;
|
||||||
int verticesCount = 0;
|
int verticesCount = 0;
|
||||||
@ -200,10 +200,22 @@ void SkeletonRenderer::draw () {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (texture) {
|
if (texture) {
|
||||||
if (slot->data->additiveBlending != additive) {
|
if (slot->data->blendMode != blendMode) {
|
||||||
batch->flush();
|
batch->flush();
|
||||||
ccGLBlendFunc(blendFunc.src, slot->data->additiveBlending ? GL_ONE : blendFunc.dst);
|
blendMode = slot->data->blendMode;
|
||||||
additive = slot->data->additiveBlending;
|
switch (slot->data->blendMode) {
|
||||||
|
case SP_BLEND_MODE_ADDITIVE:
|
||||||
|
ccGLBlendFunc(premultipliedAlpha ? GL_ONE : GL_SRC_ALPHA, GL_ONE);
|
||||||
|
break;
|
||||||
|
case SP_BLEND_MODE_MULTIPLY:
|
||||||
|
ccGLBlendFunc(GL_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
break;
|
||||||
|
case SP_BLEND_MODE_SCREEN:
|
||||||
|
ccGLBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ccGLBlendFunc(blendFunc.src, blendFunc.dst);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
color.a = skeleton->a * slot->a * a * 255;
|
color.a = skeleton->a * slot->a * a * 255;
|
||||||
float multiplier = premultipliedAlpha ? color.a : 255;
|
float multiplier = premultipliedAlpha ? color.a : 255;
|
||||||
|
|||||||
@ -158,7 +158,7 @@ void SkeletonRenderer::drawSkeleton (const Mat4 &transform, uint32_t transformFl
|
|||||||
_skeleton->b = nodeColor.b / (float)255;
|
_skeleton->b = nodeColor.b / (float)255;
|
||||||
_skeleton->a = getDisplayedOpacity() / (float)255;
|
_skeleton->a = getDisplayedOpacity() / (float)255;
|
||||||
|
|
||||||
int additive = -1;
|
int blendMode = -1;
|
||||||
Color4B color;
|
Color4B color;
|
||||||
const float* uvs = nullptr;
|
const float* uvs = nullptr;
|
||||||
int verticesCount = 0;
|
int verticesCount = 0;
|
||||||
@ -215,10 +215,22 @@ void SkeletonRenderer::drawSkeleton (const Mat4 &transform, uint32_t transformFl
|
|||||||
default: ;
|
default: ;
|
||||||
}
|
}
|
||||||
if (texture) {
|
if (texture) {
|
||||||
if (slot->data->additiveBlending != additive) {
|
if (slot->data->blendMode != blendMode) {
|
||||||
_batch->flush();
|
_batch->flush();
|
||||||
GL::blendFunc(_blendFunc.src, slot->data->additiveBlending ? GL_ONE : _blendFunc.dst);
|
blendMode = slot->data->blendMode;
|
||||||
additive = slot->data->additiveBlending;
|
switch (slot->data->blendMode) {
|
||||||
|
case SP_BLEND_MODE_ADDITIVE:
|
||||||
|
GL::blendFunc(_premultipliedAlpha ? GL_ONE : GL_SRC_ALPHA, GL_ONE);
|
||||||
|
break;
|
||||||
|
case SP_BLEND_MODE_MULTIPLY:
|
||||||
|
GL::blendFunc(GL_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
break;
|
||||||
|
case SP_BLEND_MODE_SCREEN:
|
||||||
|
GL::blendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
GL::blendFunc(_blendFunc.src, _blendFunc.dst);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
color.a = _skeleton->a * slot->a * a * 255;
|
color.a = _skeleton->a * slot->a * a * 255;
|
||||||
float multiplier = _premultipliedAlpha ? color.a : 255;
|
float multiplier = _premultipliedAlpha ? color.a : 255;
|
||||||
|
|||||||
@ -52,6 +52,7 @@ spine.AnimationState = require "spine-lua.AnimationState"
|
|||||||
spine.EventData = require "spine-lua.EventData"
|
spine.EventData = require "spine-lua.EventData"
|
||||||
spine.Event = require "spine-lua.Event"
|
spine.Event = require "spine-lua.Event"
|
||||||
spine.SkeletonBounds = require "spine-lua.SkeletonBounds"
|
spine.SkeletonBounds = require "spine-lua.SkeletonBounds"
|
||||||
|
spine.BlendMode = require "spine-lua.BlendMode"
|
||||||
|
|
||||||
spine.utils.readFile = function (fileName, base)
|
spine.utils.readFile = function (fileName, base)
|
||||||
if not base then base = system.ResourceDirectory end
|
if not base then base = system.ResourceDirectory end
|
||||||
@ -125,7 +126,15 @@ function spine.Skeleton.new (skeletonData, group)
|
|||||||
print("Error creating image: " .. attachment.name)
|
print("Error creating image: " .. attachment.name)
|
||||||
image = spine.Skeleton.failed
|
image = spine.Skeleton.failed
|
||||||
end
|
end
|
||||||
if slot.data.additiveBlending then image.blendMode = "add" end
|
if slot.data.blendMode == spine.BlendMode.normal then
|
||||||
|
image.blendMode = "normal"
|
||||||
|
elseif slot.data.blendMode == spine.BlendMode.additive then
|
||||||
|
image.blendMode = "add"
|
||||||
|
elseif slot.data.blendMode == spine.BlendMode.multiply then
|
||||||
|
image.blendMode = "multiply"
|
||||||
|
elseif slot.data.blendMode == spine.BlendMode.screen then
|
||||||
|
image.blendMode = "screen"
|
||||||
|
end
|
||||||
images[slot] = image
|
images[slot] = image
|
||||||
end
|
end
|
||||||
-- Position image based on attachment and bone.
|
-- Position image based on attachment and bone.
|
||||||
|
|||||||
@ -64,6 +64,7 @@
|
|||||||
<Compile Include="src\Attachments\MeshAttachment.cs" />
|
<Compile Include="src\Attachments\MeshAttachment.cs" />
|
||||||
<Compile Include="src\Attachments\RegionAttachment.cs" />
|
<Compile Include="src\Attachments\RegionAttachment.cs" />
|
||||||
<Compile Include="src\Attachments\SkinnedMeshAttachment.cs" />
|
<Compile Include="src\Attachments\SkinnedMeshAttachment.cs" />
|
||||||
|
<Compile Include="src\BlendMode.cs" />
|
||||||
<Compile Include="src\Bone.cs" />
|
<Compile Include="src\Bone.cs" />
|
||||||
<Compile Include="src\BoneData.cs" />
|
<Compile Include="src\BoneData.cs" />
|
||||||
<Compile Include="src\AnimationState.cs" />
|
<Compile Include="src\AnimationState.cs" />
|
||||||
|
|||||||
@ -103,6 +103,7 @@
|
|||||||
<Compile Include="src\Attachments\AttachmentType.cs" />
|
<Compile Include="src\Attachments\AttachmentType.cs" />
|
||||||
<Compile Include="src\Attachments\BoundingBoxAttachment.cs" />
|
<Compile Include="src\Attachments\BoundingBoxAttachment.cs" />
|
||||||
<Compile Include="src\Attachments\RegionAttachment.cs" />
|
<Compile Include="src\Attachments\RegionAttachment.cs" />
|
||||||
|
<Compile Include="src\BlendMode.cs" />
|
||||||
<Compile Include="src\Bone.cs" />
|
<Compile Include="src\Bone.cs" />
|
||||||
<Compile Include="src\BoneData.cs" />
|
<Compile Include="src\BoneData.cs" />
|
||||||
<Compile Include="src\IkConstraint.cs" />
|
<Compile Include="src\IkConstraint.cs" />
|
||||||
|
|||||||
35
spine-csharp/src/BlendMode.cs
Normal file
35
spine-csharp/src/BlendMode.cs
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Spine Runtimes Software License
|
||||||
|
* Version 2.1
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013, Esoteric Software
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* You are granted a perpetual, non-exclusive, non-sublicensable and
|
||||||
|
* non-transferable license to install, execute and perform the Spine Runtimes
|
||||||
|
* Software (the "Software") solely for internal use. Without the written
|
||||||
|
* permission of Esoteric Software (typically granted by licensing Spine), you
|
||||||
|
* may not (a) modify, translate, adapt or otherwise create derivative works,
|
||||||
|
* improvements of the Software or develop new applications using the Software
|
||||||
|
* or (b) remove, delete, alter or obscure any trademarks or any copyright,
|
||||||
|
* trademark, patent or other intellectual property or proprietary rights
|
||||||
|
* notices on or in the Software, including any copy thereof. Redistributions
|
||||||
|
* in binary or source form must include this license and terms.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||||
|
* EVENT SHALL ESOTERIC SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||||
|
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||||
|
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
namespace Spine {
|
||||||
|
public enum BlendMode {
|
||||||
|
normal, additive, multiply, screen
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -156,7 +156,7 @@ namespace Spine {
|
|||||||
slotData.b = ((color & 0x0000ff00) >> 8) / 255f;
|
slotData.b = ((color & 0x0000ff00) >> 8) / 255f;
|
||||||
slotData.a = ((color & 0x000000ff)) / 255f;
|
slotData.a = ((color & 0x000000ff)) / 255f;
|
||||||
slotData.attachmentName = ReadString(input);
|
slotData.attachmentName = ReadString(input);
|
||||||
slotData.additiveBlending = ReadBoolean(input);
|
slotData.blendMode = (BlendMode)ReadInt(input, true);
|
||||||
skeletonData.slots.Add(slotData);
|
skeletonData.slots.Add(slotData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -163,8 +163,10 @@ namespace Spine {
|
|||||||
if (slotMap.ContainsKey("attachment"))
|
if (slotMap.ContainsKey("attachment"))
|
||||||
slotData.attachmentName = (String)slotMap["attachment"];
|
slotData.attachmentName = (String)slotMap["attachment"];
|
||||||
|
|
||||||
if (slotMap.ContainsKey("additive"))
|
if (slotMap.ContainsKey("blend"))
|
||||||
slotData.additiveBlending = (bool)slotMap["additive"];
|
slotData.blendMode = (BlendMode)Enum.Parse(typeof(BlendMode), (String)slotMap["blend"], false);
|
||||||
|
else
|
||||||
|
slotData.blendMode = BlendMode.normal;
|
||||||
|
|
||||||
skeletonData.slots.Add(slotData);
|
skeletonData.slots.Add(slotData);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -36,7 +36,7 @@ namespace Spine {
|
|||||||
internal BoneData boneData;
|
internal BoneData boneData;
|
||||||
internal float r = 1, g = 1, b = 1, a = 1;
|
internal float r = 1, g = 1, b = 1, a = 1;
|
||||||
internal String attachmentName;
|
internal String attachmentName;
|
||||||
internal bool additiveBlending;
|
internal BlendMode blendMode;
|
||||||
|
|
||||||
public String Name { get { return name; } }
|
public String Name { get { return name; } }
|
||||||
public BoneData BoneData { get { return boneData; } }
|
public BoneData BoneData { get { return boneData; } }
|
||||||
@ -46,7 +46,7 @@ namespace Spine {
|
|||||||
public float A { get { return a; } set { a = value; } }
|
public float A { get { return a; } set { a = value; } }
|
||||||
/// <summary>May be null.</summary>
|
/// <summary>May be null.</summary>
|
||||||
public String AttachmentName { get { return attachmentName; } set { attachmentName = value; } }
|
public String AttachmentName { get { return attachmentName; } set { attachmentName = value; } }
|
||||||
public bool AdditiveBlending { get { return additiveBlending; } set { additiveBlending = value; } }
|
public BlendMode BlendMode { get { return blendMode; } set { blendMode = value; } }
|
||||||
|
|
||||||
public SlotData (String name, BoneData boneData) {
|
public SlotData (String name, BoneData boneData) {
|
||||||
if (name == null) throw new ArgumentNullException("name cannot be null.");
|
if (name == null) throw new ArgumentNullException("name cannot be null.");
|
||||||
|
|||||||
@ -50,6 +50,13 @@ spine.BoneData.prototype = {
|
|||||||
flipX: false, flipY: false
|
flipX: false, flipY: false
|
||||||
};
|
};
|
||||||
|
|
||||||
|
spine.BlendMode = {
|
||||||
|
normal: 0,
|
||||||
|
additive: 1,
|
||||||
|
multiply: 2,
|
||||||
|
screen: 3
|
||||||
|
};
|
||||||
|
|
||||||
spine.SlotData = function (name, boneData) {
|
spine.SlotData = function (name, boneData) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.boneData = boneData;
|
this.boneData = boneData;
|
||||||
@ -57,7 +64,7 @@ spine.SlotData = function (name, boneData) {
|
|||||||
spine.SlotData.prototype = {
|
spine.SlotData.prototype = {
|
||||||
r: 1, g: 1, b: 1, a: 1,
|
r: 1, g: 1, b: 1, a: 1,
|
||||||
attachmentName: null,
|
attachmentName: null,
|
||||||
additiveBlending: false
|
blendMode: spine.BlendMode.normal
|
||||||
};
|
};
|
||||||
|
|
||||||
spine.IkConstraintData = function (name) {
|
spine.IkConstraintData = function (name) {
|
||||||
@ -1766,7 +1773,7 @@ spine.SkeletonJson.prototype = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
slotData.attachmentName = slotMap["attachment"];
|
slotData.attachmentName = slotMap["attachment"];
|
||||||
slotData.additiveBlending = slotMap["additive"] && slotMap["additive"] == "true";
|
slotData.blendMode = spine.AttachmentType[slotMap["blend"] || "normal"];
|
||||||
|
|
||||||
skeletonData.slots.push(slotData);
|
skeletonData.slots.push(slotData);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,30 @@
|
|||||||
|
|
||||||
|
package com.esotericsoftware.spine;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.graphics.GL20;
|
||||||
|
|
||||||
|
public enum BlendMode {
|
||||||
|
normal(GL20.GL_SRC_ALPHA, GL20.GL_ONE, GL20.GL_ONE_MINUS_SRC_ALPHA), //
|
||||||
|
additive(GL20.GL_SRC_ALPHA, GL20.GL_ONE, GL20.GL_ONE), //
|
||||||
|
multiply(GL20.GL_DST_COLOR, GL20.GL_DST_COLOR, GL20.GL_ONE_MINUS_SRC_ALPHA), //
|
||||||
|
screen(GL20.GL_ONE, GL20.GL_ONE, GL20.GL_ONE_MINUS_SRC_COLOR), //
|
||||||
|
;
|
||||||
|
|
||||||
|
int source, sourcePMA, dest;
|
||||||
|
|
||||||
|
BlendMode (int source, int sourcePremultipledAlpha, int dest) {
|
||||||
|
this.source = source;
|
||||||
|
this.sourcePMA = sourcePremultipledAlpha;
|
||||||
|
this.dest = dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSource (boolean premultipliedAlpha) {
|
||||||
|
return premultipliedAlpha ? sourcePMA : source;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getDest () {
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
static public BlendMode[] values = values();
|
||||||
|
}
|
||||||
@ -160,7 +160,7 @@ public class SkeletonBinary {
|
|||||||
SlotData slotData = new SlotData(slotName, boneData);
|
SlotData slotData = new SlotData(slotName, boneData);
|
||||||
Color.rgba8888ToColor(slotData.color, input.readInt());
|
Color.rgba8888ToColor(slotData.color, input.readInt());
|
||||||
slotData.attachmentName = input.readString();
|
slotData.attachmentName = input.readString();
|
||||||
slotData.additiveBlending = input.readBoolean();
|
slotData.blendMode = BlendMode.values[input.readInt(true)];
|
||||||
skeletonData.slots.add(slotData);
|
skeletonData.slots.add(slotData);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -227,7 +227,7 @@ public class SkeletonBinary {
|
|||||||
String name = input.readString();
|
String name = input.readString();
|
||||||
if (name == null) name = attachmentName;
|
if (name == null) name = attachmentName;
|
||||||
|
|
||||||
switch (AttachmentType.values()[input.readByte()]) {
|
switch (AttachmentType.values[input.readByte()]) {
|
||||||
case region: {
|
case region: {
|
||||||
String path = input.readString();
|
String path = input.readString();
|
||||||
if (path == null) path = name;
|
if (path == null) path = name;
|
||||||
|
|||||||
@ -161,9 +161,7 @@ public class SkeletonJson {
|
|||||||
if (color != null) slotData.getColor().set(Color.valueOf(color));
|
if (color != null) slotData.getColor().set(Color.valueOf(color));
|
||||||
|
|
||||||
slotData.attachmentName = slotMap.getString("attachment", null);
|
slotData.attachmentName = slotMap.getString("attachment", null);
|
||||||
|
slotData.blendMode = BlendMode.valueOf(slotMap.getString("blend", BlendMode.normal.name()));
|
||||||
slotData.additiveBlending = slotMap.getBoolean("additive", false);
|
|
||||||
|
|
||||||
skeletonData.slots.add(slotData);
|
skeletonData.slots.add(slotData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -30,18 +30,16 @@
|
|||||||
|
|
||||||
package com.esotericsoftware.spine;
|
package com.esotericsoftware.spine;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.graphics.Texture;
|
||||||
|
import com.badlogic.gdx.graphics.g2d.Batch;
|
||||||
|
import com.badlogic.gdx.graphics.g2d.PolygonSpriteBatch;
|
||||||
|
import com.badlogic.gdx.utils.Array;
|
||||||
import com.esotericsoftware.spine.attachments.Attachment;
|
import com.esotericsoftware.spine.attachments.Attachment;
|
||||||
import com.esotericsoftware.spine.attachments.MeshAttachment;
|
import com.esotericsoftware.spine.attachments.MeshAttachment;
|
||||||
import com.esotericsoftware.spine.attachments.RegionAttachment;
|
import com.esotericsoftware.spine.attachments.RegionAttachment;
|
||||||
import com.esotericsoftware.spine.attachments.SkeletonAttachment;
|
import com.esotericsoftware.spine.attachments.SkeletonAttachment;
|
||||||
import com.esotericsoftware.spine.attachments.SkinnedMeshAttachment;
|
import com.esotericsoftware.spine.attachments.SkinnedMeshAttachment;
|
||||||
|
|
||||||
import com.badlogic.gdx.graphics.GL20;
|
|
||||||
import com.badlogic.gdx.graphics.Texture;
|
|
||||||
import com.badlogic.gdx.graphics.g2d.Batch;
|
|
||||||
import com.badlogic.gdx.graphics.g2d.PolygonSpriteBatch;
|
|
||||||
import com.badlogic.gdx.utils.Array;
|
|
||||||
|
|
||||||
public class SkeletonRenderer {
|
public class SkeletonRenderer {
|
||||||
static private final short[] quadTriangles = {0, 1, 2, 2, 3, 0};
|
static private final short[] quadTriangles = {0, 1, 2, 2, 3, 0};
|
||||||
|
|
||||||
@ -50,10 +48,7 @@ public class SkeletonRenderer {
|
|||||||
@SuppressWarnings("null")
|
@SuppressWarnings("null")
|
||||||
public void draw (PolygonSpriteBatch batch, Skeleton skeleton) {
|
public void draw (PolygonSpriteBatch batch, Skeleton skeleton) {
|
||||||
boolean premultipliedAlpha = this.premultipliedAlpha;
|
boolean premultipliedAlpha = this.premultipliedAlpha;
|
||||||
int srcFunc = premultipliedAlpha ? GL20.GL_ONE : GL20.GL_SRC_ALPHA;
|
BlendMode blendMode = null;
|
||||||
batch.setBlendFunction(srcFunc, GL20.GL_ONE_MINUS_SRC_ALPHA);
|
|
||||||
|
|
||||||
boolean additive = false;
|
|
||||||
|
|
||||||
float[] vertices = null;
|
float[] vertices = null;
|
||||||
short[] triangles = null;
|
short[] triangles = null;
|
||||||
@ -106,12 +101,10 @@ public class SkeletonRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (texture != null) {
|
if (texture != null) {
|
||||||
if (slot.data.getAdditiveBlending() != additive) {
|
BlendMode slotBlendMode = slot.data.getBlendMode();
|
||||||
additive = !additive;
|
if (slotBlendMode != blendMode) {
|
||||||
if (additive)
|
blendMode = slotBlendMode;
|
||||||
batch.setBlendFunction(srcFunc, GL20.GL_ONE);
|
batch.setBlendFunction(blendMode.getSource(premultipliedAlpha), blendMode.getDest());
|
||||||
else
|
|
||||||
batch.setBlendFunction(srcFunc, GL20.GL_ONE_MINUS_SRC_ALPHA);
|
|
||||||
}
|
}
|
||||||
batch.draw(texture, vertices, 0, vertices.length, triangles, 0, triangles.length);
|
batch.draw(texture, vertices, 0, vertices.length, triangles, 0, triangles.length);
|
||||||
}
|
}
|
||||||
@ -120,10 +113,7 @@ public class SkeletonRenderer {
|
|||||||
|
|
||||||
public void draw (Batch batch, Skeleton skeleton) {
|
public void draw (Batch batch, Skeleton skeleton) {
|
||||||
boolean premultipliedAlpha = this.premultipliedAlpha;
|
boolean premultipliedAlpha = this.premultipliedAlpha;
|
||||||
int srcFunc = premultipliedAlpha ? GL20.GL_ONE : GL20.GL_SRC_ALPHA;
|
BlendMode blendMode = null;
|
||||||
batch.setBlendFunction(srcFunc, GL20.GL_ONE_MINUS_SRC_ALPHA);
|
|
||||||
|
|
||||||
boolean additive = false;
|
|
||||||
|
|
||||||
Array<Slot> drawOrder = skeleton.drawOrder;
|
Array<Slot> drawOrder = skeleton.drawOrder;
|
||||||
for (int i = 0, n = drawOrder.size; i < n; i++) {
|
for (int i = 0, n = drawOrder.size; i < n; i++) {
|
||||||
@ -133,12 +123,10 @@ public class SkeletonRenderer {
|
|||||||
RegionAttachment regionAttachment = (RegionAttachment)attachment;
|
RegionAttachment regionAttachment = (RegionAttachment)attachment;
|
||||||
regionAttachment.updateWorldVertices(slot, premultipliedAlpha);
|
regionAttachment.updateWorldVertices(slot, premultipliedAlpha);
|
||||||
float[] vertices = regionAttachment.getWorldVertices();
|
float[] vertices = regionAttachment.getWorldVertices();
|
||||||
if (slot.data.getAdditiveBlending() != additive) {
|
BlendMode slotBlendMode = slot.data.getBlendMode();
|
||||||
additive = !additive;
|
if (slotBlendMode != blendMode) {
|
||||||
if (additive)
|
blendMode = slotBlendMode;
|
||||||
batch.setBlendFunction(srcFunc, GL20.GL_ONE);
|
batch.setBlendFunction(blendMode.getSource(premultipliedAlpha), blendMode.getDest());
|
||||||
else
|
|
||||||
batch.setBlendFunction(srcFunc, GL20.GL_ONE_MINUS_SRC_ALPHA);
|
|
||||||
}
|
}
|
||||||
batch.draw(regionAttachment.getRegion().getTexture(), vertices, 0, 20);
|
batch.draw(regionAttachment.getRegion().getTexture(), vertices, 0, 20);
|
||||||
|
|
||||||
|
|||||||
@ -37,7 +37,7 @@ public class SlotData {
|
|||||||
final BoneData boneData;
|
final BoneData boneData;
|
||||||
final Color color = new Color(1, 1, 1, 1);
|
final Color color = new Color(1, 1, 1, 1);
|
||||||
String attachmentName;
|
String attachmentName;
|
||||||
boolean additiveBlending;
|
BlendMode blendMode;
|
||||||
|
|
||||||
SlotData () {
|
SlotData () {
|
||||||
name = null;
|
name = null;
|
||||||
@ -73,12 +73,12 @@ public class SlotData {
|
|||||||
return attachmentName;
|
return attachmentName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean getAdditiveBlending () {
|
public BlendMode getBlendMode () {
|
||||||
return additiveBlending;
|
return blendMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAdditiveBlending (boolean additiveBlending) {
|
public void setBlendMode (BlendMode blendMode) {
|
||||||
this.additiveBlending = additiveBlending;
|
this.blendMode = blendMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString () {
|
public String toString () {
|
||||||
|
|||||||
@ -31,5 +31,7 @@
|
|||||||
package com.esotericsoftware.spine.attachments;
|
package com.esotericsoftware.spine.attachments;
|
||||||
|
|
||||||
public enum AttachmentType {
|
public enum AttachmentType {
|
||||||
region, boundingbox, mesh, skinnedmesh
|
region, boundingbox, mesh, skinnedmesh;
|
||||||
|
|
||||||
|
static public AttachmentType[] values = values();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -52,6 +52,7 @@ spine.AnimationState = require "spine-lua.AnimationState"
|
|||||||
spine.EventData = require "spine-lua.EventData"
|
spine.EventData = require "spine-lua.EventData"
|
||||||
spine.Event = require "spine-lua.Event"
|
spine.Event = require "spine-lua.Event"
|
||||||
spine.SkeletonBounds = require "spine-lua.SkeletonBounds"
|
spine.SkeletonBounds = require "spine-lua.SkeletonBounds"
|
||||||
|
spine.BlendMode = require "spine-lua.BlendMode"
|
||||||
|
|
||||||
spine.utils.readFile = function (fileName, base)
|
spine.utils.readFile = function (fileName, base)
|
||||||
local path = fileName
|
local path = fileName
|
||||||
@ -139,10 +140,14 @@ function spine.Skeleton.new (skeletonData, group)
|
|||||||
rotation = -rotation
|
rotation = -rotation
|
||||||
end
|
end
|
||||||
love.graphics.setColor(r * slot.r, g * slot.g, b * slot.b, a * slot.a)
|
love.graphics.setColor(r * slot.r, g * slot.g, b * slot.b, a * slot.a)
|
||||||
if slot.data.additiveBlending then
|
if slot.data.blendMode == spine.BlendMode.normal then
|
||||||
love.graphics.setBlendMode("additive")
|
|
||||||
else
|
|
||||||
love.graphics.setBlendMode("alpha")
|
love.graphics.setBlendMode("alpha")
|
||||||
|
elseif slot.data.blendMode == spine.BlendMode.additive then
|
||||||
|
love.graphics.setBlendMode("additive")
|
||||||
|
elseif slot.data.blendMode == spine.BlendMode.multiply then
|
||||||
|
love.graphics.setBlendMode("multiply")
|
||||||
|
elseif slot.data.blendMode == spine.BlendMode.screen then
|
||||||
|
love.graphics.setBlendMode("screen")
|
||||||
end
|
end
|
||||||
love.graphics.draw(image,
|
love.graphics.draw(image,
|
||||||
self.x + x,
|
self.x + x,
|
||||||
|
|||||||
37
spine-lua/BlendMode.lua
Normal file
37
spine-lua/BlendMode.lua
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
-------------------------------------------------------------------------------
|
||||||
|
-- Spine Runtimes Software License
|
||||||
|
-- Version 2.1
|
||||||
|
--
|
||||||
|
-- Copyright (c) 2013, Esoteric Software
|
||||||
|
-- All rights reserved.
|
||||||
|
--
|
||||||
|
-- You are granted a perpetual, non-exclusive, non-sublicensable and
|
||||||
|
-- non-transferable license to install, execute and perform the Spine Runtimes
|
||||||
|
-- Software (the "Software") solely for internal use. Without the written
|
||||||
|
-- permission of Esoteric Software (typically granted by licensing Spine), you
|
||||||
|
-- may not (a) modify, translate, adapt or otherwise create derivative works,
|
||||||
|
-- improvements of the Software or develop new applications using the Software
|
||||||
|
-- or (b) remove, delete, alter or obscure any trademarks or any copyright,
|
||||||
|
-- trademark, patent or other intellectual property or proprietary rights
|
||||||
|
-- notices on or in the Software, including any copy thereof. Redistributions
|
||||||
|
-- in binary or source form must include this license and terms.
|
||||||
|
--
|
||||||
|
-- THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
||||||
|
-- IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
-- MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||||
|
-- EVENT SHALL ESOTERIC SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
-- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||||
|
-- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
-- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||||
|
-- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
-- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
local BlendMode = {
|
||||||
|
normal = 0,
|
||||||
|
additive = 1,
|
||||||
|
multiply = 2,
|
||||||
|
screen = 3
|
||||||
|
}
|
||||||
|
return BlendMode
|
||||||
@ -39,6 +39,7 @@ local IkConstraint = require "spine-lua.IkConstraint"
|
|||||||
local EventData = require "spine-lua.EventData"
|
local EventData = require "spine-lua.EventData"
|
||||||
local Event = require "spine-lua.Event"
|
local Event = require "spine-lua.Event"
|
||||||
local AttachmentType = require "spine-lua.AttachmentType"
|
local AttachmentType = require "spine-lua.AttachmentType"
|
||||||
|
local BlendMode = require "spine-lua.BlendMode"
|
||||||
|
|
||||||
local SkeletonJson = {}
|
local SkeletonJson = {}
|
||||||
function SkeletonJson.new (attachmentLoader)
|
function SkeletonJson.new (attachmentLoader)
|
||||||
@ -154,7 +155,7 @@ function SkeletonJson.new (attachmentLoader)
|
|||||||
end
|
end
|
||||||
|
|
||||||
slotData.attachmentName = slotMap["attachment"]
|
slotData.attachmentName = slotMap["attachment"]
|
||||||
slotData.additiveBlending = slotMap["additive"]
|
slotData.blendMode = BlendMode[slotMap["blend"] or "normal"]
|
||||||
|
|
||||||
table.insert(skeletonData.slots, slotData)
|
table.insert(skeletonData.slots, slotData)
|
||||||
skeletonData.slotNameIndices[slotData.name] = #skeletonData.slots
|
skeletonData.slotNameIndices[slotData.name] = #skeletonData.slots
|
||||||
|
|||||||
@ -28,6 +28,8 @@
|
|||||||
-- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
-- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
local BlendMode = require "spine-lua.BlendMode"
|
||||||
|
|
||||||
local SlotData = {}
|
local SlotData = {}
|
||||||
function SlotData.new (name, boneData)
|
function SlotData.new (name, boneData)
|
||||||
if not name then error("name cannot be nil", 2) end
|
if not name then error("name cannot be nil", 2) end
|
||||||
@ -38,7 +40,7 @@ function SlotData.new (name, boneData)
|
|||||||
boneData = boneData,
|
boneData = boneData,
|
||||||
r = 1, g = 1, b = 1, a = 1,
|
r = 1, g = 1, b = 1, a = 1,
|
||||||
attachmentName = nil,
|
attachmentName = nil,
|
||||||
additiveBlending = false
|
blendMode = BlendMode.normal
|
||||||
}
|
}
|
||||||
|
|
||||||
function self:setColor (r, g, b, a)
|
function self:setColor (r, g, b, a)
|
||||||
|
|||||||
@ -95,7 +95,6 @@ void SkeletonDrawable::update (float deltaTime) {
|
|||||||
|
|
||||||
void SkeletonDrawable::draw (RenderTarget& target, RenderStates states) const {
|
void SkeletonDrawable::draw (RenderTarget& target, RenderStates states) const {
|
||||||
vertexArray->clear();
|
vertexArray->clear();
|
||||||
states.blendMode = BlendAlpha;
|
|
||||||
|
|
||||||
sf::Vertex vertices[4];
|
sf::Vertex vertices[4];
|
||||||
sf::Vertex vertex;
|
sf::Vertex vertex;
|
||||||
@ -103,6 +102,25 @@ void SkeletonDrawable::draw (RenderTarget& target, RenderStates states) const {
|
|||||||
Slot* slot = skeleton->drawOrder[i];
|
Slot* slot = skeleton->drawOrder[i];
|
||||||
Attachment* attachment = slot->attachment;
|
Attachment* attachment = slot->attachment;
|
||||||
if (!attachment) continue;
|
if (!attachment) continue;
|
||||||
|
|
||||||
|
sf::BlendMode blend;
|
||||||
|
switch (slot->data->blendMode) {
|
||||||
|
case BLEND_MODE_ADDITIVE:
|
||||||
|
blend = BlendAdd;
|
||||||
|
break;
|
||||||
|
case BLEND_MODE_MULTIPLY:
|
||||||
|
blend = BlendMultiply;
|
||||||
|
break;
|
||||||
|
case BLEND_MODE_SCREEN: // Unsupported, fall through.
|
||||||
|
default:
|
||||||
|
blend = BlendAlpha;
|
||||||
|
}
|
||||||
|
if (states.blendMode != blend) {
|
||||||
|
target.draw(*vertexArray, states);
|
||||||
|
vertexArray->clear();
|
||||||
|
states.blendMode = blend;
|
||||||
|
}
|
||||||
|
|
||||||
Texture* texture = 0;
|
Texture* texture = 0;
|
||||||
if (attachment->type == ATTACHMENT_REGION) {
|
if (attachment->type == ATTACHMENT_REGION) {
|
||||||
RegionAttachment* regionAttachment = (RegionAttachment*)attachment;
|
RegionAttachment* regionAttachment = (RegionAttachment*)attachment;
|
||||||
@ -212,13 +230,6 @@ void SkeletonDrawable::draw (RenderTarget& target, RenderStates states) const {
|
|||||||
if (texture) {
|
if (texture) {
|
||||||
// SMFL doesn't handle batching for us, so we'll just force a single texture per skeleton.
|
// SMFL doesn't handle batching for us, so we'll just force a single texture per skeleton.
|
||||||
states.texture = texture;
|
states.texture = texture;
|
||||||
|
|
||||||
BlendMode blend = slot->data->additiveBlending ? BlendAdd : BlendAlpha;
|
|
||||||
if (states.blendMode != blend) {
|
|
||||||
target.draw(*vertexArray, states);
|
|
||||||
vertexArray->clear();
|
|
||||||
states.blendMode = blend;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
target.draw(*vertexArray, states);
|
target.draw(*vertexArray, states);
|
||||||
|
|||||||
@ -41,6 +41,9 @@ import flash.geom.Matrix;
|
|||||||
import flash.geom.Point;
|
import flash.geom.Point;
|
||||||
import flash.utils.Dictionary;
|
import flash.utils.Dictionary;
|
||||||
|
|
||||||
|
import spine.BlendMode;
|
||||||
|
import spine.flash.SkeletonSprite;
|
||||||
|
|
||||||
import starling.core.RenderSupport;
|
import starling.core.RenderSupport;
|
||||||
import starling.core.Starling;
|
import starling.core.Starling;
|
||||||
import starling.display.BlendMode;
|
import starling.display.BlendMode;
|
||||||
@ -61,8 +64,8 @@ internal class PolygonBatch {
|
|||||||
private var _texture:Texture;
|
private var _texture:Texture;
|
||||||
private var _support:RenderSupport;
|
private var _support:RenderSupport;
|
||||||
private var _programBits:uint;
|
private var _programBits:uint;
|
||||||
private var _blendMode:String;
|
private var _blendModeNormal:String;
|
||||||
private var _additive:Boolean;
|
private var _blendMode:spine.BlendMode;
|
||||||
private var _alpha:Number;
|
private var _alpha:Number;
|
||||||
|
|
||||||
private var _verticesCount:int;
|
private var _verticesCount:int;
|
||||||
@ -88,11 +91,11 @@ internal class PolygonBatch {
|
|||||||
_support = support;
|
_support = support;
|
||||||
_alpha = alpha;
|
_alpha = alpha;
|
||||||
_programBits = 0xffffffff;
|
_programBits = 0xffffffff;
|
||||||
_additive = false;
|
_blendMode = null;
|
||||||
|
|
||||||
support.finishQuadBatch();
|
support.finishQuadBatch();
|
||||||
support.blendMode = blendMode;
|
support.blendMode = blendMode;
|
||||||
_blendMode = support.blendMode;
|
_blendModeNormal = support.blendMode;
|
||||||
|
|
||||||
var context:Context3D = Starling.context;
|
var context:Context3D = Starling.context;
|
||||||
context.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX, 1, support.mvpMatrix3D, true);
|
context.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX, 1, support.mvpMatrix3D, true);
|
||||||
@ -115,11 +118,14 @@ internal class PolygonBatch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function add (texture:Texture, vertices:Vector.<Number>, vl:int, uvs:Vector.<Number>, triangles:Vector.<uint>,
|
public function add (texture:Texture, vertices:Vector.<Number>, vl:int, uvs:Vector.<Number>, triangles:Vector.<uint>,
|
||||||
r:Number, g:Number, b:Number, a:Number, additive:Boolean, matrix:Matrix) : void {
|
r:Number, g:Number, b:Number, a:Number, blendMode:spine.BlendMode, matrix:Matrix) : void {
|
||||||
if (additive != _additive) {
|
if (blendMode != _blendMode) {
|
||||||
_additive = additive;
|
_blendMode = blendMode;
|
||||||
flush();
|
flush();
|
||||||
_support.blendMode = additive ? BlendMode.ADD : _blendMode;
|
if (blendMode == spine.BlendMode.normal)
|
||||||
|
_support.blendMode = _blendModeNormal;
|
||||||
|
else
|
||||||
|
_support.blendMode = spine.starling.SkeletonSprite.blendModes[blendMode.ordinal];
|
||||||
_support.applyBlendMode(true);
|
_support.applyBlendMode(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -58,6 +58,8 @@ public class SkeletonSprite extends DisplayObject {
|
|||||||
static private var _tempMatrix:Matrix = new Matrix();
|
static private var _tempMatrix:Matrix = new Matrix();
|
||||||
static private var _tempVertices:Vector.<Number> = new Vector.<Number>(8);
|
static private var _tempVertices:Vector.<Number> = new Vector.<Number>(8);
|
||||||
static private var _quadTriangles:Vector.<uint> = new <uint>[0, 1, 2, 2, 3, 0];
|
static private var _quadTriangles:Vector.<uint> = new <uint>[0, 1, 2, 2, 3, 0];
|
||||||
|
static internal var blendModes:Vector.<String> = new <String>[
|
||||||
|
BlendMode.NORMAL, BlendMode.ADD, BlendMode.MULTIPLY, BlendMode.SCREEN];
|
||||||
|
|
||||||
private var _skeleton:Skeleton;
|
private var _skeleton:Skeleton;
|
||||||
private var _polygonBatch:PolygonBatch;
|
private var _polygonBatch:PolygonBatch;
|
||||||
@ -165,7 +167,7 @@ public class SkeletonSprite extends DisplayObject {
|
|||||||
r *= skeletonR * slot.r * a;
|
r *= skeletonR * slot.r * a;
|
||||||
g *= skeletonG * slot.g * a;
|
g *= skeletonG * slot.g * a;
|
||||||
b *= skeletonB * slot.b * a;
|
b *= skeletonB * slot.b * a;
|
||||||
polygonBatch.add(image.texture, worldVertices, verticesLength, uvs, triangles, r, g, b, a, slot.data.additiveBlending, matrix);
|
polygonBatch.add(image.texture, worldVertices, verticesLength, uvs, triangles, r, g, b, a, slot.data.blendMode, matrix);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -206,7 +208,7 @@ public class SkeletonSprite extends DisplayObject {
|
|||||||
vertexData.setColorAndAlpha(3, rgb, a);
|
vertexData.setColorAndAlpha(3, rgb, a);
|
||||||
|
|
||||||
image.updateVertices();
|
image.updateVertices();
|
||||||
support.blendMode = slot.data.additiveBlending ? BlendMode.ADD : blendMode;
|
support.blendMode = blendModes[slot.data.blendMode.ordinal];
|
||||||
support.batchQuad(image, alpha, image.texture, _smoothing);
|
support.batchQuad(image, alpha, image.texture, _smoothing);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -191,7 +191,7 @@ function drawSkeleton (batch, skeleton) {
|
|||||||
if (!(attachment instanceof spine.RegionAttachment)) continue;
|
if (!(attachment instanceof spine.RegionAttachment)) continue;
|
||||||
attachment.computeVertices(skeleton.x, skeleton.y, slot.bone, vertices);
|
attachment.computeVertices(skeleton.x, skeleton.y, slot.bone, vertices);
|
||||||
|
|
||||||
var blendMode = slot.data.additiveBlending ? draw2D.blend.additive : draw2D.blend.alpha;
|
var blendMode = slot.data.blendMode == spine.BlendMode.additive ? draw2D.blend.additive : draw2D.blend.alpha;
|
||||||
if (batch.blendMode != blendMode) {
|
if (batch.blendMode != blendMode) {
|
||||||
batch.end();
|
batch.end();
|
||||||
batch.begin(blendMode);
|
batch.begin(blendMode);
|
||||||
|
|||||||
@ -283,8 +283,7 @@ public class SkeletonRenderer : MonoBehaviour {
|
|||||||
color.r = (byte)(r * slot.r * regionAttachment.r * color.a);
|
color.r = (byte)(r * slot.r * regionAttachment.r * color.a);
|
||||||
color.g = (byte)(g * slot.g * regionAttachment.g * color.a);
|
color.g = (byte)(g * slot.g * regionAttachment.g * color.a);
|
||||||
color.b = (byte)(b * slot.b * regionAttachment.b * color.a);
|
color.b = (byte)(b * slot.b * regionAttachment.b * color.a);
|
||||||
if (slot.data.additiveBlending)
|
if (slot.data.blendMode == BlendMode.additive) color.a = 0;
|
||||||
color.a = 0;
|
|
||||||
colors[vertexIndex] = color;
|
colors[vertexIndex] = color;
|
||||||
colors[vertexIndex + 1] = color;
|
colors[vertexIndex + 1] = color;
|
||||||
colors[vertexIndex + 2] = color;
|
colors[vertexIndex + 2] = color;
|
||||||
@ -311,8 +310,7 @@ public class SkeletonRenderer : MonoBehaviour {
|
|||||||
color.r = (byte)(r * slot.r * meshAttachment.r * color.a);
|
color.r = (byte)(r * slot.r * meshAttachment.r * color.a);
|
||||||
color.g = (byte)(g * slot.g * meshAttachment.g * color.a);
|
color.g = (byte)(g * slot.g * meshAttachment.g * color.a);
|
||||||
color.b = (byte)(b * slot.b * meshAttachment.b * color.a);
|
color.b = (byte)(b * slot.b * meshAttachment.b * color.a);
|
||||||
if (slot.data.additiveBlending)
|
if (slot.data.blendMode == BlendMode.additive) color.a = 0;
|
||||||
color.a = 0;
|
|
||||||
|
|
||||||
float[] meshUVs = meshAttachment.uvs;
|
float[] meshUVs = meshAttachment.uvs;
|
||||||
float z = i * zSpacing;
|
float z = i * zSpacing;
|
||||||
@ -332,8 +330,7 @@ public class SkeletonRenderer : MonoBehaviour {
|
|||||||
color.r = (byte)(r * slot.r * meshAttachment.r * color.a);
|
color.r = (byte)(r * slot.r * meshAttachment.r * color.a);
|
||||||
color.g = (byte)(g * slot.g * meshAttachment.g * color.a);
|
color.g = (byte)(g * slot.g * meshAttachment.g * color.a);
|
||||||
color.b = (byte)(b * slot.b * meshAttachment.b * color.a);
|
color.b = (byte)(b * slot.b * meshAttachment.b * color.a);
|
||||||
if (slot.data.additiveBlending)
|
if (slot.data.blendMode == BlendMode.additive) color.a = 0;
|
||||||
color.a = 0;
|
|
||||||
|
|
||||||
float[] meshUVs = meshAttachment.uvs;
|
float[] meshUVs = meshAttachment.uvs;
|
||||||
float z = i * zSpacing;
|
float z = i * zSpacing;
|
||||||
|
|||||||
@ -96,7 +96,7 @@ namespace Spine {
|
|||||||
Attachment attachment = slot.Attachment;
|
Attachment attachment = slot.Attachment;
|
||||||
if (attachment is RegionAttachment) {
|
if (attachment is RegionAttachment) {
|
||||||
RegionAttachment regionAttachment = (RegionAttachment)attachment;
|
RegionAttachment regionAttachment = (RegionAttachment)attachment;
|
||||||
BlendState blend = slot.Data.AdditiveBlending ? BlendState.Additive : defaultBlendState;
|
BlendState blend = slot.Data.BlendMode == BlendMode.additive ? BlendState.Additive : defaultBlendState;
|
||||||
if (device.BlendState != blend) {
|
if (device.BlendState != blend) {
|
||||||
End();
|
End();
|
||||||
device.BlendState = blend;
|
device.BlendState = blend;
|
||||||
|
|||||||
@ -88,7 +88,7 @@ namespace Spine {
|
|||||||
Slot slot = drawOrder[i];
|
Slot slot = drawOrder[i];
|
||||||
RegionAttachment regionAttachment = slot.Attachment as RegionAttachment;
|
RegionAttachment regionAttachment = slot.Attachment as RegionAttachment;
|
||||||
if (regionAttachment != null) {
|
if (regionAttachment != null) {
|
||||||
BlendState blend = slot.Data.AdditiveBlending ? BlendState.Additive : defaultBlendState;
|
BlendState blend = slot.Data.BlendMode == BlendMode.additive ? BlendState.Additive : defaultBlendState;
|
||||||
if (device.BlendState != blend) {
|
if (device.BlendState != blend) {
|
||||||
End();
|
End();
|
||||||
device.BlendState = blend;
|
device.BlendState = blend;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user