diff --git a/spine-cocos2dx/example/Classes/BatchingExample.cpp b/spine-cocos2dx/example/Classes/BatchingExample.cpp index b2f09a78d..c85940888 100644 --- a/spine-cocos2dx/example/Classes/BatchingExample.cpp +++ b/spine-cocos2dx/example/Classes/BatchingExample.cpp @@ -48,7 +48,7 @@ bool BatchingExample::init () { // Load the texture atlas. Note that the texture loader has to live // as long as the Atlas, as the Atlas destructor will call TextureLoader::unload. - _atlas = new (__FILE__, __LINE__) Atlas("spineboy.atlas", &textureLoader); + _atlas = new (__FILE__, __LINE__) Atlas("spineboy.atlas", &textureLoader, true); CCASSERT(_atlas, "Error reading atlas file."); // This attachment loader configures attachments with data needed for cocos2d-x rendering. diff --git a/spine-cocos2dx/example/proj.win32/spine-cocos2d-x.vcxproj b/spine-cocos2dx/example/proj.win32/spine-cocos2d-x.vcxproj index 1314cb9bc..84a8d56b8 100644 --- a/spine-cocos2dx/example/proj.win32/spine-cocos2d-x.vcxproj +++ b/spine-cocos2dx/example/proj.win32/spine-cocos2d-x.vcxproj @@ -19,7 +19,7 @@ Application Unicode - true + false v120 v120_xp v140 @@ -109,7 +109,7 @@ xcopy "$(ProjectDir)..\Resources" "$(OutDir)" /D /E /I /F /Y MaxSpeed true - $(EngineRoot)external;$(EngineRoot)cocos\audio\include;$(EngineRoot)external\chipmunk\include\chipmunk;$(EngineRoot)extensions;..\Classes;..;%(AdditionalIncludeDirectories);$(_COCOS_HEADER_WIN32_BEGIN);$(_COCOS_HEADER_WIN32_END) + $(EngineRoot)external;$(EngineRoot)cocos\audio\include;$(EngineRoot)external\chipmunk\include\chipmunk;$(EngineRoot)extensions;..\Classes;..;%(AdditionalIncludeDirectories);$(_COCOS_HEADER_WIN32_BEGIN);$(_COCOS_HEADER_WIN32_END);$(SolutionDir)..\..\..\spine-cpp\spine-cpp\include;$(SolutionDir)..\..\src;$(IncludePath) WIN32;NDEBUG;_WINDOWS;_USE_MATH_DEFINES;GL_GLEXT_PROTOTYPES;CC_ENABLE_CHIPMUNK_INTEGRATION=1;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) MultiThreadedDLL true @@ -121,7 +121,7 @@ xcopy "$(ProjectDir)..\Resources" "$(OutDir)" /D /E /I /F /Y true - libcurl_imp.lib;websockets.lib;%(AdditionalDependencies);$(_COCOS_LIB_WIN32_BEGIN);$(_COCOS_LIB_WIN32_END) + %(AdditionalDependencies);$(_COCOS_LIB_WIN32_BEGIN);$(_COCOS_LIB_WIN32_END) $(OutDir)$(ProjectName).exe $(OutDir);%(AdditionalLibraryDirectories);$(_COCOS_LIB_PATH_WIN32_BEGIN);$(_COCOS_LIB_PATH_WIN32_END) true diff --git a/spine-cocos2dx/src/spine/SkeletonAnimation.cpp b/spine-cocos2dx/src/spine/SkeletonAnimation.cpp index 36dca2876..621aff760 100644 --- a/spine-cocos2dx/src/spine/SkeletonAnimation.cpp +++ b/spine-cocos2dx/src/spine/SkeletonAnimation.cpp @@ -108,6 +108,7 @@ void SkeletonAnimation::initialize () { super::initialize(); _ownsAnimationStateData = true; + _updateOnlyIfVisible = false; _state = new (__FILE__, __LINE__) AnimationState(new (__FILE__, __LINE__) AnimationStateData(_skeleton->getData())); _state->setRendererObject(this); _state->setListener(animationCallback); @@ -125,6 +126,8 @@ SkeletonAnimation::~SkeletonAnimation () { } void SkeletonAnimation::update (float deltaTime) { + if (_updateOnlyIfVisible && (isAutoCulled() || !isVisible())) return; + super::update(deltaTime); deltaTime *= _timeScale; @@ -303,4 +306,8 @@ AnimationState* SkeletonAnimation::getState() const { return _state; } +void SkeletonAnimation::setUpdateOnlyIfVisible(bool status) { + _updateOnlyIfVisible = status; +} + } diff --git a/spine-cocos2dx/src/spine/SkeletonAnimation.h b/spine-cocos2dx/src/spine/SkeletonAnimation.h index b0d47fec7..7db3dfba1 100644 --- a/spine-cocos2dx/src/spine/SkeletonAnimation.h +++ b/spine-cocos2dx/src/spine/SkeletonAnimation.h @@ -99,6 +99,7 @@ public: virtual void onTrackEntryEvent (TrackEntry* entry, EventType type, Event* event); AnimationState* getState() const; + void setUpdateOnlyIfVisible(bool status); CC_CONSTRUCTOR_ACCESS: SkeletonAnimation (); @@ -109,6 +110,7 @@ protected: AnimationState* _state; bool _ownsAnimationStateData; + bool _updateOnlyIfVisible; bool _firstDraw; StartListener _startListener; diff --git a/spine-cocos2dx/src/spine/SkeletonRenderer.cpp b/spine-cocos2dx/src/spine/SkeletonRenderer.cpp index 154400149..ca33120ab 100644 --- a/spine-cocos2dx/src/spine/SkeletonRenderer.cpp +++ b/spine-cocos2dx/src/spine/SkeletonRenderer.cpp @@ -198,7 +198,7 @@ void SkeletonRenderer::initWithJsonFile (const std::string& skeletonDataFile, At } void SkeletonRenderer::initWithJsonFile (const std::string& skeletonDataFile, const std::string& atlasFile, float scale) { - _atlas = new (__FILE__, __LINE__) Atlas(atlasFile.c_str(), &textureLoader); + _atlas = new (__FILE__, __LINE__) Atlas(atlasFile.c_str(), &textureLoader, true); CCASSERT(_atlas, "Error reading atlas file."); _attachmentLoader = new (__FILE__, __LINE__) Cocos2dAtlasAttachmentLoader(_atlas); @@ -230,7 +230,7 @@ void SkeletonRenderer::initWithBinaryFile (const std::string& skeletonDataFile, } void SkeletonRenderer::initWithBinaryFile (const std::string& skeletonDataFile, const std::string& atlasFile, float scale) { - _atlas = new (__FILE__, __LINE__) Atlas(atlasFile.c_str(), &textureLoader); + _atlas = new (__FILE__, __LINE__) Atlas(atlasFile.c_str(), &textureLoader, true); CCASSERT(_atlas, "Error reading atlas file."); _attachmentLoader = new (__FILE__, __LINE__) Cocos2dAtlasAttachmentLoader(_atlas); @@ -253,9 +253,10 @@ void SkeletonRenderer::update (float deltaTime) { } void SkeletonRenderer::draw (Renderer* renderer, const Mat4& transform, uint32_t transformFlags) { + _isAutoCulled = false; // Early exit if the skeleton is invisible if (getDisplayedOpacity() == 0 || _skeleton->getColor().a == 0){ - return; + return; } const int coordCount = computeTotalCoordCount(*_skeleton, _startSlotIndex, _endSlotIndex); @@ -272,11 +273,14 @@ void SkeletonRenderer::draw (Renderer* renderer, const Mat4& transform, uint32_t const Camera* camera = Camera::getVisitingCamera(); const cocos2d::Rect brect = computeBoundingRect(worldCoords, coordCount / 2); _boundingRect = brect; - if (camera && cullRectangle(transform, brect, *camera)) - { + + const bool autoCullingEnable = cocos2d::Director::getInstance()->isAutoCullingEnable(); + if (autoCullingEnable && camera && cullRectangle(transform, brect, *camera)) + { VLA_FREE(worldCoords); + _isAutoCulled = true; return; - } + } #endif const float* worldCoordPtr = worldCoords; @@ -583,7 +587,7 @@ void SkeletonRenderer::draw (Renderer* renderer, const Mat4& transform, uint32_t if (!parent || parent->getChildrenCount() > 100 || getChildrenCount() != 0) { lastTwoColorTrianglesCommand->setForceFlush(true); } else { - const cocos2d::Vector& children = parent->getChildren(); + const cocos2d::Vector& children = parent->getChildren(); Node* sibling = nullptr; for (ssize_t i = 0; i < children.size(); i++) { if (children.at(i) == this) { @@ -617,6 +621,10 @@ void SkeletonRenderer::draw (Renderer* renderer, const Mat4& transform, uint32_t } +bool SkeletonRenderer::isAutoCulled () const { + return _isAutoCulled; +} + void SkeletonRenderer::drawDebug (Renderer* renderer, const Mat4 &transform, uint32_t transformFlags) { #if !defined(USE_MATRIX_STACK_PROJECTION_ONLY) diff --git a/spine-cocos2dx/src/spine/SkeletonRenderer.h b/spine-cocos2dx/src/spine/SkeletonRenderer.h index 99c8b1eb6..39811c045 100644 --- a/spine-cocos2dx/src/spine/SkeletonRenderer.h +++ b/spine-cocos2dx/src/spine/SkeletonRenderer.h @@ -48,7 +48,7 @@ namespace spine { void update (float deltaTime) override; void draw (cocos2d::Renderer* renderer, const cocos2d::Mat4& transform, uint32_t transformFlags) override; - //virtual bool isAutoCulled () const override; + bool isAutoCulled () const override; cocos2d::Rect getBoundingBox () const override; void onEnter () override; void onExit () override; @@ -158,6 +158,7 @@ namespace spine { int _startSlotIndex; int _endSlotIndex; + bool _isAutoCulled = false; }; } diff --git a/spine-cpp/spine-cpp/include/spine/Atlas.h b/spine-cpp/spine-cpp/include/spine/Atlas.h index d73bcdded..2733b1fc5 100644 --- a/spine-cpp/spine-cpp/include/spine/Atlas.h +++ b/spine-cpp/spine-cpp/include/spine/Atlas.h @@ -67,6 +67,7 @@ enum TextureWrap { class SP_API AtlasPage : public SpineObject, public HasRendererObject { public: String name; + String texturePath; Format format; TextureFilter minFilter; TextureFilter magFilter; @@ -100,9 +101,9 @@ class TextureLoader; class SP_API Atlas : public SpineObject { public: - Atlas(const String &path, TextureLoader *textureLoader); + Atlas(const String &path, TextureLoader *textureLoader, bool createTexture); - Atlas(const char *data, int length, const char *dir, TextureLoader *textureLoader); + Atlas(const char *data, int length, const char *dir, TextureLoader *textureLoader, bool createTexture); ~Atlas(); @@ -120,7 +121,7 @@ private: Vector _regions; TextureLoader *_textureLoader; - void load(const char *begin, int length, const char *dir); + void load(const char *begin, int length, const char *dir, bool createTexture); class Str { public: diff --git a/spine-cpp/spine-cpp/src/spine/Atlas.cpp b/spine-cpp/spine-cpp/src/spine/Atlas.cpp index 99de2dc8f..9eac5e3cf 100644 --- a/spine-cpp/spine-cpp/src/spine/Atlas.cpp +++ b/spine-cpp/spine-cpp/src/spine/Atlas.cpp @@ -39,7 +39,7 @@ using namespace spine; -Atlas::Atlas(const String &path, TextureLoader *textureLoader) : _textureLoader(textureLoader) { +Atlas::Atlas(const String &path, TextureLoader *textureLoader, bool createTexture) : _textureLoader(textureLoader) { int dirLength; char *dir; int length; @@ -57,16 +57,16 @@ Atlas::Atlas(const String &path, TextureLoader *textureLoader) : _textureLoader( data = SpineExtension::readFile(path, &length); if (data) { - load(data, length, dir); + load(data, length, dir, createTexture); } SpineExtension::free(data, __FILE__, __LINE__); SpineExtension::free(dir, __FILE__, __LINE__); } -Atlas::Atlas(const char *data, int length, const char *dir, TextureLoader *textureLoader) : _textureLoader( +Atlas::Atlas(const char *data, int length, const char *dir, TextureLoader *textureLoader, bool createTexture) : _textureLoader( textureLoader) { - load(data, length, dir); + load(data, length, dir, createTexture); } Atlas::~Atlas() { @@ -102,7 +102,7 @@ Vector &Atlas::getPages() { return _pages; } -void Atlas::load(const char *begin, int length, const char *dir) { +void Atlas::load(const char *begin, int length, const char *dir, bool createTexture) { static const char *formatNames[] = {"", "Alpha", "Intensity", "LuminanceAlpha", "RGB565", "RGBA4444", "RGB888", "RGBA8888"}; static const char *textureFilterNames[] = {"", "Nearest", "Linear", "MipMap", "MipMapNearestNearest", @@ -163,9 +163,15 @@ void Atlas::load(const char *begin, int length, const char *dir) { } } - if (_textureLoader) _textureLoader->load(*page, String(path)); - - SpineExtension::free(path, __FILE__, __LINE__); + if (createTexture) + { + if (_textureLoader) _textureLoader->load(*page, String(path)); + SpineExtension::free(path, __FILE__, __LINE__); + } + else + { + page->texturePath = String(path, true); + } _pages.add(page); } else {