Supports cocos2d-x v3.2

- Changes `draw()` with the new v3.2 API: `bool transformUpdated` -> `uint32_t transformFlags`
- cocos2d-ified the API:
  - `const char*` -> `const std::string&`
  - constructors and destructors are `protected` (not `public`)
  - using `_` prefix for ivars
This commit is contained in:
Ricardo Quesada 2014-07-25 10:16:11 -07:00
parent 234e8cf5f2
commit c8bc2bc378
6 changed files with 217 additions and 218 deletions

View File

@ -35,7 +35,7 @@ USING_NS_CC;
namespace spine { namespace spine {
PolygonBatch* PolygonBatch::createWithCapacity (int capacity) { PolygonBatch* PolygonBatch::createWithCapacity (ssize_t capacity) {
PolygonBatch* batch = new PolygonBatch(); PolygonBatch* batch = new PolygonBatch();
batch->initWithCapacity(capacity); batch->initWithCapacity(capacity);
batch->autorelease(); batch->autorelease();
@ -43,25 +43,25 @@ PolygonBatch* PolygonBatch::createWithCapacity (int capacity) {
} }
PolygonBatch::PolygonBatch () : PolygonBatch::PolygonBatch () :
capacity(0), _capacity(0),
vertices(nullptr), verticesCount(0), _vertices(nullptr), _verticesCount(0),
triangles(nullptr), trianglesCount(0), _triangles(nullptr), _trianglesCount(0),
texture(nullptr) _texture(nullptr)
{} {}
bool PolygonBatch::initWithCapacity (int capacity) { bool PolygonBatch::initWithCapacity (ssize_t capacity) {
// 32767 is max index, so 32767 / 3 - (32767 / 3 % 3) = 10920. // 32767 is max index, so 32767 / 3 - (32767 / 3 % 3) = 10920.
CCASSERT(capacity <= 10920, "capacity cannot be > 10920"); CCASSERT(capacity <= 10920, "capacity cannot be > 10920");
CCASSERT(capacity >= 0, "capacity cannot be < 0"); CCASSERT(capacity >= 0, "capacity cannot be < 0");
this->capacity = capacity; _capacity = capacity;
vertices = MALLOC(V2F_C4B_T2F, capacity); _vertices = MALLOC(V2F_C4B_T2F, capacity);
triangles = MALLOC(GLushort, capacity * 3); _triangles = MALLOC(GLushort, capacity * 3);
return true; return true;
} }
PolygonBatch::~PolygonBatch () { PolygonBatch::~PolygonBatch () {
FREE(vertices); FREE(_vertices);
FREE(triangles); FREE(_triangles);
} }
void PolygonBatch::add (const Texture2D* addTexture, void PolygonBatch::add (const Texture2D* addTexture,
@ -70,18 +70,18 @@ void PolygonBatch::add (const Texture2D* addTexture,
Color4B* color) { Color4B* color) {
if ( if (
addTexture != texture addTexture != _texture
|| verticesCount + (addVerticesCount >> 1) > capacity || _verticesCount + (addVerticesCount >> 1) > _capacity
|| trianglesCount + addTrianglesCount > capacity * 3) { || _trianglesCount + addTrianglesCount > _capacity * 3) {
this->flush(); this->flush();
texture = addTexture; _texture = addTexture;
} }
for (int i = 0; i < addTrianglesCount; ++i, ++trianglesCount) for (int i = 0; i < addTrianglesCount; ++i, ++_trianglesCount)
triangles[trianglesCount] = addTriangles[i] + verticesCount; _triangles[_trianglesCount] = addTriangles[i] + _verticesCount;
for (int i = 0; i < addVerticesCount; i += 2, ++verticesCount) { for (int i = 0; i < addVerticesCount; i += 2, ++_verticesCount) {
V2F_C4B_T2F* vertex = vertices + verticesCount; V2F_C4B_T2F* vertex = _vertices + _verticesCount;
vertex->vertices.x = addVertices[i]; vertex->vertices.x = addVertices[i];
vertex->vertices.y = addVertices[i + 1]; vertex->vertices.y = addVertices[i + 1];
vertex->colors = *color; vertex->colors = *color;
@ -91,20 +91,22 @@ void PolygonBatch::add (const Texture2D* addTexture,
} }
void PolygonBatch::flush () { void PolygonBatch::flush () {
if (!verticesCount) return; if (!_verticesCount) return;
GL::bindTexture2D(texture->getName()); GL::bindTexture2D(_texture->getName());
glEnableVertexAttribArray(GLProgram::VERTEX_ATTRIB_POSITION); glEnableVertexAttribArray(GLProgram::VERTEX_ATTRIB_POSITION);
glEnableVertexAttribArray(GLProgram::VERTEX_ATTRIB_COLOR); glEnableVertexAttribArray(GLProgram::VERTEX_ATTRIB_COLOR);
glEnableVertexAttribArray(GLProgram::VERTEX_ATTRIB_TEX_COORDS); glEnableVertexAttribArray(GLProgram::VERTEX_ATTRIB_TEX_COORDS);
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, sizeof(V2F_C4B_T2F), &vertices[0].vertices); glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, sizeof(V2F_C4B_T2F), &_vertices[0].vertices);
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(V2F_C4B_T2F), &vertices[0].colors); glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(V2F_C4B_T2F), &_vertices[0].colors);
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_TEX_COORDS, 2, GL_FLOAT, GL_FALSE, sizeof(V2F_C4B_T2F), &vertices[0].texCoords); glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_TEX_COORDS, 2, GL_FLOAT, GL_FALSE, sizeof(V2F_C4B_T2F), &_vertices[0].texCoords);
glDrawElements(GL_TRIANGLES, trianglesCount, GL_UNSIGNED_SHORT, triangles); glDrawElements(GL_TRIANGLES, _trianglesCount, GL_UNSIGNED_SHORT, _triangles);
verticesCount = 0; CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES(1, _verticesCount);
trianglesCount = 0;
_verticesCount = 0;
_trianglesCount = 0;
CHECK_GL_ERROR_DEBUG(); CHECK_GL_ERROR_DEBUG();
} }

View File

@ -37,29 +37,25 @@ namespace spine {
class PolygonBatch : public cocos2d::Ref { class PolygonBatch : public cocos2d::Ref {
public: public:
static PolygonBatch* createWithCapacity (int capacity); static PolygonBatch* createWithCapacity (ssize_t capacity);
/** @js ctor */
PolygonBatch();
/** @js NA
* @lua NA */
virtual ~PolygonBatch();
bool initWithCapacity (int capacity);
void add (const cocos2d::Texture2D* texture, void add (const cocos2d::Texture2D* texture,
const float* vertices, const float* uvs, int verticesCount, const float* vertices, const float* uvs, int verticesCount,
const int* triangles, int trianglesCount, const int* triangles, int trianglesCount,
cocos2d::Color4B* color); cocos2d::Color4B* color);
void flush (); void flush ();
private: protected:
int capacity; PolygonBatch();
cocos2d::V2F_C4B_T2F* vertices; virtual ~PolygonBatch();
int verticesCount; bool initWithCapacity (ssize_t capacity);
GLushort* triangles;
int trianglesCount; ssize_t _capacity;
const cocos2d::Texture2D* texture; cocos2d::V2F_C4B_T2F* _vertices;
int _verticesCount;
GLushort* _triangles;
int _trianglesCount;
const cocos2d::Texture2D* _texture;
}; };
} }

View File

@ -76,13 +76,13 @@ SkeletonAnimation* SkeletonAnimation::createWithData (spSkeletonData* skeletonDa
return node; return node;
} }
SkeletonAnimation* SkeletonAnimation::createWithFile (const char* skeletonDataFile, spAtlas* atlas, float scale) { SkeletonAnimation* SkeletonAnimation::createWithFile (const std::string& skeletonDataFile, spAtlas* atlas, float scale) {
SkeletonAnimation* node = new SkeletonAnimation(skeletonDataFile, atlas, scale); SkeletonAnimation* node = new SkeletonAnimation(skeletonDataFile, atlas, scale);
node->autorelease(); node->autorelease();
return node; return node;
} }
SkeletonAnimation* SkeletonAnimation::createWithFile (const char* skeletonDataFile, const char* atlasFile, float scale) { SkeletonAnimation* SkeletonAnimation::createWithFile (const std::string& skeletonDataFile, const std::string& atlasFile, float scale) {
SkeletonAnimation* node = new SkeletonAnimation(skeletonDataFile, atlasFile, scale); SkeletonAnimation* node = new SkeletonAnimation(skeletonDataFile, atlasFile, scale);
node->autorelease(); node->autorelease();
return node; return node;
@ -90,11 +90,11 @@ SkeletonAnimation* SkeletonAnimation::createWithFile (const char* skeletonDataFi
void SkeletonAnimation::initialize () { void SkeletonAnimation::initialize () {
ownsAnimationStateData = true; ownsAnimationStateData = true;
state = spAnimationState_create(spAnimationStateData_create(skeleton->data)); _state = spAnimationState_create(spAnimationStateData_create(_skeleton->data));
state->rendererObject = this; _state->rendererObject = this;
state->listener = animationCallback; _state->listener = animationCallback;
_spAnimationState* stateInternal = (_spAnimationState*)state; _spAnimationState* stateInternal = (_spAnimationState*)_state;
stateInternal->disposeTrackEntry = disposeTrackEntry; stateInternal->disposeTrackEntry = disposeTrackEntry;
} }
@ -103,74 +103,74 @@ SkeletonAnimation::SkeletonAnimation (spSkeletonData *skeletonData)
initialize(); initialize();
} }
SkeletonAnimation::SkeletonAnimation (const char* skeletonDataFile, spAtlas* atlas, float scale) SkeletonAnimation::SkeletonAnimation (const std::string& skeletonDataFile, spAtlas* atlas, float scale)
: SkeletonRenderer(skeletonDataFile, atlas, scale) { : SkeletonRenderer(skeletonDataFile, atlas, scale) {
initialize(); initialize();
} }
SkeletonAnimation::SkeletonAnimation (const char* skeletonDataFile, const char* atlasFile, float scale) SkeletonAnimation::SkeletonAnimation (const std::string& skeletonDataFile, const std::string& atlasFile, float scale)
: SkeletonRenderer(skeletonDataFile, atlasFile, scale) { : SkeletonRenderer(skeletonDataFile, atlasFile, scale) {
initialize(); initialize();
} }
SkeletonAnimation::~SkeletonAnimation () { SkeletonAnimation::~SkeletonAnimation () {
if (ownsAnimationStateData) spAnimationStateData_dispose(state->data); if (ownsAnimationStateData) spAnimationStateData_dispose(_state->data);
spAnimationState_dispose(state); spAnimationState_dispose(_state);
} }
void SkeletonAnimation::update (float deltaTime) { void SkeletonAnimation::update (float deltaTime) {
super::update(deltaTime); super::update(deltaTime);
deltaTime *= timeScale; deltaTime *= _timeScale;
spAnimationState_update(state, deltaTime); spAnimationState_update(_state, deltaTime);
spAnimationState_apply(state, skeleton); spAnimationState_apply(_state, _skeleton);
spSkeleton_updateWorldTransform(skeleton); spSkeleton_updateWorldTransform(_skeleton);
} }
void SkeletonAnimation::setAnimationStateData (spAnimationStateData* stateData) { void SkeletonAnimation::setAnimationStateData (spAnimationStateData* stateData) {
CCASSERT(stateData, "stateData cannot be null."); CCASSERT(stateData, "stateData cannot be null.");
if (ownsAnimationStateData) spAnimationStateData_dispose(state->data); if (ownsAnimationStateData) spAnimationStateData_dispose(_state->data);
spAnimationState_dispose(state); spAnimationState_dispose(_state);
ownsAnimationStateData = false; ownsAnimationStateData = false;
state = spAnimationState_create(stateData); _state = spAnimationState_create(stateData);
state->rendererObject = this; _state->rendererObject = this;
state->listener = animationCallback; _state->listener = animationCallback;
} }
void SkeletonAnimation::setMix (const char* fromAnimation, const char* toAnimation, float duration) { void SkeletonAnimation::setMix (const std::string& fromAnimation, const std::string& toAnimation, float duration) {
spAnimationStateData_setMixByName(state->data, fromAnimation, toAnimation, duration); spAnimationStateData_setMixByName(_state->data, fromAnimation.c_str(), toAnimation.c_str(), duration);
} }
spTrackEntry* SkeletonAnimation::setAnimation (int trackIndex, const char* name, bool loop) { spTrackEntry* SkeletonAnimation::setAnimation (int trackIndex, const std::string& name, bool loop) {
spAnimation* animation = spSkeletonData_findAnimation(skeleton->data, name); spAnimation* animation = spSkeletonData_findAnimation(_skeleton->data, name.c_str());
if (!animation) { if (!animation) {
log("Spine: Animation not found: %s", name); log("Spine: Animation not found: %s", name.c_str());
return 0; return 0;
} }
return spAnimationState_setAnimation(state, trackIndex, animation, loop); return spAnimationState_setAnimation(_state, trackIndex, animation, loop);
} }
spTrackEntry* SkeletonAnimation::addAnimation (int trackIndex, const char* name, bool loop, float delay) { spTrackEntry* SkeletonAnimation::addAnimation (int trackIndex, const std::string& name, bool loop, float delay) {
spAnimation* animation = spSkeletonData_findAnimation(skeleton->data, name); spAnimation* animation = spSkeletonData_findAnimation(_skeleton->data, name.c_str());
if (!animation) { if (!animation) {
log("Spine: Animation not found: %s", name); log("Spine: Animation not found: %s", name.c_str());
return 0; return 0;
} }
return spAnimationState_addAnimation(state, trackIndex, animation, loop, delay); return spAnimationState_addAnimation(_state, trackIndex, animation, loop, delay);
} }
spTrackEntry* SkeletonAnimation::getCurrent (int trackIndex) { spTrackEntry* SkeletonAnimation::getCurrent (int trackIndex) {
return spAnimationState_getCurrent(state, trackIndex); return spAnimationState_getCurrent(_state, trackIndex);
} }
void SkeletonAnimation::clearTracks () { void SkeletonAnimation::clearTracks () {
spAnimationState_clearTracks(state); spAnimationState_clearTracks(_state);
} }
void SkeletonAnimation::clearTrack (int trackIndex) { void SkeletonAnimation::clearTrack (int trackIndex) {
spAnimationState_clearTrack(state, trackIndex); spAnimationState_clearTrack(_state, trackIndex);
} }
void SkeletonAnimation::onAnimationStateEvent (int trackIndex, spEventType type, spEvent* event, int loopCount) { void SkeletonAnimation::onAnimationStateEvent (int trackIndex, spEventType type, spEvent* event, int loopCount) {
@ -191,7 +191,7 @@ void SkeletonAnimation::onAnimationStateEvent (int trackIndex, spEventType type,
} }
void SkeletonAnimation::onTrackEntryEvent (int trackIndex, spEventType type, spEvent* event, int loopCount) { void SkeletonAnimation::onTrackEntryEvent (int trackIndex, spEventType type, spEvent* event, int loopCount) {
spTrackEntry* entry = spAnimationState_getCurrent(state, trackIndex); spTrackEntry* entry = spAnimationState_getCurrent(_state, trackIndex);
if (!entry->rendererObject) return; if (!entry->rendererObject) return;
_TrackEntryListeners* listeners = (_TrackEntryListeners*)entry->rendererObject; _TrackEntryListeners* listeners = (_TrackEntryListeners*)entry->rendererObject;
switch (type) { switch (type) {
@ -226,4 +226,8 @@ void SkeletonAnimation::setEventListener (spTrackEntry* entry, spine::EventListe
getListeners(entry)->eventListener = listener; getListeners(entry)->eventListener = listener;
} }
spAnimationState* SkeletonAnimation::getState() const {
return _state;
}
} }

View File

@ -46,33 +46,21 @@ typedef std::function<void(int trackIndex, spEvent* event)> EventListener;
* played later. */ * played later. */
class SkeletonAnimation: public SkeletonRenderer { class SkeletonAnimation: public SkeletonRenderer {
public: public:
spAnimationState* state;
static SkeletonAnimation* createWithData (spSkeletonData* skeletonData); static SkeletonAnimation* createWithData (spSkeletonData* skeletonData);
static SkeletonAnimation* createWithFile (const char* skeletonDataFile, spAtlas* atlas, float scale = 0); static SkeletonAnimation* createWithFile (const std::string& skeletonDataFile, spAtlas* atlas, float scale = 0);
static SkeletonAnimation* createWithFile (const char* skeletonDataFile, const char* atlasFile, float scale = 0); static SkeletonAnimation* createWithFile (const std::string& skeletonDataFile, const std::string& atlasFile, float scale = 0);
SkeletonAnimation (spSkeletonData* skeletonData);
SkeletonAnimation (const char* skeletonDataFile, spAtlas* atlas, float scale = 0);
SkeletonAnimation (const char* skeletonDataFile, const char* atlasFile, float scale = 0);
virtual ~SkeletonAnimation ();
virtual void update (float deltaTime); virtual void update (float deltaTime);
void setAnimationStateData (spAnimationStateData* stateData); void setAnimationStateData (spAnimationStateData* stateData);
void setMix (const char* fromAnimation, const char* toAnimation, float duration); void setMix (const std::string& fromAnimation, const std::string& toAnimation, float duration);
spTrackEntry* setAnimation (int trackIndex, const char* name, bool loop); spTrackEntry* setAnimation (int trackIndex, const std::string& name, bool loop);
spTrackEntry* addAnimation (int trackIndex, const char* name, bool loop, float delay = 0); spTrackEntry* addAnimation (int trackIndex, const std::string& name, bool loop, float delay = 0);
spTrackEntry* getCurrent (int trackIndex = 0); spTrackEntry* getCurrent (int trackIndex = 0);
void clearTracks (); void clearTracks ();
void clearTrack (int trackIndex = 0); void clearTrack (int trackIndex = 0);
StartListener startListener;
EndListener endListener;
CompleteListener completeListener;
EventListener eventListener;
void setStartListener (spTrackEntry* entry, StartListener listener); void setStartListener (spTrackEntry* entry, StartListener listener);
void setEndListener (spTrackEntry* entry, EndListener listener); void setEndListener (spTrackEntry* entry, EndListener listener);
void setCompleteListener (spTrackEntry* entry, CompleteListener listener); void setCompleteListener (spTrackEntry* entry, CompleteListener listener);
@ -81,14 +69,27 @@ public:
virtual void onAnimationStateEvent (int trackIndex, spEventType type, spEvent* event, int loopCount); virtual void onAnimationStateEvent (int trackIndex, spEventType type, spEvent* event, int loopCount);
virtual void onTrackEntryEvent (int trackIndex, spEventType type, spEvent* event, int loopCount); virtual void onTrackEntryEvent (int trackIndex, spEventType type, spEvent* event, int loopCount);
spAnimationState* getState() const;
StartListener startListener;
EndListener endListener;
CompleteListener completeListener;
EventListener eventListener;
protected: protected:
SkeletonAnimation (); SkeletonAnimation ();
SkeletonAnimation (spSkeletonData* skeletonData);
SkeletonAnimation (const std::string&skeletonDataFile, spAtlas* atlas, float scale = 0);
SkeletonAnimation (const std::string& skeletonDataFile, const std::string& atlasFile, float scale = 0);
virtual ~SkeletonAnimation ();
void initialize ();
spAnimationState* _state;
bool ownsAnimationStateData;
private: private:
typedef SkeletonRenderer super; typedef SkeletonRenderer super;
bool ownsAnimationStateData;
void initialize ();
}; };
} }

View File

@ -48,30 +48,30 @@ SkeletonRenderer* SkeletonRenderer::createWithData (spSkeletonData* skeletonData
return node; return node;
} }
SkeletonRenderer* SkeletonRenderer::createWithFile (const char* skeletonDataFile, spAtlas* atlas, float scale) { SkeletonRenderer* SkeletonRenderer::createWithFile (const std::string& skeletonDataFile, spAtlas* atlas, float scale) {
SkeletonRenderer* node = new SkeletonRenderer(skeletonDataFile, atlas, scale); SkeletonRenderer* node = new SkeletonRenderer(skeletonDataFile, atlas, scale);
node->autorelease(); node->autorelease();
return node; return node;
} }
SkeletonRenderer* SkeletonRenderer::createWithFile (const char* skeletonDataFile, const char* atlasFile, float scale) { SkeletonRenderer* SkeletonRenderer::createWithFile (const std::string& skeletonDataFile, const std::string& atlasFile, float scale) {
SkeletonRenderer* node = new SkeletonRenderer(skeletonDataFile, atlasFile, scale); SkeletonRenderer* node = new SkeletonRenderer(skeletonDataFile, atlasFile, scale);
node->autorelease(); node->autorelease();
return node; return node;
} }
void SkeletonRenderer::initialize () { void SkeletonRenderer::initialize () {
atlas = 0; _atlas = 0;
debugSlots = false; _debugSlots = false;
debugBones = false; _debugBones = false;
timeScale = 1; _timeScale = 1;
worldVertices = MALLOC(float, 1000); // Max number of vertices per mesh. _worldVertices = MALLOC(float, 1000); // Max number of vertices per mesh.
batch = PolygonBatch::createWithCapacity(2000); // Max number of vertices and triangles per batch. _batch = PolygonBatch::createWithCapacity(2000); // Max number of vertices and triangles per batch.
batch->retain(); _batch->retain();
blendFunc = BlendFunc::ALPHA_PREMULTIPLIED; _blendFunc = BlendFunc::ALPHA_PREMULTIPLIED;
setOpacityModifyRGB(true); setOpacityModifyRGB(true);
setGLProgram(ShaderCache::getInstance()->getGLProgram(GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR)); setGLProgram(ShaderCache::getInstance()->getGLProgram(GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR));
@ -79,9 +79,9 @@ void SkeletonRenderer::initialize () {
} }
void SkeletonRenderer::setSkeletonData (spSkeletonData *skeletonData, bool ownsSkeletonData) { void SkeletonRenderer::setSkeletonData (spSkeletonData *skeletonData, bool ownsSkeletonData) {
skeleton = spSkeleton_create(skeletonData); _skeleton = spSkeleton_create(skeletonData);
rootBone = skeleton->bones[0]; _rootBone = _skeleton->bones[0];
this->ownsSkeletonData = ownsSkeletonData; _ownsSkeletonData = ownsSkeletonData;
} }
SkeletonRenderer::SkeletonRenderer () { SkeletonRenderer::SkeletonRenderer () {
@ -94,27 +94,27 @@ SkeletonRenderer::SkeletonRenderer (spSkeletonData *skeletonData, bool ownsSkele
setSkeletonData(skeletonData, ownsSkeletonData); setSkeletonData(skeletonData, ownsSkeletonData);
} }
SkeletonRenderer::SkeletonRenderer (const char* skeletonDataFile, spAtlas* atlas, float scale) { SkeletonRenderer::SkeletonRenderer (const std::string& skeletonDataFile, spAtlas* atlas, float scale) {
initialize(); initialize();
spSkeletonJson* json = spSkeletonJson_create(atlas); spSkeletonJson* json = spSkeletonJson_create(atlas);
json->scale = scale; json->scale = scale;
spSkeletonData* skeletonData = spSkeletonJson_readSkeletonDataFile(json, skeletonDataFile); spSkeletonData* skeletonData = spSkeletonJson_readSkeletonDataFile(json, skeletonDataFile.c_str());
CCASSERT(skeletonData, json->error ? json->error : "Error reading skeleton data."); CCASSERT(skeletonData, json->error ? json->error : "Error reading skeleton data.");
spSkeletonJson_dispose(json); spSkeletonJson_dispose(json);
setSkeletonData(skeletonData, true); setSkeletonData(skeletonData, true);
} }
SkeletonRenderer::SkeletonRenderer (const char* skeletonDataFile, const char* atlasFile, float scale) { SkeletonRenderer::SkeletonRenderer (const std::string& skeletonDataFile, const std::string& atlasFile, float scale) {
initialize(); initialize();
atlas = spAtlas_createFromFile(atlasFile, 0); _atlas = spAtlas_createFromFile(atlasFile.c_str(), 0);
CCASSERT(atlas, "Error reading atlas file."); CCASSERT(_atlas, "Error reading atlas file.");
spSkeletonJson* json = spSkeletonJson_create(atlas); spSkeletonJson* json = spSkeletonJson_create(_atlas);
json->scale = scale; json->scale = scale;
spSkeletonData* skeletonData = spSkeletonJson_readSkeletonDataFile(json, skeletonDataFile); spSkeletonData* skeletonData = spSkeletonJson_readSkeletonDataFile(json, skeletonDataFile.c_str());
CCASSERT(skeletonData, json->error ? json->error : "Error reading skeleton data file."); CCASSERT(skeletonData, json->error ? json->error : "Error reading skeleton data file.");
spSkeletonJson_dispose(json); spSkeletonJson_dispose(json);
@ -122,33 +122,32 @@ SkeletonRenderer::SkeletonRenderer (const char* skeletonDataFile, const char* at
} }
SkeletonRenderer::~SkeletonRenderer () { SkeletonRenderer::~SkeletonRenderer () {
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);
batch->release(); _batch->release();
FREE(worldVertices); FREE(_worldVertices);
} }
void SkeletonRenderer::update (float deltaTime) { void SkeletonRenderer::update (float deltaTime) {
spSkeleton_update(skeleton, deltaTime * timeScale); spSkeleton_update(_skeleton, deltaTime * _timeScale);
} }
void SkeletonRenderer::draw (Renderer* renderer, const Mat4& transform, bool transformUpdated) { void SkeletonRenderer::draw (Renderer* renderer, const Mat4& transform, uint32_t transformFlags) {
drawCommand.init(_globalZOrder); _drawCommand.init(_globalZOrder);
drawCommand.func = CC_CALLBACK_0(SkeletonRenderer::drawSkeleton, this, transform, transformUpdated); _drawCommand.func = CC_CALLBACK_0(SkeletonRenderer::drawSkeleton, this, transform, transformFlags);
renderer->addCommand(&drawCommand); renderer->addCommand(&_drawCommand);
} }
void SkeletonRenderer::drawSkeleton (const Mat4 &transform, bool transformUpdated) { void SkeletonRenderer::drawSkeleton (const Mat4 &transform, uint32_t transformFlags) {
getGLProgram()->use();
getGLProgram()->setUniformsForBuiltins(transform); getGLProgramState()->apply(transform);
GL::bindVAO(0);
Color3B nodeColor = getColor(); Color3B nodeColor = getColor();
skeleton->r = nodeColor.r / (float)255; _skeleton->r = nodeColor.r / (float)255;
skeleton->g = nodeColor.g / (float)255; _skeleton->g = nodeColor.g / (float)255;
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 additive = -1;
Color4B color; Color4B color;
@ -157,14 +156,14 @@ void SkeletonRenderer::drawSkeleton (const Mat4 &transform, bool transformUpdate
const int* triangles = nullptr; const int* triangles = nullptr;
int trianglesCount = 0; int trianglesCount = 0;
float r = 0, g = 0, b = 0, a = 0; float r = 0, g = 0, b = 0, a = 0;
for (int i = 0, n = skeleton->slotCount; i < n; i++) { for (int i = 0, n = _skeleton->slotCount; i < n; i++) {
spSlot* slot = skeleton->drawOrder[i]; spSlot* slot = _skeleton->drawOrder[i];
if (!slot->attachment) continue; if (!slot->attachment) continue;
Texture2D *texture = nullptr; Texture2D *texture = nullptr;
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->skeleton->x, slot->skeleton->y, slot->bone, worldVertices); spRegionAttachment_computeWorldVertices(attachment, slot->skeleton->x, slot->skeleton->y, slot->bone, _worldVertices);
texture = getTexture(attachment); texture = getTexture(attachment);
uvs = attachment->uvs; uvs = attachment->uvs;
verticesCount = 8; verticesCount = 8;
@ -178,7 +177,7 @@ void SkeletonRenderer::drawSkeleton (const Mat4 &transform, bool transformUpdate
} }
case SP_ATTACHMENT_MESH: { case SP_ATTACHMENT_MESH: {
spMeshAttachment* attachment = (spMeshAttachment*)slot->attachment; spMeshAttachment* attachment = (spMeshAttachment*)slot->attachment;
spMeshAttachment_computeWorldVertices(attachment, slot->skeleton->x, slot->skeleton->y, slot, worldVertices); spMeshAttachment_computeWorldVertices(attachment, slot->skeleton->x, slot->skeleton->y, slot, _worldVertices);
texture = getTexture(attachment); texture = getTexture(attachment);
uvs = attachment->uvs; uvs = attachment->uvs;
verticesCount = attachment->verticesCount; verticesCount = attachment->verticesCount;
@ -192,7 +191,7 @@ void SkeletonRenderer::drawSkeleton (const Mat4 &transform, bool transformUpdate
} }
case SP_ATTACHMENT_SKINNED_MESH: { case SP_ATTACHMENT_SKINNED_MESH: {
spSkinnedMeshAttachment* attachment = (spSkinnedMeshAttachment*)slot->attachment; spSkinnedMeshAttachment* attachment = (spSkinnedMeshAttachment*)slot->attachment;
spSkinnedMeshAttachment_computeWorldVertices(attachment, slot->skeleton->x, slot->skeleton->y, slot, worldVertices); spSkinnedMeshAttachment_computeWorldVertices(attachment, slot->skeleton->x, slot->skeleton->y, slot, _worldVertices);
texture = getTexture(attachment); texture = getTexture(attachment);
uvs = attachment->uvs; uvs = attachment->uvs;
verticesCount = attachment->uvsCount; verticesCount = attachment->uvsCount;
@ -208,49 +207,49 @@ void SkeletonRenderer::drawSkeleton (const Mat4 &transform, bool transformUpdate
} }
if (texture) { if (texture) {
if (slot->data->additiveBlending != additive) { if (slot->data->additiveBlending != additive) {
batch->flush(); _batch->flush();
GL::blendFunc(blendFunc.src, slot->data->additiveBlending ? GL_ONE : blendFunc.dst); GL::blendFunc(_blendFunc.src, slot->data->additiveBlending ? GL_ONE : _blendFunc.dst);
additive = slot->data->additiveBlending; additive = slot->data->additiveBlending;
} }
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;
color.r = skeleton->r * slot->r * r * multiplier; color.r = _skeleton->r * slot->r * r * multiplier;
color.g = skeleton->g * slot->g * g * multiplier; color.g = _skeleton->g * slot->g * g * multiplier;
color.b = skeleton->b * slot->b * b * multiplier; color.b = _skeleton->b * slot->b * b * multiplier;
batch->add(texture, worldVertices, uvs, verticesCount, triangles, trianglesCount, &color); _batch->add(texture, _worldVertices, uvs, verticesCount, triangles, trianglesCount, &color);
} }
} }
batch->flush(); _batch->flush();
if (debugSlots || debugBones) { if (_debugSlots || _debugBones) {
Director* director = Director::getInstance(); Director* director = Director::getInstance();
director->pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW); director->pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
director->loadMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW, transform); director->loadMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW, transform);
if (debugSlots) { if (_debugSlots) {
// Slots. // Slots.
DrawPrimitives::setDrawColor4B(0, 0, 255, 255); DrawPrimitives::setDrawColor4B(0, 0, 255, 255);
glLineWidth(1); glLineWidth(1);
Vec2 points[4]; Vec2 points[4];
V3F_C4B_T2F_Quad quad; V3F_C4B_T2F_Quad quad;
for (int i = 0, n = skeleton->slotCount; i < n; i++) { for (int i = 0, n = _skeleton->slotCount; i < n; i++) {
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->skeleton->x, slot->skeleton->y, slot->bone, worldVertices); spRegionAttachment_computeWorldVertices(attachment, slot->skeleton->x, slot->skeleton->y, slot->bone, _worldVertices);
points[0] = Vec2(worldVertices[0], worldVertices[1]); points[0] = Vec2(_worldVertices[0], _worldVertices[1]);
points[1] = Vec2(worldVertices[2], worldVertices[3]); points[1] = Vec2(_worldVertices[2], _worldVertices[3]);
points[2] = Vec2(worldVertices[4], worldVertices[5]); points[2] = Vec2(_worldVertices[4], _worldVertices[5]);
points[3] = Vec2(worldVertices[6], worldVertices[7]); points[3] = Vec2(_worldVertices[6], _worldVertices[7]);
DrawPrimitives::drawPoly(points, 4, true); DrawPrimitives::drawPoly(points, 4, true);
} }
} }
if (debugBones) { if (_debugBones) {
// Bone lengths. // Bone lengths.
glLineWidth(2); glLineWidth(2);
DrawPrimitives::setDrawColor4B(255, 0, 0, 255); DrawPrimitives::setDrawColor4B(255, 0, 0, 255);
for (int i = 0, n = skeleton->boneCount; i < n; i++) { for (int i = 0, n = _skeleton->boneCount; i < n; i++) {
spBone *bone = skeleton->bones[i]; spBone *bone = _skeleton->bones[i];
float x = bone->data->length * bone->m00 + bone->worldX; float x = bone->data->length * bone->m00 + bone->worldX;
float y = bone->data->length * bone->m10 + bone->worldY; float y = bone->data->length * bone->m10 + bone->worldY;
DrawPrimitives::drawLine(Vec2(bone->worldX, bone->worldY), Vec2(x, y)); DrawPrimitives::drawLine(Vec2(bone->worldX, bone->worldY), Vec2(x, y));
@ -258,8 +257,8 @@ void SkeletonRenderer::drawSkeleton (const Mat4 &transform, bool transformUpdate
// Bone origins. // Bone origins.
DrawPrimitives::setPointSize(4); DrawPrimitives::setPointSize(4);
DrawPrimitives::setDrawColor4B(0, 0, 255, 255); // Root bone is blue. DrawPrimitives::setDrawColor4B(0, 0, 255, 255); // Root bone is blue.
for (int i = 0, n = skeleton->boneCount; i < n; i++) { for (int i = 0, n = _skeleton->boneCount; i < n; i++) {
spBone *bone = skeleton->bones[i]; spBone *bone = _skeleton->bones[i];
DrawPrimitives::drawPoint(Vec2(bone->worldX, bone->worldY)); DrawPrimitives::drawPoint(Vec2(bone->worldX, bone->worldY));
if (i == 0) DrawPrimitives::setDrawColor4B(0, 255, 0, 255); if (i == 0) DrawPrimitives::setDrawColor4B(0, 255, 0, 255);
} }
@ -283,26 +282,26 @@ Texture2D* SkeletonRenderer::getTexture (spSkinnedMeshAttachment* attachment) co
Rect SkeletonRenderer::getBoundingBox () const { Rect SkeletonRenderer::getBoundingBox () const {
float minX = FLT_MAX, minY = FLT_MAX, maxX = FLT_MIN, maxY = FLT_MIN; float minX = FLT_MAX, minY = FLT_MAX, maxX = FLT_MIN, maxY = FLT_MIN;
float scaleX = getScaleX(), scaleY = getScaleY(); float scaleX = getScaleX(), scaleY = getScaleY();
for (int i = 0; i < skeleton->slotCount; ++i) { for (int i = 0; i < _skeleton->slotCount; ++i) {
spSlot* slot = skeleton->slots[i]; spSlot* slot = _skeleton->slots[i];
if (!slot->attachment) continue; if (!slot->attachment) continue;
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->skeleton->x, slot->skeleton->y, slot->bone, worldVertices); spRegionAttachment_computeWorldVertices(attachment, slot->skeleton->x, slot->skeleton->y, 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->skeleton->x, slot->skeleton->y, slot, worldVertices); spMeshAttachment_computeWorldVertices(mesh, slot->skeleton->x, slot->skeleton->y, 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->skeleton->x, slot->skeleton->y, slot, worldVertices); spSkinnedMeshAttachment_computeWorldVertices(mesh, slot->skeleton->x, slot->skeleton->y, 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 = min(minX, x); minX = min(minX, x);
minY = min(minY, y); minY = min(minY, y);
maxX = max(maxX, x); maxX = max(maxX, x);
@ -316,54 +315,54 @@ Rect SkeletonRenderer::getBoundingBox () const {
// --- Convenience methods for Skeleton_* functions. // --- Convenience methods for Skeleton_* functions.
void SkeletonRenderer::updateWorldTransform () { void SkeletonRenderer::updateWorldTransform () {
spSkeleton_updateWorldTransform(skeleton); spSkeleton_updateWorldTransform(_skeleton);
} }
void SkeletonRenderer::setToSetupPose () { void SkeletonRenderer::setToSetupPose () {
spSkeleton_setToSetupPose(skeleton); spSkeleton_setToSetupPose(_skeleton);
} }
void SkeletonRenderer::setBonesToSetupPose () { void SkeletonRenderer::setBonesToSetupPose () {
spSkeleton_setBonesToSetupPose(skeleton); spSkeleton_setBonesToSetupPose(_skeleton);
} }
void SkeletonRenderer::setSlotsToSetupPose () { void SkeletonRenderer::setSlotsToSetupPose () {
spSkeleton_setSlotsToSetupPose(skeleton); spSkeleton_setSlotsToSetupPose(_skeleton);
} }
spBone* SkeletonRenderer::findBone (const char* boneName) const { spBone* SkeletonRenderer::findBone (const std::string& boneName) const {
return spSkeleton_findBone(skeleton, boneName); return spSkeleton_findBone(_skeleton, boneName.c_str());
} }
spSlot* SkeletonRenderer::findSlot (const char* slotName) const { spSlot* SkeletonRenderer::findSlot (const std::string& slotName) const {
return spSkeleton_findSlot(skeleton, slotName); return spSkeleton_findSlot(_skeleton, slotName.c_str());
} }
bool SkeletonRenderer::setSkin (const char* skinName) { bool SkeletonRenderer::setSkin (const std::string& skinName) {
return spSkeleton_setSkinByName(skeleton, skinName) ? true : false; return spSkeleton_setSkinByName(_skeleton, skinName.c_str()) ? true : false;
} }
spAttachment* SkeletonRenderer::getAttachment (const char* slotName, const char* attachmentName) const { spAttachment* SkeletonRenderer::getAttachment (const std::string& slotName, const std::string& attachmentName) const {
return spSkeleton_getAttachmentForSlotName(skeleton, slotName, attachmentName); return spSkeleton_getAttachmentForSlotName(_skeleton, slotName.c_str(), attachmentName.c_str());
} }
bool SkeletonRenderer::setAttachment (const char* slotName, const char* attachmentName) { bool SkeletonRenderer::setAttachment (const std::string& slotName, const std::string& attachmentName) {
return spSkeleton_setAttachment(skeleton, slotName, attachmentName) ? true : false; return spSkeleton_setAttachment(_skeleton, slotName.c_str(), attachmentName.c_str()) ? true : false;
} }
// --- CCBlendProtocol // --- CCBlendProtocol
const BlendFunc& SkeletonRenderer::getBlendFunc () const { const BlendFunc& SkeletonRenderer::getBlendFunc () const {
return blendFunc; return _blendFunc;
} }
void SkeletonRenderer::setBlendFunc (const BlendFunc &blendFunc) { void SkeletonRenderer::setBlendFunc (const BlendFunc &blendFunc) {
this->blendFunc = blendFunc; _blendFunc = blendFunc;
} }
void SkeletonRenderer::setOpacityModifyRGB (bool value) { void SkeletonRenderer::setOpacityModifyRGB (bool value) {
premultipliedAlpha = value; _premultipliedAlpha = value;
} }
bool SkeletonRenderer::isOpacityModifyRGB () { bool SkeletonRenderer::isOpacityModifyRGB () const {
return premultipliedAlpha; return _premultipliedAlpha;
} }
} }

View File

@ -41,26 +41,13 @@ class PolygonBatch;
/** Draws a skeleton. */ /** Draws a skeleton. */
class SkeletonRenderer: public cocos2d::Node, public cocos2d::BlendProtocol { class SkeletonRenderer: public cocos2d::Node, public cocos2d::BlendProtocol {
public: public:
spSkeleton* skeleton;
spBone* rootBone;
float timeScale;
bool debugSlots;
bool debugBones;
bool premultipliedAlpha;
static SkeletonRenderer* createWithData (spSkeletonData* skeletonData, bool ownsSkeletonData = false); static SkeletonRenderer* createWithData (spSkeletonData* skeletonData, bool ownsSkeletonData = false);
static SkeletonRenderer* createWithFile (const char* skeletonDataFile, spAtlas* atlas, float scale = 0); static SkeletonRenderer* createWithFile (const std::string& skeletonDataFile, spAtlas* atlas, float scale = 0);
static SkeletonRenderer* createWithFile (const char* skeletonDataFile, const char* atlasFile, float scale = 0); static SkeletonRenderer* createWithFile (const std::string& skeletonDataFile, const std::string& atlasFile, float scale = 0);
SkeletonRenderer (spSkeletonData* skeletonData, bool ownsSkeletonData = false);
SkeletonRenderer (const char* skeletonDataFile, spAtlas* atlas, float scale = 0);
SkeletonRenderer (const char* skeletonDataFile, const char* atlasFile, float scale = 0);
virtual ~SkeletonRenderer ();
virtual void update (float deltaTime) override; virtual void update (float deltaTime) override;
virtual void draw (cocos2d::Renderer* renderer, const cocos2d::Mat4& transform, bool transformUpdated) override; virtual void draw (cocos2d::Renderer* renderer, const cocos2d::Mat4& transform, uint32_t transformFlags) override;
virtual void drawSkeleton (const cocos2d::Mat4& transform, bool transformUpdated); virtual void drawSkeleton (const cocos2d::Mat4& transform, uint32_t transformFlags);
virtual cocos2d::Rect getBoundingBox () const override; virtual cocos2d::Rect getBoundingBox () const override;
// --- Convenience methods for common Skeleton_* functions. // --- Convenience methods for common Skeleton_* functions.
@ -71,41 +58,51 @@ public:
void setSlotsToSetupPose (); void setSlotsToSetupPose ();
/* Returns 0 if the bone was not found. */ /* Returns 0 if the bone was not found. */
spBone* findBone (const char* boneName) const; spBone* findBone (const std::string& boneName) const;
/* Returns 0 if the slot was not found. */ /* Returns 0 if the slot was not found. */
spSlot* findSlot (const char* slotName) const; spSlot* findSlot (const std::string& slotName) const;
/* Sets the skin used to look up attachments not found in the SkeletonData defaultSkin. Attachments from the new skin are /* Sets the skin used to look up attachments not found in the SkeletonData defaultSkin. Attachments from the new skin are
* attached if the corresponding attachment from the old skin was attached. Returns false if the skin was not found. * attached if the corresponding attachment from the old skin was attached. Returns false if the skin was not found.
* @param skin May be 0.*/ * @param skin May be 0.*/
bool setSkin (const char* skinName); bool setSkin (const std::string& skinName);
/* Returns 0 if the slot or attachment was not found. */ /* Returns 0 if the slot or attachment was not found. */
spAttachment* getAttachment (const char* slotName, const char* attachmentName) const; spAttachment* getAttachment (const std::string& slotName, const std::string& attachmentName) const;
/* Returns false if the slot or attachment was not found. */ /* Returns false if the slot or attachment was not found. */
bool setAttachment (const char* slotName, const char* attachmentName); bool setAttachment (const std::string& slotName, const std::string& attachmentName);
// --- BlendProtocol // --- BlendProtocol
virtual void setBlendFunc (const cocos2d::BlendFunc& blendFunc); virtual void setBlendFunc (const cocos2d::BlendFunc& blendFunc);
virtual const cocos2d::BlendFunc& getBlendFunc () const; virtual const cocos2d::BlendFunc& getBlendFunc () const;
virtual void setOpacityModifyRGB (bool value); virtual void setOpacityModifyRGB (bool value);
virtual bool isOpacityModifyRGB (); virtual bool isOpacityModifyRGB () const;
protected: protected:
SkeletonRenderer (); SkeletonRenderer ();
SkeletonRenderer (spSkeletonData* skeletonData, bool ownsSkeletonData = false);
SkeletonRenderer (const std::string& skeletonDataFile, spAtlas* atlas, float scale = 0);
SkeletonRenderer (const std::string& skeletonDataFile, const std::string& atlasFile, float scale = 0);
virtual ~SkeletonRenderer ();
void initialize ();
void setSkeletonData (spSkeletonData* skeletonData, bool ownsSkeletonData); void setSkeletonData (spSkeletonData* skeletonData, bool ownsSkeletonData);
virtual cocos2d::Texture2D* getTexture (spRegionAttachment* attachment) const; virtual cocos2d::Texture2D* getTexture (spRegionAttachment* attachment) const;
virtual cocos2d::Texture2D* getTexture (spMeshAttachment* attachment) const; virtual cocos2d::Texture2D* getTexture (spMeshAttachment* attachment) const;
virtual cocos2d::Texture2D* getTexture (spSkinnedMeshAttachment* attachment) const; virtual cocos2d::Texture2D* getTexture (spSkinnedMeshAttachment* attachment) const;
private: bool _ownsSkeletonData;
bool ownsSkeletonData; spAtlas* _atlas;
spAtlas* atlas; cocos2d::CustomCommand _drawCommand;
cocos2d::CustomCommand drawCommand; cocos2d::BlendFunc _blendFunc;
cocos2d::BlendFunc blendFunc; PolygonBatch* _batch;
PolygonBatch* batch; float* _worldVertices;
float* worldVertices; bool _premultipliedAlpha;
void initialize (); spSkeleton* _skeleton;
spBone* _rootBone;
float _timeScale;
bool _debugSlots;
bool _debugBones;
}; };
} }