[cocos2dx] Added support for vertex effects. See #898

This commit is contained in:
badlogic 2017-06-26 15:00:59 +02:00
parent 65d1f51acc
commit 7488383b15
10 changed files with 291 additions and 47 deletions

View File

@ -46,6 +46,7 @@
* Added `spSkeletonClipper` and `spTriangulator`, used to implement software clipping of attachments. * Added `spSkeletonClipper` and `spTriangulator`, used to implement software clipping of attachments.
* `AnimationState#apply` returns boolean indicating if any timeline was applied or not. * `AnimationState#apply` returns boolean indicating if any timeline was applied or not.
* `Animation#apply` and `Timeline#apply`` now take enums `MixPose` and `MixDirection` instead of booleans * `Animation#apply` and `Timeline#apply`` now take enums `MixPose` and `MixDirection` instead of booleans
* Added `spVertexEffect` and corresponding implementations `spJitterVertexEffect` and `spSwirlVertexEffect`. Create/dispose through the corresponding `spXXXVertexEffect_create()/dispose()` functions. Set on framework/engine specific renderer. See changes for spine-c based frameworks/engines below.
### Cocos2d-X ### Cocos2d-X
* Fixed renderer to work with 3.6 changes * Fixed renderer to work with 3.6 changes
@ -55,6 +56,7 @@
* Added mesh debug rendering. Enable/Disable via `SkeletonRenderer::setDebugMeshesEnabled()`. * Added mesh debug rendering. Enable/Disable via `SkeletonRenderer::setDebugMeshesEnabled()`.
* Added support for clipping. * Added support for clipping.
* SkeletonRenderer now combines the displayed color of the Node (cascaded from all parents) with the skeleton color for tinting. * SkeletonRenderer now combines the displayed color of the Node (cascaded from all parents) with the skeleton color for tinting.
* Added support for vertex effects. See `RaptorExample.cpp`.
### Cocos2d-Objc ### Cocos2d-Objc
* Fixed renderer to work with 3.6 changes * Fixed renderer to work with 3.6 changes
@ -64,6 +66,7 @@
### SFML ### SFML
* Fixed renderer to work with 3.6 changes. Sadly, two color tinting does not work, as the vertex format in SFML is fixed. * Fixed renderer to work with 3.6 changes. Sadly, two color tinting does not work, as the vertex format in SFML is fixed.
* Added support for clipping. * Added support for clipping.
* Added support for vertex effects. See raptor example.
### Unreal Engine 4 ### Unreal Engine 4
* Fixed renderer to work with 3.6 changes * Fixed renderer to work with 3.6 changes

View File

@ -103,7 +103,7 @@
#define COS(A) cosf(A) #define COS(A) cosf(A)
#define SQRT(A) sqrtf(A) #define SQRT(A) sqrtf(A)
#define ACOS(A) acosf(A) #define ACOS(A) acosf(A)
#define POW(A,B) pow(A, B); #define POW(A,B) pow(A, B)
#else #else
#define FMOD(A,B) (float)fmod(A, B) #define FMOD(A,B) (float)fmod(A, B)
#define ATAN2(A,B) (float)atan2(A, B) #define ATAN2(A,B) (float)atan2(A, B)

View File

@ -30,10 +30,13 @@
#include "RaptorExample.h" #include "RaptorExample.h"
#include "TankExample.h" #include "TankExample.h"
#include <spine/extension.h>
USING_NS_CC; USING_NS_CC;
using namespace spine; using namespace spine;
spSwirlVertexEffect* effect = spSwirlVertexEffect_create(400);
Scene* RaptorExample::scene () { Scene* RaptorExample::scene () {
Scene *scene = Scene::create(); Scene *scene = Scene::create();
scene->addChild(RaptorExample::create()); scene->addChild(RaptorExample::create());
@ -46,7 +49,13 @@ bool RaptorExample::init () {
skeletonNode = SkeletonAnimation::createWithJsonFile("raptor-pro.json", "raptor.atlas", 0.5f); skeletonNode = SkeletonAnimation::createWithJsonFile("raptor-pro.json", "raptor.atlas", 0.5f);
skeletonNode->setAnimation(0, "walk", true); skeletonNode->setAnimation(0, "walk", true);
skeletonNode->setAnimation(1, "empty", false); skeletonNode->setAnimation(1, "empty", false);
skeletonNode->addAnimation(1, "gungrab", false, 2); skeletonNode->addAnimation(1, "gungrab", false, 2);
skeletonNode->setTwoColorTint(true);
effect->centerY = 200;
swirlTime = 0;
skeletonNode->setVertexEffect(&effect->super);
skeletonNode->setPosition(Vec2(_contentSize.width / 2, 20)); skeletonNode->setPosition(Vec2(_contentSize.width / 2, 20));
addChild(skeletonNode); addChild(skeletonNode);
@ -68,3 +77,10 @@ bool RaptorExample::init () {
return true; return true;
} }
void RaptorExample::update(float fDelta) {
swirlTime += fDelta;
float percent = fmod(swirlTime, 2);
if (percent > 1) percent = 1 - (percent - 1);
effect->angle = _spMath_interpolate(_spMath_pow2_apply, -60, 60, percent);
}

View File

@ -41,9 +41,12 @@ public:
CREATE_FUNC(RaptorExample); CREATE_FUNC(RaptorExample);
virtual bool init (); virtual bool init ();
virtual void update(float fDelta);
private: private:
spine::SkeletonAnimation* skeletonNode; spine::SkeletonAnimation* skeletonNode;
float swirlTime;
}; };
#endif // _RAPTOREXAMPLE_H_ #endif // _RAPTOREXAMPLE_H_

View File

@ -59,6 +59,7 @@ LOCAL_SRC_FILES := hellocpp/main.cpp \
../../../../spine-c/spine-c/src/spine/TransformConstraint.c \ ../../../../spine-c/spine-c/src/spine/TransformConstraint.c \
../../../../spine-c/spine-c/src/spine/TransformConstraintData.c \ ../../../../spine-c/spine-c/src/spine/TransformConstraintData.c \
../../../../spine-c/spine-c/src/spine/VertexAttachment.c \ ../../../../spine-c/spine-c/src/spine/VertexAttachment.c \
../../../../spine-c/spine-c/src/spine/VertexEffect.c \
../../../../spine-c/spine-c/src/spine/extension.c ../../../../spine-c/spine-c/src/spine/extension.c

View File

@ -0,0 +1,98 @@
/******************************************************************************
* Spine Runtimes Software License v2.5
*
* Copyright (c) 2013-2016, Esoteric Software
* All rights reserved.
*
* You are granted a perpetual, non-exclusive, non-sublicensable, and
* non-transferable license to use, install, execute, and perform the Spine
* Runtimes software and derivative works solely for personal or internal
* use. Without the written permission of Esoteric Software (see Section 2 of
* the Spine Software License Agreement), you may not (a) modify, translate,
* adapt, or develop new applications using the Spine Runtimes or otherwise
* create derivative works or improvements of the Spine Runtimes 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 SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
* USE, DATA, OR PROFITS) 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.
*****************************************************************************/
#include <spine/VertexEffect.h>
#include <spine/extension.h>
void _spJitterVertexEffect_begin(spVertexEffect* self, spSkeleton* skeleton) {
}
void _spJitterVertexEffect_transform(spVertexEffect* self, float* x, float* y, float* u, float* v, spColor* light, spColor* dark) {
spJitterVertexEffect* internal = (spJitterVertexEffect*)self;
float jitterX = internal->jitterX;
float jitterY = internal->jitterY;
(*x) += _spMath_randomTriangular(-jitterX, jitterY);
(*y) += _spMath_randomTriangular(-jitterX, jitterY);
}
void _spJitterVertexEffect_end(spVertexEffect* self) {
}
spJitterVertexEffect* spJitterVertexEffect_create(float jitterX, float jitterY) {
spJitterVertexEffect* effect = CALLOC(spJitterVertexEffect, 1);
effect->super.begin = _spJitterVertexEffect_begin;
effect->super.transform = _spJitterVertexEffect_transform;
effect->super.end = _spJitterVertexEffect_end;
effect->jitterX = jitterX;
effect->jitterY = jitterY;
return effect;
}
void spJitterVertexEffect_dispose(spJitterVertexEffect* effect) {
FREE(effect);
}
void _spSwirlVertexEffect_begin(spVertexEffect* self, spSkeleton* skeleton) {
spSwirlVertexEffect* internal = (spSwirlVertexEffect*)self;
internal->worldX = skeleton->x + internal->centerX;
internal->worldY = skeleton->y + internal->centerY;
}
void _spSwirlVertexEffect_transform(spVertexEffect* self, float* positionX, float* positionY, float* u, float* v, spColor* light, spColor* dark) {
spSwirlVertexEffect* internal = (spSwirlVertexEffect*)self;
float radAngle = internal->angle * DEG_RAD;
float x = *positionX - internal->worldX;
float y = *positionY - internal->worldY;
float dist = SQRT(x * x + y * y);
if (dist < internal->radius) {
float theta = _spMath_interpolate(_spMath_pow2_apply, 0, radAngle, (internal->radius - dist) / internal->radius);
float cosine = COS(theta);
float sine = SIN(theta);
(*positionX) = cosine * x - sine * y + internal->worldX;
(*positionY) = sine * x + cosine * y + internal->worldY;
}
}
void _spSwirlVertexEffect_end(spVertexEffect* self) {
}
spSwirlVertexEffect* spSwirlVertexEffect_create(float radius) {
spSwirlVertexEffect* effect = CALLOC(spSwirlVertexEffect, 1);
effect->super.begin = _spSwirlVertexEffect_begin;
effect->super.transform = _spSwirlVertexEffect_transform;
effect->super.end = _spSwirlVertexEffect_end;
effect->radius = radius;
return effect;
}
void spSwirlVertexEffect_dispose(spSwirlVertexEffect* effect) {
FREE(effect);
}

View File

@ -170,6 +170,8 @@
76FAC18D1E3F97D2001CCC8C /* PointAttachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 76FAC18B1E3F97D2001CCC8C /* PointAttachment.c */; }; 76FAC18D1E3F97D2001CCC8C /* PointAttachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 76FAC18B1E3F97D2001CCC8C /* PointAttachment.c */; };
76FAC18F1E3F98A0001CCC8C /* Color.c in Sources */ = {isa = PBXBuildFile; fileRef = 76FAC18A1E3F97D2001CCC8C /* Color.c */; }; 76FAC18F1E3F98A0001CCC8C /* Color.c in Sources */ = {isa = PBXBuildFile; fileRef = 76FAC18A1E3F97D2001CCC8C /* Color.c */; };
76FAC1901E3F98A0001CCC8C /* PointAttachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 76FAC18B1E3F97D2001CCC8C /* PointAttachment.c */; }; 76FAC1901E3F98A0001CCC8C /* PointAttachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 76FAC18B1E3F97D2001CCC8C /* PointAttachment.c */; };
76FB150F1F01377200C5377F /* VertexEffect.c in Sources */ = {isa = PBXBuildFile; fileRef = 76FB150E1F01377200C5377F /* VertexEffect.c */; };
76FB15111F0139B400C5377F /* VertexEffect.c in Sources */ = {isa = PBXBuildFile; fileRef = 76FB150E1F01377200C5377F /* VertexEffect.c */; };
8262943E1AAF051F00CB7CF7 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8262943D1AAF051F00CB7CF7 /* Security.framework */; }; 8262943E1AAF051F00CB7CF7 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8262943D1AAF051F00CB7CF7 /* Security.framework */; };
BF171245129291EC00B8313A /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BF170DB012928DE900B8313A /* OpenGLES.framework */; }; BF171245129291EC00B8313A /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BF170DB012928DE900B8313A /* OpenGLES.framework */; };
BF1712471292920000B8313A /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = BF170DB412928DE900B8313A /* libz.dylib */; }; BF1712471292920000B8313A /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = BF170DB412928DE900B8313A /* libz.dylib */; };
@ -335,6 +337,7 @@
76F5BD541D2BD7D3005917E5 /* TankExample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TankExample.h; sourceTree = "<group>"; }; 76F5BD541D2BD7D3005917E5 /* TankExample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TankExample.h; sourceTree = "<group>"; };
76FAC18A1E3F97D2001CCC8C /* Color.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Color.c; path = "../../../spine-c/spine-c/src/spine/Color.c"; sourceTree = "<group>"; }; 76FAC18A1E3F97D2001CCC8C /* Color.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Color.c; path = "../../../spine-c/spine-c/src/spine/Color.c"; sourceTree = "<group>"; };
76FAC18B1E3F97D2001CCC8C /* PointAttachment.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = PointAttachment.c; path = "../../../spine-c/spine-c/src/spine/PointAttachment.c"; sourceTree = "<group>"; }; 76FAC18B1E3F97D2001CCC8C /* PointAttachment.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = PointAttachment.c; path = "../../../spine-c/spine-c/src/spine/PointAttachment.c"; sourceTree = "<group>"; };
76FB150E1F01377200C5377F /* VertexEffect.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = VertexEffect.c; sourceTree = "<group>"; };
8262943D1AAF051F00CB7CF7 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; }; 8262943D1AAF051F00CB7CF7 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };
BF170DB012928DE900B8313A /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; }; BF170DB012928DE900B8313A /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; };
BF170DB412928DE900B8313A /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; }; BF170DB412928DE900B8313A /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; };
@ -552,6 +555,7 @@
76AAA3B21D180F7300C54FCB /* spine */ = { 76AAA3B21D180F7300C54FCB /* spine */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
76FB150E1F01377200C5377F /* VertexEffect.c */,
76D520E11EB3625700572471 /* Array.c */, 76D520E11EB3625700572471 /* Array.c */,
76D520D71EB3611300572471 /* ClippingAttachment.c */, 76D520D71EB3611300572471 /* ClippingAttachment.c */,
76D520D81EB3611300572471 /* SkeletonClipping.c */, 76D520D81EB3611300572471 /* SkeletonClipping.c */,
@ -803,6 +807,7 @@
76F28CB81DEC7EBB00CDE54D /* Bone.c in Sources */, 76F28CB81DEC7EBB00CDE54D /* Bone.c in Sources */,
76F28CB61DEC7EBB00CDE54D /* Attachment.c in Sources */, 76F28CB61DEC7EBB00CDE54D /* Attachment.c in Sources */,
503AE10217EB989F00D1A890 /* RootViewController.mm in Sources */, 503AE10217EB989F00D1A890 /* RootViewController.mm in Sources */,
76FB150F1F01377200C5377F /* VertexEffect.c in Sources */,
503AE10117EB989F00D1A890 /* main.m in Sources */, 503AE10117EB989F00D1A890 /* main.m in Sources */,
76D520DB1EB3611300572471 /* SkeletonClipping.c in Sources */, 76D520DB1EB3611300572471 /* SkeletonClipping.c in Sources */,
76F28CCB1DEC7EBB00CDE54D /* Skin.c in Sources */, 76F28CCB1DEC7EBB00CDE54D /* Skin.c in Sources */,
@ -820,6 +825,7 @@
isa = PBXSourcesBuildPhase; isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
76FB15111F0139B400C5377F /* VertexEffect.c in Sources */,
76D520E71EB3634600572471 /* CoinExample.cpp in Sources */, 76D520E71EB3634600572471 /* CoinExample.cpp in Sources */,
76D520E31EB3625B00572471 /* Array.c in Sources */, 76D520E31EB3625B00572471 /* Array.c in Sources */,
76D520DE1EB3619800572471 /* ClippingAttachment.c in Sources */, 76D520DE1EB3619800572471 /* ClippingAttachment.c in Sources */,

View File

@ -179,6 +179,7 @@ xcopy "$(ProjectDir)..\Resources" "$(OutDir)" /D /E /I /F /Y
<ClCompile Include="..\..\..\spine-c\spine-c\src\spine\TransformConstraint.c" /> <ClCompile Include="..\..\..\spine-c\spine-c\src\spine\TransformConstraint.c" />
<ClCompile Include="..\..\..\spine-c\spine-c\src\spine\TransformConstraintData.c" /> <ClCompile Include="..\..\..\spine-c\spine-c\src\spine\TransformConstraintData.c" />
<ClCompile Include="..\..\..\spine-c\spine-c\src\spine\VertexAttachment.c" /> <ClCompile Include="..\..\..\spine-c\spine-c\src\spine\VertexAttachment.c" />
<ClCompile Include="..\..\..\spine-c\spine-c\src\spine\VertexEffect.c" />
<ClCompile Include="..\..\src\spine\AttachmentVertices.cpp" /> <ClCompile Include="..\..\src\spine\AttachmentVertices.cpp" />
<ClCompile Include="..\..\src\spine\Cocos2dAttachmentLoader.cpp" /> <ClCompile Include="..\..\src\spine\Cocos2dAttachmentLoader.cpp" />
<ClCompile Include="..\..\src\spine\SkeletonAnimation.cpp" /> <ClCompile Include="..\..\src\spine\SkeletonAnimation.cpp" />

View File

@ -77,21 +77,21 @@ void SkeletonRenderer::setSkeletonData (spSkeletonData *skeletonData, bool ownsS
} }
SkeletonRenderer::SkeletonRenderer () SkeletonRenderer::SkeletonRenderer ()
: _atlas(nullptr), _attachmentLoader(nullptr), _debugSlots(false), _debugBones(false), _debugMeshes(false), _timeScale(1) { : _atlas(nullptr), _attachmentLoader(nullptr), _debugSlots(false), _debugBones(false), _debugMeshes(false), _timeScale(1), _effect(nullptr) {
} }
SkeletonRenderer::SkeletonRenderer (spSkeletonData *skeletonData, bool ownsSkeletonData) SkeletonRenderer::SkeletonRenderer (spSkeletonData *skeletonData, bool ownsSkeletonData)
: _atlas(nullptr), _attachmentLoader(nullptr), _debugSlots(false), _debugBones(false), _debugMeshes(false), _timeScale(1) { : _atlas(nullptr), _attachmentLoader(nullptr), _debugSlots(false), _debugBones(false), _debugMeshes(false), _timeScale(1), _effect(nullptr) {
initWithData(skeletonData, ownsSkeletonData); initWithData(skeletonData, ownsSkeletonData);
} }
SkeletonRenderer::SkeletonRenderer (const std::string& skeletonDataFile, spAtlas* atlas, float scale) SkeletonRenderer::SkeletonRenderer (const std::string& skeletonDataFile, spAtlas* atlas, float scale)
: _atlas(nullptr), _attachmentLoader(nullptr), _debugSlots(false), _debugBones(false), _debugMeshes(false), _timeScale(1) { : _atlas(nullptr), _attachmentLoader(nullptr), _debugSlots(false), _debugBones(false), _debugMeshes(false), _timeScale(1), _effect(nullptr) {
initWithJsonFile(skeletonDataFile, atlas, scale); initWithJsonFile(skeletonDataFile, atlas, scale);
} }
SkeletonRenderer::SkeletonRenderer (const std::string& skeletonDataFile, const std::string& atlasFile, float scale) SkeletonRenderer::SkeletonRenderer (const std::string& skeletonDataFile, const std::string& atlasFile, float scale)
: _atlas(nullptr), _attachmentLoader(nullptr), _debugSlots(false), _debugBones(false), _debugMeshes(false), _timeScale(1) { : _atlas(nullptr), _attachmentLoader(nullptr), _debugSlots(false), _debugBones(false), _debugMeshes(false), _timeScale(1), _effect(nullptr) {
initWithJsonFile(skeletonDataFile, atlasFile, scale); initWithJsonFile(skeletonDataFile, atlasFile, scale);
} }
@ -183,6 +183,8 @@ void SkeletonRenderer::draw (Renderer* renderer, const Mat4& transform, uint32_t
SkeletonBatch* batch = SkeletonBatch::getInstance(); SkeletonBatch* batch = SkeletonBatch::getInstance();
SkeletonTwoColorBatch* twoColorBatch = SkeletonTwoColorBatch::getInstance(); SkeletonTwoColorBatch* twoColorBatch = SkeletonTwoColorBatch::getInstance();
bool isTwoColorTint = this->isTwoColorTint(); bool isTwoColorTint = this->isTwoColorTint();
if (_effect) _effect->begin(_effect, _skeleton);
Color4F nodeColor; Color4F nodeColor;
nodeColor.r = getDisplayedColor().r / (float)255; nodeColor.r = getDisplayedColor().r / (float)255;
@ -321,26 +323,70 @@ void SkeletonRenderer::draw (Renderer* renderer, const Mat4& transform, uint32_t
float* verts = _clipper->clippedVertices->items; float* verts = _clipper->clippedVertices->items;
float* uvs = _clipper->clippedUVs->items; float* uvs = _clipper->clippedUVs->items;
for (int v = 0, vn = batchedTriangles->getTriangles().vertCount, vv = 0; v < vn; ++v, vv+=2) { if (_effect) {
V3F_C4B_T2F* vertex = batchedTriangles->getTriangles().verts + v; spColor light;
vertex->vertices.x = verts[vv]; spColor dark;
vertex->vertices.y = verts[vv + 1]; light.r = color.r / 255.0f;
vertex->texCoords.u = uvs[vv]; light.g = color.g / 255.0f;
vertex->texCoords.v = uvs[vv + 1]; light.b = color.b / 255.0f;
vertex->colors.r = (GLubyte)color.r; light.a = color.a / 255.0f;
vertex->colors.g = (GLubyte)color.g; dark.r = dark.g = dark.b = dark.a = 0;
vertex->colors.b = (GLubyte)color.b; for (int v = 0, vn = batchedTriangles->getTriangles().vertCount, vv = 0; v < vn; ++v, vv+=2) {
vertex->colors.a = (GLubyte)color.a; V3F_C4B_T2F* vertex = batchedTriangles->getTriangles().verts + v;
spColor lightCopy = light;
spColor darkCopy = dark;
vertex->vertices.x = verts[vv];
vertex->vertices.y = verts[vv + 1];
vertex->texCoords.u = uvs[vv];
vertex->texCoords.v = uvs[vv + 1];
_effect->transform(_effect, &vertex->vertices.x, &vertex->vertices.y, &vertex->texCoords.u, &vertex->texCoords.v, &lightCopy, &darkCopy);
vertex->colors.r = (GLubyte)(lightCopy.r * 255);
vertex->colors.g = (GLubyte)(lightCopy.g * 255);
vertex->colors.b = (GLubyte)(lightCopy.b * 255);
vertex->colors.a = (GLubyte)(lightCopy.a * 255);
}
} else {
for (int v = 0, vn = batchedTriangles->getTriangles().vertCount, vv = 0; v < vn; ++v, vv+=2) {
V3F_C4B_T2F* vertex = batchedTriangles->getTriangles().verts + v;
vertex->vertices.x = verts[vv];
vertex->vertices.y = verts[vv + 1];
vertex->texCoords.u = uvs[vv];
vertex->texCoords.v = uvs[vv + 1];
vertex->colors.r = (GLubyte)color.r;
vertex->colors.g = (GLubyte)color.g;
vertex->colors.b = (GLubyte)color.b;
vertex->colors.a = (GLubyte)color.a;
}
} }
} else { } else {
cocos2d::TrianglesCommand* batchedTriangles = batch->addCommand(renderer, _globalZOrder, attachmentVertices->_texture, _glProgramState, blendFunc, triangles, transform, transformFlags); cocos2d::TrianglesCommand* batchedTriangles = batch->addCommand(renderer, _globalZOrder, attachmentVertices->_texture, _glProgramState, blendFunc, triangles, transform, transformFlags);
for (int v = 0, vn = batchedTriangles->getTriangles().vertCount; v < vn; ++v) { if (_effect) {
V3F_C4B_T2F* vertex = batchedTriangles->getTriangles().verts + v; spColor light;
vertex->colors.r = (GLubyte)color.r; spColor dark;
vertex->colors.g = (GLubyte)color.g; light.r = color.r / 255.0f;
vertex->colors.b = (GLubyte)color.b; light.g = color.g / 255.0f;
vertex->colors.a = (GLubyte)color.a; light.b = color.b / 255.0f;
light.a = color.a / 255.0f;
dark.r = dark.g = dark.b = dark.a = 0;
for (int v = 0, vn = batchedTriangles->getTriangles().vertCount; v < vn; ++v) {
V3F_C4B_T2F* vertex = batchedTriangles->getTriangles().verts + v;
spColor lightCopy = light;
spColor darkCopy = dark;
_effect->transform(_effect, &vertex->vertices.x, &vertex->vertices.y, &vertex->texCoords.u, &vertex->texCoords.v, &lightCopy, &darkCopy);
vertex->colors.r = (GLubyte)(lightCopy.r * 255);
vertex->colors.g = (GLubyte)(lightCopy.g * 255);
vertex->colors.b = (GLubyte)(lightCopy.b * 255);
vertex->colors.a = (GLubyte)(lightCopy.a * 255);
}
} else {
for (int v = 0, vn = batchedTriangles->getTriangles().vertCount; v < vn; ++v) {
V3F_C4B_T2F* vertex = batchedTriangles->getTriangles().verts + v;
vertex->colors.r = (GLubyte)color.r;
vertex->colors.g = (GLubyte)color.g;
vertex->colors.b = (GLubyte)color.b;
vertex->colors.a = (GLubyte)color.a;
}
} }
} }
} else { } else {
@ -361,34 +407,94 @@ void SkeletonRenderer::draw (Renderer* renderer, const Mat4& transform, uint32_t
float* verts = _clipper->clippedVertices->items; float* verts = _clipper->clippedVertices->items;
float* uvs = _clipper->clippedUVs->items; float* uvs = _clipper->clippedUVs->items;
for (int v = 0, vn = batchedTriangles->getTriangles().vertCount, vv = 0; v < vn; ++v, vv += 2) {
V3F_C4B_C4B_T2F* vertex = batchedTriangles->getTriangles().verts + v; if (_effect) {
vertex->position.x = verts[vv]; spColor light;
vertex->position.y = verts[vv + 1]; spColor dark;
vertex->texCoords.u = uvs[vv]; light.r = color.r / 255.0f;
vertex->texCoords.v = uvs[vv + 1]; light.g = color.g / 255.0f;
vertex->color.r = (GLubyte)color.r; light.b = color.b / 255.0f;
vertex->color.g = (GLubyte)color.g; light.a = color.a / 255.0f;
vertex->color.b = (GLubyte)color.b; dark.r = darkColor.r / 255.0f;
vertex->color.a = (GLubyte)color.a; dark.g = darkColor.g / 255.0f;
vertex->color2.r = (GLubyte)darkColor.r; dark.b = darkColor.b / 255.0f;
vertex->color2.g = (GLubyte)darkColor.g; dark.a = darkColor.a / 255.0f;
vertex->color2.b = (GLubyte)darkColor.b; for (int v = 0, vn = batchedTriangles->getTriangles().vertCount, vv = 0; v < vn; ++v, vv += 2) {
vertex->color2.a = 1; V3F_C4B_C4B_T2F* vertex = batchedTriangles->getTriangles().verts + v;
spColor lightCopy = light;
spColor darkCopy = dark;
vertex->position.x = verts[vv];
vertex->position.y = verts[vv + 1];
vertex->texCoords.u = uvs[vv];
vertex->texCoords.v = uvs[vv + 1];
_effect->transform(_effect, &vertex->position.x, &vertex->position.y, &vertex->texCoords.u, &vertex->texCoords.v, &lightCopy, &darkCopy);
vertex->color.r = (GLubyte)(lightCopy.r * 255);
vertex->color.g = (GLubyte)(lightCopy.g * 255);
vertex->color.b = (GLubyte)(lightCopy.b * 255);
vertex->color.a = (GLubyte)(lightCopy.a * 255);
vertex->color2.r = (GLubyte)(darkCopy.r * 255);
vertex->color2.g = (GLubyte)(darkCopy.g * 255);
vertex->color2.b = (GLubyte)(darkCopy.b * 255);
vertex->color2.a = 1;
}
} else {
for (int v = 0, vn = batchedTriangles->getTriangles().vertCount, vv = 0; v < vn; ++v, vv += 2) {
V3F_C4B_C4B_T2F* vertex = batchedTriangles->getTriangles().verts + v;
vertex->position.x = verts[vv];
vertex->position.y = verts[vv + 1];
vertex->texCoords.u = uvs[vv];
vertex->texCoords.v = uvs[vv + 1];
vertex->color.r = (GLubyte)color.r;
vertex->color.g = (GLubyte)color.g;
vertex->color.b = (GLubyte)color.b;
vertex->color.a = (GLubyte)color.a;
vertex->color2.r = (GLubyte)darkColor.r;
vertex->color2.g = (GLubyte)darkColor.g;
vertex->color2.b = (GLubyte)darkColor.b;
vertex->color2.a = 1;
}
} }
} else { } else {
TwoColorTrianglesCommand* batchedTriangles = lastTwoColorTrianglesCommand = twoColorBatch->addCommand(renderer, _globalZOrder, attachmentVertices->_texture->getName(), _glProgramState, blendFunc, trianglesTwoColor, transform, transformFlags); TwoColorTrianglesCommand* batchedTriangles = lastTwoColorTrianglesCommand = twoColorBatch->addCommand(renderer, _globalZOrder, attachmentVertices->_texture->getName(), _glProgramState, blendFunc, trianglesTwoColor, transform, transformFlags);
for (int v = 0, vn = batchedTriangles->getTriangles().vertCount; v < vn; ++v) { if (_effect) {
V3F_C4B_C4B_T2F* vertex = batchedTriangles->getTriangles().verts + v; spColor light;
vertex->color.r = (GLubyte)color.r; spColor dark;
vertex->color.g = (GLubyte)color.g; light.r = color.r / 255.0f;
vertex->color.b = (GLubyte)color.b; light.g = color.g / 255.0f;
vertex->color.a = (GLubyte)color.a; light.b = color.b / 255.0f;
vertex->color2.r = (GLubyte)darkColor.r; light.a = color.a / 255.0f;
vertex->color2.g = (GLubyte)darkColor.g; dark.r = darkColor.r / 255.0f;
vertex->color2.b = (GLubyte)darkColor.b; dark.g = darkColor.g / 255.0f;
vertex->color2.a = 1; dark.b = darkColor.b / 255.0f;
dark.a = darkColor.a / 255.0f;
for (int v = 0, vn = batchedTriangles->getTriangles().vertCount; v < vn; ++v) {
V3F_C4B_C4B_T2F* vertex = batchedTriangles->getTriangles().verts + v;
spColor lightCopy = light;
spColor darkCopy = dark;
_effect->transform(_effect, &vertex->position.x, &vertex->position.y, &vertex->texCoords.u, &vertex->texCoords.v, &lightCopy, &darkCopy);
vertex->color.r = (GLubyte)(lightCopy.r * 255);
vertex->color.g = (GLubyte)(lightCopy.g * 255);
vertex->color.b = (GLubyte)(lightCopy.b * 255);
vertex->color.a = (GLubyte)(lightCopy.a * 255);
vertex->color2.r = (GLubyte)(darkCopy.r * 255);
vertex->color2.g = (GLubyte)(darkCopy.g * 255);
vertex->color2.b = (GLubyte)(darkCopy.b * 255);
vertex->color2.a = 1;
}
} else {
for (int v = 0, vn = batchedTriangles->getTriangles().vertCount; v < vn; ++v) {
V3F_C4B_C4B_T2F* vertex = batchedTriangles->getTriangles().verts + v;
vertex->color.r = (GLubyte)color.r;
vertex->color.g = (GLubyte)color.g;
vertex->color.b = (GLubyte)color.b;
vertex->color.a = (GLubyte)color.a;
vertex->color2.r = (GLubyte)darkColor.r;
vertex->color2.g = (GLubyte)darkColor.g;
vertex->color2.b = (GLubyte)darkColor.b;
vertex->color2.a = 1;
}
} }
} }
} }
@ -432,6 +538,8 @@ void SkeletonRenderer::draw (Renderer* renderer, const Mat4& transform, uint32_t
} }
} }
} }
if (_effect) _effect->end(_effect);
if (_debugSlots || _debugBones || _debugMeshes) { if (_debugSlots || _debugBones || _debugMeshes) {
drawDebug(renderer, transform, transformFlags); drawDebug(renderer, transform, transformFlags);
@ -595,6 +703,10 @@ void SkeletonRenderer::setTwoColorTint(bool enabled) {
bool SkeletonRenderer::isTwoColorTint() { bool SkeletonRenderer::isTwoColorTint() {
return getGLProgramState() == SkeletonTwoColorBatch::getInstance()->getTwoColorTintProgramState(); return getGLProgramState() == SkeletonTwoColorBatch::getInstance()->getTwoColorTintProgramState();
} }
void SkeletonRenderer::setVertexEffect(spVertexEffect *effect) {
this->_effect = effect;
}
spSkeleton* SkeletonRenderer::getSkeleton () { spSkeleton* SkeletonRenderer::getSkeleton () {
return _skeleton; return _skeleton;

View File

@ -99,6 +99,9 @@ public:
void setTwoColorTint(bool enabled); void setTwoColorTint(bool enabled);
/* Whether two color tinting is enabled */ /* Whether two color tinting is enabled */
bool isTwoColorTint(); bool isTwoColorTint();
/* Sets the vertex effect to be used, set to 0 to disable vertex effects */
void setVertexEffect(spVertexEffect* effect);
// --- BlendProtocol // --- BlendProtocol
virtual void setBlendFunc (const cocos2d::BlendFunc& blendFunc)override; virtual void setBlendFunc (const cocos2d::BlendFunc& blendFunc)override;
@ -125,7 +128,7 @@ CC_CONSTRUCTOR_ACCESS:
protected: protected:
void setSkeletonData (spSkeletonData* skeletonData, bool ownsSkeletonData); void setSkeletonData (spSkeletonData* skeletonData, bool ownsSkeletonData);
virtual AttachmentVertices* getAttachmentVertices (spRegionAttachment* attachment) const; virtual AttachmentVertices* getAttachmentVertices (spRegionAttachment* attachment) const;
virtual AttachmentVertices* getAttachmentVertices (spMeshAttachment* attachment) const; virtual AttachmentVertices* getAttachmentVertices (spMeshAttachment* attachment) const;
bool _ownsSkeletonData; bool _ownsSkeletonData;
spAtlas* _atlas; spAtlas* _atlas;
@ -140,6 +143,7 @@ protected:
bool _debugBones; bool _debugBones;
bool _debugMeshes; bool _debugMeshes;
spSkeletonClipping* _clipper; spSkeletonClipping* _clipper;
spVertexEffect* _effect;
}; };
} }