diff --git a/cocos/2d/ccUtils.cpp b/cocos/2d/ccUtils.cpp index c6058d30b2..5d97c3226b 100644 --- a/cocos/2d/ccUtils.cpp +++ b/cocos/2d/ccUtils.cpp @@ -22,13 +22,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ****************************************************************************/ -#include "CCGLView.h" #include "2d/ccUtils.h" -#include "2d/platform/CCImage.h" -#include "2d/platform/CCFileUtils.h" -#include "base/ccMacros.h" -#include "base/CCDirector.h" -#include "renderer/CCRenderer.h" NS_CC_BEGIN @@ -42,111 +36,5 @@ int ccNextPOT(int x) x = x | (x >>16); return x + 1; } - -UtilsHelper* UtilsHelper::s_sharedHelper = nullptr; - -UtilsHelper::UtilsHelper() -{ -} - -UtilsHelper::~UtilsHelper() -{ -} - -UtilsHelper* UtilsHelper::getInstance() -{ - if (!s_sharedHelper) - { - s_sharedHelper = new UtilsHelper(); - } - return s_sharedHelper; -} - -void UtilsHelper::destroyInstance() -{ - CC_SAFE_DELETE(s_sharedHelper); -} - - -void UtilsHelper::captureScreen(const std::function& afterCaptured, const std::string& filename, const Rect& rect) -{ - _captureScreen.init(std::numeric_limits::max()); - _captureScreen.func = CC_CALLBACK_0(UtilsHelper::onCaptureScreen, this, afterCaptured, filename, rect); - Director::getInstance()->getRenderer()->addCommand(&_captureScreen); -} - -void UtilsHelper::onCaptureScreen(const std::function& afterCaptured, const std::string& filename, const Rect& rect) -{ - // Generally the user specifiy the rect with design resolution, thus we have to convert it - // into a significant value which is metered by pixel. - Size frameSize = Director::getInstance()->getOpenGLView()->getFrameSize(); - int originx = 0; - int originy = 0; - int width = (int)frameSize.width; - int height = (int)frameSize.height; - bool succeed = false; - std::string outputFile = ""; - - if (!rect.equals(Rect::ZERO)) - { - originx = (int)rect.origin.x; - originy = (int)rect.origin.y; - width = (int)rect.size.width * Director::getInstance()->getOpenGLView()->getScaleX(); - height = (int)rect.size.height * Director::getInstance()->getOpenGLView()->getScaleY(); - - auto clip = [](int in, int min, int max) { return std::max(std::min(in, max), min); }; - originx = clip(originx, 0, (int)frameSize.width); - originy = clip(originy, 0, (int)frameSize.height); - width = clip(width, 0, frameSize.width - originx); - height = clip(height, 0, frameSize.height - originy); - } - - do - { - GLubyte* buffer = new GLubyte[width * height * 4]; - if (!buffer) - { - break; - } - - glPixelStorei(GL_PACK_ALIGNMENT, 1); - glReadPixels(originx, originy, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer); - - GLubyte* flippedBuffer = new GLubyte[width * height * 4]; - if (!flippedBuffer) - { - break; - } - - for (int row = 0; row < height; ++row) - { - memcpy(flippedBuffer + (height - row - 1) * width * 4, buffer + row * width * 4, width * 4); - } - CC_SAFE_DELETE_ARRAY(buffer); - - Image* image = new Image(); - if (image) - { - image->initWithRawData(flippedBuffer, width * height * 4, width, height, 8); - if (FileUtils::getInstance()->isAbsolutePath(filename)) - { - outputFile = filename; - } - else - { - outputFile = FileUtils::getInstance()->getWritablePath() + filename; - } - image->saveToFile(outputFile); - succeed = true; - } - CC_SAFE_DELETE_ARRAY(flippedBuffer); - CC_SAFE_DELETE(image); - }while(0); - - if (afterCaptured) - { - afterCaptured(succeed, outputFile); - } -} NS_CC_END \ No newline at end of file diff --git a/cocos/2d/ccUtils.h b/cocos/2d/ccUtils.h index 1e25c312f7..8f6e4ba746 100644 --- a/cocos/2d/ccUtils.h +++ b/cocos/2d/ccUtils.h @@ -24,9 +24,7 @@ THE SOFTWARE. ****************************************************************************/ #ifndef __SUPPORT_CC_UTILS_H__ #define __SUPPORT_CC_UTILS_H__ -#include -#include "math/CCGeometry.h" -#include "renderer/CCCustomCommand.h" +#include "base/ccMacros.h" /** @file ccUtils.h Misc free functions @@ -48,27 +46,6 @@ Examples: */ int ccNextPOT(int value); - -class CC_DLL UtilsHelper -{ -public: - static UtilsHelper* getInstance(); - static void destroyInstance(); - - /** capture screen */ - void captureScreen(const std::function& afterCaptued, const std::string& filename, const Rect& rect = Rect::ZERO); - -protected: - UtilsHelper(); - virtual ~UtilsHelper(); - - void onCaptureScreen(const std::function& afterCaptued, const std::string& fileanme, const Rect& rect); - - - static UtilsHelper* s_sharedHelper; - - CustomCommand _captureScreen; -}; NS_CC_END diff --git a/cocos/base/CCDirector.cpp b/cocos/base/CCDirector.cpp index 01f2d392d6..f13d31097b 100644 --- a/cocos/base/CCDirector.cpp +++ b/cocos/base/CCDirector.cpp @@ -1216,6 +1216,87 @@ void Director::setEventDispatcher(EventDispatcher* dispatcher) } } +void Director::captureScreen(const std::function& afterCaptured, const std::string& filename, const Rect& rect) +{ + _captureScreen.init(std::numeric_limits::max()); + _captureScreen.func = CC_CALLBACK_0(Director::onCaptureScreen, this, afterCaptured, filename, rect); + Director::getInstance()->getRenderer()->addCommand(&_captureScreen); +} + +void Director::onCaptureScreen(const std::function& afterCaptured, const std::string& filename, const Rect& rect) +{ + // Generally the user specifiy the rect with design resolution, thus we have to convert it + // into a significant value which is metered by pixel. + Size frameSize = Director::getInstance()->getOpenGLView()->getFrameSize(); + int originx = 0; + int originy = 0; + int width = (int)frameSize.width; + int height = (int)frameSize.height; + bool succeed = false; + std::string outputFile = ""; + + if (!rect.equals(Rect::ZERO)) + { + originx = (int)rect.origin.x; + originy = (int)rect.origin.y; + width = (int)rect.size.width * Director::getInstance()->getOpenGLView()->getScaleX(); + height = (int)rect.size.height * Director::getInstance()->getOpenGLView()->getScaleY(); + + auto clip = [](int in, int min, int max) { return std::max(std::min(in, max), min); }; + originx = clip(originx, 0, (int)frameSize.width); + originy = clip(originy, 0, (int)frameSize.height); + width = clip(width, 0, frameSize.width - originx); + height = clip(height, 0, frameSize.height - originy); + } + + do + { + GLubyte* buffer = new GLubyte[width * height * 4]; + if (!buffer) + { + break; + } + + glPixelStorei(GL_PACK_ALIGNMENT, 1); + glReadPixels(originx, originy, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer); + + GLubyte* flippedBuffer = new GLubyte[width * height * 4]; + if (!flippedBuffer) + { + break; + } + + for (int row = 0; row < height; ++row) + { + memcpy(flippedBuffer + (height - row - 1) * width * 4, buffer + row * width * 4, width * 4); + } + CC_SAFE_DELETE_ARRAY(buffer); + + Image* image = new Image(); + if (image) + { + image->initWithRawData(flippedBuffer, width * height * 4, width, height, 8); + if (FileUtils::getInstance()->isAbsolutePath(filename)) + { + outputFile = filename; + } + else + { + outputFile = FileUtils::getInstance()->getWritablePath() + filename; + } + image->saveToFile(outputFile); + succeed = true; + } + CC_SAFE_DELETE_ARRAY(flippedBuffer); + CC_SAFE_DELETE(image); + }while(0); + + if (afterCaptured) + { + afterCaptured(succeed, outputFile); + } +} + /*************************************************** * implementation of DisplayLinkDirector **************************************************/ diff --git a/cocos/base/CCDirector.h b/cocos/base/CCDirector.h index 6a69f8c2c1..32d4144e07 100644 --- a/cocos/base/CCDirector.h +++ b/cocos/base/CCDirector.h @@ -38,6 +38,7 @@ THE SOFTWARE. #include "2d/CCLabelAtlas.h" #include #include "math/CCMath.h" +#include "renderer/CCCustomCommand.h" NS_CC_BEGIN @@ -403,6 +404,11 @@ public: * get Frame Rate */ float getFrameRate() const { return _frameRate; } + + /** + * Capture screen + */ + void captureScreen(const std::function& afterCaptued, const std::string& filename, const Rect& rect = Rect::ZERO); protected: void purgeDirector(); @@ -421,6 +427,9 @@ protected: //textureCache creation or release void initTextureCache(); void destroyTextureCache(); + + /* Captrue screen implementation */ + void onCaptureScreen(const std::function& afterCaptued, const std::string& fileanme, const Rect& rect); /** Scheduler associated with this director @since v2.0 @@ -502,6 +511,9 @@ protected: /* Renderer for the Director */ Renderer *_renderer; + + /* Capture screen command */ + CustomCommand _captureScreen; #if (CC_TARGET_PLATFORM != CC_PLATFORM_WINRT) /* Console for the director */ diff --git a/tests/cpp-tests/Classes/NewRendererTest/NewRendererTest.cpp b/tests/cpp-tests/Classes/NewRendererTest/NewRendererTest.cpp index 329fffd83a..4b4f63e1cd 100644 --- a/tests/cpp-tests/Classes/NewRendererTest/NewRendererTest.cpp +++ b/tests/cpp-tests/Classes/NewRendererTest/NewRendererTest.cpp @@ -611,7 +611,7 @@ void CaptureScreenTest::onCaptured(Ref*, const Rect& rect) Director::getInstance()->getTextureCache()->removeTextureForKey(_filename); removeChildByTag(ChildTag); _filename = "CaptureScreenTest.png"; - UtilsHelper::getInstance()->captureScreen(CC_CALLBACK_2(CaptureScreenTest::afterCaptured, this), _filename, rect); + Director::getInstance()->captureScreen(CC_CALLBACK_2(CaptureScreenTest::afterCaptured, this), _filename, rect); } void CaptureScreenTest::afterCaptured(bool succeed, const std::string& outputFile)