From dfb016dde3c0589d2247590f602e658c5d55f832 Mon Sep 17 00:00:00 2001 From: vision Date: Wed, 14 May 2014 16:25:47 +0800 Subject: [PATCH] move the utility from Renderer to UtilsHelper --- cocos/2d/ccUtils.cpp | 116 +++++++++++++++++- cocos/2d/ccUtils.h | 28 ++++- cocos/cocos2d.h | 1 + cocos/renderer/CCRenderer.cpp | 80 ------------ cocos/renderer/CCRenderer.h | 8 -- .../NewRendererTest/NewRendererTest.cpp | 9 +- 6 files changed, 144 insertions(+), 98 deletions(-) diff --git a/cocos/2d/ccUtils.cpp b/cocos/2d/ccUtils.cpp index 456cb573a3..c6058d30b2 100644 --- a/cocos/2d/ccUtils.cpp +++ b/cocos/2d/ccUtils.cpp @@ -22,9 +22,15 @@ 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" -namespace cocos2d { +NS_CC_BEGIN int ccNextPOT(int x) { @@ -36,5 +42,111 @@ int ccNextPOT(int x) x = x | (x >>16); return x + 1; } + +UtilsHelper* UtilsHelper::s_sharedHelper = nullptr; -} \ No newline at end of file +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 a30cc72288..1e25c312f7 100644 --- a/cocos/2d/ccUtils.h +++ b/cocos/2d/ccUtils.h @@ -24,12 +24,15 @@ THE SOFTWARE. ****************************************************************************/ #ifndef __SUPPORT_CC_UTILS_H__ #define __SUPPORT_CC_UTILS_H__ +#include +#include "math/CCGeometry.h" +#include "renderer/CCCustomCommand.h" /** @file ccUtils.h Misc free functions */ -namespace cocos2d { +NS_CC_BEGIN /* ccNextPOT function is licensed under the same license that is used in Texture2D.m. */ @@ -45,7 +48,28 @@ 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 #endif // __SUPPORT_CC_UTILS_H__ diff --git a/cocos/cocos2d.h b/cocos/cocos2d.h index 143678e877..1d1bb563f7 100644 --- a/cocos/cocos2d.h +++ b/cocos/cocos2d.h @@ -236,6 +236,7 @@ THE SOFTWARE. #include "2d/ccUTF8.h" #include "2d/CCUserDefault.h" #include "2d/CCVertex.h" +#include "2d/ccUtils.h" // text_input_node #include "2d/CCIMEDelegate.h" diff --git a/cocos/renderer/CCRenderer.cpp b/cocos/renderer/CCRenderer.cpp index 42753bea86..5246f6efb5 100644 --- a/cocos/renderer/CCRenderer.cpp +++ b/cocos/renderer/CCRenderer.cpp @@ -37,9 +37,6 @@ #include "base/CCEventDispatcher.h" #include "base/CCEventListenerCustom.h" #include "base/CCEventType.h" -#include "2d/platform/CCImage.h" -#include "2d/platform/CCFileUtils.h" -#include "CCGLView.h" NS_CC_BEGIN @@ -538,81 +535,4 @@ bool Renderer::checkVisibility(const Matrix &transform, const Size &size) return ret; } -void Renderer::captureScreen(const std::function& afterCaptured, const std::string& filename, const Rect& rect) -{ - _captureScreen.init(std::numeric_limits::max()); - _captureScreen.func = CC_CALLBACK_0(Renderer::onCaptureScreen, this, afterCaptured, filename, true, rect); - addCommand(&_captureScreen); -} - -void Renderer::onCaptureScreen(const std::function& afterCaptured, const std::string& filename, bool flipped, 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) - { - CC_SAFE_DELETE_ARRAY(buffer); - break; - } - - glPixelStorei(GL_PACK_ALIGNMENT, 1); - glReadPixels(originx, originy, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer); - - if (flipped) - { - GLubyte* flippedBuffer = new GLubyte[width * height * 4]; - if (!flippedBuffer) - { - CC_SAFE_DELETE(flippedBuffer); - break; - } - - for (int row = 0; row < height; ++row) - { - memcpy(flippedBuffer + (height - row - 1) * width * 4, buffer + row * width * 4, width * 4); - } - memcpy(buffer, flippedBuffer, width * height * 4); - CC_SAFE_DELETE_ARRAY(flippedBuffer); - } - - Image* image = new Image(); - if (image) - { - image->initWithRawData(buffer, width * height * 4, width, height, 8); - CC_SAFE_DELETE_ARRAY(buffer); - outputFile = FileUtils::getInstance()->getWritablePath() + filename; - image->saveToFile(outputFile); - succeed = true; - } - CC_SAFE_DELETE(image); - }while(0); - - afterCaptured(succeed, outputFile); -} - NS_CC_END diff --git a/cocos/renderer/CCRenderer.h b/cocos/renderer/CCRenderer.h index 2157d84b6d..94c9da4794 100644 --- a/cocos/renderer/CCRenderer.h +++ b/cocos/renderer/CCRenderer.h @@ -28,7 +28,6 @@ #include "base/CCPlatformMacros.h" #include "CCRenderCommand.h" -#include "CCCustomCommand.h" #include "renderer/CCGLProgram.h" #include "CCGL.h" #include @@ -118,9 +117,6 @@ public: /** returns whether or not a rectangle is visible or not */ bool checkVisibility(const Matrix& transform, const Size& size); - /** capture screen */ - void captureScreen(const std::function& afterCaptued, const std::string& filename, const Rect& rect = Rect::ZERO); - protected: void setupIndices(); @@ -139,8 +135,6 @@ protected: void convertToWorldCoordinates(V3F_C4B_T2F_Quad* quads, ssize_t quantity, const Matrix& modelView); - void onCaptureScreen(const std::function& afterCaptued, const std::string& fileanme, bool flipped, const Rect& rect); - std::stack _commandGroupStack; std::vector _renderGroups; @@ -165,8 +159,6 @@ protected: bool _isRendering; GroupCommandManager* _groupCommandManager; - - CustomCommand _captureScreen; #if CC_ENABLE_CACHE_TEXTURE_DATA EventListenerCustom* _cacheTextureListener; diff --git a/tests/cpp-tests/Classes/NewRendererTest/NewRendererTest.cpp b/tests/cpp-tests/Classes/NewRendererTest/NewRendererTest.cpp index 17761b3f38..329fffd83a 100644 --- a/tests/cpp-tests/Classes/NewRendererTest/NewRendererTest.cpp +++ b/tests/cpp-tests/Classes/NewRendererTest/NewRendererTest.cpp @@ -611,10 +611,7 @@ void CaptureScreenTest::onCaptured(Ref*, const Rect& rect) Director::getInstance()->getTextureCache()->removeTextureForKey(_filename); removeChildByTag(ChildTag); _filename = "CaptureScreenTest.png"; - Director::getInstance()->getRenderer()->captureScreen( - CC_CALLBACK_2(CaptureScreenTest::afterCaptured, this), - _filename, - rect); + UtilsHelper::getInstance()->captureScreen(CC_CALLBACK_2(CaptureScreenTest::afterCaptured, this), _filename, rect); } void CaptureScreenTest::afterCaptured(bool succeed, const std::string& outputFile) @@ -630,6 +627,6 @@ void CaptureScreenTest::afterCaptured(bool succeed, const std::string& outputFil } else { - log("Something went wrong"); + log("Captrue screen failed."); } -} \ No newline at end of file +}