diff --git a/cocos/base/CCDirector.cpp b/cocos/base/CCDirector.cpp index 11d9e407a1..791482c1b8 100644 --- a/cocos/base/CCDirector.cpp +++ b/cocos/base/CCDirector.cpp @@ -1225,71 +1225,6 @@ void Director::setEventDispatcher(EventDispatcher* dispatcher) } } -void Director::captureScreen(const std::function& afterCaptured, const std::string& filename) -{ - _captureScreenCommand.init(std::numeric_limits::max()); - _captureScreenCommand.func = CC_CALLBACK_0(Director::onCaptureScreen, this, afterCaptured, filename); - Director::getInstance()->getRenderer()->addCommand(&_captureScreenCommand); -} - -void Director::onCaptureScreen(const std::function& afterCaptured, const std::string& filename) -{ - Size frameSize = _openGLView->getFrameSize(); -#if (CC_TARGET_PLATFORM == CC_PLATFORM_MAC) || (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) || (CC_TARGET_PLATFORM == CC_PLATFORM_LINUX) - frameSize = frameSize * _openGLView->getFrameZoomFactor() * _openGLView->getRetinaFactor(); -#endif - - int width = static_cast(frameSize.width); - int height = static_cast(frameSize.height); - - bool succeed = false; - std::string outputFile = ""; - - do - { - std::shared_ptr buffer(new GLubyte[width * height * 4], [](GLubyte* p){ CC_SAFE_DELETE_ARRAY(p); }); - if (!buffer) - { - break; - } - - glPixelStorei(GL_PACK_ALIGNMENT, 1); - glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer.get()); - - std::shared_ptr flippedBuffer(new GLubyte[width * height * 4], [](GLubyte* p) { CC_SAFE_DELETE_ARRAY(p); }); - if (!flippedBuffer) - { - break; - } - - for (int row = 0; row < height; ++row) - { - memcpy(flippedBuffer.get() + (height - row - 1) * width * 4, buffer.get() + row * width * 4, width * 4); - } - - std::shared_ptr image(new Image); - if (image) - { - image->initWithRawData(flippedBuffer.get(), width * height * 4, width, height, 8); - if (FileUtils::getInstance()->isAbsolutePath(filename)) - { - outputFile = filename; - } - else - { - CCASSERT(filename.find("/") == std::string::npos, "The existence of a relative path is not guaranteed!"); - outputFile = FileUtils::getInstance()->getWritablePath() + filename; - } - succeed = image->saveToFile(outputFile); - } - }while(0); - - if (afterCaptured) - { - afterCaptured(succeed, outputFile); - } -} - /*************************************************** * implementation of DisplayLinkDirector **************************************************/ diff --git a/cocos/base/CCDirector.h b/cocos/base/CCDirector.h index e5858b32ff..902cce2bd4 100644 --- a/cocos/base/CCDirector.h +++ b/cocos/base/CCDirector.h @@ -404,11 +404,6 @@ public: * get Frame Rate */ float getFrameRate() const { return _frameRate; } - - /** - * Capture screen - */ - void captureScreen(const std::function& afterCaptued, const std::string& filename); protected: void purgeDirector(); @@ -427,9 +422,6 @@ protected: //textureCache creation or release void initTextureCache(); void destroyTextureCache(); - - /* Captrue screen implementation */ - void onCaptureScreen(const std::function& afterCaptued, const std::string& fileanme); /** Scheduler associated with this director @since v2.0 diff --git a/cocos/base/ccUtils.cpp b/cocos/base/ccUtils.cpp index f907513a5a..2fecd38428 100644 --- a/cocos/base/ccUtils.cpp +++ b/cocos/base/ccUtils.cpp @@ -24,6 +24,12 @@ THE SOFTWARE. ****************************************************************************/ #include "base/ccUtils.h" +#include "base/CCDirector.h" +#include "renderer/CCCustomCommand.h" +#include "renderer/CCRenderer.h" +#include "platform/CCImage.h" +#include "platform/CCFileUtils.h" +#include "CCGLView.h" NS_CC_BEGIN @@ -38,4 +44,74 @@ int ccNextPOT(int x) return x + 1; } +namespace Utilities +{ +void captureScreen(const std::function& afterCaptured, const std::string& filename) +{ + static CustomCommand captureScreenCommand; + captureScreenCommand.init(std::numeric_limits::max()); + captureScreenCommand.func = std::bind(onCaptureScreen, afterCaptured, filename); + Director::getInstance()->getRenderer()->addCommand(&captureScreenCommand); +} + +void onCaptureScreen(const std::function& afterCaptured, const std::string& filename) +{ + auto glView = Director::getInstance()->getOpenGLView(); + auto frameSize = glView->getFrameSize(); +#if (CC_TARGET_PLATFORM == CC_PLATFORM_MAC) || (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) || (CC_TARGET_PLATFORM == CC_PLATFORM_LINUX) + frameSize = frameSize * glView->getFrameZoomFactor() * glView->getRetinaFactor(); +#endif + + int width = static_cast(frameSize.width); + int height = static_cast(frameSize.height); + + bool succeed = false; + std::string outputFile = ""; + + do + { + std::shared_ptr buffer(new GLubyte[width * height * 4], [](GLubyte* p){ CC_SAFE_DELETE_ARRAY(p); }); + if (!buffer) + { + break; + } + + glPixelStorei(GL_PACK_ALIGNMENT, 1); + glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer.get()); + + std::shared_ptr flippedBuffer(new GLubyte[width * height * 4], [](GLubyte* p) { CC_SAFE_DELETE_ARRAY(p); }); + if (!flippedBuffer) + { + break; + } + + for (int row = 0; row < height; ++row) + { + memcpy(flippedBuffer.get() + (height - row - 1) * width * 4, buffer.get() + row * width * 4, width * 4); + } + + std::shared_ptr image(new Image); + if (image) + { + image->initWithRawData(flippedBuffer.get(), width * height * 4, width, height, 8); + if (FileUtils::getInstance()->isAbsolutePath(filename)) + { + outputFile = filename; + } + else + { + CCASSERT(filename.find("/") == std::string::npos, "The existence of a relative path is not guaranteed!"); + outputFile = FileUtils::getInstance()->getWritablePath() + filename; + } + succeed = image->saveToFile(outputFile); + } + }while(0); + + if (afterCaptured) + { + afterCaptured(succeed, outputFile); + } +} +} + NS_CC_END diff --git a/cocos/base/ccUtils.h b/cocos/base/ccUtils.h index e9fa7fc716..0c35c9181a 100644 --- a/cocos/base/ccUtils.h +++ b/cocos/base/ccUtils.h @@ -47,7 +47,19 @@ Examples: int ccNextPOT(int value); +namespace Utilities +{ + /** + * Capture screen interface + */ + void captureScreen(const std::function& afterCaptured, const std::string& filename); + + /** + * The implementation of capturing screen + */ + void onCaptureScreen(const std::function& afterCaptured, const std::string& filename); +} + NS_CC_END #endif // __SUPPORT_CC_UTILS_H__ - diff --git a/cocos/cocos2d.h b/cocos/cocos2d.h index 41b3a0a89f..98cb708b91 100644 --- a/cocos/cocos2d.h +++ b/cocos/cocos2d.h @@ -60,6 +60,7 @@ THE SOFTWARE. #include "base/CCUserDefault.h" #include "base/CCIMEDelegate.h" #include "base/CCIMEDispatcher.h" +#include "base/ccUtils.h" // EventDispatcher #include "base/CCEventType.h" diff --git a/tests/cpp-tests/Classes/NewRendererTest/NewRendererTest.cpp b/tests/cpp-tests/Classes/NewRendererTest/NewRendererTest.cpp index 34e1d1b8fe..89444b1a7a 100644 --- a/tests/cpp-tests/Classes/NewRendererTest/NewRendererTest.cpp +++ b/tests/cpp-tests/Classes/NewRendererTest/NewRendererTest.cpp @@ -609,7 +609,7 @@ void CaptureScreenTest::onCaptured(Ref*) Director::getInstance()->getTextureCache()->removeTextureForKey(_filename); removeChildByTag(childTag); _filename = "CaptureScreenTest.png"; - Director::getInstance()->captureScreen(CC_CALLBACK_2(CaptureScreenTest::afterCaptured, this), _filename); + Utilities::captureScreen(CC_CALLBACK_2(CaptureScreenTest::afterCaptured, this), _filename); } void CaptureScreenTest::afterCaptured(bool succeed, const std::string& outputFile)